mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
refactor: AdressItem typing
This commit is contained in:
parent
f9ddae3237
commit
0414f82d53
3 changed files with 79 additions and 39 deletions
|
@ -1,35 +1,36 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
type CustomEmail = {
|
import type {
|
||||||
localPart: string | null
|
AdressItemProps,
|
||||||
separator: string
|
AdressModelValue,
|
||||||
domain: string | null
|
BaseItemComputedProps,
|
||||||
}
|
} from '@/types/form'
|
||||||
|
|
||||||
const props = withDefaults(
|
withDefaults(
|
||||||
defineProps<{
|
defineProps<AdressItemProps & BaseItemComputedProps<AdressModelValue>>(),
|
||||||
modelValue: CustomEmail
|
|
||||||
choices: string[]
|
|
||||||
placeholder?: string
|
|
||||||
id?: string
|
|
||||||
state?: false | null
|
|
||||||
type?: string
|
|
||||||
}>(),
|
|
||||||
{
|
{
|
||||||
placeholder: undefined,
|
|
||||||
id: undefined,
|
id: undefined,
|
||||||
state: undefined,
|
name: undefined,
|
||||||
|
placeholder: undefined,
|
||||||
|
touchKey: undefined,
|
||||||
type: 'email',
|
type: 'email',
|
||||||
|
|
||||||
|
modelValue: undefined,
|
||||||
|
state: undefined,
|
||||||
|
validation: undefined,
|
||||||
|
ariaDescribedby: undefined,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
'update:modelValue': [value: CustomEmail]
|
'update:modelValue': [value: AdressModelValue]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
function onInput(key: 'localPart' | 'domain', modelValue: string | null) {
|
const model = defineModel<AdressModelValue>({ required: true })
|
||||||
|
|
||||||
|
function onInput(key: 'localPart' | 'domain', value: string | null) {
|
||||||
emit('update:modelValue', {
|
emit('update:modelValue', {
|
||||||
...props.modelValue,
|
...model.value,
|
||||||
[key]: modelValue,
|
[key]: value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -37,32 +38,38 @@ function onInput(key: 'localPart' | 'domain', modelValue: string | null) {
|
||||||
<template>
|
<template>
|
||||||
<BInputGroup v-bind="$attrs">
|
<BInputGroup v-bind="$attrs">
|
||||||
<InputItem
|
<InputItem
|
||||||
:id="id"
|
:id="`${id}-local-part`"
|
||||||
:modelValue="modelValue.localPart"
|
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
:state="state"
|
touch-key="localPart"
|
||||||
:aria-describedby="id + 'local-part-desc'"
|
:model-value="model.localPart"
|
||||||
@update:modelValue="onInput('localPart', $event)"
|
:aria-describedby="`${id}-local-part-desc`"
|
||||||
|
:state="validation?.localPart?.$error ? false : null"
|
||||||
|
:validation="validation?.localPart"
|
||||||
|
@update:model-value="onInput('localPart', $event as string)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<BInputGroupText>{{ modelValue.separator }}</BInputGroupText>
|
<BInputGroupText>{{ modelValue.separator }}</BInputGroupText>
|
||||||
|
|
||||||
<SelectItem
|
<SelectItem
|
||||||
:modelValue="modelValue.domain"
|
:id="`${id}-domain`"
|
||||||
|
touch-key="domain"
|
||||||
|
:model-value="modelValue.domain"
|
||||||
:choices="choices"
|
:choices="choices"
|
||||||
:aria-describedby="id + 'domain-desc'"
|
:aria-describedby="`${id}-domain-desc`"
|
||||||
@update:modelValue="onInput('domain', $event)"
|
:state="validation?.domain?.$error ? false : null"
|
||||||
/>
|
:validation="validation?.domain"
|
||||||
|
@update:model-value="onInput('domain', $event)"
|
||||||
<span
|
|
||||||
class="visually-hidden"
|
|
||||||
:id="id + 'local-part-desc'"
|
|
||||||
v-t="'address.local_part_description.' + type"
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
class="visually-hidden"
|
|
||||||
:id="id + 'domain-desc'"
|
|
||||||
v-t="'address.domain_description.' + type"
|
|
||||||
/>
|
/>
|
||||||
</BInputGroup>
|
</BInputGroup>
|
||||||
|
|
||||||
|
<span
|
||||||
|
:id="`${id}-local-part-desc`"
|
||||||
|
v-t="'address.local_part_description.' + type"
|
||||||
|
class="visually-hidden"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
:id="`${id}-domain-desc`"
|
||||||
|
v-t="'address.domain_description.' + type"
|
||||||
|
class="visually-hidden"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
5
app/src/composables/form.ts
Normal file
5
app/src/composables/form.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import type { InjectionKey } from 'vue'
|
||||||
|
|
||||||
|
export const ValidationTouchSymbol = Symbol() as InjectionKey<
|
||||||
|
(key?: string) => void
|
||||||
|
>
|
28
app/src/types/form.ts
Normal file
28
app/src/types/form.ts
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import type { BaseValidation } from '@vuelidate/core'
|
||||||
|
type StateValidation = false | null
|
||||||
|
|
||||||
|
// WRITABLE
|
||||||
|
|
||||||
|
type BaseWritableItemProps = {
|
||||||
|
id?: string
|
||||||
|
name?: string
|
||||||
|
placeholder?: string
|
||||||
|
touchKey?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BaseItemComputedProps<MV extends any = any> = {
|
||||||
|
ariaDescribedby?: string | string[]
|
||||||
|
modelValue?: MV
|
||||||
|
state?: StateValidation
|
||||||
|
validation?: BaseValidation
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AdressItemProps = BaseWritableItemProps & {
|
||||||
|
choices: string[]
|
||||||
|
type?: 'domain' | 'email'
|
||||||
|
}
|
||||||
|
export type AdressModelValue = {
|
||||||
|
localPart: string | null
|
||||||
|
separator: string
|
||||||
|
domain: string | null
|
||||||
|
}
|
Loading…
Reference in a new issue