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", "name": "FloatLabel",
"to": "/floatlabel" "to": "/floatlabel",
"badge": "NEW"
}, },
{ {
"name": "IconField", "name": "IconField",

View File

@ -4,7 +4,7 @@
</DocSectionText> </DocSectionText>
<div class="card flex justify-center"> <div class="card flex justify-center">
<FloatLabel> <FloatLabel>
<InputText id="username" v-model="value" /> <InputText id="username" v-model="value" autocomplete="off" />
<label for="username">Username</label> <label for="username">Username</label>
</FloatLabel> </FloatLabel>
</div> </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> <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> </template>
<script> <script>
import AccessibilityDoc from '@/doc/floatlabel/AccessibilityDoc.vue'; import AccessibilityDoc from '@/doc/floatlabel/AccessibilityDoc.vue';
import BasicDoc from '@/doc/floatlabel/BasicDoc.vue'; import BasicDoc from '@/doc/floatlabel/BasicDoc.vue';
import ImportDoc from '@/doc/floatlabel/ImportDoc.vue'; import ImportDoc from '@/doc/floatlabel/ImportDoc.vue';
import InvalidDoc from '@/doc/floatlabel/InvalidDoc.vue';
import PTComponent from '@/doc/floatlabel/pt/index.vue'; import PTComponent from '@/doc/floatlabel/pt/index.vue';
import ThemingDoc from '@/doc/floatlabel/theming/index.vue'; import ThemingDoc from '@/doc/floatlabel/theming/index.vue';
import VariantsDoc from '@/doc/floatlabel/VariantsDoc.vue';
export default { export default {
data() { data() {
@ -23,6 +25,16 @@ export default {
label: 'Basic', label: 'Basic',
component: BasicDoc component: BasicDoc
}, },
{
id: 'variants',
label: 'Variants',
component: VariantsDoc
},
{
id: 'invalid',
label: 'Invalid',
component: InvalidDoc
},
{ {
id: 'accessibility', id: 'accessibility',
label: 'Accessibility', label: 'Accessibility',

View File

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

View File

@ -14,7 +14,8 @@ const theme = ({ dt }) => `
transition-property: all; transition-property: all;
transition-timing-function: ease; transition-timing-function: ease;
line-height: 1; line-height: 1;
left: 0.75rem; font-weight: ${dt('floatlabel.font.weight')};
left: ${dt('floatlabel.position.x')};
color: ${dt('floatlabel.color')}; color: ${dt('floatlabel.color')};
transition-duration: ${dt('floatlabel.transition.duration')}; transition-duration: ${dt('floatlabel.transition.duration')};
} }
@ -23,6 +24,10 @@ const theme = ({ dt }) => `
top: 1rem; top: 1rem;
} }
.p-floatlabel:has(.p-invalid) label {
color: ${dt('floatlabel.invalid.color')};
}
.p-floatlabel:has(input:focus) label, .p-floatlabel:has(input:focus) label,
.p-floatlabel:has(input.p-filled) label, .p-floatlabel:has(input.p-filled) label,
.p-floatlabel:has(input:-webkit-autofill) 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(textarea.p-filled) label,
.p-floatlabel:has(.p-inputwrapper-focus) label, .p-floatlabel:has(.p-inputwrapper-focus) label,
.p-floatlabel:has(.p-inputwrapper-filled) label { .p-floatlabel:has(.p-inputwrapper-filled) label {
top: -.75rem; top: ${dt('floatlabel.focus.top')};
font-size: 12px; 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')}; color: ${dt('floatlabel.focus.color')};
} }
@ -51,13 +70,48 @@ const theme = ({ dt }) => `
transition-timing-function: ease; transition-timing-function: ease;
} }
.p-floatlabel > .p-invalid + label { .p-floatlabel-in .p-inputtext {
color: ${dt('floatlabel.invalid.color')}; 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 = { 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({ export default BaseStyle.extend({

View File

@ -2,7 +2,33 @@ export default {
root: { root: {
color: '{form.field.float.label.color}', color: '{form.field.float.label.color}',
focusColor: '{form.field.float.label.focus.color}', focusColor: '{form.field.float.label.focus.color}',
activeColor: '{form.field.float.label.active.color}',
invalidColor: '{form.field.float.label.invalid.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}', disabledColor: '{surface.500}',
placeholderColor: '{surface.500}', placeholderColor: '{surface.500}',
floatLabelColor: '{surface.500}', floatLabelColor: '{surface.500}',
floatLabelFocusColor: '{surface.500}', floatLabelFocusColor: '{primary.600}',
floatLabelActiveColor: '{surface.500}',
floatLabelInvalidColor: '{red.400}', floatLabelInvalidColor: '{red.400}',
iconColor: '{surface.400}', iconColor: '{surface.400}',
shadow: '0 0 #0000, 0 0 #0000, 0 1px 2px 0 rgba(18, 18, 23, 0.05)' 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}', disabledColor: '{surface.400}',
placeholderColor: '{surface.400}', placeholderColor: '{surface.400}',
floatLabelColor: '{surface.400}', floatLabelColor: '{surface.400}',
floatLabelFocusColor: '{surface.400}', floatLabelFocusColor: '{primary.color}',
floatLabelActiveColor: '{surface.400}',
floatLabelInvalidColor: '{red.300}', floatLabelInvalidColor: '{red.300}',
iconColor: '{surface.400}', iconColor: '{surface.400}',
shadow: '0 0 #0000, 0 0 #0000, 0 1px 2px 0 rgba(18, 18, 23, 0.05)' 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: { root: {
color: '{form.field.float.label.color}', color: '{form.field.float.label.color}',
focusColor: '{form.field.float.label.focus.color}', focusColor: '{form.field.float.label.focus.color}',
activeColor: '{form.field.float.label.active.color}',
invalidColor: '{form.field.float.label.invalid.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}', disabledColor: '{surface.500}',
placeholderColor: '{surface.500}', placeholderColor: '{surface.500}',
floatLabelColor: '{surface.500}', floatLabelColor: '{surface.500}',
floatLabelFocusColor: '{surface.500}', floatLabelFocusColor: '{primary.color}',
floatLabelActiveColor: '{surface.500}',
floatLabelInvalidColor: '{red.400}', floatLabelInvalidColor: '{red.400}',
iconColor: '{surface.500}', iconColor: '{surface.500}',
shadow: 'none' shadow: 'none'
@ -385,7 +386,8 @@ export default {
disabledColor: '{surface.400}', disabledColor: '{surface.400}',
placeholderColor: '{surface.400}', placeholderColor: '{surface.400}',
floatLabelColor: '{surface.400}', floatLabelColor: '{surface.400}',
floatLabelFocusColor: '{surface.400}', floatLabelFocusColor: '{primary.color}',
floatLabelActiveColor: '{surface.400}',
floatLabelInvalidColor: '{red.300}', floatLabelInvalidColor: '{red.300}',
iconColor: '{surface.400}', iconColor: '{surface.400}',
shadow: 'none' shadow: 'none'

View File

@ -2,7 +2,33 @@ export default {
root: { root: {
color: '{form.field.float.label.color}', color: '{form.field.float.label.color}',
focusColor: '{form.field.float.label.focus.color}', focusColor: '{form.field.float.label.focus.color}',
activeColor: '{form.field.float.label.active.color}',
invalidColor: '{form.field.float.label.invalid.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}', disabledColor: '{surface.600}',
placeholderColor: '{surface.600}', placeholderColor: '{surface.600}',
floatLabelColor: '{surface.600}', floatLabelColor: '{surface.600}',
floatLabelFocusColor: '{surface.600}', floatLabelFocusColor: '{primary.color}',
floatLabelActiveColor: '{surface.600}',
floatLabelInvalidColor: '{red.500}', floatLabelInvalidColor: '{red.500}',
iconColor: '{surface.900}', iconColor: '{surface.900}',
shadow: 'none' shadow: 'none'
@ -380,7 +381,8 @@ export default {
disabledColor: '{surface.400}', disabledColor: '{surface.400}',
placeholderColor: '{surface.400}', placeholderColor: '{surface.400}',
floatLabelColor: '{surface.400}', floatLabelColor: '{surface.400}',
floatLabelFocusColor: '{surface.400}', floatLabelFocusColor: '{primary.color}',
floatLabelActiveColor: '{surface.400}',
floatLabelInvalidColor: '{red.400}', floatLabelInvalidColor: '{red.400}',
iconColor: '{surface.0}', iconColor: '{surface.0}',
shadow: 'none' shadow: 'none'