@byyuurin/ui 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -3
- package/dist/module.json +1 -1
- package/dist/module.mjs +4 -3
- package/dist/module.mjs.map +1 -1
- package/dist/runtime/app/injections.d.ts +9299 -8
- package/dist/runtime/app/injections.js +35 -5
- package/dist/runtime/components/Accordion.vue +17 -19
- package/dist/runtime/components/Alert.vue +6 -9
- package/dist/runtime/components/App.vue +14 -19
- package/dist/runtime/components/Avatar.vue +5 -8
- package/dist/runtime/components/AvatarGroup.vue +2 -5
- package/dist/runtime/components/Badge.vue +3 -6
- package/dist/runtime/components/Breadcrumb.vue +22 -23
- package/dist/runtime/components/Button.vue +2 -3
- package/dist/runtime/components/ButtonGroup.vue +2 -5
- package/dist/runtime/components/Calendar.vue +185 -0
- package/dist/runtime/components/Card.vue +2 -5
- package/dist/runtime/components/Carousel.vue +11 -16
- package/dist/runtime/components/Checkbox.vue +13 -11
- package/dist/runtime/components/Chip.vue +6 -9
- package/dist/runtime/components/Collapsible.vue +2 -5
- package/dist/runtime/components/Drawer.vue +88 -45
- package/dist/runtime/components/DropdownMenu.vue +143 -0
- package/dist/runtime/components/DropdownMenuContent.vue +188 -0
- package/dist/runtime/components/Form.vue +311 -0
- package/dist/runtime/components/FormItem.vue +129 -0
- package/dist/runtime/components/Input.vue +34 -23
- package/dist/runtime/components/InputNumber.vue +23 -18
- package/dist/runtime/components/Kbd.vue +2 -6
- package/dist/runtime/components/Link.vue +25 -7
- package/dist/runtime/components/Modal.vue +31 -22
- package/dist/runtime/components/OverlayProvider.vue +29 -0
- package/dist/runtime/components/Pagination.vue +34 -27
- package/dist/runtime/components/PinInput.vue +23 -17
- package/dist/runtime/components/Popover.vue +5 -8
- package/dist/runtime/components/Progress.vue +2 -5
- package/dist/runtime/components/RadioGroup.vue +52 -49
- package/dist/runtime/components/ScrollArea.vue +2 -6
- package/dist/runtime/components/Select.vue +96 -89
- package/dist/runtime/components/Separator.vue +2 -6
- package/dist/runtime/components/Skeleton.vue +2 -5
- package/dist/runtime/components/Slider.vue +13 -11
- package/dist/runtime/components/Switch.vue +18 -11
- package/dist/runtime/components/Table.vue +23 -13
- package/dist/runtime/components/Tabs.vue +14 -16
- package/dist/runtime/components/Textarea.vue +20 -17
- package/dist/runtime/components/Toast.vue +12 -13
- package/dist/runtime/components/{Toaster.vue → ToastProvider.vue} +18 -16
- package/dist/runtime/components/Tooltip.vue +5 -8
- package/dist/runtime/composables/useFormItem.d.ts +27 -0
- package/dist/runtime/composables/useFormItem.js +64 -0
- package/dist/runtime/composables/useKbd.d.ts +1 -1
- package/dist/runtime/composables/useOverlay.d.ts +29 -0
- package/dist/runtime/composables/useOverlay.js +69 -0
- package/dist/runtime/composables/useTheme.d.ts +6 -2
- package/dist/runtime/composables/useTheme.js +10 -3
- package/dist/runtime/composables/useToast.d.ts +4 -20
- package/dist/runtime/composables/useToast.js +6 -5
- package/dist/runtime/index.d.ts +6 -2
- package/dist/runtime/index.js +6 -2
- package/dist/runtime/locale/en.js +6 -0
- package/dist/runtime/locale/zh-tw.js +6 -0
- package/dist/runtime/theme/accordion.js +3 -3
- package/dist/runtime/theme/alert.js +3 -3
- package/dist/runtime/theme/app.d.ts +1 -0
- package/dist/runtime/theme/app.js +2 -1
- package/dist/runtime/theme/avatar.js +2 -2
- package/dist/runtime/theme/badge.d.ts +21 -45
- package/dist/runtime/theme/breadcrumb.d.ts +3 -3
- package/dist/runtime/theme/breadcrumb.js +5 -5
- package/dist/runtime/theme/button.d.ts +111 -57
- package/dist/runtime/theme/button.js +13 -13
- package/dist/runtime/theme/calendar.d.ts +56 -0
- package/dist/runtime/theme/calendar.js +69 -0
- package/dist/runtime/theme/card.js +6 -6
- package/dist/runtime/theme/carousel.js +1 -1
- package/dist/runtime/theme/checkbox.js +5 -5
- package/dist/runtime/theme/chip.d.ts +11 -44
- package/dist/runtime/theme/chip.js +3 -3
- package/dist/runtime/theme/drawer.d.ts +85 -47
- package/dist/runtime/theme/drawer.js +46 -19
- package/dist/runtime/theme/dropdown-menu.d.ts +71 -0
- package/dist/runtime/theme/dropdown-menu.js +83 -0
- package/dist/runtime/theme/form-item.d.ts +76 -0
- package/dist/runtime/theme/form-item.js +34 -0
- package/dist/runtime/theme/form.d.ts +8 -0
- package/dist/runtime/theme/form.js +7 -0
- package/dist/runtime/theme/index.d.ts +5 -1
- package/dist/runtime/theme/index.js +5 -1
- package/dist/runtime/theme/input-number.d.ts +41 -61
- package/dist/runtime/theme/input-number.js +1 -1
- package/dist/runtime/theme/input.d.ts +99 -71
- package/dist/runtime/theme/input.js +15 -15
- package/dist/runtime/theme/kbd.d.ts +2 -2
- package/dist/runtime/theme/kbd.js +1 -1
- package/dist/runtime/theme/link.d.ts +1 -1
- package/dist/runtime/theme/link.js +3 -3
- package/dist/runtime/theme/modal.d.ts +5 -33
- package/dist/runtime/theme/modal.js +4 -4
- package/dist/runtime/theme/pagination.d.ts +27 -3
- package/dist/runtime/theme/pagination.js +6 -2
- package/dist/runtime/theme/pinInput.d.ts +42 -42
- package/dist/runtime/theme/pinInput.js +13 -13
- package/dist/runtime/theme/progress.d.ts +117 -53
- package/dist/runtime/theme/progress.js +4 -4
- package/dist/runtime/theme/radio-group.d.ts +2 -2
- package/dist/runtime/theme/radio-group.js +7 -7
- package/dist/runtime/theme/select.d.ts +100 -84
- package/dist/runtime/theme/select.js +21 -20
- package/dist/runtime/theme/separator.d.ts +13 -28
- package/dist/runtime/theme/separator.js +1 -1
- package/dist/runtime/theme/skeleton.d.ts +1 -1
- package/dist/runtime/theme/skeleton.js +1 -1
- package/dist/runtime/theme/slider.js +1 -1
- package/dist/runtime/theme/switch.js +5 -5
- package/dist/runtime/theme/table.d.ts +3 -0
- package/dist/runtime/theme/table.js +8 -7
- package/dist/runtime/theme/tabs.d.ts +51 -68
- package/dist/runtime/theme/tabs.js +10 -10
- package/dist/runtime/theme/textarea.d.ts +37 -43
- package/dist/runtime/theme/textarea.js +13 -13
- package/dist/runtime/theme/{toaster.d.ts → toast-provider.d.ts} +26 -41
- package/dist/runtime/theme/toast.js +5 -5
- package/dist/runtime/theme/tooltip.js +1 -1
- package/dist/runtime/types/components.d.ts +6 -1
- package/dist/runtime/types/form.d.ts +45 -0
- package/dist/runtime/types/form.js +0 -0
- package/dist/runtime/types/index.d.ts +5 -2
- package/dist/runtime/types/index.js +1 -0
- package/dist/runtime/types/locale.d.ts +6 -0
- package/dist/runtime/types/utils.d.ts +35 -12
- package/dist/runtime/utils/extend-theme.js +15 -4
- package/dist/runtime/utils/form.d.ts +5 -0
- package/dist/runtime/utils/form.js +24 -0
- package/dist/runtime/utils/index.d.ts +2 -0
- package/dist/runtime/utils/index.js +4 -0
- package/dist/runtime/utils/link.d.ts +4 -26
- package/dist/runtime/utils/link.js +10 -3
- package/dist/shared/ui.3e7fad19.mjs +5 -0
- package/dist/shared/ui.3e7fad19.mjs.map +1 -0
- package/dist/unocss.mjs +21 -16
- package/dist/unocss.mjs.map +1 -1
- package/dist/unplugin.mjs +1 -1
- package/dist/vite.mjs +1 -1
- package/package.json +20 -18
- package/dist/runtime/components/ModalProvider.vue +0 -11
- package/dist/runtime/composables/useModal.d.ts +0 -10
- package/dist/runtime/composables/useModal.js +0 -47
- package/dist/shared/ui.ba24b380.mjs +0 -4
- package/dist/shared/ui.ba24b380.mjs.map +0 -1
- /package/dist/runtime/theme/{toaster.js → toast-provider.js} +0 -0
|
@@ -5,7 +5,7 @@ import type { switch as _switch } from '../theme'
|
|
|
5
5
|
import type { ComponentAttrs } from '../types'
|
|
6
6
|
|
|
7
7
|
export interface SwitchEmits {
|
|
8
|
-
|
|
8
|
+
change: [payload: Event]
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export interface SwitchSlots {
|
|
@@ -37,6 +37,7 @@ export interface SwitchProps extends ComponentAttrs<typeof _switch>, Pick<Switch
|
|
|
37
37
|
import { reactivePick } from '@vueuse/core'
|
|
38
38
|
import { Label, Primitive, SwitchRoot, SwitchThumb, useForwardProps } from 'reka-ui'
|
|
39
39
|
import { computed, useId } from 'vue'
|
|
40
|
+
import { useFormItem } from '../composables/useFormItem'
|
|
40
41
|
import { useTheme } from '../composables/useTheme'
|
|
41
42
|
|
|
42
43
|
const props = withDefaults(defineProps<SwitchProps>(), {})
|
|
@@ -45,18 +46,26 @@ const slots = defineSlots<SwitchSlots>()
|
|
|
45
46
|
const modelValue = defineModel<boolean>({ default: undefined })
|
|
46
47
|
|
|
47
48
|
const rootProps = useForwardProps(reactivePick(props, 'required', 'value', 'defaultValue'))
|
|
48
|
-
const id = useId()
|
|
49
49
|
|
|
50
|
-
const {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
const { id: _id, size, name, disabled, ariaAttrs, emitFormChange, emitFormInput } = useFormItem<SwitchProps>(props)
|
|
51
|
+
const id = _id.value ?? useId()
|
|
52
|
+
|
|
53
|
+
const { theme, generateStyle } = useTheme()
|
|
54
|
+
const style = computed(() => generateStyle('switch', {
|
|
55
|
+
...props,
|
|
56
|
+
size: size.value,
|
|
57
|
+
disabled: disabled.value,
|
|
58
|
+
checked: false,
|
|
59
|
+
unchecked: false,
|
|
60
|
+
}))
|
|
55
61
|
|
|
56
62
|
function onUpdate(value: any) {
|
|
57
63
|
// @ts-expect-error - 'target' does not exist in type 'EventInit'
|
|
58
64
|
const event = new Event('change', { target: { value } })
|
|
65
|
+
|
|
59
66
|
emit('change', event)
|
|
67
|
+
emitFormChange()
|
|
68
|
+
emitFormInput()
|
|
60
69
|
}
|
|
61
70
|
</script>
|
|
62
71
|
|
|
@@ -64,12 +73,10 @@ function onUpdate(value: any) {
|
|
|
64
73
|
<Primitive :as="props.as" :class="style.root({ class: [props.class, props.ui?.root] })">
|
|
65
74
|
<div :class="style.container({ class: props.ui?.container })">
|
|
66
75
|
<SwitchRoot
|
|
67
|
-
|
|
68
|
-
v-bind="rootProps"
|
|
76
|
+
v-bind="{ ...rootProps, ...ariaAttrs, id, name }"
|
|
69
77
|
v-model="modelValue"
|
|
70
|
-
:name="props.name"
|
|
71
|
-
:disabled="props.disabled || props.loading"
|
|
72
78
|
:class="style.base({ class: props.ui?.base })"
|
|
79
|
+
:disabled="disabled || props.loading"
|
|
73
80
|
@update:model-value="onUpdate"
|
|
74
81
|
>
|
|
75
82
|
<SwitchThumb :class="style.thumb({ class: props.ui?.thumb })">
|
|
@@ -10,9 +10,10 @@ type DynamicHeaderSlots<T, K = keyof T> = Record<string, (props: HeaderContext<T
|
|
|
10
10
|
type DynamicCellSlots<T, K = keyof T> = Record<string, (props: CellContext<T, unknown>) => any> & Record<`${K extends string ? K : never}-cell`, (props: CellContext<T, unknown>) => any>
|
|
11
11
|
|
|
12
12
|
export type TableSlots<T> = {
|
|
13
|
-
expanded
|
|
14
|
-
empty
|
|
15
|
-
|
|
13
|
+
expanded?: (props: { row: Row<T> }) => any
|
|
14
|
+
empty?: any
|
|
15
|
+
loading?: any
|
|
16
|
+
caption?: any
|
|
16
17
|
} & DynamicHeaderSlots<T> & DynamicCellSlots<T>
|
|
17
18
|
|
|
18
19
|
export type TableData = RowData
|
|
@@ -33,11 +34,18 @@ export interface TableProps<T extends TableData> extends ComponentAttrs<typeof t
|
|
|
33
34
|
data?: T[]
|
|
34
35
|
columns?: TableColumn<T>[]
|
|
35
36
|
caption?: string
|
|
37
|
+
/**
|
|
38
|
+
* The text to display when the table is empty.
|
|
39
|
+
* @default t('table.noData')
|
|
40
|
+
*/
|
|
41
|
+
empty?: string
|
|
36
42
|
/**
|
|
37
43
|
* Whether the table should have a sticky header.
|
|
38
44
|
* @default false
|
|
39
45
|
*/
|
|
40
46
|
sticky?: boolean
|
|
47
|
+
/** Whether the table should be in loading state. */
|
|
48
|
+
loading?: boolean
|
|
41
49
|
/**
|
|
42
50
|
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/global-filtering#table-options)
|
|
43
51
|
* @link [Guide](https://tanstack.com/table/v8/docs/guide/global-filtering)
|
|
@@ -111,8 +119,7 @@ import { useLocale } from '../composables/useLocale'
|
|
|
111
119
|
import { useTheme } from '../composables/useTheme'
|
|
112
120
|
|
|
113
121
|
const props = defineProps<TableProps<T>>()
|
|
114
|
-
|
|
115
|
-
defineSlots<TableSlots<T>>()
|
|
122
|
+
const slots = defineSlots<TableSlots<T>>()
|
|
116
123
|
|
|
117
124
|
const globalFilterState = defineModel<string>('globalFilter', { default: undefined })
|
|
118
125
|
const columnFiltersState = defineModel<ColumnFiltersState>('columnFilters', { default: [] })
|
|
@@ -137,7 +144,7 @@ const columns = computed<TableColumn<T>[]>(
|
|
|
137
144
|
)
|
|
138
145
|
|
|
139
146
|
const tableApi = useVueTable({
|
|
140
|
-
...reactiveOmit(props, 'data', 'columns', 'caption', 'sticky', 'class', 'ui'),
|
|
147
|
+
...reactiveOmit(props, 'data', 'columns', 'caption', 'sticky', 'loading', 'class', 'ui'),
|
|
141
148
|
data,
|
|
142
149
|
columns: columns.value,
|
|
143
150
|
getCoreRowModel: getCoreRowModel(),
|
|
@@ -229,11 +236,8 @@ function valueUpdater<T extends Updater<any>>(updaterOrValue: T, ref: Ref) {
|
|
|
229
236
|
}
|
|
230
237
|
|
|
231
238
|
const { t } = useLocale()
|
|
232
|
-
const {
|
|
233
|
-
const style = computed(() =>
|
|
234
|
-
const styler = createStyler(theme.value.table)
|
|
235
|
-
return styler(props)
|
|
236
|
-
})
|
|
239
|
+
const { generateStyle } = useTheme()
|
|
240
|
+
const style = computed(() => generateStyle('table', props))
|
|
237
241
|
|
|
238
242
|
defineExpose({
|
|
239
243
|
tableApi,
|
|
@@ -243,7 +247,7 @@ defineExpose({
|
|
|
243
247
|
<template>
|
|
244
248
|
<Primitive :as="props.as" :class="style.root({ class: [props.class, props.ui?.root] })">
|
|
245
249
|
<table :class="style.base({ class: props.ui?.base })">
|
|
246
|
-
<caption v-if="props.caption" :class="style.caption({ class: props.caption })">
|
|
250
|
+
<caption v-if="props.caption || slots.caption" :class="style.caption({ class: props.caption })">
|
|
247
251
|
<slot name="caption">
|
|
248
252
|
{{ props.caption }}
|
|
249
253
|
</slot>
|
|
@@ -287,10 +291,16 @@ defineExpose({
|
|
|
287
291
|
</template>
|
|
288
292
|
</template>
|
|
289
293
|
|
|
294
|
+
<tr v-else-if="props.loading && slots.loading">
|
|
295
|
+
<td :colspan="columns.length" :class="style.loading({ class: props.ui?.loading })">
|
|
296
|
+
<slot name="loading"></slot>
|
|
297
|
+
</td>
|
|
298
|
+
</tr>
|
|
299
|
+
|
|
290
300
|
<tr v-else :class="style.tr({ class: props.ui?.tr })">
|
|
291
301
|
<td :colspan="columns.length" :class="style.empty({ class: props.ui?.empty })">
|
|
292
302
|
<slot name="empty">
|
|
293
|
-
{{ t('table.noData') }}
|
|
303
|
+
{{ props.empty || t('table.noData') }}
|
|
294
304
|
</slot>
|
|
295
305
|
</td>
|
|
296
306
|
</tr>
|
|
@@ -6,15 +6,6 @@ import type { ComponentAttrs, DynamicSlots } from '../types'
|
|
|
6
6
|
|
|
7
7
|
export interface TabsEmits extends TabsRootEmits<string | number> {}
|
|
8
8
|
|
|
9
|
-
type SlotProps<T> = (props: { item: T, index: number }) => any
|
|
10
|
-
|
|
11
|
-
export type TabsSlots<T extends { slot?: string }> = {
|
|
12
|
-
leading?: SlotProps<T>
|
|
13
|
-
default?: SlotProps<T>
|
|
14
|
-
trailing?: SlotProps<T>
|
|
15
|
-
content?: SlotProps<T>
|
|
16
|
-
} & DynamicSlots<T, SlotProps<T>>
|
|
17
|
-
|
|
18
9
|
export interface TabsItem {
|
|
19
10
|
label?: string
|
|
20
11
|
icon?: string
|
|
@@ -23,11 +14,21 @@ export interface TabsItem {
|
|
|
23
14
|
/** A unique value for the tab item. Defaults to the index. */
|
|
24
15
|
value?: string | number
|
|
25
16
|
disabled?: boolean
|
|
17
|
+
[key: string]: any
|
|
26
18
|
}
|
|
27
19
|
|
|
20
|
+
type SlotProps<T extends TabsItem> = (props: { item: T, index: number }) => any
|
|
21
|
+
|
|
22
|
+
export type TabsSlots<T extends TabsItem = TabsItem> = {
|
|
23
|
+
leading?: SlotProps<T>
|
|
24
|
+
default?: SlotProps<T>
|
|
25
|
+
trailing?: SlotProps<T>
|
|
26
|
+
content?: SlotProps<T>
|
|
27
|
+
} & DynamicSlots<T, undefined, SlotProps<T>>
|
|
28
|
+
|
|
28
29
|
type TabsVariants = VariantProps<typeof tabs>
|
|
29
30
|
|
|
30
|
-
export interface TabsProps<T> extends ComponentAttrs<typeof tabs>, Pick<TabsRootProps<string | number>, 'defaultValue' | 'modelValue' | 'activationMode' | 'unmountOnHide'> {
|
|
31
|
+
export interface TabsProps<T extends TabsItem = TabsItem> extends ComponentAttrs<typeof tabs>, Pick<TabsRootProps<string | number>, 'defaultValue' | 'modelValue' | 'activationMode' | 'unmountOnHide'> {
|
|
31
32
|
/**
|
|
32
33
|
* The element or component this component should render as.
|
|
33
34
|
* @default "div"
|
|
@@ -73,11 +74,8 @@ const slots = defineSlots<TabsSlots<T>>()
|
|
|
73
74
|
|
|
74
75
|
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'orientation', 'activationMode', 'unmountOnHide'), emit)
|
|
75
76
|
|
|
76
|
-
const {
|
|
77
|
-
const style = computed(() =>
|
|
78
|
-
const styler = createStyler(theme.value.tabs)
|
|
79
|
-
return styler(props)
|
|
80
|
-
})
|
|
77
|
+
const { generateStyle } = useTheme()
|
|
78
|
+
const style = computed(() => generateStyle('tabs', props))
|
|
81
79
|
</script>
|
|
82
80
|
|
|
83
81
|
<template>
|
|
@@ -111,7 +109,7 @@ const style = computed(() => {
|
|
|
111
109
|
:value="item.value || String(index)"
|
|
112
110
|
:class="style.content({ class: props.ui?.content })"
|
|
113
111
|
>
|
|
114
|
-
<slot :name="item.slot || 'content'" :item="item" :index="index">
|
|
112
|
+
<slot :name="((item.slot || 'content') as keyof TabsSlots<T>)" :item="(item as Extract<T, { slot: string }>)" :index="index">
|
|
115
113
|
{{ item.content }}
|
|
116
114
|
</slot>
|
|
117
115
|
</TabsContent>
|
|
@@ -5,9 +5,9 @@ import type { textarea } from '../theme'
|
|
|
5
5
|
import type { ComponentAttrs } from '../types'
|
|
6
6
|
|
|
7
7
|
export interface TextareaEmits {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
'update:modelValue': [payload: string]
|
|
9
|
+
'blur': [event: FocusEvent]
|
|
10
|
+
'change': [event: Event]
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export interface TextareaSlots {
|
|
@@ -41,7 +41,8 @@ export interface TextareaProps extends ComponentAttrs<typeof textarea> {
|
|
|
41
41
|
|
|
42
42
|
<script setup lang="ts">
|
|
43
43
|
import { Primitive } from 'reka-ui'
|
|
44
|
-
import { computed, nextTick, onMounted,
|
|
44
|
+
import { computed, nextTick, onMounted, useTemplateRef, watch } from 'vue'
|
|
45
|
+
import { useFormItem } from '../composables/useFormItem'
|
|
45
46
|
import { useTheme } from '../composables/useTheme'
|
|
46
47
|
|
|
47
48
|
defineOptions({
|
|
@@ -59,13 +60,15 @@ const emit = defineEmits<TextareaEmits>()
|
|
|
59
60
|
defineSlots<TextareaSlots>()
|
|
60
61
|
const [modelValue, modelModifiers] = defineModel<string | number>()
|
|
61
62
|
|
|
62
|
-
const textareaRef =
|
|
63
|
+
const textareaRef = useTemplateRef('textareaRef')
|
|
63
64
|
|
|
64
|
-
const {
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
const { id, name, size, highlight, disabled, ariaAttrs, emitFormInput, emitFormChange, emitFormBlur, emitFormFocus } = useFormItem<TextareaProps>(props)
|
|
66
|
+
const { generateStyle } = useTheme()
|
|
67
|
+
const style = computed(() => generateStyle('textarea', {
|
|
68
|
+
...props,
|
|
69
|
+
size: size.value,
|
|
70
|
+
highlight: highlight.value,
|
|
71
|
+
}))
|
|
69
72
|
|
|
70
73
|
function autoFocus() {
|
|
71
74
|
if (props.autofocus)
|
|
@@ -77,6 +80,7 @@ function updateInput(value: string) {
|
|
|
77
80
|
value = value.trim()
|
|
78
81
|
|
|
79
82
|
modelValue.value = value
|
|
83
|
+
emitFormInput()
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
function onInput(event: Event) {
|
|
@@ -96,10 +100,12 @@ function onChange(event: Event) {
|
|
|
96
100
|
(event.target as HTMLInputElement).value = value.trim()
|
|
97
101
|
|
|
98
102
|
emit('change', event)
|
|
103
|
+
emitFormChange()
|
|
99
104
|
}
|
|
100
105
|
|
|
101
106
|
function onBlur(event: FocusEvent) {
|
|
102
107
|
emit('blur', event)
|
|
108
|
+
emitFormBlur()
|
|
103
109
|
}
|
|
104
110
|
|
|
105
111
|
function autoResize() {
|
|
@@ -147,23 +153,20 @@ onMounted(() => {
|
|
|
147
153
|
<Primitive
|
|
148
154
|
:as="props.as"
|
|
149
155
|
:class="style.root({ class: [props.class, props.ui?.root] })"
|
|
150
|
-
:aria-disabled="
|
|
156
|
+
:aria-disabled="disabled ? true : undefined"
|
|
151
157
|
>
|
|
152
158
|
<textarea
|
|
153
|
-
:id="props.id"
|
|
154
159
|
ref="textareaRef"
|
|
160
|
+
:class="style.base({ class: props.ui?.base })"
|
|
155
161
|
:value="modelValue"
|
|
156
|
-
:name="props.name"
|
|
157
162
|
:rows="props.rows"
|
|
158
163
|
:placeholder="props.placeholder"
|
|
159
|
-
:class="style.base({ class: props.ui?.base })"
|
|
160
|
-
:disabled="props.disabled"
|
|
161
164
|
:required="props.required"
|
|
162
|
-
v-bind="
|
|
165
|
+
v-bind="{ ...$attrs, ...ariaAttrs, id, name, disabled }"
|
|
163
166
|
@input="onInput"
|
|
164
167
|
@blur="onBlur"
|
|
165
168
|
@change="onChange"
|
|
166
|
-
@focus="
|
|
169
|
+
@focus="emitFormFocus"
|
|
167
170
|
></textarea>
|
|
168
171
|
|
|
169
172
|
<slot></slot>
|
|
@@ -11,7 +11,7 @@ export interface ToastSlots {
|
|
|
11
11
|
title?: (props?: {}) => any
|
|
12
12
|
description?: (props?: {}) => any
|
|
13
13
|
actions?: (props?: {}) => any
|
|
14
|
-
close?: (props: { ui:
|
|
14
|
+
close?: (props: { ui: ComponentAttrs<typeof toast>['ui'] }) => any
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
type ToastVariants = VariantProps<typeof toast>
|
|
@@ -61,14 +61,11 @@ const el = ref<InstanceType<typeof ToastRoot>>()
|
|
|
61
61
|
const { height } = useElementBounding(() => el.value?.$el.getBoundingClientRect ? el.value.$el : undefined)
|
|
62
62
|
|
|
63
63
|
const { t } = useLocale()
|
|
64
|
-
const { theme,
|
|
65
|
-
const style = computed(() => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
title: !!(props.title || slots.title),
|
|
70
|
-
})
|
|
71
|
-
})
|
|
64
|
+
const { theme, generateStyle } = useTheme()
|
|
65
|
+
const style = computed(() => generateStyle('toast', {
|
|
66
|
+
...props,
|
|
67
|
+
title: !!(props.title || slots.title),
|
|
68
|
+
}))
|
|
72
69
|
|
|
73
70
|
defineExpose({
|
|
74
71
|
height,
|
|
@@ -108,7 +105,10 @@ defineExpose({
|
|
|
108
105
|
</div>
|
|
109
106
|
</div>
|
|
110
107
|
|
|
111
|
-
<div
|
|
108
|
+
<div
|
|
109
|
+
v-if="(props.orientation === 'horizontal' && actions?.length) || props.close || slots.close"
|
|
110
|
+
:class="style.actions({ class: props.ui?.actions })"
|
|
111
|
+
>
|
|
112
112
|
<template v-if="props.orientation === 'horizontal'">
|
|
113
113
|
<slot name="actions">
|
|
114
114
|
<ToastAction v-for="(action, index) in props.actions" :key="index" :alt-text="action.label || 'Action'" as-child @click.stop>
|
|
@@ -117,10 +117,9 @@ defineExpose({
|
|
|
117
117
|
</slot>
|
|
118
118
|
</template>
|
|
119
119
|
|
|
120
|
-
<ToastClose as-child>
|
|
121
|
-
<slot name="close" :ui="ui">
|
|
120
|
+
<ToastClose v-if="props.close || slots.close" as-child>
|
|
121
|
+
<slot name="close" :ui="props.ui">
|
|
122
122
|
<Button
|
|
123
|
-
v-if="props.close"
|
|
124
123
|
:icon="props.closeIcon || theme.app.icons.close"
|
|
125
124
|
size="sm"
|
|
126
125
|
variant="link"
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
-
import type { ToastProviderProps } from 'reka-ui'
|
|
4
|
-
import type {
|
|
5
|
-
import type { ComponentAttrs } from '../types'
|
|
3
|
+
import type { ToastProviderProps as RekaToastProviderProps } from 'reka-ui'
|
|
4
|
+
import type { toastProvider } from '../theme'
|
|
5
|
+
import type { ComponentAttrs, ToastProps } from '../types'
|
|
6
|
+
|
|
7
|
+
export interface ToastState extends Omit<ToastProps, 'defaultOpen'> {
|
|
8
|
+
id: string | number
|
|
9
|
+
onClick?: (toast: ToastState) => void
|
|
10
|
+
}
|
|
6
11
|
|
|
7
12
|
export interface ToasterSlots {
|
|
8
13
|
default?: (props?: {}) => any
|
|
9
14
|
}
|
|
10
15
|
|
|
11
|
-
type ToasterVariants = VariantProps<typeof
|
|
16
|
+
type ToasterVariants = VariantProps<typeof toastProvider>
|
|
12
17
|
|
|
13
|
-
export interface
|
|
18
|
+
export interface ToastProviderProps extends ComponentAttrs<typeof toastProvider>, Omit<RekaToastProviderProps, 'swipeDirection'> {
|
|
14
19
|
/** @default "bottom-right" */
|
|
15
20
|
position?: ToasterVariants['position']
|
|
16
21
|
/**
|
|
@@ -35,7 +40,7 @@ import { useToast } from '../composables/useToast'
|
|
|
35
40
|
import { omit } from '../utils'
|
|
36
41
|
import Toast from './Toast.vue'
|
|
37
42
|
|
|
38
|
-
const props = withDefaults(defineProps<
|
|
43
|
+
const props = withDefaults(defineProps<ToastProviderProps>(), {
|
|
39
44
|
position: 'bottom-right',
|
|
40
45
|
expand: true,
|
|
41
46
|
portal: true,
|
|
@@ -61,20 +66,17 @@ const swipeDirection = computed(() => {
|
|
|
61
66
|
return 'left'
|
|
62
67
|
}
|
|
63
68
|
|
|
64
|
-
console.warn(`[
|
|
69
|
+
console.warn(`[ToastProvider] Unknown position "${props.position}"`)
|
|
65
70
|
|
|
66
71
|
return 'right'
|
|
67
72
|
})
|
|
68
73
|
|
|
69
|
-
const {
|
|
70
|
-
const style = computed(() => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
clickable: false,
|
|
76
|
-
})
|
|
77
|
-
})
|
|
74
|
+
const { generateStyle } = useTheme()
|
|
75
|
+
const style = computed(() => generateStyle('toastProvider', {
|
|
76
|
+
...props,
|
|
77
|
+
swipeDirection: swipeDirection.value,
|
|
78
|
+
clickable: false,
|
|
79
|
+
}))
|
|
78
80
|
|
|
79
81
|
function onUpdateOpen(value: boolean, id: string | number) {
|
|
80
82
|
if (value)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { TooltipArrowProps, TooltipContentProps, TooltipRootEmits, TooltipRootProps } from 'reka-ui'
|
|
2
|
+
import type { TooltipArrowProps, TooltipContentEmits, TooltipContentProps, TooltipRootEmits, TooltipRootProps } from 'reka-ui'
|
|
3
3
|
import type { tooltip } from '../theme'
|
|
4
|
-
import type { ComponentAttrs } from '../types'
|
|
4
|
+
import type { ComponentAttrs, EmitsToProps } from '../types'
|
|
5
5
|
|
|
6
6
|
export interface TooltipEmits extends TooltipRootEmits {}
|
|
7
7
|
|
|
@@ -12,7 +12,7 @@ export interface TooltipSlots {
|
|
|
12
12
|
|
|
13
13
|
export interface TooltipProps extends ComponentAttrs<typeof tooltip>, TooltipRootProps {
|
|
14
14
|
text?: string
|
|
15
|
-
content?: Omit<TooltipContentProps, 'as' | 'asChild'>
|
|
15
|
+
content?: Omit<TooltipContentProps, 'as' | 'asChild'> & Partial<EmitsToProps<TooltipContentEmits>>
|
|
16
16
|
arrow?: boolean | Omit<TooltipArrowProps, 'as' | 'asChild'>
|
|
17
17
|
/** @default true */
|
|
18
18
|
portal?: boolean
|
|
@@ -44,11 +44,8 @@ const contentProps = toRef(() => defu(props.content, contentDefaults) as Tooltip
|
|
|
44
44
|
|
|
45
45
|
const arrowProps = toRef(() => props.arrow as TooltipArrowProps)
|
|
46
46
|
|
|
47
|
-
const {
|
|
48
|
-
const style = computed(() =>
|
|
49
|
-
const styler = createStyler(theme.value.tooltip)
|
|
50
|
-
return styler(props)
|
|
51
|
-
})
|
|
47
|
+
const { generateStyle } = useTheme()
|
|
48
|
+
const style = computed(() => generateStyle('tooltip', props))
|
|
52
49
|
</script>
|
|
53
50
|
|
|
54
51
|
<template>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { GetObjectField } from '../types/index.js';
|
|
2
|
+
interface Props<T> {
|
|
3
|
+
id?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
size?: GetObjectField<T, 'size'>;
|
|
6
|
+
highlight?: boolean;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function useFormItem<T>(props?: Props<T>, options?: {
|
|
10
|
+
bind?: boolean;
|
|
11
|
+
deferInputValidation?: boolean;
|
|
12
|
+
}): {
|
|
13
|
+
id: import("vue").ComputedRef<string | undefined>;
|
|
14
|
+
name: import("vue").ComputedRef<string | undefined>;
|
|
15
|
+
size: import("vue").ComputedRef<any>;
|
|
16
|
+
highlight: import("vue").ComputedRef<boolean | undefined>;
|
|
17
|
+
disabled: import("vue").ComputedRef<boolean | undefined>;
|
|
18
|
+
emitFormBlur: () => void;
|
|
19
|
+
emitFormInput: import("@vueuse/core").PromisifyFn<() => void>;
|
|
20
|
+
emitFormChange: () => void;
|
|
21
|
+
emitFormFocus: () => void;
|
|
22
|
+
ariaAttrs: import("vue").ComputedRef<{
|
|
23
|
+
'aria-describedby': string;
|
|
24
|
+
'aria-invalid': boolean;
|
|
25
|
+
} | undefined>;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { useDebounceFn } from "@vueuse/core";
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import {
|
|
4
|
+
injectFormBus,
|
|
5
|
+
injectFormInputId,
|
|
6
|
+
injectFormInputs,
|
|
7
|
+
injectFormItem,
|
|
8
|
+
injectFormOptions
|
|
9
|
+
} from "../app/injections.js";
|
|
10
|
+
export function useFormItem(props, options) {
|
|
11
|
+
const formOptions = injectFormOptions();
|
|
12
|
+
const formBus = injectFormBus();
|
|
13
|
+
const formItem = injectFormItem();
|
|
14
|
+
const formInputs = injectFormInputs();
|
|
15
|
+
const inputId = injectFormInputId();
|
|
16
|
+
if (formItem && inputId) {
|
|
17
|
+
if (options?.bind === false) {
|
|
18
|
+
inputId.value = void 0;
|
|
19
|
+
} else if (props?.id) {
|
|
20
|
+
inputId.value = props?.id;
|
|
21
|
+
}
|
|
22
|
+
if (formInputs && formItem.value.name && inputId.value)
|
|
23
|
+
formInputs.value[formItem.value.name] = { id: inputId.value, pattern: formItem.value.errorPattern };
|
|
24
|
+
}
|
|
25
|
+
function emitFormEvent(type, name, eager) {
|
|
26
|
+
if (formBus && formItem && name)
|
|
27
|
+
formBus.emit({ type, name, eager });
|
|
28
|
+
}
|
|
29
|
+
function emitFormBlur() {
|
|
30
|
+
emitFormEvent("blur", formItem?.value.name);
|
|
31
|
+
}
|
|
32
|
+
function emitFormFocus() {
|
|
33
|
+
emitFormEvent("focus", formItem?.value.name);
|
|
34
|
+
}
|
|
35
|
+
function emitFormChange() {
|
|
36
|
+
emitFormEvent("change", formItem?.value.name);
|
|
37
|
+
}
|
|
38
|
+
const emitFormInput = useDebounceFn(
|
|
39
|
+
() => {
|
|
40
|
+
emitFormEvent("input", formItem?.value.name, !options?.deferInputValidation || formItem?.value.eagerValidation);
|
|
41
|
+
},
|
|
42
|
+
formItem?.value.validateOnInputDelay ?? formOptions?.value.validateOnInputDelay ?? 0
|
|
43
|
+
);
|
|
44
|
+
return {
|
|
45
|
+
id: computed(() => props?.id ?? inputId?.value),
|
|
46
|
+
name: computed(() => props?.name ?? formItem?.value.name),
|
|
47
|
+
size: computed(() => props?.size ?? formItem?.value.size),
|
|
48
|
+
highlight: computed(() => formItem?.value.error ? true : props?.highlight),
|
|
49
|
+
disabled: computed(() => formOptions?.value.disabled || props?.disabled),
|
|
50
|
+
emitFormBlur,
|
|
51
|
+
emitFormInput,
|
|
52
|
+
emitFormChange,
|
|
53
|
+
emitFormFocus,
|
|
54
|
+
ariaAttrs: computed(() => {
|
|
55
|
+
if (!formItem?.value)
|
|
56
|
+
return;
|
|
57
|
+
const descriptiveAttrs = ["error", "hint", "help", "description"].filter((type) => formItem?.value?.[type]).map((type) => `${formItem?.value.ariaId}-${type}`) || [];
|
|
58
|
+
return {
|
|
59
|
+
"aria-describedby": descriptiveAttrs.join(" "),
|
|
60
|
+
"aria-invalid": !!formItem?.value.error
|
|
61
|
+
};
|
|
62
|
+
})
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -29,7 +29,7 @@ export declare const kbdKeysMap: {
|
|
|
29
29
|
export type KbdKey = keyof typeof kbdKeysMap;
|
|
30
30
|
export type KbdKeySpecific = keyof KbdKeysSpecificMap;
|
|
31
31
|
export declare const useKbd: () => {
|
|
32
|
-
macOS: import("vue").ComputedRef<
|
|
32
|
+
macOS: import("vue").ComputedRef<false | "" | RegExpMatchArray | null | undefined>;
|
|
33
33
|
getKbdKey: (value?: KbdKey | (string & {})) => string | undefined;
|
|
34
34
|
};
|
|
35
35
|
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Component } from 'vue';
|
|
2
|
+
import type { ComponentProps } from 'vue-component-type-helpers';
|
|
3
|
+
export interface OverlayOptions<ComponentProps = Record<string, any>> {
|
|
4
|
+
defaultOpen?: boolean;
|
|
5
|
+
props?: ComponentProps;
|
|
6
|
+
unmountOnHide?: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface _ComponentState<T extends Component> {
|
|
9
|
+
component?: T;
|
|
10
|
+
id: string | number;
|
|
11
|
+
isMounted: boolean;
|
|
12
|
+
modelValue: boolean;
|
|
13
|
+
resolve?: (value: unknown) => void;
|
|
14
|
+
}
|
|
15
|
+
export type OverlayComponentState = OverlayOptions<Component> & _ComponentState<Component>;
|
|
16
|
+
export interface OverlayComponentInstance<T> {
|
|
17
|
+
open: (props?: ComponentProps<T>) => Promise<any>;
|
|
18
|
+
close: (value?: any) => void;
|
|
19
|
+
patch: (props: Partial<ComponentProps<T>>) => void;
|
|
20
|
+
}
|
|
21
|
+
export declare const useOverlay: () => {
|
|
22
|
+
overlays: import("vue").ShallowReactive<OverlayComponentState[]>;
|
|
23
|
+
open: <T extends Component>(id: OverlayComponentState["id"], props?: ComponentProps<T>) => Promise<any>;
|
|
24
|
+
close: (id: OverlayComponentState["id"], value?: any) => void;
|
|
25
|
+
create: <T extends Component>(component: T, options?: OverlayOptions<ComponentProps<T>>) => OverlayComponentInstance<T>;
|
|
26
|
+
patch: <T extends Component>(id: OverlayComponentState["id"], props: Partial<ComponentProps<T>>) => void;
|
|
27
|
+
unmount: (id: OverlayComponentState["id"]) => void;
|
|
28
|
+
};
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createSharedComposable } from "@vueuse/core";
|
|
2
|
+
import { markRaw, reactive, shallowReactive } from "vue";
|
|
3
|
+
export const useOverlay = createSharedComposable(() => {
|
|
4
|
+
const overlays = shallowReactive([]);
|
|
5
|
+
const generateId = () => `overlay-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
6
|
+
function create(component, options = {}) {
|
|
7
|
+
const { props = {}, defaultOpen = false, unmountOnHide = true } = options;
|
|
8
|
+
const state = reactive({
|
|
9
|
+
id: generateId(),
|
|
10
|
+
modelValue: defaultOpen,
|
|
11
|
+
component: markRaw(component),
|
|
12
|
+
isMounted: defaultOpen,
|
|
13
|
+
unmountOnHide,
|
|
14
|
+
props
|
|
15
|
+
});
|
|
16
|
+
overlays.push(state);
|
|
17
|
+
return {
|
|
18
|
+
open: (props2) => open(state.id, props2),
|
|
19
|
+
close: (value) => close(state.id, value),
|
|
20
|
+
patch: (props2) => patch(state.id, props2)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function open(id, props) {
|
|
24
|
+
const overlay = getOverlay(id);
|
|
25
|
+
if (props)
|
|
26
|
+
patch(id, props);
|
|
27
|
+
overlay.modelValue = true;
|
|
28
|
+
overlay.isMounted = true;
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
overlay.resolve = resolve;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function close(id, value) {
|
|
34
|
+
const overlay = getOverlay(id);
|
|
35
|
+
overlay.modelValue = false;
|
|
36
|
+
if (overlay.resolve) {
|
|
37
|
+
overlay.resolve(value);
|
|
38
|
+
overlay.resolve = void 0;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function unmount(id) {
|
|
42
|
+
const overlay = getOverlay(id);
|
|
43
|
+
overlay.isMounted = false;
|
|
44
|
+
if (overlay.unmountOnHide) {
|
|
45
|
+
const index = overlays.findIndex((item) => item.id === id);
|
|
46
|
+
overlays.splice(index, 1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function patch(id, props) {
|
|
50
|
+
const overlay = getOverlay(id);
|
|
51
|
+
Object.entries(props).forEach(([key, value]) => {
|
|
52
|
+
overlay.props[key] = value;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function getOverlay(id) {
|
|
56
|
+
const item = overlays.find((item2) => item2.id === id);
|
|
57
|
+
if (!item)
|
|
58
|
+
throw new Error("Overlay not found");
|
|
59
|
+
return item;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
overlays,
|
|
63
|
+
open,
|
|
64
|
+
close,
|
|
65
|
+
create,
|
|
66
|
+
patch,
|
|
67
|
+
unmount
|
|
68
|
+
};
|
|
69
|
+
});
|