big update
This commit is contained in:
@@ -1,14 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
<script lang="ts">
|
||||
import type { TColor } from '../colors'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<{
|
||||
export type TUiAlertProps = {
|
||||
color?: TColor
|
||||
value?: string
|
||||
close?: boolean
|
||||
}>()
|
||||
}
|
||||
|
||||
const emit = defineEmits<{ (e: 'close'): void }>()
|
||||
export type TUiAlertEmits = {
|
||||
(e: 'close'): void
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiIcon from './Icon.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<TUiAlertProps>()
|
||||
|
||||
// Emit.
|
||||
const emit = defineEmits<TUiAlertEmits>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
+34
-8
@@ -1,26 +1,52 @@
|
||||
<script setup lang="ts">
|
||||
<script lang="ts">
|
||||
import type { TColor } from '../colors'
|
||||
import type { TUiIcon } from '../icons'
|
||||
|
||||
import UiIcon from './Icon.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<{
|
||||
export type TUiBtnProps = {
|
||||
label?: string
|
||||
type?: 'button' | 'submit'
|
||||
color?: TColor
|
||||
icon?: TUiIcon
|
||||
to?: string
|
||||
}>()
|
||||
}
|
||||
|
||||
export type TUiBtnEmits = {
|
||||
(e: 'click', v: PointerEvent): void
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiIcon from './Icon.vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<TUiBtnProps>()
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<TUiBtnEmits>()
|
||||
|
||||
// Handlers.
|
||||
const clickHandler = (e: PointerEvent) => emit('click', e)
|
||||
|
||||
// Computed.
|
||||
const cssClass = computed(() => {
|
||||
let obj: any = {
|
||||
'ui-btn': true,
|
||||
'ui-btn-icon': props.icon
|
||||
}
|
||||
|
||||
if (props.color) obj[props.color] = true
|
||||
return obj
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
class="ui-btn"
|
||||
:is="props.to ? 'router-link' : 'button'"
|
||||
:to="props.to"
|
||||
:class="props.color"
|
||||
:type="props.type"
|
||||
@click="clickHandler"
|
||||
:class="cssClass"
|
||||
>
|
||||
<ui-icon v-if="props.icon" :name="props.icon" />
|
||||
<div v-if="props.label" class="label">{{ props.label }}</div>
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
<script lang="ts">
|
||||
export type TUiCardProps = {
|
||||
title?: string
|
||||
}>()
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<TUiCardProps>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
+22
-11
@@ -1,32 +1,43 @@
|
||||
<script lang="ts">
|
||||
export type TUiDialogProps = {
|
||||
title?: string
|
||||
open?: boolean
|
||||
close?: boolean
|
||||
}
|
||||
|
||||
export type TUiDialogEmits = {
|
||||
(e: 'update:open', v: boolean): void
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import UiIcon from './Icon.vue'
|
||||
|
||||
const props = defineProps({
|
||||
open: { type: Boolean, default: false },
|
||||
close: { type: Boolean, default: false },
|
||||
title: { type: String }
|
||||
})
|
||||
// Props.
|
||||
const props = defineProps<TUiDialogProps>()
|
||||
|
||||
const emit = defineEmits(['update:open'])
|
||||
// Emits.
|
||||
const emit = defineEmits<TUiDialogEmits>()
|
||||
|
||||
// Init data.
|
||||
const dialogState = ref(props.open)
|
||||
|
||||
// Methods.
|
||||
const closeDialog = () => {
|
||||
dialogState.value = false
|
||||
emit('update:open', false)
|
||||
}
|
||||
|
||||
// Handlers.
|
||||
const clickWrapperHandler = (e: MouseEvent) => {
|
||||
if (e.target instanceof Element) {
|
||||
if (e.target.classList.contains('ui-dialog')) closeDialog()
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.open,
|
||||
val => (dialogState.value = val)
|
||||
)
|
||||
// Etc.
|
||||
watch(() => props.open, val => (dialogState.value = val))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -34,7 +45,7 @@ watch(
|
||||
<div class="ui-dialog-window">
|
||||
<div class="ui-dialog-window-header" v-if="props.title">
|
||||
<h4>{{ title }}</h4>
|
||||
<ui-icon name="close" @click="closeDialog" />
|
||||
<ui-icon name="close" @click="closeDialog" class="ui-icon-close" />
|
||||
</div>
|
||||
<div v-if="$slots.default" class="ui-dialog-window-content">
|
||||
<slot name="default" />
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
modelValue?: any
|
||||
label?: string
|
||||
type?: 'text' | 'number' | 'date' | 'password' | 'checkbox'
|
||||
error?: string
|
||||
readonly?: boolean
|
||||
disabled?: boolean
|
||||
placeholder?: string
|
||||
tag?: 'input' | 'textarea' | 'select'
|
||||
checked?: boolean
|
||||
options?: { text: string, value: any }[]
|
||||
multiple?: boolean
|
||||
}>()
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<{
|
||||
(e: 'input', v: any): void
|
||||
(e: 'update:modelValue', v: any): void
|
||||
(e: 'update:error'): void
|
||||
}>()
|
||||
|
||||
// Handlers.
|
||||
const inputHandler = (val: any) => {
|
||||
emit('input', val)
|
||||
emit('update:error')
|
||||
|
||||
if (val?.target?.value) {
|
||||
let value: any = val.target.value
|
||||
|
||||
try {
|
||||
switch (props.type) {
|
||||
case 'number':
|
||||
value = Number(value)
|
||||
break
|
||||
case 'date':
|
||||
value = new Date(value)
|
||||
break
|
||||
case 'text':
|
||||
case 'password':
|
||||
case 'checkbox':
|
||||
value = String(value)
|
||||
break
|
||||
}
|
||||
} catch (ex) {}
|
||||
|
||||
emit('update:modelValue', value)
|
||||
} else {
|
||||
emit('update:modelValue', undefined)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="{ 'ui-field': true, error: props.error, disabled: props.disabled }"
|
||||
>
|
||||
<div v-if="props.label" class="label">{{ props.label }}</div>
|
||||
<input
|
||||
v-if="!tag || tag === 'input'"
|
||||
class="input"
|
||||
:type="props.type"
|
||||
:value="props.modelValue"
|
||||
:readonly="props.readonly"
|
||||
:disabled="props.disabled"
|
||||
:checked="checked"
|
||||
:placeholder="props.placeholder"
|
||||
@input="inputHandler"
|
||||
/>
|
||||
<textarea
|
||||
v-if="tag === 'textarea'"
|
||||
class="input"
|
||||
:value="props.modelValue"
|
||||
:readonly="props.readonly"
|
||||
:disabled="props.disabled"
|
||||
:placeholder="props.placeholder"
|
||||
@input="inputHandler"
|
||||
/>
|
||||
<select
|
||||
v-if="tag === 'select'"
|
||||
class="input"
|
||||
:value="props.modelValue"
|
||||
:readonly="props.readonly"
|
||||
:disabled="props.disabled"
|
||||
:placeholder="props.placeholder"
|
||||
:multiple="props.multiple"
|
||||
@input="inputHandler"
|
||||
>
|
||||
<option v-for="item in props.options" :value="item.value">
|
||||
{{ item.text }}
|
||||
</option>
|
||||
</select>
|
||||
<div v-if="props.error" class="message">{{ props.error }}</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,31 +1,51 @@
|
||||
<script lang="ts">
|
||||
import type { TUiFiledWrapperProps } from './FieldWrapper.vue'
|
||||
|
||||
export type TUiFieldCheckboxProps = TUiFiledWrapperProps & {
|
||||
modelValue?: boolean
|
||||
}
|
||||
|
||||
export type TUiFieldCheckboxEmits = {
|
||||
(e: 'input', v: Event): void
|
||||
(e: 'update:model-value', v?: boolean): void
|
||||
(e: 'update:error', v?: string): void
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiField from './Field.vue'
|
||||
import { computed } from 'vue'
|
||||
import UiFieldWrapper from './FieldWrapper.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<{
|
||||
modelValue?: boolean
|
||||
disabled?: boolean
|
||||
readonly?: boolean
|
||||
}>()
|
||||
const props = defineProps<TUiFieldCheckboxProps>()
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<{ (e: 'update:modelValue', v?: boolean): void }>()
|
||||
|
||||
// Value.
|
||||
const value = computed(() => props.modelValue)
|
||||
const emit = defineEmits<TUiFieldCheckboxEmits>()
|
||||
|
||||
// Handlers.
|
||||
const updateHandler = () => emit('update:modelValue', !props.modelValue)
|
||||
const inputHandler = (val: Event) => {
|
||||
emit('input', val)
|
||||
emit('update:error')
|
||||
|
||||
if (val.target instanceof HTMLInputElement) {
|
||||
emit('update:model-value', !props.modelValue)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ui-field
|
||||
type="checkbox"
|
||||
class="ui-field-checkbox"
|
||||
:checked="value"
|
||||
<ui-field-wrapper
|
||||
:label="props.label"
|
||||
:error="props.error"
|
||||
:disabled="props.disabled"
|
||||
:readonly="props.readonly"
|
||||
@input="updateHandler"
|
||||
/>
|
||||
:description="props.description"
|
||||
class="ui-field-checkbox"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="props.modelValue"
|
||||
:disabled="props.disabled || props.readonly"
|
||||
@input="inputHandler"
|
||||
/>
|
||||
</ui-field-wrapper>
|
||||
</template>
|
||||
|
||||
@@ -1,32 +1,39 @@
|
||||
<script lang="ts">
|
||||
import type { TUiFieldInputProps, TUiFieldInputEmits } from './FieldInput.vue'
|
||||
|
||||
export type TUiFieldDateProps = TUiFieldInputProps<Date>
|
||||
export type TUiFieldDateEmits = TUiFieldInputEmits
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { cFieldsSchema, getDateCommonFormat } from 'axp-ts'
|
||||
import UiFieldInput from './FieldInput.vue'
|
||||
|
||||
import UiField from './Field.vue'
|
||||
// Props.
|
||||
const props = defineProps<TUiFieldDateProps>()
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue?: Date
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{ (e: 'update:modelValue', v?: Date): void }>()
|
||||
// Emits.
|
||||
const emit = defineEmits<TUiFieldDateEmits>()
|
||||
|
||||
// Etc.
|
||||
const valueStr = computed({
|
||||
get: () => {
|
||||
try {
|
||||
const value = cFieldsSchema.shape.date.parse(props.modelValue)
|
||||
const format = getDateCommonFormat(value)
|
||||
return format
|
||||
} catch (e) {}
|
||||
return getDateCommonFormat(value)
|
||||
} catch (e) { }
|
||||
},
|
||||
set: (val) => {
|
||||
set: val => {
|
||||
emit('update:error')
|
||||
try {
|
||||
const value = cFieldsSchema.shape.date.parse(val)
|
||||
emit('update:modelValue', value)
|
||||
} catch (e) {}
|
||||
emit('update:model-value', value)
|
||||
} catch (e) { }
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ui-field type="date" class="ui-field-date" v-model="valueStr" />
|
||||
<ui-field-input :="{ ...props, ...$attrs }" v-model="valueStr" type="date" />
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<script lang="ts">
|
||||
import type { TUiFiledWrapperProps } from './FieldWrapper.vue'
|
||||
|
||||
type TModelValue = FileList
|
||||
|
||||
export type TUiFieldFileProps = TUiFiledWrapperProps & {
|
||||
modelValue?: TModelValue
|
||||
multiple?: boolean
|
||||
accept?: string
|
||||
}
|
||||
|
||||
export type TUiFieldFileEmits = {
|
||||
(e: 'input', v?: Event): void
|
||||
(e: 'update:model-value', v?: TModelValue): void
|
||||
(e: 'update:error', v?: string): void
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiFieldWrapper from './FieldWrapper.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<TUiFieldFileProps>()
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<TUiFieldFileEmits>()
|
||||
|
||||
// Handlers.
|
||||
const inputHandler = (e: Event) => {
|
||||
emit('input', e)
|
||||
emit('update:error')
|
||||
|
||||
if (e.target instanceof HTMLInputElement && e.target.files) {
|
||||
emit('update:model-value', e.target.files)
|
||||
} else {
|
||||
emit('update:model-value')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ui-field-wrapper
|
||||
:label="props.label"
|
||||
:error="props.error"
|
||||
:disabled="props.disabled"
|
||||
:readonly="props.readonly"
|
||||
:description="props.description"
|
||||
>
|
||||
<input
|
||||
type="file"
|
||||
:multiple="props.multiple"
|
||||
:disabled="props.disabled || props.readonly"
|
||||
:accept="props.accept"
|
||||
@input="inputHandler"
|
||||
/>
|
||||
</ui-field-wrapper>
|
||||
</template>
|
||||
@@ -0,0 +1,64 @@
|
||||
<script lang="ts">
|
||||
import type { TUiFiledWrapperProps } from './FieldWrapper.vue'
|
||||
|
||||
export type TUiFieldInputProps<T extends string | number | Date> =
|
||||
TUiFiledWrapperProps & {
|
||||
type?: 'text' | 'number' | 'password' | 'date' | 'checkbox'
|
||||
modelValue?: T
|
||||
placeholder?: string
|
||||
}
|
||||
|
||||
export type TUiFieldInputEmits = {
|
||||
(e: 'input', v: Event): void
|
||||
(e: 'update:model-value', v?: string | number | Date): void
|
||||
(e: 'update:error', v?: string): void
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiFieldWrapper from './FieldWrapper.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<TUiFieldInputProps<any>>()
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<TUiFieldInputEmits>()
|
||||
|
||||
// Handlers.
|
||||
const inputHandler = (val: Event) => {
|
||||
emit('input', val)
|
||||
emit('update:error')
|
||||
|
||||
if (val.target instanceof HTMLInputElement) {
|
||||
const { value } = val.target
|
||||
switch (props.type) {
|
||||
case 'number':
|
||||
emit('update:model-value', Number(value))
|
||||
break
|
||||
default:
|
||||
emit('update:model-value', String(value))
|
||||
}
|
||||
} else {
|
||||
emit('update:model-value', undefined)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ui-field-wrapper
|
||||
:label="props.label"
|
||||
:error="props.error"
|
||||
:disabled="props.disabled"
|
||||
:readonly="props.readonly"
|
||||
:description="props.description"
|
||||
>
|
||||
<input
|
||||
:type="props.type"
|
||||
:value="props.modelValue"
|
||||
:placeholder="props.placeholder"
|
||||
:disabled="props.disabled"
|
||||
:readonly="props.readonly"
|
||||
@input="inputHandler"
|
||||
/>
|
||||
</ui-field-wrapper>
|
||||
</template>
|
||||
@@ -1,7 +1,16 @@
|
||||
<script lang="ts">
|
||||
import type { TUiFieldInputProps } from './FieldInput.vue'
|
||||
|
||||
export type TUiFieldNumberProps = TUiFieldInputProps<number>
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiField from './Field.vue'
|
||||
import UiFieldInput from './FieldInput.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<TUiFieldNumberProps>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ui-field type="number" class="ui-field-number" />
|
||||
<ui-field-input :="{ ...props, ...$attrs }" type="number" />
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
<script lang="ts">
|
||||
import type { TUiFieldInputProps } from './FieldInput.vue'
|
||||
|
||||
export type TFieldPasswordProps = TUiFieldInputProps<string>
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiField from './Field.vue'
|
||||
import UiFieldInput from './FieldInput.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<TFieldPasswordProps>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ui-field type="password" class="ui-field-password" />
|
||||
<ui-field-input :="{ ...props, ...$attrs }" type="password" />
|
||||
</template>
|
||||
|
||||
@@ -1,22 +1,32 @@
|
||||
<script lang="ts">
|
||||
import type { TUiFieldInputProps, TUiFieldInputEmits } from './FieldInput.vue'
|
||||
|
||||
export type TUiFieldPhoneProps = TUiFieldInputProps<number>
|
||||
export type TUiFieldPhoneEmits = TUiFieldInputEmits
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { getPhoneNumberFormat, getPhoneNumberValue } from 'axp-ts'
|
||||
|
||||
import UiField from './Field.vue'
|
||||
import UiFieldInput from './FieldInput.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<{ modelValue?: number }>()
|
||||
const props = defineProps<TUiFieldPhoneProps>()
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<{ (e: 'update:modelValue', v?: number): void }>()
|
||||
const emit = defineEmits<TUiFieldPhoneEmits>()
|
||||
|
||||
// Value string.
|
||||
const valueStr = computed({
|
||||
get: () => getPhoneNumberFormat(props.modelValue),
|
||||
set: val => emit('update:modelValue', getPhoneNumberValue(val))
|
||||
set: val => {
|
||||
emit('update:error')
|
||||
emit('update:model-value', getPhoneNumberValue(val))
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ui-field v-model="valueStr" class="ui-field-phone" />
|
||||
<ui-field-input :="{ ...props, ...$attrs }" v-model="valueStr" />
|
||||
</template>
|
||||
|
||||
@@ -1,27 +1,59 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import UiField from './Field.vue'
|
||||
<script lang="ts">
|
||||
import type { TUiFiledWrapperProps } from './FieldWrapper.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue?: string | string[] | number | number[],
|
||||
export type TUiFieldSelectProps = TUiFiledWrapperProps & {
|
||||
modelValue?: string | string[] | number | number[]
|
||||
options?: { text: string; value: string | number }[]
|
||||
multiple?: boolean
|
||||
options: { text: string, value: any }[]
|
||||
}>()
|
||||
}
|
||||
|
||||
const emit = defineEmits<{ (e: 'update:modelValue', v?: any): void }>()
|
||||
export type TUiFieldSelectEmits = {
|
||||
(e: 'input', v: Event): void
|
||||
(e: 'update:model-value', v?: string | string[] | number | number[]): void
|
||||
(e: 'update:error', v?: string): void
|
||||
}
|
||||
</script>
|
||||
|
||||
const displayValue = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emit('update:modelValue', val)
|
||||
})
|
||||
<script setup lang="ts">
|
||||
import UiFieldWrapper from './FieldWrapper.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<TUiFieldSelectProps>()
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<TUiFieldSelectEmits>()
|
||||
|
||||
// Handlers.
|
||||
const inputHandler = (val: Event) => {
|
||||
emit('input', val)
|
||||
emit('update:error')
|
||||
|
||||
if (val.target instanceof HTMLSelectElement) {
|
||||
emit('update:model-value', val.target.value)
|
||||
} else {
|
||||
emit('update:model-value')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ui-field
|
||||
tag="select"
|
||||
<ui-field-wrapper
|
||||
:label="props.label"
|
||||
:error="props.error"
|
||||
:disabled="props.disabled"
|
||||
:readonly="props.readonly"
|
||||
:description="props.description"
|
||||
class="ui-field-select"
|
||||
:options="props.options"
|
||||
:multiple="props.multiple"
|
||||
v-model="displayValue"
|
||||
/>
|
||||
>
|
||||
<select
|
||||
:value="props.modelValue"
|
||||
:multiple="props.multiple"
|
||||
:disabled="props.disabled || props.readonly"
|
||||
@input="inputHandler"
|
||||
>
|
||||
<option v-for="item in props.options" :value="item.value">
|
||||
{{ item.text }}
|
||||
</option>
|
||||
</select>
|
||||
</ui-field-wrapper>
|
||||
</template>
|
||||
|
||||
@@ -15,5 +15,5 @@ const options: { text: string, value: TGender }[] = [
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ui-field-select class="ui-field-select-gender" :options="options" />
|
||||
<ui-field-select :options="options" />
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
<script lang="ts">
|
||||
import type { TUiFieldInputProps } from './FieldInput.vue'
|
||||
|
||||
export type TUiFieldText = TUiFieldInputProps<string>
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiField from './Field.vue'
|
||||
import UiFieldInput from './FieldInput.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<TUiFieldText>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ui-field class="ui-field-text" />
|
||||
<ui-field-input :="{ ...props, ...$attrs }" type="text" />
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,50 @@
|
||||
<script lang="ts">
|
||||
import type { TUiFiledWrapperProps } from './FieldWrapper.vue'
|
||||
|
||||
export type TUiFieldTextAreaProps = TUiFiledWrapperProps & {
|
||||
modelValue?: string
|
||||
}
|
||||
|
||||
export type TUiFieldTextAreaEmits = {
|
||||
(e: 'input', v: Event): void
|
||||
(e: 'update:model-value', v?: string | number | Date): void
|
||||
(e: 'update:error', v?: string): void
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiField from './Field.vue'
|
||||
import UiFieldWrapper from './FieldWrapper.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<TUiFieldTextAreaProps>()
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<TUiFieldTextAreaEmits>()
|
||||
|
||||
// Handlers.
|
||||
const inputHandler = (val: Event) => {
|
||||
emit('input', val)
|
||||
emit('update:error')
|
||||
|
||||
if (val.target instanceof HTMLTextAreaElement) {
|
||||
emit('update:model-value', val.target.value)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ui-field tag="textarea" class="ui-field-textarea" />
|
||||
<ui-field-wrapper
|
||||
:label="props.label"
|
||||
:error="props.error"
|
||||
:disabled="props.disabled"
|
||||
:readonly="props.readonly"
|
||||
:description="props.description"
|
||||
class="ui-field-textarea"
|
||||
>
|
||||
<textarea
|
||||
:value="props.modelValue"
|
||||
:disabled="props.disabled || props.readonly"
|
||||
@input="inputHandler"
|
||||
/>
|
||||
</ui-field-wrapper>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<script lang="ts">
|
||||
export type TUiFiledWrapperProps = {
|
||||
label?: string
|
||||
error?: string
|
||||
disabled?: boolean
|
||||
readonly?: boolean
|
||||
description?: string
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
// Props.
|
||||
const props = defineProps<TUiFiledWrapperProps>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'ui-field': true,
|
||||
error: props.error,
|
||||
disabled: props.disabled,
|
||||
readonly: props.readonly
|
||||
}"
|
||||
>
|
||||
<div class="ui-field-wrap">
|
||||
<div v-if="props.label" class="label">{{ props.label }}</div>
|
||||
<div class="input">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="props.description" class="description">
|
||||
{{ props.description }}
|
||||
</div>
|
||||
<div v-if="props.error" class="message">{{ props.error }}</div>
|
||||
</div>
|
||||
</template>
|
||||
+41
-32
@@ -1,16 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import type { Ref } from 'vue'
|
||||
import type { TNotificationItem, BaseFormModel } from 'axp-ts'
|
||||
<script lang="ts">
|
||||
import type { TNotificationItem, IFormModel } from 'axp-ts'
|
||||
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { colors } from '../colors'
|
||||
|
||||
import UiBtn from './Btn.vue'
|
||||
import UiAlert from './Alert.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<{
|
||||
modelValue?: BaseFormModel<any>
|
||||
export type TUiFormProps<T = any> = {
|
||||
modelValue?: IFormModel<T>
|
||||
title?: string
|
||||
noTitle?: boolean
|
||||
messages?: TNotificationItem[]
|
||||
@@ -18,16 +10,30 @@ const props = defineProps<{
|
||||
disabled?: boolean
|
||||
load?: boolean
|
||||
showAll?: boolean
|
||||
fn?: (obj?: any) => Promise<any>
|
||||
}>()
|
||||
fn?: (obj?: T) => Promise<T>
|
||||
}
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<{
|
||||
(e: 'submit', v?: BaseFormModel<any>): void
|
||||
(e: 'failedValid', v?: BaseFormModel<any>): void
|
||||
export type TUiFormEmits<T = any> = {
|
||||
(e: 'submit', v?: IFormModel<T>): void
|
||||
(e: 'failedValid', v?: IFormModel<T>): void
|
||||
(e: 'update:load', v: boolean): void
|
||||
(e: 'fnCompleted', v?: any): void
|
||||
}>()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import UiBtn from './Btn.vue'
|
||||
import UiAlert from './Alert.vue'
|
||||
|
||||
import { colors } from '../colors'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<TUiFormProps>()
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<TUiFormEmits>()
|
||||
|
||||
// Controls.
|
||||
const ctrls = computed(() => {
|
||||
@@ -35,7 +41,6 @@ const ctrls = computed(() => {
|
||||
if (props.showAll) {
|
||||
return props.modelValue.ctrls
|
||||
} else {
|
||||
// @ts-ignore
|
||||
return props.modelValue.ctrls.filter(e => !e.hidden)
|
||||
}
|
||||
}
|
||||
@@ -76,7 +81,6 @@ const submitHandler = async () => {
|
||||
if (err.code && err.text)
|
||||
if (
|
||||
props.modelValue &&
|
||||
// @ts-ignore
|
||||
props.modelValue.ctrls.find(e => e.key === err.code)
|
||||
) {
|
||||
props.modelValue.setValidError(err.code, err.text)
|
||||
@@ -118,18 +122,23 @@ const getColorMessage = (item: TNotificationItem) => {
|
||||
/>
|
||||
</div>
|
||||
<div class="ui-form-body">
|
||||
<component
|
||||
v-if="props.modelValue"
|
||||
v-for="ctrl in ctrls"
|
||||
:is="ctrl.component"
|
||||
:label="ctrl.label"
|
||||
v-model="props.modelValue.obj[ctrl.key]"
|
||||
v-model:error="props.modelValue._errors[ctrl.key]"
|
||||
:readonly="ctrl.readonly"
|
||||
:disabled="load || props.load || props.disabled || ctrl.disabled"
|
||||
:class="'ui-field-' + ctrl.key"
|
||||
/>
|
||||
<slot v-if="$slots.pre" name="pre" />
|
||||
<slot v-if="$slots.default" name="default" />
|
||||
<template v-else>
|
||||
<component
|
||||
v-if="props.modelValue"
|
||||
v-for="ctrl in ctrls"
|
||||
:is="ctrl.component"
|
||||
:label="ctrl.label"
|
||||
v-model="props.modelValue.obj[ctrl.key]"
|
||||
v-model:error="props.modelValue._errors[ctrl.key]"
|
||||
:readonly="ctrl.readonly"
|
||||
:disabled="load || props.load || props.disabled || ctrl.disabled"
|
||||
:description="ctrl.description"
|
||||
:class="'ui-field-key-' + ctrl.key"
|
||||
/>
|
||||
</template>
|
||||
<slot v-if="$slots.post" name="post" />
|
||||
</div>
|
||||
<div v-if="!props.noActions" class="ui-form-actions">
|
||||
<slot v-if="$slots.actions" name="actions" />
|
||||
|
||||
+12
-10
@@ -1,19 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
<script lang="ts">
|
||||
import type { TUiIcon } from '../icons'
|
||||
|
||||
export type TUiIconProps = {
|
||||
name: TUiIcon
|
||||
fill?: boolean
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { icons } from '../icons'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<{
|
||||
name: TUiIcon
|
||||
fill?: boolean
|
||||
}>()
|
||||
const props = defineProps<TUiIconProps>()
|
||||
|
||||
const iconName = computed(() => {
|
||||
// @ts-ignore
|
||||
return icons[props.name]
|
||||
})
|
||||
// Etc.
|
||||
const icon = computed(() => icons[props.name])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -23,7 +25,7 @@ const iconName = computed(() => {
|
||||
:fill="fill ? 'currentColor' : 'none'"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.2"
|
||||
v-html="iconName"
|
||||
v-html="icon"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
<script lang="ts">
|
||||
export type TUiIconVisibilityProps = {
|
||||
modelValue?: boolean,
|
||||
color?: boolean,
|
||||
cursor?: boolean
|
||||
}
|
||||
|
||||
export type TUiIconVisibilityEmits = {
|
||||
(e: 'update:modelValue', v: boolean): void
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiIcon from './Icon.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<{
|
||||
modelValue?: boolean,
|
||||
color?: boolean,
|
||||
cursor?: boolean
|
||||
}>()
|
||||
const props = defineProps<TUiIconVisibilityProps>()
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<{ (e: 'update:modelValue', v: boolean): void }>()
|
||||
const emit = defineEmits<TUiIconVisibilityEmits>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import UiFieldCheckbox from './FieldCheckbox.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<{
|
||||
<script lang="ts">
|
||||
export type TUiPickerDaysProps = {
|
||||
modelValue?: number[]
|
||||
label?: string
|
||||
error?: string
|
||||
readonly?: boolean
|
||||
disabled?: boolean
|
||||
}>()
|
||||
}
|
||||
|
||||
export type TUiPickerDaysEmits = {
|
||||
(e: 'update:modelValue', v: number[]): void
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiFieldCheckbox from './FieldCheckbox.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<TUiPickerDaysProps>()
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<{ (e: 'update:modelValue', v: number[]): void }>()
|
||||
const emit = defineEmits<TUiPickerDaysEmits>()
|
||||
|
||||
// Init data.
|
||||
const days = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс']
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
<script lang="ts">
|
||||
export type TTheme = 'light' | 'dark'
|
||||
export type TUiThemeName = 'light' | 'dark'
|
||||
|
||||
export type TUiToggleThemeProps = {
|
||||
modelValue?: TUiThemeName
|
||||
}
|
||||
|
||||
export type TUiToggleThemeEmits = {
|
||||
(e: 'update:modelValue', v: TUiThemeName): void
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UiIcon from './Icon.vue'
|
||||
|
||||
// Props.
|
||||
const props = defineProps<{
|
||||
modelValue?: TTheme
|
||||
}>()
|
||||
const props = defineProps<TUiToggleThemeProps>()
|
||||
|
||||
// Emits.
|
||||
const emit = defineEmits<{ (e: 'update:modelValue', v: TTheme): void }>()
|
||||
const emit = defineEmits<TUiToggleThemeEmits>()
|
||||
|
||||
// Handlers.
|
||||
const clickHandler = ({}: PointerEvent) =>
|
||||
|
||||
+61
-16
@@ -1,20 +1,65 @@
|
||||
export { default as UiBtn } from './Btn.vue'
|
||||
export { default as UiAlert } from './Alert.vue'
|
||||
export { default as UiField } from './Field.vue'
|
||||
export { default as UiFieldText } from './FieldText.vue'
|
||||
export { default as UiFieldTextArea } from './FieldTextArea.vue'
|
||||
export { default as UiFieldPassword } from './FieldPassword.vue'
|
||||
export { default as UiFieldNumber } from './FieldNumber.vue'
|
||||
export { default as UiFieldPhone } from './FieldPhone.vue'
|
||||
export { default as UiFieldDate } from './FieldDate.vue'
|
||||
export { default as UiFieldCheckbox } from './FieldCheckbox.vue'
|
||||
export { default as UiFieldSelect } from './FieldSelect.vue'
|
||||
export { default as UiFieldSelectGender } from './FieldSelectGender.vue'
|
||||
export { default as UiPickerDays } from './PickerDays.vue'
|
||||
export { default as UiIcon } from './Icon.vue'
|
||||
export { default as UiIconVisibility } from './IconVisibility.vue'
|
||||
export { default as UiForm } from './Form.vue'
|
||||
export * from './Alert.vue'
|
||||
|
||||
export { default as UiBtn } from './Btn.vue'
|
||||
export * from './Btn.vue'
|
||||
|
||||
export { default as UiCard } from './Card.vue'
|
||||
export { default as UiTable } from './Table.vue'
|
||||
export * from './Card.vue'
|
||||
|
||||
export { default as UiDialog } from './Dialog.vue'
|
||||
export * from './Dialog.vue'
|
||||
|
||||
export { default as UiIcon } from './Icon.vue'
|
||||
export * from './Icon.vue'
|
||||
|
||||
export { default as UiIconVisibility } from './IconVisibility.vue'
|
||||
export * from './IconVisibility.vue'
|
||||
|
||||
export { default as UiTable } from './Table.vue'
|
||||
export * from './Table.vue'
|
||||
|
||||
export { default as UiToggleTheme } from './ToggleTheme.vue'
|
||||
export * from './ToggleTheme.vue'
|
||||
|
||||
export { default as UiFieldWrapper } from './FieldWrapper.vue'
|
||||
export * from './FieldWrapper.vue'
|
||||
|
||||
export { default as UiFieldInput } from './FieldInput.vue'
|
||||
export * from './FieldInput.vue'
|
||||
|
||||
export { default as UiFieldText } from './FieldText.vue'
|
||||
export * from './FieldText.vue'
|
||||
|
||||
export { default as UiFieldNumber } from './FieldNumber.vue'
|
||||
export * from './FieldNumber.vue'
|
||||
|
||||
export { default as UiFieldPassword } from './FieldPassword.vue'
|
||||
export * from './FieldPassword.vue'
|
||||
|
||||
export { default as UiFieldPhone } from './FieldPhone.vue'
|
||||
export * from './FieldPhone.vue'
|
||||
|
||||
export { default as UiFieldDate } from './FieldDate.vue'
|
||||
export * from './FieldDate.vue'
|
||||
|
||||
export { default as UiFieldTextArea } from './FieldTextArea.vue'
|
||||
export * from './FieldTextArea.vue'
|
||||
|
||||
export { default as UiFieldFile } from './FieldFile.vue'
|
||||
export * from './FieldFile.vue'
|
||||
|
||||
export { default as UiFieldCheckbox } from './FieldCheckbox.vue'
|
||||
export * from './FieldCheckbox.vue'
|
||||
|
||||
export { default as UiFieldSelect } from './FieldSelect.vue'
|
||||
export * from './FieldSelect.vue'
|
||||
|
||||
export { default as UiFieldSelectGender } from './FieldSelectGender.vue'
|
||||
export * from './FieldSelectGender.vue'
|
||||
|
||||
export { default as UiPickerDays } from './PickerDays.vue'
|
||||
export * from './PickerDays.vue'
|
||||
|
||||
export { default as UiForm } from './Form.vue'
|
||||
export * from './Form.vue'
|
||||
|
||||
Reference in New Issue
Block a user