11<template >
22 <Field
3- v-slot =" { errorMessage, validate }"
3+ v-slot =" { errorMessage, validate, handleInput }"
44 v-model =" modelValue"
55 :name =" field.name"
66 type =" text"
4949 }"
5050 :color =" option?.color || field?.color || settings?.color"
5151 :density =" fieldDensity"
52- :height =" fieldHeight "
52+ :height =" getHeight(option) "
5353 :icon =" getIcon(option, 'icon')"
54- :minWidth =" fieldMinWidth || (option?.icon ? 'auto' : '100px')"
54+ :maxWidth =" getMaxWidth(option)"
55+ :minWidth =" getMinWidth(option)"
5556 :prependIcon =" getIcon(option, 'prependIcon')"
5657 :variant =" getVariant(option.value)"
57- :width =" fieldWidth "
58- @click.prevent =" onActions(validate, 'click', option.value);"
59- @keydown.space.prevent =" onActions(validate, 'click', option.value)"
58+ :width =" getWidth(option) "
59+ @click.prevent =" onActions(validate, 'click', option.value); handleInput(modelValue) "
60+ @keydown.space.prevent =" onActions(validate, 'click', option.value); handleInput(modelValue) "
6061 @mousedown =" onFocus(option.value)"
6162 @mouseleave =" onFocus(null)"
6263 @mouseup =" onFocus(null)"
6768 >
6869 <span
6970 class =" vsf-button-field__btn-label"
71+ :class =" getLabelClass(option)"
7072 v-html =" option.label"
7173 ></span >
7274 </template >
@@ -141,7 +143,7 @@ async function onActions(validate: FieldValidateResult, action: ValidateAction,
141143
142144 if (! field ?.disabled && value ) {
143145 if (field ?.multiple ) {
144- const localModelValue = modelValue .value as string [];
146+ const localModelValue = modelValue .value == null ? [] : modelValue . value as string [];
145147
146148 if (localModelValue != null && localModelValue .includes (String (value ))) {
147149 const index = localModelValue .indexOf (String (value ));
@@ -210,6 +212,8 @@ function getId(option: { id?: string; }, key: string | number) {
210212
211213
212214// -------------------------------------------------- Properties //
215+
216+ // ------------------------- Density & Sizes //
213217const densityValues = {
214218 comfortable: ' 48px' ,
215219 compact: ' 40px' ,
@@ -220,21 +224,57 @@ const densityValues = {
220224
221225const fieldDensity = computed <VBtn [' density' ]>(() => (field ?.density ?? settings .value ?.density ) as VBtn [' density' ]);
222226
223- function useSize(val : string ) {
227+ function getDensityValue(): string {
228+ return fieldDensity .value ? densityValues [fieldDensity .value ] : densityValues [' default' ];
229+ }
230+
231+ function getMinWidth(option : Option ): string | number | undefined {
232+ const minWidth = option ?.minWidth ?? field ?.minWidth ;
224233
225- if (field ?.[ val ] ) {
226- return field [ val ] as string ;
234+ if (minWidth != null ) {
235+ return minWidth as string ;
227236 }
228- else if (val === ' minWidth' ) {
229- return field [val ] || undefined ;
237+
238+ if (option ?.icon ) {
239+ return getDensityValue ();
230240 }
231241
232- return fieldDensity .value ? densityValues [fieldDensity .value ] : densityValues [' default' ];
242+ return ' 100px' ;
243+ }
244+
245+ function getMaxWidth(option : Option ): string | number | undefined {
246+ const maxWidth = option ?.maxWidth ?? field ?.maxWidth ;
247+
248+ if (maxWidth != null ) {
249+ return maxWidth as string ;
250+ }
251+
252+ return undefined ;
233253}
234254
235- const fieldHeight = computed (() => useSize (' height' ));
236- const fieldWidth = computed (() => useSize (' width' ));
237- const fieldMinWidth = computed (() => useSize (' minWidth' ));
255+ function getWidth(option : Option ): string | number | undefined {
256+ const width = option ?.width ?? field ?.width ;
257+
258+ if (width != null ) {
259+ return width as string ;
260+ }
261+
262+ if (option ?.icon ) {
263+ return getDensityValue ();
264+ }
265+
266+ return ' fit-content' ;
267+ }
268+
269+ function getHeight(option : Option ): string | number | undefined {
270+ const height = option ?.height ?? field ?.height ;
271+
272+ if (height != null ) {
273+ return height as string ;
274+ }
275+
276+ return getDensityValue ();
277+ }
238278
239279const isActive = (val : string | number ): boolean | undefined => {
240280 if (! modelValue .value ) {
@@ -244,6 +284,7 @@ const isActive = (val: string | number): boolean | undefined => {
244284 return modelValue .value === val || (modelValue .value as string []).includes (val as string );
245285};
246286
287+ // ------------------------- Variants //
247288const fieldVariant = ref <VSFButtonFieldProps [' field' ][' variant' ]>(field ?.variant );
248289
249290function getVariant(val : string | number ): VSFButtonFieldProps [' field' ][' variant' ] {
@@ -317,6 +358,7 @@ const buttontextcolor = ref('rgb(var(--v-theme-on-surface))');
317358// -------------------------------------------------- Classes //
318359const itemGroupClass = computed (() => {
319360 return {
361+ [` align-${field ?.align } ` ]: field ?.align != null ,
320362 ' d-flex' : true ,
321363 ' flex-column' : field ?.block ,
322364 [` ga-${gap .value } ` ]: ! containsSizeUnit (gap .value ),
@@ -344,6 +386,16 @@ const buttonClass = computed(() => {
344386 return {};
345387});
346388
389+ const getLabelClass = (option : Option ): object => {
390+ const isActiveOption = isActive (option .value );
391+ const optionVariant = getVariant (option .value );
392+ const useBgColor = isActiveOption || optionVariant === ' flat' || optionVariant === ' elevated' ;
393+
394+ return {
395+ [` bg-${option ?.color } ` ]: useBgColor ,
396+ };
397+ };
398+
347399// -------------------------------------------------- Focused //
348400const isFocused = shallowRef (null );
349401
0 commit comments