Skip to content

Commit 065005b

Browse files
* fixing ts issues
* fixing some quirks and issues with button field
1 parent 16faccd commit 065005b

File tree

4 files changed

+55
-27
lines changed

4 files changed

+55
-27
lines changed

src/plugin/VStepperForm.vue

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@
103103
</v-stepper-window>
104104

105105
<v-stepper-actions v-if="!settings.hideActions">
106-
107106
<template #next>
108107
<v-btn
109108
v-if="!lastPage"
@@ -129,11 +128,6 @@
129128
/>
130129
</template>
131130
</v-stepper-actions>
132-
133-
<v-row>
134-
<v-col>
135-
</v-col>
136-
</v-row>
137131
</Form>
138132
</template>
139133
</v-stepper>

src/plugin/components/fields/VSFButtonField/VSFButtonField.vue

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<template>
2+
{{ fieldWidth }}
23
<Field
34
v-slot="{ errorMessage, validate }"
45
v-model="modelValue"
@@ -36,24 +37,25 @@
3637
}"
3738
>
3839
<template #default>
39-
<!-- {{ fieldVariant }} -->
40-
<!-- {{ modelValue === option.value ? 'solo' : fieldVariant }} -->
4140
<v-btn
4241
v-bind="boundSettings"
4342
:id="getId(option, key)"
4443
:active="isActive(option.value)"
4544
:appendIcon="getIcon(option, 'appendIcon')"
4645
class="text-none"
4746
:class="{
47+
...buttonClass,
4848
[`${field.selectedClass}`]: isActive(option.value),
4949
}"
50+
:color="option?.color || field?.color || settings?.color"
51+
:density="(buttonDensity as VBtn['density'])"
5052
:height="fieldHeight"
5153
:icon="getIcon(option, 'icon')"
52-
:minWidth="field?.minWidth || '100px'"
54+
:minWidth="fieldMinWidth || (option?.icon ? 'auto' : '100px')"
5355
:prependIcon="getIcon(option, 'prependIcon')"
5456
: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);"
5759
@keydown.space.prevent="onActions(validate, 'click', option.value)"
5860
@mousedown="onFocus(option.value)"
5961
@mouseleave="onFocus(null)"
@@ -100,12 +102,13 @@ import { Field } from 'vee-validate';
100102
import { VMessages } from 'vuetify/components';
101103
import type { Option, VSFButtonFieldProps } from './index';
102104
import type { FieldLabelProps } from '../../shared/FieldLabel.vue';
105+
import type { VBtn } from 'vuetify/components';
103106
import { useBindingSettings } from '../../../composables/bindings';
104107
import { useOnActions } from '../../../composables/validation';
105108
import FieldLabel from '../../shared/FieldLabel.vue';
106109
107110
const emit = defineEmits(['validate']);
108-
const modelValue = defineModel<any>();
111+
const modelValue = defineModel<unknown>();
109112
const props = defineProps<VSFButtonFieldProps>();
110113
111114
const { field } = props;
@@ -131,20 +134,24 @@ if (modelValue?.value == null) {
131134
const currentValue = ref(modelValue.value);
132135
133136
// ------------------------- 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> {
135138
if (currentValue.value === value && (fieldValidateOn.value === 'change' || fieldValidateOn.value === 'input')) {
136139
return;
137140
}
138141
139142
if (!field?.disabled && value) {
140143
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);
144149
}
145150
else {
146-
Array(modelValue.value).push(value);
151+
localModelValue.push(String(value));
147152
}
153+
154+
modelValue.value = localModelValue;
148155
}
149156
else {
150157
modelValue.value = value;
@@ -165,13 +172,22 @@ async function onActions(validate: FieldValidateResult, action: ValidateAction,
165172
});
166173
}
167174
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+
});
168184
169185
// -------------------------------------------------- Bound Settings //
170186
const bindSettings = computed(() => ({
171187
...field,
172188
border: field?.border ? `${field?.color} ${field?.border}` : undefined,
173189
color: field.color || settings.value?.color,
174-
density: field.density || settings.value?.density,
190+
density: field?.density ?? settings.value?.density as VBtn['density'],
175191
hideDetails: field.hideDetails || settings.value?.hideDetails,
176192
multiple: undefined,
177193
}));
@@ -203,7 +219,7 @@ function getId(option: { id?: string; }, key: string | number) {
203219
204220
205221
// -------------------------------------------------- Properties //
206-
const densityHeight = {
222+
const densityValues = {
207223
comfortable: '48px',
208224
compact: '40px',
209225
default: '56px',
@@ -213,21 +229,28 @@ const densityHeight = {
213229
214230
const fieldDensity = computed(() => field?.density ?? settings.value?.density);
215231
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;
219239
}
220240
241+
return fieldDensity.value ? densityValues[fieldDensity.value] : densityValues['default'];
242+
}
221243
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'));
224247
225248
const isActive = (val: string | number): boolean | undefined => {
226249
if (!modelValue.value) {
227250
return undefined;
228251
}
229252
230-
return modelValue.value === val || Array(modelValue.value).includes(val);
253+
return modelValue.value === val || (modelValue.value as string[]).includes(val as string);
231254
};
232255
233256
const fieldVariant = ref<VSFButtonFieldProps['field']['variant']>(field?.variant);
@@ -318,6 +341,16 @@ const buttonFieldContainerClass = computed(() => {
318341
};
319342
});
320343
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+
321354
// -------------------------------------------------- Focused //
322355
const isFocused = shallowRef(null);
323356

src/plugin/components/fields/VSFButtonField/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type { VBtn } from 'vuetify/components';
99

1010
export interface Option {
1111
appendIcon?: VBtn['appendIcon'];
12+
color?: VBtn['color'];
1213
icon?: VBtn['icon'];
1314
id?: Field['id'];
1415
label: Field['label'];

src/plugin/types/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ declare global {
5353
* VTextField
5454
* VTextarea
5555
*/
56-
export type GlobalDensity = null | 'default' | 'comfortable' | 'compact';
56+
export type GlobalDensity = null | 'default' | 'comfortable' | 'compact' | 'expanded' | 'oversized';
5757
export type GlobalVariant = 'filled' | 'underlined' | 'outlined' | 'plain' | 'solo' | 'solo-inverted' | 'solo-filled';
5858

5959

@@ -126,7 +126,7 @@ export interface Field {
126126
class?: string;
127127
color?: Props['color'];
128128
columns?: Props['fieldColumns'];
129-
density?: Props['density'];
129+
density?: GlobalDensity;
130130
disabled?: boolean | ((value: any) => boolean);
131131
error?: boolean;
132132
errorMessages?: string | string[];

0 commit comments

Comments
 (0)