refactor: use defineModel

This commit is contained in:
axolotle 2024-08-22 00:45:07 +02:00
parent 2ba27d6c33
commit d2cf9522b1
13 changed files with 43 additions and 57 deletions

View file

@ -19,7 +19,6 @@ import { isDisplayComponent, isWritableComponent } from '@/types/form'
const props = withDefaults(
defineProps<{
id?: string
modelValue?: MV
fields?: FFD
validations?: FormValidation<MV>
submitText?: string
@ -31,7 +30,6 @@ const props = withDefaults(
}>(),
{
id: 'ynh-form',
modelValue: undefined,
fields: undefined,
validations: undefined,
submitText: undefined,
@ -71,6 +69,8 @@ const slots = defineSlots<
}
>()
const modelValue = defineModel<MV>()
const { t } = useI18n()
const globalErrorFeedback = computed(() => {
@ -94,7 +94,7 @@ const sections = computed(() => {
function onModelUpdate(key: keyof MV, value: MV[keyof MV]) {
emit('update:modelValue', {
...props.modelValue!,
...modelValue.value!,
[key]: value,
})
}
@ -119,7 +119,7 @@ const Fields = createReusableTemplate<{
<FormField
v-if="!field.readonly"
v-bind="field"
:model-value="props.modelValue![k]"
:model-value="modelValue![k]"
:validation="props.validations?.form[k]"
@update:model-value="onModelUpdate(k, $event)"
>
@ -130,7 +130,7 @@ const Fields = createReusableTemplate<{
<FormFieldReadonly
v-else
v-bind="field"
:model-value="props.modelValue![k]"
:model-value="modelValue![k]"
/>
</slot>
<slot

View file

@ -36,7 +36,6 @@ const props = withDefaults(defineProps<FormFieldProps<C, MV>>(), {
prepend: undefined,
rules: undefined,
modelValue: undefined,
validation: undefined,
})
@ -51,7 +50,7 @@ const slots = defineSlots<{
description?: any
}>()
const model = defineModel<MV>()
const modelValue = defineModel<MV>()
const attrs = useAttrs()
const { t } = useI18n()
@ -137,7 +136,6 @@ const [DefineTemplate, ReuseTemplate] = createReusableTemplate<{
v-bind="{
...(props.cProps ?? ({} as ItemComponentToItemProps[C])),
ariaDescribedby,
modelValue: props.modelValue,
state,
validation: validation,
}"
@ -146,7 +144,7 @@ const [DefineTemplate, ReuseTemplate] = createReusableTemplate<{
<Component
v-bind="props.cProps"
:is="component"
v-model="model"
v-model="modelValue"
:aria-describedby="ariaDescribedby"
:state="state"
:validation="validation"

View file

@ -44,13 +44,12 @@ const props = withDefaults(
defaultValue: undefined,
addBtnText: undefined,
modelValue: undefined,
validation: undefined,
},
)
const emit = defineEmits<{
'update:modelValue': [value: MV]
'update:modelValue': [modelValue: MV]
}>()
const slots = defineSlots<{
@ -62,6 +61,8 @@ const slots = defineSlots<{
description?: () => any
}>()
const modelValue = defineModel<MV>()
const { t } = useI18n()
const attrs = useAttrs()
@ -104,7 +105,7 @@ const error = computed(() => {
const subProps = computed<FormFieldProps<C, ArrInnerType<MV>>[]>(() => {
return (
props.modelValue?.map((modelValue: ArrInnerType<MV>, i) => {
modelValue.value?.map((modelValue: ArrInnerType<MV>, i) => {
return {
cProps: {
...(props.cProps ?? ({} as ItemComponentToItemProps[C])),
@ -143,22 +144,22 @@ const errorMessage = computed(() => {
})
function addElement() {
const value = [...(props?.modelValue || []), props.defaultValue!()] as MV
const value = [...(modelValue.value || []), props.defaultValue!()] as MV
emit('update:modelValue', value)
// FIXME: Focus newly inserted form item
}
function removeElement(index: number) {
if (!props.modelValue) return
const value = [...props.modelValue] as MV
if (!modelValue.value) return
const value = [...modelValue.value] as MV
value.splice(index, 1)
emit('update:modelValue', value)
}
function updateElement(index: number, newValue: ArrInnerType<MV>) {
if (!props.modelValue) return
const value = [...props.modelValue] as MV
if (!modelValue.value) return
const value = [...modelValue.value] as MV
value.splice(index, 1, newValue)
emit('update:modelValue', value)
}

View file

@ -19,10 +19,11 @@ defineOptions({
const props = withDefaults(defineProps<FormFieldReadonlyProps<C, MV>>(), {
id: undefined,
modelValue: undefined,
cols: () => ({ md: 4, lg: 3 }),
})
const modelValue = defineModel<MV>()
const { t } = useI18n()
const cols = computed<Cols>(() => ({
@ -32,7 +33,7 @@ const cols = computed<Cols>(() => ({
}))
const text = computed(() => {
return parseValue(props.modelValue)
return parseValue(modelValue.value)
})
function parseValue(value: any) {

View file

@ -9,11 +9,9 @@ const props = withDefaults(
defineProps<{
items?: T[] | null
itemsName: string | null
modelValue?: string
}>(),
{
items: undefined,
modelValue: undefined,
},
)

View file

@ -14,7 +14,6 @@ withDefaults(
touchKey: undefined,
type: 'email',
modelValue: undefined,
state: undefined,
validation: undefined,
ariaDescribedby: undefined,

View file

@ -12,23 +12,18 @@ withDefaults(
labels: () => ({ true: 'yes', false: 'no' }),
ariaDescribedby: undefined,
modelValue: undefined,
state: undefined,
validation: undefined,
},
)
defineEmits<{
'update:modelValue': [value: boolean]
}>()
const model = defineModel<boolean>()
const modelValue = defineModel<boolean>()
</script>
<template>
<BFormCheckbox
:id="id"
v-model="model"
v-model="modelValue"
:name="name"
:aria-describedby="ariaDescribedby"
:state="state"

View file

@ -21,7 +21,6 @@ const props = withDefaults(
dropPlaceholder: undefined,
ariaDescribedby: undefined,
modelValue: () => ({ file: null }),
state: undefined,
validation: undefined,
},
@ -31,13 +30,17 @@ const emit = defineEmits<{
'update:modelValue': [value: FileModelValue]
}>()
const modelValue = defineModel<FileModelValue>({
default: () => ({ file: null }),
})
const touch = inject(ValidationTouchSymbol)
const inputElem = ref<InstanceType<typeof BFormFile> | null>(null)
const placeholder = computed(() => {
return props.modelValue.file === null
return modelValue.value.file === null
? props.placeholder
: props.modelValue.file.name
: modelValue.value.file.name
})
function onInput(file: File | File[] | null) {

View file

@ -20,18 +20,12 @@ const props = withDefaults(
type: 'text',
ariaDescribedby: undefined,
modelValue: undefined,
state: undefined,
validation: undefined,
},
)
defineEmits<{
'update:modelValue': [value: string | number | null]
}>()
const touch = inject(ValidationTouchSymbol)
const model = defineModel<string | number | null>({
const modelValue = defineModel<string | number | null>({
set(value) {
if (props.type === 'number' && typeof value === 'string') {
if (value === '') return ''
@ -41,6 +35,8 @@ const model = defineModel<string | number | null>({
},
})
const touch = inject(ValidationTouchSymbol)
const autocomplete = computed(() => {
const typeToAutocomplete = {
password: 'new-password',
@ -64,7 +60,7 @@ const fromValidation = computed(() => {
<BFormInput
:id="id"
v-bind="fromValidation"
v-model="model"
v-model="modelValue"
:name="name"
:placeholder="placeholder"
:autocomplete="autocomplete"

View file

@ -15,7 +15,6 @@ const props = withDefaults(
// options: undefined,
ariaDescribedby: undefined,
modelValue: undefined,
state: undefined,
validation: undefined,
},
@ -23,7 +22,7 @@ const props = withDefaults(
const touch = inject(ValidationTouchSymbol)
const model = defineModel<string[]>()
const modelValue = defineModel<string[]>()
const required = computed(() => 'required' in (props?.validation ?? {}))
@ -34,7 +33,7 @@ const required = computed(() => 'required' in (props?.validation ?? {}))
<template>
<BFormTags
:id="id"
v-model="model"
v-model="modelValue"
:name="name"
:placeholder="placeholder"
:limit="limit"

View file

@ -30,18 +30,17 @@ const props = withDefaults(
tagIcon: undefined,
ariaDescribedby: undefined,
modelValue: undefined,
state: undefined,
validation: undefined,
},
)
const emit = defineEmits<{
'update:modelValue': [value: string[]]
'tag-update': [value: TagUpdateArgs]
}>()
const model = defineModel<string[]>()
const modelValue = defineModel<string[]>()
const searchElem = ref<InstanceType<typeof BDropdown> | null>(null)
const dropdownElem = ref<InstanceType<typeof BFormInput> | null>(null)
@ -55,7 +54,7 @@ const availableOptions = computed(() => {
return props.options.filter((opt) => {
const tag = typeof opt === 'string' ? opt : opt.value
let filterIn =
model.value?.indexOf(tag) === -1 &&
modelValue.value?.indexOf(tag) === -1 &&
!(props.disabledItems?.includes(tag) ?? false)
if (filterIn && criteria.value) {
filterIn = tag.toLowerCase().indexOf(criteria.value) > -1
@ -120,7 +119,7 @@ function onDropdownKeydown(e: KeyboardEvent) {
<BFormTags
v-bind="$attrs"
:id="id"
v-model="model"
v-model="modelValue"
:name="name"
:aria-describedby="ariaDescribedby"
:state="state"

View file

@ -24,7 +24,7 @@ defineEmits<{
'update:modelValue': [value: string | null]
}>()
const model = defineModel<string>()
const modelValue = defineModel<string>()
const touch = inject(ValidationTouchSymbol)
@ -34,7 +34,7 @@ const required = computed(() => 'required' in (props?.validation ?? {}))
<template>
<BFormTextarea
:id="id"
v-model="model"
v-model="modelValue"
:name="name"
:placeholder="placeholder"
:aria-describedby="ariaDescribedby"

View file

@ -55,7 +55,6 @@ type BaseWritableItemProps = {
export type BaseItemComputedProps<MV extends any = any> = {
ariaDescribedby?: string | string[]
modelValue?: MV
state?: StateValidation
validation?: BaseValidation
}
@ -238,8 +237,7 @@ type FormFieldRules<MV extends any> = MV extends object
: ValidationArgs<MV | Partial<MV>>
: ValidationRuleCollection<MV>
type BaseFormFieldComputedProps<MV extends any = any> = {
modelValue?: MV
type BaseFormFieldComputedProps = {
validation?: BaseValidation
}
@ -295,14 +293,13 @@ export type FormFieldProps<
C extends AnyWritableComponents,
MV extends any,
> = Omit<FormField<C, MV>, 'hr' | 'visible' | 'readonly'> &
BaseFormFieldComputedProps<MV>
BaseFormFieldComputedProps
// BaseFormFieldComputedProps<MV>
export type FormFieldReadonlyProps<
C extends AnyWritableComponents,
MV extends any,
> = Omit<FormFieldReadonly<C>, 'hr' | 'visible' | 'readonly' | 'rules'> & {
modelValue?: MV
}
> = Omit<FormFieldReadonly<C>, 'hr' | 'visible' | 'readonly' | 'rules'>
export type FormFieldDict<T extends Obj = Obj> = {
[k in keyof T | string]: k extends keyof T