Fixed #6418 - New Float Label Variants

pull/6424/head
Cagatay Civici 2024-09-17 13:26:24 +03:00
parent edae389d35
commit 9c4f33b0c2
13 changed files with 378 additions and 18 deletions

View File

@ -97,7 +97,8 @@
},
{
"name": "FloatLabel",
"to": "/floatlabel"
"to": "/floatlabel",
"badge": "NEW"
},
{
"name": "IconField",

View File

@ -4,7 +4,7 @@
</DocSectionText>
<div class="card flex justify-center">
<FloatLabel>
<InputText id="username" v-model="value" />
<InputText id="username" v-model="value" autocomplete="off" />
<label for="username">Username</label>
</FloatLabel>
</div>

View File

@ -0,0 +1,113 @@
<template>
<DocSectionText v-bind="$attrs">
<p>When the form element is invalid, the label is also highlighted.</p>
</DocSectionText>
<div class="card flex justify-center items-center gap-4">
<FloatLabel>
<InputText id="value1" v-model="value1" autocomplete="off" :invalid="!value1" />
<label for="value1">Username</label>
</FloatLabel>
<FloatLabel variant="in">
<InputText id="value2" v-model="value2" autocomplete="off" :invalid="!value2" />
<label for="value2">Username</label>
</FloatLabel>
<FloatLabel variant="on">
<InputText id="value3" v-model="value3" autocomplete="off" :invalid="!value3" />
<label for="value3">Username</label>
</FloatLabel>
</div>
<DocSectionCode :code="code" />
</template>
<script>
export default {
data() {
return {
value1: '',
value2: '',
value3: '',
code: {
basic: `
<FloatLabel>
<InputText id="value1" v-model="value1" :invalid="!value1" />
<label for="value1">Username</label>
</FloatLabel>
<FloatLabel variant="in">
<InputText id="value2" v-model="value2" :invalid="!value2" />
<label for="value2">Username</label>
</FloatLabel>
<FloatLabel variant="on">
<InputText id="value3" v-model="value3" :invalid="!value3" />
<label for="value3">Username</label>
</FloatLabel>
`,
options: `
<template>
<div class="card flex justify-center items-center gap-4">
<FloatLabel>
<InputText id="value1" v-model="value1" :invalid="!value1" />
<label for="value1">Username</label>
</FloatLabel>
<FloatLabel variant="in">
<InputText id="value2" v-model="value2" :invalid="!value2" />
<label for="value2">Username</label>
</FloatLabel>
<FloatLabel variant="on">
<InputText id="value3" v-model="value3" :invalid="!value3" />
<label for="value3">Username</label>
</FloatLabel>
</div>
</template>
<script setup>
export default {
data() {
return {
value1: '',
value2: '',
value3: ''
}
}
}
<\/script>
`,
composition: `
<template>
<div class="card flex justify-center items-center gap-4">
<FloatLabel>
<InputText id="value1" v-model="value1" :invalid="!value1" />
<label for="value1">Username</label>
</FloatLabel>
<FloatLabel variant="in">
<InputText id="value2" v-model="value2" :invalid="!value2" />
<label for="value2">Username</label>
</FloatLabel>
<FloatLabel variant="on">
<InputText id="value3" v-model="value3" :invalid="!value3" />
<label for="value3">Username</label>
</FloatLabel>
</div>
</template>
<script setup>
import { ref } from 'vue';
const value1 = ref(null);
const value2 = ref(null);
const value3 = ref(null);
<\/script>
`
}
};
}
};
</script>

View File

@ -0,0 +1,90 @@
<template>
<DocSectionText v-bind="$attrs">
<p>The <i>variant</i> property defines the position of the label. Default value is <i>over</i>, whereas <i>in</i> and <i>on</i> are the alternatives.</p>
</DocSectionText>
<div class="card flex flex-wrap justify-center gap-4">
<FloatLabel variant="in">
<InputText id="inlabel" v-model="value1" autocomplete="off" />
<label for="inlabel">In Label</label>
</FloatLabel>
<FloatLabel variant="on">
<InputText id="onlabel" v-model="value2" autocomplete="off" />
<label for="onlabel">On Label</label>
</FloatLabel>
</div>
<DocSectionCode :code="code" />
</template>
<script>
export default {
data() {
return {
value1: null,
value2: null,
code: {
basic: `
<FloatLabel variant="in">
<InputText id="inlabel" v-model="value1" />
<label for="inlabel">In Label</label>
</FloatLabel>
<FloatLabel variant="on">
<InputText id="onlabel" v-model="value2" />
<label for="onlabel">On Label</label>
</FloatLabel>
`,
options: `
<template>
<div class="card flex flex-wrap justify-center gap-4">
<FloatLabel variant="in">
<InputText id="inlabel" v-model="value1" />
<label for="inlabel">In Label</label>
</FloatLabel>
<FloatLabel variant="on">
<InputText id="onlabel" v-model="value2" />
<label for="onlabel">On Label</label>
</FloatLabel>
</div>
</template>
<script setup>
export default {
data() {
return {
value1: null,
value2: null
}
}
}
<\/script>
`,
composition: `
<template>
<div class="card flex flex-wrap justify-center gap-4">
<FloatLabel variant="in">
<InputText id="inlabel" v-model="value1" />
<label for="inlabel">In Label</label>
</FloatLabel>
<FloatLabel variant="on">
<InputText id="onlabel" v-model="value2" />
<label for="onlabel">On Label</label>
</FloatLabel>
</div>
</template>
<script setup>
import { ref } from 'vue';
const value1 = ref(null);
const value2 = ref(null);
<\/script>
`
}
};
}
};
</script>

View File

@ -1,13 +1,15 @@
<template>
<DocComponent title="Vue Float Label" header="FloatLabel" description="FloatLabel appears on top of the input field when focused." :componentDocs="docs" :ptTabComponent="ptComponent" :apiDocs="['FloatLabel']" :themingDocs="themingDoc" />
<DocComponent title="Vue Float Label" header="FloatLabel" description="FloatLabel visually integrates a label with its form element." :componentDocs="docs" :ptTabComponent="ptComponent" :apiDocs="['FloatLabel']" :themingDocs="themingDoc" />
</template>
<script>
import AccessibilityDoc from '@/doc/floatlabel/AccessibilityDoc.vue';
import BasicDoc from '@/doc/floatlabel/BasicDoc.vue';
import ImportDoc from '@/doc/floatlabel/ImportDoc.vue';
import InvalidDoc from '@/doc/floatlabel/InvalidDoc.vue';
import PTComponent from '@/doc/floatlabel/pt/index.vue';
import ThemingDoc from '@/doc/floatlabel/theming/index.vue';
import VariantsDoc from '@/doc/floatlabel/VariantsDoc.vue';
export default {
data() {
@ -23,6 +25,16 @@ export default {
label: 'Basic',
component: BasicDoc
},
{
id: 'variants',
label: 'Variants',
component: VariantsDoc
},
{
id: 'invalid',
label: 'Invalid',
component: InvalidDoc
},
{
id: 'accessibility',
label: 'Accessibility',

View File

@ -5,6 +5,12 @@ import FloatLabelStyle from 'primevue/floatlabel/style';
export default {
name: 'BaseFloatLabel',
extends: BaseComponent,
props: {
variant: {
type: String,
default: 'over'
}
},
style: FloatLabelStyle,
provide() {
return {

View File

@ -14,7 +14,8 @@ const theme = ({ dt }) => `
transition-property: all;
transition-timing-function: ease;
line-height: 1;
left: 0.75rem;
font-weight: ${dt('floatlabel.font.weight')};
left: ${dt('floatlabel.position.x')};
color: ${dt('floatlabel.color')};
transition-duration: ${dt('floatlabel.transition.duration')};
}
@ -23,6 +24,10 @@ const theme = ({ dt }) => `
top: 1rem;
}
.p-floatlabel:has(.p-invalid) label {
color: ${dt('floatlabel.invalid.color')};
}
.p-floatlabel:has(input:focus) label,
.p-floatlabel:has(input.p-filled) label,
.p-floatlabel:has(input:-webkit-autofill) label,
@ -30,8 +35,22 @@ const theme = ({ dt }) => `
.p-floatlabel:has(textarea.p-filled) label,
.p-floatlabel:has(.p-inputwrapper-focus) label,
.p-floatlabel:has(.p-inputwrapper-filled) label {
top: -.75rem;
font-size: 12px;
top: ${dt('floatlabel.focus.top')};
margin-top: 0;
font-size: ${dt('floatlabel.focus.font.size')};
font-weight: ${dt('floatlabel.label.focus.font.weight')};
}
.p-floatlabel:has(input.p-filled) label,
.p-floatlabel:has(textarea.p-filled) label,
.p-floatlabel:has(.p-inputwrapper-filled) label {
color: ${dt('floatlabel.active.color')};
}
.p-floatlabel:has(input:focus) label ,
.p-floatlabel:has(input:-webkit-autofill) label,
.p-floatlabel:has(textarea:focus) label ,
.p-floatlabel:has(.p-inputwrapper-focus) label {
color: ${dt('floatlabel.focus.color')};
}
@ -51,13 +70,48 @@ const theme = ({ dt }) => `
transition-timing-function: ease;
}
.p-floatlabel > .p-invalid + label {
color: ${dt('floatlabel.invalid.color')};
.p-floatlabel-in .p-inputtext {
padding-top: ${dt('floatlabel.in.input.padding.top')};
}
.p-floatlabel-in:has(input:focus) label,
.p-floatlabel-in:has(input.p-filled) label,
.p-floatlabel-in:has(input:-webkit-autofill) label,
.p-floatlabel-in:has(textarea:focus) label,
.p-floatlabel-in:has(textarea.p-filled) label,
.p-floatlabel-in:has(.p-inputwrapper-focus) label,
.p-floatlabel-in:has(.p-inputwrapper-filled) label {
top: ${dt('floatlabel.in.focus.top')};
}
.p-floatlabel-on .p-inputtext {
padding-top: ${dt('floatlabel.on.input.padding.top')};
padding-bottom: ${dt('floatlabel.on.input.padding.bottom')};
}
.p-floatlabel-on:has(input:focus) label,
.p-floatlabel-on:has(input.p-filled) label,
.p-floatlabel-on:has(input:-webkit-autofill) label,
.p-floatlabel-on:has(textarea:focus) label,
.p-floatlabel-on:has(textarea.p-filled) label,
.p-floatlabel-on:has(.p-inputwrapper-focus) label,
.p-floatlabel-on:has(.p-inputwrapper-filled) label {
top: 0;
transform: translateY(-50%);
background: ${dt('floatlabel.on.focus.background')};
padding: ${dt('floatlabel.on.focus.padding')};
}
`;
const classes = {
root: 'p-floatlabel'
root: ({ instance, props }) => [
'p-floatlabel',
{
'p-floatlabel-over': props.variant === 'over',
'p-floatlabel-on': props.variant === 'on',
'p-floatlabel-in': props.variant === 'in'
}
]
};
export default BaseStyle.extend({

View File

@ -2,7 +2,33 @@ export default {
root: {
color: '{form.field.float.label.color}',
focusColor: '{form.field.float.label.focus.color}',
activeColor: '{form.field.float.label.active.color}',
invalidColor: '{form.field.float.label.invalid.color}',
transitionDuration: '0.2s'
transitionDuration: '0.2s',
positionX: '{form.field.padding.x}',
fontWeight: '500',
focus: {
top: '-1.25rem',
fontSize: '0.875rem',
fontWeight: '400'
}
},
in: {
input: {
paddingTop: '1.5rem'
},
focus: {
top: '{form.field.padding.y}'
}
},
on: {
input: {
paddingTop: '1rem',
paddingBottom: '1rem'
},
focus: {
background: '{form.field.background}',
padding: '0 0.125rem'
}
}
};

View File

@ -258,7 +258,8 @@ export default {
disabledColor: '{surface.500}',
placeholderColor: '{surface.500}',
floatLabelColor: '{surface.500}',
floatLabelFocusColor: '{surface.500}',
floatLabelFocusColor: '{primary.600}',
floatLabelActiveColor: '{surface.500}',
floatLabelInvalidColor: '{red.400}',
iconColor: '{surface.400}',
shadow: '0 0 #0000, 0 0 #0000, 0 1px 2px 0 rgba(18, 18, 23, 0.05)'
@ -380,7 +381,8 @@ export default {
disabledColor: '{surface.400}',
placeholderColor: '{surface.400}',
floatLabelColor: '{surface.400}',
floatLabelFocusColor: '{surface.400}',
floatLabelFocusColor: '{primary.color}',
floatLabelActiveColor: '{surface.400}',
floatLabelInvalidColor: '{red.300}',
iconColor: '{surface.400}',
shadow: '0 0 #0000, 0 0 #0000, 0 1px 2px 0 rgba(18, 18, 23, 0.05)'

View File

@ -2,7 +2,33 @@ export default {
root: {
color: '{form.field.float.label.color}',
focusColor: '{form.field.float.label.focus.color}',
activeColor: '{form.field.float.label.active.color}',
invalidColor: '{form.field.float.label.invalid.color}',
transitionDuration: '0.2s'
transitionDuration: '0.2s',
positionX: '{form.field.padding.x}',
fontWeight: '500',
focus: {
top: '-1.25rem',
fontSize: '0.875rem',
fontWeight: '400'
}
},
in: {
input: {
paddingTop: '1.875rem'
},
focus: {
top: '{form.field.padding.y}'
}
},
on: {
input: {
paddingTop: '1.25rem',
paddingBottom: '1.25rem'
},
focus: {
background: '{form.field.background}',
padding: '0 0.125rem'
}
}
};

View File

@ -260,7 +260,8 @@ export default {
disabledColor: '{surface.500}',
placeholderColor: '{surface.500}',
floatLabelColor: '{surface.500}',
floatLabelFocusColor: '{surface.500}',
floatLabelFocusColor: '{primary.color}',
floatLabelActiveColor: '{surface.500}',
floatLabelInvalidColor: '{red.400}',
iconColor: '{surface.500}',
shadow: 'none'
@ -385,7 +386,8 @@ export default {
disabledColor: '{surface.400}',
placeholderColor: '{surface.400}',
floatLabelColor: '{surface.400}',
floatLabelFocusColor: '{surface.400}',
floatLabelFocusColor: '{primary.color}',
floatLabelActiveColor: '{surface.400}',
floatLabelInvalidColor: '{red.300}',
iconColor: '{surface.400}',
shadow: 'none'

View File

@ -2,7 +2,33 @@ export default {
root: {
color: '{form.field.float.label.color}',
focusColor: '{form.field.float.label.focus.color}',
activeColor: '{form.field.float.label.active.color}',
invalidColor: '{form.field.float.label.invalid.color}',
transitionDuration: '0.2s'
transitionDuration: '0.2s',
positionX: '{form.field.padding.x}',
fontWeight: '500',
focus: {
top: '-1.25rem',
fontSize: '0.875rem',
fontWeight: '400'
}
},
in: {
input: {
paddingTop: '1.5rem'
},
focus: {
top: '{form.field.padding.y}'
}
},
on: {
input: {
paddingTop: '1rem',
paddingBottom: '1rem'
},
focus: {
background: '{form.field.background}',
padding: '0 0.125rem'
}
}
};

View File

@ -258,7 +258,8 @@ export default {
disabledColor: '{surface.600}',
placeholderColor: '{surface.600}',
floatLabelColor: '{surface.600}',
floatLabelFocusColor: '{surface.600}',
floatLabelFocusColor: '{primary.color}',
floatLabelActiveColor: '{surface.600}',
floatLabelInvalidColor: '{red.500}',
iconColor: '{surface.900}',
shadow: 'none'
@ -380,7 +381,8 @@ export default {
disabledColor: '{surface.400}',
placeholderColor: '{surface.400}',
floatLabelColor: '{surface.400}',
floatLabelFocusColor: '{surface.400}',
floatLabelFocusColor: '{primary.color}',
floatLabelActiveColor: '{surface.400}',
floatLabelInvalidColor: '{red.400}',
iconColor: '{surface.0}',
shadow: 'none'