1
1
<template >
2
+ {{ fieldWidth }}
2
3
<Field
3
4
v-slot =" { errorMessage, validate }"
4
5
v-model =" modelValue"
36
37
}"
37
38
>
38
39
<template #default >
39
- <!-- {{ fieldVariant }} -->
40
- <!-- {{ modelValue === option.value ? 'solo' : fieldVariant }} -->
41
40
<v-btn
42
41
v-bind =" boundSettings"
43
42
:id =" getId(option, key)"
44
43
:active =" isActive(option.value)"
45
44
:appendIcon =" getIcon(option, 'appendIcon')"
46
45
class =" text-none"
47
46
:class =" {
47
+ ...buttonClass,
48
48
[`${field.selectedClass}`]: isActive(option.value),
49
49
}"
50
+ :color =" option?.color || field?.color || settings?.color"
51
+ :density =" (buttonDensity as VBtn['density'])"
50
52
:height =" fieldHeight"
51
53
:icon =" getIcon(option, 'icon')"
52
- :minWidth =" field?.minWidth || ' 100px'"
54
+ :minWidth =" fieldMinWidth || (option?.icon ? 'auto' : ' 100px') "
53
55
:prependIcon =" getIcon(option, 'prependIcon')"
54
56
:variant =" getVariant(option.value)"
55
- :width =" field?.width || '100px' "
56
- @click =" onActions(validate, 'click', option.value);"
57
+ :width =" fieldWidth "
58
+ @click.prevent =" onActions(validate, 'click', option.value);"
57
59
@keydown.space.prevent =" onActions(validate, 'click', option.value)"
58
60
@mousedown =" onFocus(option.value)"
59
61
@mouseleave =" onFocus(null)"
@@ -100,12 +102,13 @@ import { Field } from 'vee-validate';
100
102
import { VMessages } from ' vuetify/components' ;
101
103
import type { Option , VSFButtonFieldProps } from ' ./index' ;
102
104
import type { FieldLabelProps } from ' ../../shared/FieldLabel.vue' ;
105
+ import type { VBtn } from ' vuetify/components' ;
103
106
import { useBindingSettings } from ' ../../../composables/bindings' ;
104
107
import { useOnActions } from ' ../../../composables/validation' ;
105
108
import FieldLabel from ' ../../shared/FieldLabel.vue' ;
106
109
107
110
const emit = defineEmits ([' validate' ]);
108
- const modelValue = defineModel <any >();
111
+ const modelValue = defineModel <unknown >();
109
112
const props = defineProps <VSFButtonFieldProps >();
110
113
111
114
const { field } = props ;
@@ -131,20 +134,24 @@ if (modelValue?.value == null) {
131
134
const currentValue = ref (modelValue .value );
132
135
133
136
// ------------------------- Validate On Actions //
134
- async function onActions(validate : FieldValidateResult , action : ValidateAction , value ? : unknown ): Promise <void > {
137
+ async function onActions(validate : FieldValidateResult , action : ValidateAction , value ? : string | number ): Promise <void > {
135
138
if (currentValue .value === value && (fieldValidateOn .value === ' change' || fieldValidateOn .value === ' input' )) {
136
139
return ;
137
140
}
138
141
139
142
if (! field ?.disabled && value ) {
140
143
if (field ?.multiple ) {
141
- if (Array (modelValue .value ).includes (value )) {
142
- const index = Array (modelValue .value ).indexOf (value );
143
- Array (modelValue .value ).splice (index , 1 );
144
+ const localModelValue = modelValue .value as string [];
145
+
146
+ if (localModelValue != null && localModelValue .includes (String (value ))) {
147
+ const index = localModelValue .indexOf (String (value ));
148
+ localModelValue .splice (index , 1 );
144
149
}
145
150
else {
146
- Array ( modelValue . value ). push (value );
151
+ localModelValue . push (String ( value ) );
147
152
}
153
+
154
+ modelValue .value = localModelValue ;
148
155
}
149
156
else {
150
157
modelValue .value = value ;
@@ -165,13 +172,22 @@ async function onActions(validate: FieldValidateResult, action: ValidateAction,
165
172
});
166
173
}
167
174
175
+ const buttonDensity = computed <VSFButtonFieldProps [' field' ][' density' ]>(() => {
176
+ const density = field ?.density ?? settings .value ?.density ;
177
+
178
+ if ([' comfortable' , ' compact' , ' default' ].includes (density as string )) {
179
+ return density ;
180
+ }
181
+
182
+ return ;
183
+ });
168
184
169
185
// -------------------------------------------------- Bound Settings //
170
186
const bindSettings = computed (() => ({
171
187
... field ,
172
188
border: field ?.border ? ` ${field ?.color } ${field ?.border } ` : undefined ,
173
189
color: field .color || settings .value ?.color ,
174
- density: field .density || settings .value ?.density ,
190
+ density: field ? .density ?? settings .value ?.density as VBtn [ ' density ' ] ,
175
191
hideDetails: field .hideDetails || settings .value ?.hideDetails ,
176
192
multiple: undefined ,
177
193
}));
@@ -203,7 +219,7 @@ function getId(option: { id?: string; }, key: string | number) {
203
219
204
220
205
221
// -------------------------------------------------- Properties //
206
- const densityHeight = {
222
+ const densityValues = {
207
223
comfortable: ' 48px' ,
208
224
compact: ' 40px' ,
209
225
default: ' 56px' ,
@@ -213,21 +229,28 @@ const densityHeight = {
213
229
214
230
const fieldDensity = computed (() => field ?.density ?? settings .value ?.density );
215
231
216
- const fieldHeight = computed (() => {
217
- if (field ?.height ) {
218
- return field ?.height ;
232
+ function useSize(val : string ) {
233
+
234
+ if (field ?.[val ]) {
235
+ return field [val ] as string ;
236
+ }
237
+ else if (val === ' minWidth' ) {
238
+ return field [val ] || undefined ;
219
239
}
220
240
241
+ return fieldDensity .value ? densityValues [fieldDensity .value ] : densityValues [' default' ];
242
+ }
221
243
222
- return fieldDensity .value ? densityHeight [fieldDensity .value ] : densityHeight [' default' ];
223
- });
244
+ const fieldHeight = computed (() => useSize (' height' ));
245
+ const fieldWidth = computed (() => useSize (' width' ));
246
+ const fieldMinWidth = computed (() => useSize (' minWidth' ));
224
247
225
248
const isActive = (val : string | number ): boolean | undefined => {
226
249
if (! modelValue .value ) {
227
250
return undefined ;
228
251
}
229
252
230
- return modelValue .value === val || Array (modelValue .value ).includes (val );
253
+ return modelValue .value === val || (modelValue .value as string [] ).includes (val as string );
231
254
};
232
255
233
256
const fieldVariant = ref <VSFButtonFieldProps [' field' ][' variant' ]>(field ?.variant );
@@ -318,6 +341,16 @@ const buttonFieldContainerClass = computed(() => {
318
341
};
319
342
});
320
343
344
+ const buttonClass = computed (() => {
345
+ if (fieldDensity .value === ' expanded' || fieldDensity .value === ' oversized' ) {
346
+ return {
347
+ [` v-btn--density-${fieldDensity .value } ` ]: true ,
348
+ };
349
+ }
350
+
351
+ return {};
352
+ });
353
+
321
354
// -------------------------------------------------- Focused //
322
355
const isFocused = shallowRef (null );
323
356
0 commit comments