mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-27 18:30:35 +01:00
chore(module): lint
This commit is contained in:
@@ -21,7 +21,7 @@ export default defineNuxtModule<ModuleOptions>({
|
|||||||
prefix: 'U',
|
prefix: 'U',
|
||||||
colors: undefined
|
colors: undefined
|
||||||
},
|
},
|
||||||
async setup (options, nuxt) {
|
async setup(options, nuxt) {
|
||||||
const { resolve } = createResolver(import.meta.url)
|
const { resolve } = createResolver(import.meta.url)
|
||||||
|
|
||||||
options.colors = options.colors || ['primary', 'red', 'orange', 'amber', 'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'fuchia', 'pink', 'rose']
|
options.colors = options.colors || ['primary', 'red', 'orange', 'amber', 'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'fuchia', 'pink', 'rose']
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ const inputId = _inputId.value ?? useId()
|
|||||||
|
|
||||||
const modelValue = defineModel<boolean | undefined>({
|
const modelValue = defineModel<boolean | undefined>({
|
||||||
default: undefined,
|
default: undefined,
|
||||||
set (value) {
|
set(value) {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -60,10 +60,10 @@ const modelValue = defineModel<boolean | undefined>({
|
|||||||
const indeterminate = computed(() => (modelValue.value === undefined && props.indeterminate))
|
const indeterminate = computed(() => (modelValue.value === undefined && props.indeterminate))
|
||||||
|
|
||||||
const checked = computed({
|
const checked = computed({
|
||||||
get () {
|
get() {
|
||||||
return indeterminate.value ? 'indeterminate' : modelValue.value
|
return indeterminate.value ? 'indeterminate' : modelValue.value
|
||||||
},
|
},
|
||||||
set (value) {
|
set(value) {
|
||||||
modelValue.value = value === 'indeterminate' ? undefined : value
|
modelValue.value = value === 'indeterminate' ? undefined : value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -71,7 +71,7 @@ const checked = computed({
|
|||||||
// FIXME: I think there's a race condition between this and the v-model event.
|
// FIXME: I think there's a race condition between this and the v-model event.
|
||||||
// This must be triggered after the value updates, otherwise the form validates
|
// This must be triggered after the value updates, otherwise the form validates
|
||||||
// the previous value.
|
// the previous value.
|
||||||
function onChecked () {
|
function onChecked() {
|
||||||
emitFormChange()
|
emitFormChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export interface FormProps<T extends object> {
|
|||||||
id?: string | number
|
id?: string | number
|
||||||
schema?: FormSchema<T>
|
schema?: FormSchema<T>
|
||||||
state: Partial<T>
|
state: Partial<T>
|
||||||
validate?: (state: Partial<T>) => Promise<FormError[] | void>
|
validate?: (state: Partial<T>) => Promise<FormError[]>
|
||||||
validateOn?: FormInputEvents[]
|
validateOn?: FormInputEvents[]
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
validateOnInputDelay?: number
|
validateOnInputDelay?: number
|
||||||
@@ -38,7 +38,7 @@ import { useId } from '#imports'
|
|||||||
import { getYupErrors, isYupSchema, getValibotError, isValibotSchema, getZodErrors, isZodSchema, getJoiErrors, isJoiSchema } from '#ui/utils/form'
|
import { getYupErrors, isYupSchema, getValibotError, isValibotSchema, getZodErrors, isZodSchema, getJoiErrors, isJoiSchema } from '#ui/utils/form'
|
||||||
|
|
||||||
const props = withDefaults(defineProps<FormProps<T>>(), {
|
const props = withDefaults(defineProps<FormProps<T>>(), {
|
||||||
validateOn () {
|
validateOn() {
|
||||||
return ['input', 'blur', 'change'] as FormInputEvents[]
|
return ['input', 'blur', 'change'] as FormInputEvents[]
|
||||||
},
|
},
|
||||||
validateOnInputDelay: 300
|
validateOnInputDelay: 300
|
||||||
@@ -55,7 +55,6 @@ const parentBus = inject<UseEventBusReturn<FormEvent, string> | undefined>(
|
|||||||
)
|
)
|
||||||
provide('form-events', bus)
|
provide('form-events', bus)
|
||||||
|
|
||||||
|
|
||||||
const nestedForms = ref<Map<string | number, { validate: () => any }>>(new Map())
|
const nestedForms = ref<Map<string | number, { validate: () => any }>>(new Map())
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@@ -98,14 +97,14 @@ provide('form-errors', errors)
|
|||||||
|
|
||||||
const inputs = ref<Record<string, string>>({})
|
const inputs = ref<Record<string, string>>({})
|
||||||
provide('form-inputs', inputs)
|
provide('form-inputs', inputs)
|
||||||
function resolveErrorIds (errs: FormError[]): FormErrorWithId[] {
|
function resolveErrorIds(errs: FormError[]): FormErrorWithId[] {
|
||||||
return errs.map((err) => ({
|
return errs.map(err => ({
|
||||||
...err,
|
...err,
|
||||||
id: inputs.value[err.name]
|
id: inputs.value[err.name]
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getErrors (): Promise<FormErrorWithId[]> {
|
async function getErrors(): Promise<FormErrorWithId[]> {
|
||||||
let errs = props.validate ? (await props.validate(props.state)) ?? [] : []
|
let errs = props.validate ? (await props.validate(props.state)) ?? [] : []
|
||||||
|
|
||||||
if (props.schema) {
|
if (props.schema) {
|
||||||
@@ -125,26 +124,23 @@ async function getErrors (): Promise<FormErrorWithId[]> {
|
|||||||
return resolveErrorIds(errs)
|
return resolveErrorIds(errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _validate (
|
async function _validate(opts: { name?: string | string[], silent?: boolean, nested?: boolean } = { silent: false, nested: true }): Promise<T | false> {
|
||||||
opts: { name?: string | string[], silent?: boolean, nested?: boolean } = { silent: false, nested: true }
|
|
||||||
): Promise<T | false> {
|
|
||||||
const names = opts.name && !Array.isArray(opts.name) ? [opts.name] : opts.name
|
const names = opts.name && !Array.isArray(opts.name) ? [opts.name] : opts.name
|
||||||
|
|
||||||
const nestedValidatePromises = !names && opts.nested ? Array.from(nestedForms.value.values()).map(
|
const nestedValidatePromises = !names && opts.nested
|
||||||
({ validate }) => validate().then(() => undefined).catch((error: Error) => {
|
? Array.from(nestedForms.value.values()).map(
|
||||||
if (!(error instanceof FormValidationException)) {
|
({ validate }) => validate().then(() => undefined).catch((error: Error) => {
|
||||||
throw error
|
if (!(error instanceof FormValidationException)) {
|
||||||
}
|
throw error
|
||||||
return error
|
}
|
||||||
})
|
return error
|
||||||
) : []
|
})
|
||||||
|
)
|
||||||
|
: []
|
||||||
|
|
||||||
if (names) {
|
if (names) {
|
||||||
const otherErrors = errors.value.filter(
|
const otherErrors = errors.value.filter(error => !names!.includes(error.name))
|
||||||
(error) => !names!.includes(error.name)
|
const pathErrors = (await getErrors()).filter(error => names!.includes(error.name)
|
||||||
)
|
|
||||||
const pathErrors = (await getErrors()).filter((error) =>
|
|
||||||
names!.includes(error.name)
|
|
||||||
)
|
)
|
||||||
errors.value = otherErrors.concat(pathErrors)
|
errors.value = otherErrors.concat(pathErrors)
|
||||||
} else {
|
} else {
|
||||||
@@ -160,7 +156,7 @@ async function _validate (
|
|||||||
return props.state as T
|
return props.state as T
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onSubmit (payload: Event) {
|
async function onSubmit(payload: Event) {
|
||||||
const event = payload as SubmitEvent
|
const event = payload as SubmitEvent
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -170,7 +166,6 @@ async function onSubmit (payload: Event) {
|
|||||||
data: props.state
|
data: props.state
|
||||||
}
|
}
|
||||||
emit('submit', submitEvent)
|
emit('submit', submitEvent)
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (!(error instanceof FormValidationException)) {
|
if (!(error instanceof FormValidationException)) {
|
||||||
throw error
|
throw error
|
||||||
@@ -190,30 +185,30 @@ defineExpose<Form<T>>({
|
|||||||
validate: _validate,
|
validate: _validate,
|
||||||
errors,
|
errors,
|
||||||
|
|
||||||
setErrors (errs: FormError[], name?: string) {
|
setErrors(errs: FormError[], name?: string) {
|
||||||
if (name) {
|
if (name) {
|
||||||
errors.value = errors.value
|
errors.value = errors.value
|
||||||
.filter((error) => error.name !== name)
|
.filter(error => error.name !== name)
|
||||||
.concat(resolveErrorIds(errs))
|
.concat(resolveErrorIds(errs))
|
||||||
} else {
|
} else {
|
||||||
errors.value = resolveErrorIds(errs)
|
errors.value = resolveErrorIds(errs)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async submit () {
|
async submit() {
|
||||||
await onSubmit(new Event('submit'))
|
await onSubmit(new Event('submit'))
|
||||||
},
|
},
|
||||||
|
|
||||||
getErrors (name?: string) {
|
getErrors(name?: string) {
|
||||||
if (name) {
|
if (name) {
|
||||||
return errors.value.filter((err) => err.name === name)
|
return errors.value.filter(err => err.name === name)
|
||||||
}
|
}
|
||||||
return errors.value
|
return errors.value
|
||||||
},
|
},
|
||||||
|
|
||||||
clear (name?: string) {
|
clear(name?: string) {
|
||||||
if (name) {
|
if (name) {
|
||||||
errors.value = errors.value.filter((err) => err.name !== name)
|
errors.value = errors.value.filter(err => err.name !== name)
|
||||||
} else {
|
} else {
|
||||||
errors.value = []
|
errors.value = []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,10 +52,10 @@ const ui = computed(() => tv({ extend: formField, slots: props.ui })({
|
|||||||
const formErrors = inject<Ref<FormError[]> | null>('form-errors', null)
|
const formErrors = inject<Ref<FormError[]> | null>('form-errors', null)
|
||||||
|
|
||||||
const error = computed(() => {
|
const error = computed(() => {
|
||||||
return (props.error && typeof props.error === 'string') ||
|
return (props.error && typeof props.error === 'string')
|
||||||
typeof props.error === 'boolean'
|
|| typeof props.error === 'boolean'
|
||||||
? props.error
|
? props.error
|
||||||
: formErrors?.value?.find((error) => error.name === props.name)?.message
|
: formErrors?.value?.find(error => error.name === props.name)?.message
|
||||||
})
|
})
|
||||||
|
|
||||||
const inputId = ref(useId())
|
const inputId = ref(useId())
|
||||||
|
|||||||
@@ -73,14 +73,14 @@ const ui = computed(() => tv({ extend: input, slots: props.ui })({
|
|||||||
|
|
||||||
const inputRef = ref<HTMLInputElement | null>(null)
|
const inputRef = ref<HTMLInputElement | null>(null)
|
||||||
|
|
||||||
function autoFocus () {
|
function autoFocus() {
|
||||||
if (props.autofocus) {
|
if (props.autofocus) {
|
||||||
inputRef.value?.focus()
|
inputRef.value?.focus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom function to handle the v-model properties
|
// Custom function to handle the v-model properties
|
||||||
function updateInput (value: string) {
|
function updateInput(value: string) {
|
||||||
if (modelModifiers.trim) {
|
if (modelModifiers.trim) {
|
||||||
value = value.trim()
|
value = value.trim()
|
||||||
}
|
}
|
||||||
@@ -93,13 +93,13 @@ function updateInput (value: string) {
|
|||||||
emitFormInput()
|
emitFormInput()
|
||||||
}
|
}
|
||||||
|
|
||||||
function onInput (event: Event) {
|
function onInput(event: Event) {
|
||||||
if (!modelModifiers.lazy) {
|
if (!modelModifiers.lazy) {
|
||||||
updateInput((event.target as HTMLInputElement).value)
|
updateInput((event.target as HTMLInputElement).value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onChange (event: Event) {
|
function onChange(event: Event) {
|
||||||
const value = (event.target as HTMLInputElement).value
|
const value = (event.target as HTMLInputElement).value
|
||||||
|
|
||||||
if (modelModifiers.lazy) {
|
if (modelModifiers.lazy) {
|
||||||
@@ -112,7 +112,7 @@ function onChange (event: Event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onBlur (event: FocusEvent) {
|
function onBlur(event: FocusEvent) {
|
||||||
emitFormBlur()
|
emitFormBlur()
|
||||||
emit('blur', event)
|
emit('blur', event)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ const ui = computed(() => tv({
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
function isLinkActive (slotProps: any) {
|
function isLinkActive(slotProps: any) {
|
||||||
if (props.active !== undefined) {
|
if (props.active !== undefined) {
|
||||||
return props.active
|
return props.active
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ function isLinkActive (slotProps: any) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveLinkClass (slotProps: any) {
|
function resolveLinkClass(slotProps: any) {
|
||||||
const active = isLinkActive(slotProps)
|
const active = isLinkActive(slotProps)
|
||||||
|
|
||||||
if (props.raw) {
|
if (props.raw) {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const props = withDefaults(defineProps<LinkBaseProps>(), {
|
|||||||
type: 'button'
|
type: 'button'
|
||||||
})
|
})
|
||||||
|
|
||||||
function onClick (e: MouseEvent) {
|
function onClick(e: MouseEvent) {
|
||||||
if (props.disabled) {
|
if (props.disabled) {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@@ -43,10 +43,10 @@ function onClick (e: MouseEvent) {
|
|||||||
<template>
|
<template>
|
||||||
<Primitive
|
<Primitive
|
||||||
v-bind="href ? {
|
v-bind="href ? {
|
||||||
as: 'a',
|
'as': 'a',
|
||||||
href: disabled ? undefined : href,
|
'href': disabled ? undefined : href,
|
||||||
'aria-disabled': disabled ? 'true' : undefined,
|
'aria-disabled': disabled ? 'true' : undefined,
|
||||||
role: disabled ? 'link' : undefined
|
'role': disabled ? 'link' : undefined
|
||||||
} : as === 'button' ? {
|
} : as === 'button' ? {
|
||||||
as,
|
as,
|
||||||
type,
|
type,
|
||||||
|
|||||||
@@ -58,8 +58,8 @@ const contentProps = toRef(() => props.content)
|
|||||||
const contentEvents = computed(() => {
|
const contentEvents = computed(() => {
|
||||||
if (props.preventClose) {
|
if (props.preventClose) {
|
||||||
return {
|
return {
|
||||||
'pointerDownOutside': (e: Event) => e.preventDefault(),
|
pointerDownOutside: (e: Event) => e.preventDefault(),
|
||||||
'interactOutside': (e: Event) => e.preventDefault()
|
interactOutside: (e: Event) => e.preventDefault()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const appConfig = _appConfig as AppConfig & { ui: { popover: Partial<typeof them
|
|||||||
|
|
||||||
const popover = tv({ extend: tv(theme), ...(appConfig.ui?.popover || {}) })
|
const popover = tv({ extend: tv(theme), ...(appConfig.ui?.popover || {}) })
|
||||||
|
|
||||||
export interface PopoverProps extends PopoverRootProps, Pick<HoverCardRootProps, 'openDelay' | 'closeDelay'>{
|
export interface PopoverProps extends PopoverRootProps, Pick<HoverCardRootProps, 'openDelay' | 'closeDelay'> {
|
||||||
/**
|
/**
|
||||||
* The mode of the popover.
|
* The mode of the popover.
|
||||||
* @defaultValue "click"
|
* @defaultValue "click"
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export type RadioGroupEmits = {
|
|||||||
export interface RadioGroupSlots<T> {
|
export interface RadioGroupSlots<T> {
|
||||||
legend(): any
|
legend(): any
|
||||||
label(props: { option: RadioGroupOption<T> }): any
|
label(props: { option: RadioGroupOption<T> }): any
|
||||||
description(props: { option: RadioGroupOption<T>}): any
|
description(props: { option: RadioGroupOption<T> }): any
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ const ui = computed(() => tv({ extend: radioGroup, slots: props.ui })({
|
|||||||
required: props.required
|
required: props.required
|
||||||
}))
|
}))
|
||||||
|
|
||||||
function normalizeOption (option: any) {
|
function normalizeOption(option: any) {
|
||||||
if (['string', 'number', 'boolean'].includes(typeof option)) {
|
if (['string', 'number', 'boolean'].includes(typeof option)) {
|
||||||
return {
|
return {
|
||||||
id: `${inputId}:${option}`,
|
id: `${inputId}:${option}`,
|
||||||
@@ -82,7 +82,7 @@ const normalizedOptions = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const modelValue = defineModel<T>({
|
const modelValue = defineModel<T>({
|
||||||
set (value) {
|
set(value) {
|
||||||
emits('change', value)
|
emits('change', value)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ const modelValue = defineModel<T>({
|
|||||||
// FIXME: I think there's a race condition between this and the v-model event.
|
// FIXME: I think there's a race condition between this and the v-model event.
|
||||||
// This must be triggered after the value updates, otherwise the form validates
|
// This must be triggered after the value updates, otherwise the form validates
|
||||||
// the previous value.
|
// the previous value.
|
||||||
function onUpdate () {
|
function onUpdate() {
|
||||||
emitFormChange()
|
emitFormChange()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -61,8 +61,8 @@ const contentProps = toRef(() => props.content)
|
|||||||
const contentEvents = computed(() => {
|
const contentEvents = computed(() => {
|
||||||
if (props.preventClose) {
|
if (props.preventClose) {
|
||||||
return {
|
return {
|
||||||
'pointerDownOutside': (e: Event) => e.preventDefault(),
|
pointerDownOutside: (e: Event) => e.preventDefault(),
|
||||||
'interactOutside': (e: Event) => e.preventDefault()
|
interactOutside: (e: Event) => e.preventDefault()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ const ui = computed(() => tv({ extend: switchTv, slots: props.ui })({
|
|||||||
// FIXME: I think there's a race condition between this and the v-model event.
|
// FIXME: I think there's a race condition between this and the v-model event.
|
||||||
// This must be triggered after the value updates, otherwise the form validates
|
// This must be triggered after the value updates, otherwise the form validates
|
||||||
// the previous value.
|
// the previous value.
|
||||||
async function onChecked () {
|
async function onChecked() {
|
||||||
emitFormChange()
|
emitFormChange()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -65,14 +65,14 @@ const ui = computed(() => tv({ extend: textarea, slots: props.ui })({
|
|||||||
|
|
||||||
const textareaRef = ref<HTMLTextAreaElement | null>(null)
|
const textareaRef = ref<HTMLTextAreaElement | null>(null)
|
||||||
|
|
||||||
function autoFocus () {
|
function autoFocus() {
|
||||||
if (props.autofocus) {
|
if (props.autofocus) {
|
||||||
textareaRef.value?.focus()
|
textareaRef.value?.focus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom function to handle the v-model properties
|
// Custom function to handle the v-model properties
|
||||||
function updateInput (value: string) {
|
function updateInput(value: string) {
|
||||||
if (modelModifiers.trim) {
|
if (modelModifiers.trim) {
|
||||||
value = value.trim()
|
value = value.trim()
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ function updateInput (value: string) {
|
|||||||
emitFormInput()
|
emitFormInput()
|
||||||
}
|
}
|
||||||
|
|
||||||
function onInput (event: Event) {
|
function onInput(event: Event) {
|
||||||
autoResize()
|
autoResize()
|
||||||
|
|
||||||
if (!modelModifiers.lazy) {
|
if (!modelModifiers.lazy) {
|
||||||
@@ -93,7 +93,7 @@ function onInput (event: Event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onChange (event: Event) {
|
function onChange(event: Event) {
|
||||||
const value = (event.target as HTMLInputElement).value
|
const value = (event.target as HTMLInputElement).value
|
||||||
|
|
||||||
if (modelModifiers.lazy) {
|
if (modelModifiers.lazy) {
|
||||||
@@ -106,7 +106,7 @@ function onChange (event: Event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onBlur (event: FocusEvent) {
|
function onBlur(event: FocusEvent) {
|
||||||
emitFormBlur()
|
emitFormBlur()
|
||||||
emit('blur', event)
|
emit('blur', event)
|
||||||
}
|
}
|
||||||
@@ -117,9 +117,8 @@ onMounted(() => {
|
|||||||
}, props.autofocusDelay)
|
}, props.autofocusDelay)
|
||||||
})
|
})
|
||||||
|
|
||||||
function autoResize () {
|
function autoResize() {
|
||||||
if (props.autoresize) {
|
if (props.autoresize) {
|
||||||
|
|
||||||
if (!textareaRef.value) {
|
if (!textareaRef.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -127,10 +126,10 @@ function autoResize () {
|
|||||||
textareaRef.value.rows = props.rows
|
textareaRef.value.rows = props.rows
|
||||||
|
|
||||||
const styles = window.getComputedStyle(textareaRef.value)
|
const styles = window.getComputedStyle(textareaRef.value)
|
||||||
const paddingTop = parseInt(styles.paddingTop)
|
const paddingTop = Number.parseInt(styles.paddingTop)
|
||||||
const paddingBottom = parseInt(styles.paddingBottom)
|
const paddingBottom = Number.parseInt(styles.paddingBottom)
|
||||||
const padding = paddingTop + paddingBottom
|
const padding = paddingTop + paddingBottom
|
||||||
const lineHeight = parseInt(styles.lineHeight)
|
const lineHeight = Number.parseInt(styles.lineHeight)
|
||||||
const { scrollHeight } = textareaRef.value
|
const { scrollHeight } = textareaRef.value
|
||||||
const newRows = (scrollHeight - padding) / lineHeight
|
const newRows = (scrollHeight - padding) / lineHeight
|
||||||
|
|
||||||
|
|||||||
@@ -40,16 +40,16 @@ const { toasts, remove } = useToast()
|
|||||||
|
|
||||||
const swipeDirection = computed(() => {
|
const swipeDirection = computed(() => {
|
||||||
switch (props.position) {
|
switch (props.position) {
|
||||||
case 'top-center':
|
case 'top-center':
|
||||||
return 'up'
|
return 'up'
|
||||||
case 'top-right':
|
case 'top-right':
|
||||||
case 'bottom-right':
|
case 'bottom-right':
|
||||||
return 'right'
|
return 'right'
|
||||||
case 'bottom-center':
|
case 'bottom-center':
|
||||||
return 'down'
|
return 'down'
|
||||||
case 'top-left':
|
case 'top-left':
|
||||||
case 'bottom-left':
|
case 'bottom-left':
|
||||||
return 'left'
|
return 'left'
|
||||||
}
|
}
|
||||||
return 'right'
|
return 'right'
|
||||||
})
|
})
|
||||||
@@ -59,7 +59,7 @@ const ui = computed(() => tv({ extend: toaster, slots: props.ui })({
|
|||||||
swipeDirection: swipeDirection.value
|
swipeDirection: swipeDirection.value
|
||||||
}))
|
}))
|
||||||
|
|
||||||
function onUpdateOpen (value: boolean, id: string | number) {
|
function onUpdateOpen(value: boolean, id: string | number) {
|
||||||
if (value) {
|
if (value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ const refs = ref<{ height: number }[]>([])
|
|||||||
const height = computed(() => refs.value.reduce((acc, { height }) => acc + height + 16, 0))
|
const height = computed(() => refs.value.reduce((acc, { height }) => acc + height + 16, 0))
|
||||||
const frontHeight = computed(() => refs.value[refs.value.length - 1]?.height || 0)
|
const frontHeight = computed(() => refs.value[refs.value.length - 1]?.height || 0)
|
||||||
|
|
||||||
function getOffset (index: number) {
|
function getOffset(index: number) {
|
||||||
return refs.value.slice(index + 1).reduce((acc, { height }) => acc + height + 16, 0)
|
return refs.value.slice(index + 1).reduce((acc, { height }) => acc + height + 16, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export interface UseComponentIconsProps {
|
|||||||
loadingIcon?: IconProps['name']
|
loadingIcon?: IconProps['name']
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useComponentIcons (props: UseComponentIconsProps) {
|
export function useComponentIcons(props: UseComponentIconsProps) {
|
||||||
const appConfig = useAppConfig()
|
const appConfig = useAppConfig()
|
||||||
|
|
||||||
const isLeading = computed(() => (props.icon && props.leading) || (props.icon && !props.trailing) || (props.loading && !props.trailing && !props.trailingIcon) || !!props.leadingIcon)
|
const isLeading = computed(() => (props.icon && props.leading) || (props.icon && !props.trailing) || (props.loading && !props.trailing && !props.trailingIcon) || !!props.leadingIcon)
|
||||||
|
|||||||
@@ -5,16 +5,16 @@ import type { FormEvent, FormInputEvents, FormFieldInjectedOptions, FormInjected
|
|||||||
type Props<T> = {
|
type Props<T> = {
|
||||||
id?: string
|
id?: string
|
||||||
name?: string
|
name?: string
|
||||||
// @ts-ignore FIXME: TS doesn't like this
|
// @ts-expect-error FIXME: TS doesn't like this
|
||||||
size?: T['size']
|
size?: T['size']
|
||||||
// @ts-ignore FIXME: TS doesn't like this
|
// @ts-expect-error FIXME: TS doesn't like this
|
||||||
color?: T['color']
|
color?: T['color']
|
||||||
eagerValidation?: boolean
|
eagerValidation?: boolean
|
||||||
legend?: string
|
legend?: string
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useFormField <T> (inputProps?: Props<T>) {
|
export function useFormField<T>(inputProps?: Props<T>) {
|
||||||
const formOptions = inject<FormInjectedOptions | undefined>('form-options', undefined)
|
const formOptions = inject<FormInjectedOptions | undefined>('form-options', undefined)
|
||||||
const formBus = inject<UseEventBusReturn<FormEvent, string> | undefined>('form-events', undefined)
|
const formBus = inject<UseEventBusReturn<FormEvent, string> | undefined>('form-events', undefined)
|
||||||
const formField = inject<FormFieldInjectedOptions<T> | undefined>('form-field', undefined)
|
const formField = inject<FormFieldInjectedOptions<T> | undefined>('form-field', undefined)
|
||||||
@@ -33,18 +33,18 @@ export function useFormField <T> (inputProps?: Props<T>) {
|
|||||||
|
|
||||||
const blurred = ref(false)
|
const blurred = ref(false)
|
||||||
|
|
||||||
function emitFormEvent (type: FormInputEvents, name: string) {
|
function emitFormEvent(type: FormInputEvents, name: string) {
|
||||||
if (formBus && formField) {
|
if (formBus && formField) {
|
||||||
formBus.emit({ type, name })
|
formBus.emit({ type, name })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitFormBlur () {
|
function emitFormBlur() {
|
||||||
emitFormEvent('blur', formField?.name.value as string)
|
emitFormEvent('blur', formField?.name.value as string)
|
||||||
blurred.value = true
|
blurred.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitFormChange () {
|
function emitFormChange() {
|
||||||
emitFormEvent('change', formField?.name.value as string)
|
emitFormEvent('change', formField?.name.value as string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ export interface Toast extends Omit<ToastProps, 'defaultOpen'> {
|
|||||||
click?: (toast: Toast) => void
|
click?: (toast: Toast) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useToast () {
|
export function useToast() {
|
||||||
const toasts = useState<Toast[]>('toasts', () => [])
|
const toasts = useState<Toast[]>('toasts', () => [])
|
||||||
|
|
||||||
function add (toast: Partial<Toast>): Toast {
|
function add(toast: Partial<Toast>): Toast {
|
||||||
const body = {
|
const body = {
|
||||||
id: new Date().getTime().toString(),
|
id: new Date().getTime().toString(),
|
||||||
open: true,
|
open: true,
|
||||||
@@ -26,7 +26,7 @@ export function useToast () {
|
|||||||
return body
|
return body
|
||||||
}
|
}
|
||||||
|
|
||||||
function update (id: string | number, toast: Partial<Toast>) {
|
function update(id: string | number, toast: Partial<Toast>) {
|
||||||
const index = toasts.value.findIndex((t: Toast) => t.id === id)
|
const index = toasts.value.findIndex((t: Toast) => t.id === id)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
toasts.value[index] = {
|
toasts.value[index] = {
|
||||||
@@ -36,7 +36,7 @@ export function useToast () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function remove (id: string | number) {
|
function remove(id: string | number) {
|
||||||
const index = toasts.value.findIndex((t: Toast) => t.id === id)
|
const index = toasts.value.findIndex((t: Toast) => t.id === id)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
toasts.value[index] = {
|
toasts.value[index] = {
|
||||||
|
|||||||
1
src/runtime/types/app.config.d.ts
vendored
1
src/runtime/types/app.config.d.ts
vendored
@@ -1,5 +1,6 @@
|
|||||||
declare module '#build/app.config' {
|
declare module '#build/app.config' {
|
||||||
import type { AppConfig } from '@nuxt/schema'
|
import type { AppConfig } from '@nuxt/schema'
|
||||||
|
|
||||||
const _default: AppConfig
|
const _default: AppConfig
|
||||||
export default _default
|
export default _default
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ export interface FormInjectedOptions {
|
|||||||
export interface FormFieldInjectedOptions<T> {
|
export interface FormFieldInjectedOptions<T> {
|
||||||
inputId: Ref<string | undefined>
|
inputId: Ref<string | undefined>
|
||||||
name: ComputedRef<string | undefined>
|
name: ComputedRef<string | undefined>
|
||||||
// @ts-ignore FIXME: TS doesn't like this
|
// @ts-expect-error FIXME: TS doesn't like this
|
||||||
size: ComputedRef<T['size']>
|
size: ComputedRef<T['size']>
|
||||||
error: ComputedRef<string | boolean | undefined>
|
error: ComputedRef<string | boolean | undefined>
|
||||||
eagerValidation: ComputedRef<boolean | undefined>
|
eagerValidation: ComputedRef<boolean | undefined>
|
||||||
@@ -83,7 +83,7 @@ export class FormValidationException extends Error {
|
|||||||
errors: FormErrorWithId[]
|
errors: FormErrorWithId[]
|
||||||
childrens: FormValidationException[]
|
childrens: FormValidationException[]
|
||||||
|
|
||||||
constructor (formId: string | number, errors: FormErrorWithId[], childErrors: FormValidationException[]) {
|
constructor(formId: string | number, errors: FormErrorWithId[], childErrors: FormValidationException[]) {
|
||||||
super('Form validation exception')
|
super('Form validation exception')
|
||||||
this.formId = formId
|
this.formId = formId
|
||||||
this.errors = errors
|
this.errors = errors
|
||||||
|
|||||||
@@ -4,21 +4,21 @@ import type { ObjectSchema as YupObjectSchema, ValidationError as YupError } fro
|
|||||||
import type { ObjectSchemaAsync as ValibotObjectSchema } from 'valibot'
|
import type { ObjectSchemaAsync as ValibotObjectSchema } from 'valibot'
|
||||||
import type { FormError } from '#ui/types/form'
|
import type { FormError } from '#ui/types/form'
|
||||||
|
|
||||||
export function isYupSchema (schema: any): schema is YupObjectSchema<any> {
|
export function isYupSchema(schema: any): schema is YupObjectSchema<any> {
|
||||||
return schema.validate && schema.__isYupSchema__
|
return schema.validate && schema.__isYupSchema__
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isYupError (error: any): error is YupError {
|
export function isYupError(error: any): error is YupError {
|
||||||
return error.inner !== undefined
|
return error.inner !== undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getYupErrors (state: any, schema: YupObjectSchema<any>): Promise<FormError[]> {
|
export async function getYupErrors(state: any, schema: YupObjectSchema<any>): Promise<FormError[]> {
|
||||||
try {
|
try {
|
||||||
await schema.validate(state, { abortEarly: false })
|
await schema.validate(state, { abortEarly: false })
|
||||||
return []
|
return []
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (isYupError(error)) {
|
if (isYupError(error)) {
|
||||||
return error.inner.map((issue) => ({
|
return error.inner.map(issue => ({
|
||||||
name: issue.path ?? '',
|
name: issue.path ?? '',
|
||||||
message: issue.message
|
message: issue.message
|
||||||
}))
|
}))
|
||||||
@@ -28,14 +28,14 @@ export async function getYupErrors (state: any, schema: YupObjectSchema<any>): P
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isZodSchema (schema: any): schema is ZodSchema {
|
export function isZodSchema(schema: any): schema is ZodSchema {
|
||||||
return schema.parse !== undefined
|
return schema.parse !== undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getZodErrors (state: any, schema: ZodSchema): Promise<FormError[]> {
|
export async function getZodErrors(state: any, schema: ZodSchema): Promise<FormError[]> {
|
||||||
const result = await schema.safeParseAsync(state)
|
const result = await schema.safeParseAsync(state)
|
||||||
if (result.success === false) {
|
if (result.success === false) {
|
||||||
return result.error.issues.map((issue) => ({
|
return result.error.issues.map(issue => ({
|
||||||
name: issue.path.join('.'),
|
name: issue.path.join('.'),
|
||||||
message: issue.message
|
message: issue.message
|
||||||
}))
|
}))
|
||||||
@@ -43,21 +43,21 @@ export async function getZodErrors (state: any, schema: ZodSchema): Promise<Form
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isJoiSchema (schema: any): schema is JoiSchema {
|
export function isJoiSchema(schema: any): schema is JoiSchema {
|
||||||
return schema.validateAsync !== undefined && schema.id !== undefined
|
return schema.validateAsync !== undefined && schema.id !== undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isJoiError (error: any): error is JoiError {
|
export function isJoiError(error: any): error is JoiError {
|
||||||
return error.isJoi === true
|
return error.isJoi === true
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getJoiErrors (state: any, schema: JoiSchema): Promise<FormError[]> {
|
export async function getJoiErrors(state: any, schema: JoiSchema): Promise<FormError[]> {
|
||||||
try {
|
try {
|
||||||
await schema.validateAsync(state, { abortEarly: false })
|
await schema.validateAsync(state, { abortEarly: false })
|
||||||
return []
|
return []
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (isJoiError(error)) {
|
if (isJoiError(error)) {
|
||||||
return error.details.map((detail) => ({
|
return error.details.map(detail => ({
|
||||||
name: detail.path.join('.'),
|
name: detail.path.join('.'),
|
||||||
message: detail.message
|
message: detail.message
|
||||||
}))
|
}))
|
||||||
@@ -67,15 +67,15 @@ export async function getJoiErrors (state: any, schema: JoiSchema): Promise<Form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isValibotSchema (schema: any): schema is ValibotObjectSchema<any> {
|
export function isValibotSchema(schema: any): schema is ValibotObjectSchema<any> {
|
||||||
return schema._parse !== undefined
|
return schema._parse !== undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getValibotError (state: any, schema: ValibotObjectSchema<any>): Promise<FormError[]> {
|
export async function getValibotError(state: any, schema: ValibotObjectSchema<any>): Promise<FormError[]> {
|
||||||
const result = await schema._parse(state)
|
const result = await schema._parse(state)
|
||||||
if (result.issues) {
|
if (result.issues) {
|
||||||
return result.issues.map((issue) => ({
|
return result.issues.map(issue => ({
|
||||||
name: issue.path?.map((p) => p.key).join('.') || '',
|
name: issue.path?.map(p => p.key).join('.') || '',
|
||||||
message: issue.message
|
message: issue.message
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export function pick<Data extends object, Keys extends keyof Data> (data: Data, keys: Keys[]): Pick<Data, Keys> {
|
export function pick<Data extends object, Keys extends keyof Data>(data: Data, keys: Keys[]): Pick<Data, Keys> {
|
||||||
const result = {} as Pick<Data, Keys>
|
const result = {} as Pick<Data, Keys>
|
||||||
|
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
@@ -8,17 +8,18 @@ export function pick<Data extends object, Keys extends keyof Data> (data: Data,
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
export function omit<Data extends object, Keys extends keyof Data> (data: Data, keys: Keys[]): Omit<Data, Keys> {
|
export function omit<Data extends object, Keys extends keyof Data>(data: Data, keys: Keys[]): Omit<Data, Keys> {
|
||||||
const result = { ...data }
|
const result = { ...data }
|
||||||
|
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||||
delete result[key]
|
delete result[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
return result as Omit<Data, Keys>
|
return result as Omit<Data, Keys>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function looseToNumber (val: any): any {
|
export function looseToNumber(val: any): any {
|
||||||
const n = parseFloat(val)
|
const n = Number.parseFloat(val)
|
||||||
return isNaN(n) ? val : n
|
return Number.isNaN(n) ? val : n
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { Nuxt } from '@nuxt/schema'
|
|||||||
import type { ModuleOptions } from './module'
|
import type { ModuleOptions } from './module'
|
||||||
import * as theme from './theme'
|
import * as theme from './theme'
|
||||||
|
|
||||||
export function addTemplates (options: ModuleOptions, nuxt: Nuxt) {
|
export function addTemplates(options: ModuleOptions, nuxt: Nuxt) {
|
||||||
const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950]
|
const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950]
|
||||||
|
|
||||||
const template = addTemplate({
|
const template = addTemplate({
|
||||||
|
|||||||
Reference in New Issue
Block a user