@byyuurin/ui 0.0.8 → 0.0.9
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/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 +2 -7
- package/dist/runtime/app/injections.js +0 -5
- package/dist/runtime/components/Accordion.vue +10 -8
- package/dist/runtime/components/Alert.vue +5 -8
- 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 +2 -5
- package/dist/runtime/components/Breadcrumb.vue +11 -8
- package/dist/runtime/components/Button.vue +2 -3
- package/dist/runtime/components/ButtonGroup.vue +2 -5
- package/dist/runtime/components/Calendar.vue +176 -0
- package/dist/runtime/components/Card.vue +2 -5
- package/dist/runtime/components/Carousel.vue +6 -13
- package/dist/runtime/components/Checkbox.vue +2 -5
- package/dist/runtime/components/Chip.vue +6 -9
- package/dist/runtime/components/Collapsible.vue +2 -5
- package/dist/runtime/components/Drawer.vue +80 -37
- package/dist/runtime/components/Input.vue +10 -13
- package/dist/runtime/components/InputNumber.vue +2 -5
- package/dist/runtime/components/Kbd.vue +2 -6
- package/dist/runtime/components/Link.vue +8 -5
- package/dist/runtime/components/Modal.vue +20 -11
- package/dist/runtime/components/OverlayProvider.vue +29 -0
- package/dist/runtime/components/Pagination.vue +34 -27
- package/dist/runtime/components/PinInput.vue +2 -5
- package/dist/runtime/components/Popover.vue +2 -5
- package/dist/runtime/components/Progress.vue +2 -5
- package/dist/runtime/components/RadioGroup.vue +6 -7
- package/dist/runtime/components/ScrollArea.vue +2 -6
- package/dist/runtime/components/Select.vue +10 -13
- package/dist/runtime/components/Separator.vue +2 -6
- package/dist/runtime/components/Skeleton.vue +2 -5
- package/dist/runtime/components/Slider.vue +2 -5
- package/dist/runtime/components/Switch.vue +6 -5
- package/dist/runtime/components/Table.vue +2 -5
- package/dist/runtime/components/Tabs.vue +2 -5
- package/dist/runtime/components/Textarea.vue +2 -5
- package/dist/runtime/components/Toast.vue +7 -11
- package/dist/runtime/components/{Toaster.vue → ToastProvider.vue} +18 -16
- package/dist/runtime/components/Tooltip.vue +2 -5
- 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 +9 -3
- package/dist/runtime/composables/useToast.d.ts +4 -20
- package/dist/runtime/composables/useToast.js +6 -5
- package/dist/runtime/index.d.ts +3 -2
- package/dist/runtime/index.js +3 -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/avatar.js +2 -2
- package/dist/runtime/theme/breadcrumb.js +5 -5
- 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.js +3 -3
- package/dist/runtime/theme/drawer.d.ts +24 -21
- package/dist/runtime/theme/drawer.js +46 -19
- package/dist/runtime/theme/index.d.ts +2 -1
- package/dist/runtime/theme/index.js +2 -1
- package/dist/runtime/theme/input-number.js +1 -1
- package/dist/runtime/theme/input.js +14 -14
- 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.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.js +13 -13
- 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.js +20 -20
- 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.js +7 -7
- package/dist/runtime/theme/tabs.js +10 -10
- package/dist/runtime/theme/textarea.js +13 -13
- package/dist/runtime/theme/toast.js +5 -5
- package/dist/runtime/theme/tooltip.js +1 -1
- package/dist/runtime/types/components.d.ts +3 -1
- package/dist/runtime/types/locale.d.ts +6 -0
- package/dist/runtime/types/utils.d.ts +4 -2
- package/dist/shared/ui.1a1f119c.mjs +5 -0
- package/dist/shared/ui.1a1f119c.mjs.map +1 -0
- package/dist/unocss.mjs +19 -14
- package/dist/unocss.mjs.map +1 -1
- package/dist/unplugin.mjs +1 -1
- package/dist/vite.mjs +1 -1
- package/package.json +9 -9
- 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.d.ts → toast-provider.d.ts} +0 -0
- /package/dist/runtime/theme/{toaster.js → toast-provider.js} +0 -0
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { VariantProps } from '@byyuurin/ui-kit'
|
|
3
|
+
import type { DialogContentProps, DialogRootEmits, DialogRootProps } from 'reka-ui'
|
|
4
4
|
import type { drawer } from '../theme'
|
|
5
|
-
import type { ComponentAttrs } from '../types'
|
|
5
|
+
import type { ButtonProps, ComponentAttrs } from '../types'
|
|
6
6
|
|
|
7
|
-
export interface DrawerEmits extends
|
|
7
|
+
export interface DrawerEmits extends DialogRootEmits {
|
|
8
|
+
'after-leave': []
|
|
9
|
+
}
|
|
8
10
|
|
|
9
11
|
export interface DrawerSlots {
|
|
10
12
|
default?: (props?: {}) => any
|
|
11
|
-
handle?: (props?: {}) => any
|
|
12
13
|
content?: (props?: {}) => any
|
|
13
14
|
header?: (props?: {}) => any
|
|
14
15
|
title?: (props?: {}) => any
|
|
15
16
|
description?: (props?: {}) => any
|
|
17
|
+
close?: (props?: {}) => any
|
|
16
18
|
body?: (props?: {}) => any
|
|
17
19
|
footer?: (props?: {}) => any
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
type DrawerVariants = VariantProps<typeof drawer>
|
|
23
|
+
|
|
24
|
+
export interface DrawerProps extends ComponentAttrs<typeof drawer>, DialogRootProps {
|
|
21
25
|
title?: string
|
|
22
26
|
description?: string
|
|
23
27
|
/** The content of the drawer. */
|
|
@@ -27,20 +31,29 @@ export interface DrawerProps extends ComponentAttrs<typeof drawer>, Pick<DrawerR
|
|
|
27
31
|
* @default true
|
|
28
32
|
*/
|
|
29
33
|
overlay?: boolean
|
|
34
|
+
/** @default true */
|
|
35
|
+
transition?: boolean
|
|
36
|
+
/**
|
|
37
|
+
* The direction of the drawer.
|
|
38
|
+
* @default "bottom"
|
|
39
|
+
*/
|
|
40
|
+
direction?: DrawerVariants['direction']
|
|
30
41
|
/**
|
|
31
42
|
* Whether to inset the drawer from the edges.
|
|
32
43
|
*/
|
|
33
44
|
inset?: boolean
|
|
34
45
|
/**
|
|
35
|
-
* Render
|
|
46
|
+
* Render the drawer in a portal.
|
|
36
47
|
* @default true
|
|
37
48
|
*/
|
|
38
|
-
|
|
49
|
+
portal?: boolean
|
|
39
50
|
/**
|
|
40
|
-
*
|
|
51
|
+
* Display a close button to dismiss the drawer.
|
|
41
52
|
* @default true
|
|
42
53
|
*/
|
|
43
|
-
|
|
54
|
+
close?: ButtonProps | boolean
|
|
55
|
+
/** @default app.icons.close */
|
|
56
|
+
closeIcon?: string
|
|
44
57
|
/**
|
|
45
58
|
* When `false`, the drawer will not close when clicking outside or pressing escape.
|
|
46
59
|
* @default true
|
|
@@ -51,71 +64,101 @@ export interface DrawerProps extends ComponentAttrs<typeof drawer>, Pick<DrawerR
|
|
|
51
64
|
|
|
52
65
|
<script setup lang="ts">
|
|
53
66
|
import { reactivePick } from '@vueuse/core'
|
|
54
|
-
import { useForwardPropsEmits } from 'reka-ui'
|
|
55
|
-
import { DrawerContent, DrawerDescription, DrawerOverlay, DrawerPortal, DrawerRoot, DrawerTitle, DrawerTrigger } from 'vaul-vue'
|
|
67
|
+
import { DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogPortal, DialogRoot, DialogTitle, DialogTrigger, useForwardPropsEmits, VisuallyHidden } from 'reka-ui'
|
|
56
68
|
import { computed, toRef } from 'vue'
|
|
69
|
+
import { useLocale } from '../composables/useLocale'
|
|
57
70
|
import { useTheme } from '../composables/useTheme'
|
|
71
|
+
import Button from './Button.vue'
|
|
58
72
|
|
|
59
73
|
const props = withDefaults(defineProps<DrawerProps>(), {
|
|
60
74
|
direction: 'bottom',
|
|
75
|
+
modal: true,
|
|
61
76
|
portal: true,
|
|
62
77
|
overlay: true,
|
|
63
|
-
|
|
78
|
+
transition: true,
|
|
79
|
+
dismissible: true,
|
|
80
|
+
close: true,
|
|
64
81
|
})
|
|
65
82
|
const emit = defineEmits<DrawerEmits>()
|
|
66
83
|
const slots = defineSlots<DrawerSlots>()
|
|
67
84
|
|
|
68
|
-
const rootProps = useForwardPropsEmits(reactivePick(props, '
|
|
69
|
-
const contentProps = toRef(() =>
|
|
85
|
+
const rootProps = useForwardPropsEmits(reactivePick(props, 'open', 'defaultOpen', 'modal'), emit)
|
|
86
|
+
const contentProps = toRef(() => ({
|
|
87
|
+
...props.content,
|
|
88
|
+
...(slots.content || slots.header || (!props.description && !slots.description)) ? { 'aria-describedby': undefined } : {},
|
|
89
|
+
}))
|
|
90
|
+
const contentEvents = computed(() => {
|
|
91
|
+
if (props.dismissible)
|
|
92
|
+
return {}
|
|
70
93
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
94
|
+
return {
|
|
95
|
+
pointerDownOutside: (e: Event) => e.preventDefault(),
|
|
96
|
+
interactOutside: (e: Event) => e.preventDefault(),
|
|
97
|
+
escapeKeyDown: (e: Event) => e.preventDefault(),
|
|
98
|
+
}
|
|
75
99
|
})
|
|
100
|
+
|
|
101
|
+
const { t } = useLocale()
|
|
102
|
+
const { theme, generateStyle } = useTheme()
|
|
103
|
+
const style = computed(() => generateStyle('drawer', props))
|
|
76
104
|
</script>
|
|
77
105
|
|
|
78
106
|
<template>
|
|
79
|
-
<
|
|
80
|
-
<
|
|
81
|
-
<slot></slot>
|
|
82
|
-
</
|
|
107
|
+
<DialogRoot v-slot="{ open }" v-bind="rootProps">
|
|
108
|
+
<DialogTrigger v-if="slots.default" as-child :class="props.class">
|
|
109
|
+
<slot :open="open"></slot>
|
|
110
|
+
</DialogTrigger>
|
|
83
111
|
|
|
84
|
-
<
|
|
85
|
-
<
|
|
112
|
+
<DialogPortal :disabled="!props.portal">
|
|
113
|
+
<DialogOverlay v-if="props.overlay" :class="style.overlay({ class: props.ui?.overlay })" />
|
|
86
114
|
|
|
87
|
-
<
|
|
115
|
+
<DialogContent
|
|
88
116
|
:class="style.content({ class: [!slots.default && props.class, props.ui?.content] })"
|
|
117
|
+
:data-direction="props.direction"
|
|
89
118
|
v-bind="contentProps"
|
|
119
|
+
v-on="contentEvents"
|
|
120
|
+
@after-leave="emit('after-leave')"
|
|
90
121
|
>
|
|
91
|
-
<
|
|
92
|
-
<
|
|
93
|
-
</
|
|
122
|
+
<VisuallyHidden v-if="slots.content || slots.header || (!props.title && !slots.title)">
|
|
123
|
+
<DialogTitle />
|
|
124
|
+
</VisuallyHidden>
|
|
94
125
|
|
|
95
126
|
<slot name="content">
|
|
96
127
|
<div :class="style.container({ class: props.ui?.container })">
|
|
97
128
|
<div
|
|
98
|
-
v-if="slots.header || props.title || slots.title || props.description || slots.description"
|
|
129
|
+
v-if="slots.header || props.title || slots.title || props.description || slots.description || props.close || slots.close"
|
|
99
130
|
:class="style.header({ class: props.ui?.header })"
|
|
100
131
|
>
|
|
101
132
|
<slot name="header">
|
|
102
|
-
<
|
|
133
|
+
<DialogTitle
|
|
103
134
|
v-if="props.title || slots.title"
|
|
104
135
|
:class="style.title({ class: props.ui?.title })"
|
|
105
136
|
>
|
|
106
137
|
<slot name="title">
|
|
107
138
|
{{ props.title }}
|
|
108
139
|
</slot>
|
|
109
|
-
</
|
|
140
|
+
</DialogTitle>
|
|
141
|
+
|
|
142
|
+
<DialogClose v-if="props.close || slots.close" as-child>
|
|
143
|
+
<slot name="close">
|
|
144
|
+
<Button
|
|
145
|
+
variant="ghost"
|
|
146
|
+
:icon="props.closeIcon || theme.app.icons.close"
|
|
147
|
+
v-bind="typeof props.close === 'boolean' ? {} : props.close"
|
|
148
|
+
:class="style.close({ class: props.ui?.close })"
|
|
149
|
+
:aria-label="t('modal.close')"
|
|
150
|
+
/>
|
|
151
|
+
</slot>
|
|
152
|
+
</DialogClose>
|
|
110
153
|
|
|
111
|
-
<
|
|
154
|
+
<DialogDescription
|
|
112
155
|
v-if="props.description || slots.description"
|
|
113
156
|
:class="style.description({ class: props.ui?.description })"
|
|
114
157
|
>
|
|
115
158
|
<slot name="description">
|
|
116
159
|
{{ props.description }}
|
|
117
160
|
</slot>
|
|
118
|
-
</
|
|
161
|
+
</DialogDescription>
|
|
119
162
|
</slot>
|
|
120
163
|
</div>
|
|
121
164
|
|
|
@@ -128,7 +171,7 @@ const style = computed(() => {
|
|
|
128
171
|
</div>
|
|
129
172
|
</div>
|
|
130
173
|
</slot>
|
|
131
|
-
</
|
|
132
|
-
</
|
|
133
|
-
</
|
|
174
|
+
</DialogContent>
|
|
175
|
+
</DialogPortal>
|
|
176
|
+
</DialogRoot>
|
|
134
177
|
</template>
|
|
@@ -71,19 +71,16 @@ const inputRef = ref<HTMLInputElement | null>(null)
|
|
|
71
71
|
const { size, orientation } = useButtonGroup(props)
|
|
72
72
|
const { isLeading, leadingIconName, isTrailing, trailingIconName } = useComponentIcons(props)
|
|
73
73
|
|
|
74
|
-
const {
|
|
75
|
-
const style = computed(() => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
trailing: isTrailing.value || !!slots.trailing,
|
|
85
|
-
})
|
|
86
|
-
})
|
|
74
|
+
const { generateStyle } = useTheme()
|
|
75
|
+
const style = computed(() => generateStyle('input', {
|
|
76
|
+
...props,
|
|
77
|
+
// @ts-expect-error ignore type
|
|
78
|
+
type: props.type,
|
|
79
|
+
size: size.value,
|
|
80
|
+
groupOrientation: orientation.value,
|
|
81
|
+
leading: isLeading.value || !!slots.leading,
|
|
82
|
+
trailing: isTrailing.value || !!slots.trailing,
|
|
83
|
+
}))
|
|
87
84
|
|
|
88
85
|
function autoFocus() {
|
|
89
86
|
if (props.autofocus)
|
|
@@ -83,14 +83,11 @@ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', '
|
|
|
83
83
|
const inputRef = ref<InstanceType<typeof NumberFieldInput> | null>(null)
|
|
84
84
|
|
|
85
85
|
const { t } = useLocale()
|
|
86
|
-
const { theme,
|
|
86
|
+
const { theme, generateStyle } = useTheme()
|
|
87
87
|
const incrementIcon = computed(() => props.incrementIcon || (props.orientation === 'horizontal' ? theme.value.app.icons.plus : theme.value.app.icons.chevronUp))
|
|
88
88
|
const decrementIcon = computed(() => props.decrementIcon || (props.orientation === 'horizontal' ? theme.value.app.icons.minus : theme.value.app.icons.chevronDown))
|
|
89
89
|
|
|
90
|
-
const style = computed(() =>
|
|
91
|
-
const styler = createStyler(theme.value.inputNumber)
|
|
92
|
-
return styler(props)
|
|
93
|
-
})
|
|
90
|
+
const style = computed(() => generateStyle('inputNumber', props))
|
|
94
91
|
|
|
95
92
|
onMounted(() => {
|
|
96
93
|
setTimeout(() => {
|
|
@@ -36,12 +36,8 @@ const props = withDefaults(defineProps<KbdProps>(), {
|
|
|
36
36
|
defineSlots<KbdSlots>()
|
|
37
37
|
|
|
38
38
|
const { getKbdKey } = useKbd()
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
const style = computed(() => {
|
|
42
|
-
const styler = createStyler(theme.value.kbd)
|
|
43
|
-
return styler(props)
|
|
44
|
-
})
|
|
39
|
+
const { generateStyle } = useTheme()
|
|
40
|
+
const style = computed(() => generateStyle('kbd', props))
|
|
45
41
|
</script>
|
|
46
42
|
|
|
47
43
|
<template>
|
|
@@ -163,10 +163,12 @@ function isPartiallyEqual(item1: any, item2: any) {
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
const isExternalLink = computed(() => {
|
|
166
|
-
|
|
166
|
+
const to = props.to || props.href
|
|
167
|
+
|
|
168
|
+
if (!to)
|
|
167
169
|
return false
|
|
168
170
|
|
|
169
|
-
return typeof
|
|
171
|
+
return typeof to === 'string' && hasProtocol(to, { acceptRelative: true })
|
|
170
172
|
})
|
|
171
173
|
|
|
172
174
|
function isLinkActive({ route: linkRoute, isActive, isExactActive }: any) {
|
|
@@ -301,6 +303,7 @@ function resolveLinkClass({ route, isActive, isExactActive }: any = {}) {
|
|
|
301
303
|
href: to ? href : undefined,
|
|
302
304
|
navigate,
|
|
303
305
|
}"
|
|
306
|
+
:is-external="isExternalLink"
|
|
304
307
|
:class="resolveLinkClass({ route: linkRoute, isActive, isExactActive })"
|
|
305
308
|
>
|
|
306
309
|
<slot :active="isLinkActive({ route: linkRoute, isActive, isExactActive })">
|
|
@@ -318,7 +321,7 @@ function resolveLinkClass({ route, isActive, isExactActive }: any = {}) {
|
|
|
318
321
|
type,
|
|
319
322
|
disabled,
|
|
320
323
|
href: to || href,
|
|
321
|
-
target: isExternalLink ? '_blank' :
|
|
324
|
+
target: target || (isExternalLink ? '_blank' : undefined),
|
|
322
325
|
active: false,
|
|
323
326
|
}"
|
|
324
327
|
>
|
|
@@ -332,8 +335,8 @@ function resolveLinkClass({ route, isActive, isExactActive }: any = {}) {
|
|
|
332
335
|
as,
|
|
333
336
|
type,
|
|
334
337
|
disabled,
|
|
335
|
-
href: ((to
|
|
336
|
-
target: isExternalLink ? '_blank' :
|
|
338
|
+
href: ((typeof to === 'string' ? to : href) as string),
|
|
339
|
+
target: target || (isExternalLink ? '_blank' : undefined),
|
|
337
340
|
}"
|
|
338
341
|
:is-external="isExternalLink"
|
|
339
342
|
:class="resolveLinkClass()"
|
|
@@ -4,7 +4,9 @@ import type { DialogContentProps, DialogRootEmits, DialogRootProps } from 'reka-
|
|
|
4
4
|
import type { modal } from '../theme'
|
|
5
5
|
import type { ButtonProps, ComponentAttrs } from '../types'
|
|
6
6
|
|
|
7
|
-
export interface ModalEmits extends DialogRootEmits {
|
|
7
|
+
export interface ModalEmits extends DialogRootEmits {
|
|
8
|
+
'after-leave': []
|
|
9
|
+
}
|
|
8
10
|
|
|
9
11
|
export interface ModalSlots {
|
|
10
12
|
default?: (props: { open: boolean }) => any
|
|
@@ -35,6 +37,10 @@ export interface ModalProps extends ComponentAttrs<typeof modal>, DialogRootProp
|
|
|
35
37
|
* @default true
|
|
36
38
|
*/
|
|
37
39
|
dismissible?: boolean
|
|
40
|
+
/**
|
|
41
|
+
* Display a close button to dismiss the modal.
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
38
44
|
close?: ButtonProps | boolean
|
|
39
45
|
/** @default app.icons.close */
|
|
40
46
|
closeIcon?: string
|
|
@@ -43,7 +49,7 @@ export interface ModalProps extends ComponentAttrs<typeof modal>, DialogRootProp
|
|
|
43
49
|
|
|
44
50
|
<script setup lang="ts">
|
|
45
51
|
import { reactivePick } from '@vueuse/core'
|
|
46
|
-
import { DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogPortal, DialogRoot, DialogTitle, DialogTrigger, useForwardPropsEmits } from 'reka-ui'
|
|
52
|
+
import { DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogPortal, DialogRoot, DialogTitle, DialogTrigger, useForwardPropsEmits, VisuallyHidden } from 'reka-ui'
|
|
47
53
|
import { computed, toRef } from 'vue'
|
|
48
54
|
import { useLocale } from '../composables/useLocale'
|
|
49
55
|
import { useTheme } from '../composables/useTheme'
|
|
@@ -60,7 +66,10 @@ const props = withDefaults(defineProps<ModalProps>(), {
|
|
|
60
66
|
const emit = defineEmits<ModalEmits>()
|
|
61
67
|
const slots = defineSlots<ModalSlots>()
|
|
62
68
|
const rootProps = useForwardPropsEmits(reactivePick(props, 'open', 'defaultOpen', 'modal'), emit)
|
|
63
|
-
const contentProps = toRef(() =>
|
|
69
|
+
const contentProps = toRef(() => ({
|
|
70
|
+
...props.content,
|
|
71
|
+
...(slots.content || slots.header || (!props.description && !slots.description)) ? { 'aria-describedby': undefined } : {},
|
|
72
|
+
}))
|
|
64
73
|
const contentEvents = computed(() => {
|
|
65
74
|
if (props.dismissible)
|
|
66
75
|
return {}
|
|
@@ -73,11 +82,8 @@ const contentEvents = computed(() => {
|
|
|
73
82
|
})
|
|
74
83
|
|
|
75
84
|
const { t } = useLocale()
|
|
76
|
-
const { theme,
|
|
77
|
-
const style = computed(() =>
|
|
78
|
-
const styler = createStyler(theme.value.modal)
|
|
79
|
-
return styler(props)
|
|
80
|
-
})
|
|
85
|
+
const { theme, generateStyle } = useTheme()
|
|
86
|
+
const style = computed(() => generateStyle('modal', props))
|
|
81
87
|
</script>
|
|
82
88
|
|
|
83
89
|
<template>
|
|
@@ -92,7 +98,11 @@ const style = computed(() => {
|
|
|
92
98
|
<DialogPortal :disabled="!props.portal">
|
|
93
99
|
<DialogOverlay v-if="props.overlay" :class="style.overlay({ class: props.ui?.overlay })" />
|
|
94
100
|
|
|
95
|
-
<DialogContent :class="style.content({ class: props.ui?.content })" v-bind="contentProps" v-on="contentEvents">
|
|
101
|
+
<DialogContent :class="style.content({ class: props.ui?.content })" v-bind="contentProps" v-on="contentEvents" @after-leave="emit('after-leave')">
|
|
102
|
+
<VisuallyHidden v-if="slots.content || slots.header || (!props.title && !slots.title)">
|
|
103
|
+
<DialogTitle />
|
|
104
|
+
</VisuallyHidden>
|
|
105
|
+
|
|
96
106
|
<slot name="content">
|
|
97
107
|
<div
|
|
98
108
|
v-if="slots.header || props.title || slots.title || props.description || slots.description || props.close || slots.close"
|
|
@@ -108,10 +118,9 @@ const style = computed(() => {
|
|
|
108
118
|
</slot>
|
|
109
119
|
</DialogTitle>
|
|
110
120
|
|
|
111
|
-
<DialogClose as-child>
|
|
121
|
+
<DialogClose v-if="props.close || slots.close" as-child>
|
|
112
122
|
<slot name="close">
|
|
113
123
|
<Button
|
|
114
|
-
v-if="props.close"
|
|
115
124
|
variant="ghost"
|
|
116
125
|
:icon="props.closeIcon || theme.app.icons.close"
|
|
117
126
|
v-bind="typeof props.close === 'boolean' ? {} : props.close"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import type { OverlayComponentState } from '../composables/useOverlay'
|
|
4
|
+
import { useOverlay } from '../composables/useOverlay'
|
|
5
|
+
|
|
6
|
+
const { overlays, unmount, close } = useOverlay()
|
|
7
|
+
const mountedOverlays = computed(() => overlays.filter((overlay) => overlay.isMounted))
|
|
8
|
+
|
|
9
|
+
function onOverlayUnmount(id: OverlayComponentState['id']) {
|
|
10
|
+
close(id)
|
|
11
|
+
unmount(id)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function onClose(id: OverlayComponentState['id'], value: any) {
|
|
15
|
+
close(id, value)
|
|
16
|
+
}
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<component
|
|
21
|
+
:is="overlay.component"
|
|
22
|
+
v-for="overlay in mountedOverlays"
|
|
23
|
+
:key="overlay.id"
|
|
24
|
+
v-bind="overlay.props"
|
|
25
|
+
v-model:open="overlay.modelValue"
|
|
26
|
+
@close="onClose(overlay.id, $event)"
|
|
27
|
+
@after-leave="onOverlayUnmount(overlay.id)"
|
|
28
|
+
/>
|
|
29
|
+
</template>
|
|
@@ -70,6 +70,10 @@ export interface PaginationProps extends ComponentAttrs<typeof pagination>, Pick
|
|
|
70
70
|
* @default true
|
|
71
71
|
*/
|
|
72
72
|
showControls?: boolean
|
|
73
|
+
/**
|
|
74
|
+
* A function to render page controls as links.
|
|
75
|
+
*/
|
|
76
|
+
to?: (page: number) => ButtonProps['to']
|
|
73
77
|
}
|
|
74
78
|
</script>
|
|
75
79
|
|
|
@@ -77,6 +81,7 @@ export interface PaginationProps extends ComponentAttrs<typeof pagination>, Pick
|
|
|
77
81
|
import { reactivePick } from '@vueuse/core'
|
|
78
82
|
import { PaginationEllipsis, PaginationFirst, PaginationLast, PaginationList, PaginationListItem, PaginationNext, PaginationPrev, PaginationRoot, useForwardPropsEmits } from 'reka-ui'
|
|
79
83
|
import { computed } from 'vue'
|
|
84
|
+
import { useLocale } from '../composables/useLocale'
|
|
80
85
|
import { useTheme } from '../composables/useTheme'
|
|
81
86
|
import Button from './Button.vue'
|
|
82
87
|
|
|
@@ -95,71 +100,73 @@ const slots = defineSlots<PaginationSlots>()
|
|
|
95
100
|
|
|
96
101
|
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultPage', 'disabled', 'itemsPerPage', 'page', 'showEdges', 'siblingCount', 'total'), emit)
|
|
97
102
|
|
|
98
|
-
const {
|
|
103
|
+
const { dir } = useLocale()
|
|
104
|
+
const { theme, generateStyle } = useTheme()
|
|
105
|
+
const style = computed(() => generateStyle('pagination', props))
|
|
99
106
|
|
|
100
|
-
const firstIcon = computed(() => props.firstIcon || theme.value.app.icons.chevronDoubleLeft)
|
|
101
|
-
const prevIcon = computed(() => props.prevIcon || theme.value.app.icons.chevronLeft)
|
|
102
|
-
const nextIcon = computed(() => props.nextIcon || theme.value.app.icons.chevronRight)
|
|
103
|
-
const lastIcon = computed(() => props.lastIcon || theme.value.app.icons.chevronDoubleRight)
|
|
107
|
+
const firstIcon = computed(() => props.firstIcon || (dir.value === 'rtl' ? theme.value.app.icons.chevronDoubleRight : theme.value.app.icons.chevronDoubleLeft))
|
|
108
|
+
const prevIcon = computed(() => props.prevIcon || (dir.value === 'rtl' ? theme.value.app.icons.chevronRight : theme.value.app.icons.chevronLeft))
|
|
109
|
+
const nextIcon = computed(() => props.nextIcon || (dir.value === 'rtl' ? theme.value.app.icons.chevronLeft : theme.value.app.icons.chevronRight))
|
|
110
|
+
const lastIcon = computed(() => props.lastIcon || (dir.value === 'rtl' ? theme.value.app.icons.chevronDoubleLeft : theme.value.app.icons.chevronDoubleRight))
|
|
104
111
|
const ellipsisIcon = computed(() => props.ellipsisIcon || theme.value.app.icons.ellipsis)
|
|
105
|
-
|
|
106
|
-
const style = computed(() => {
|
|
107
|
-
const styler = createStyler(theme.value.pagination)
|
|
108
|
-
return styler(props)
|
|
109
|
-
})
|
|
110
112
|
</script>
|
|
111
113
|
|
|
112
114
|
<template>
|
|
113
115
|
<PaginationRoot v-slot="{ page, pageCount }" v-bind="rootProps" :class="style.root({ class: [props.class, props.ui?.root] })">
|
|
114
116
|
<PaginationList v-slot="{ items }" :class="style.list({ class: props.ui?.list })">
|
|
115
|
-
<PaginationFirst v-if="props.showControls || !!slots.first" as-child>
|
|
117
|
+
<PaginationFirst v-if="props.showControls || !!slots.first" :class="style.first({ class: props.ui?.first })" as-child>
|
|
116
118
|
<slot name="first">
|
|
117
|
-
<Button :
|
|
119
|
+
<Button :variant="props.variant" :size="props.size" :icon="firstIcon" :to="props.to?.(1)" />
|
|
118
120
|
</slot>
|
|
119
121
|
</PaginationFirst>
|
|
120
|
-
<PaginationPrev v-if="props.showControls || !!slots.prev" as-child>
|
|
122
|
+
<PaginationPrev v-if="props.showControls || !!slots.prev" :class="style.prev({ class: props.ui?.prev })" as-child>
|
|
121
123
|
<slot name="prev">
|
|
122
|
-
<Button :
|
|
124
|
+
<Button :variant="props.variant" :size="props.size" :icon="prevIcon" :to="page > 1 ? props.to?.(page - 1) : undefined" />
|
|
123
125
|
</slot>
|
|
124
126
|
</PaginationPrev>
|
|
125
127
|
|
|
126
128
|
<template v-for="(item, index) in items">
|
|
127
|
-
<PaginationListItem v-if="item.type === 'page'" :key="index"
|
|
129
|
+
<PaginationListItem v-if="item.type === 'page'" :key="index" :class="style.item({ class: props.ui?.item })" :value="item.value" as-child>
|
|
128
130
|
<slot name="item" v-bind="{ item, index, page, pageCount }">
|
|
129
131
|
<Button
|
|
130
|
-
:class="style.item({ class: props.ui?.item })"
|
|
131
132
|
:variant="props.page === item.value ? props.activeVariant : props.variant"
|
|
132
133
|
:size="props.size"
|
|
133
134
|
:label="String(item.value)"
|
|
134
|
-
:
|
|
135
|
+
:to="props.to?.(item.value)"
|
|
136
|
+
:ui="{ label: style.label({ class: props.ui?.label }) }"
|
|
135
137
|
/>
|
|
136
138
|
</slot>
|
|
137
139
|
</PaginationListItem>
|
|
138
140
|
|
|
139
|
-
<PaginationEllipsis
|
|
141
|
+
<PaginationEllipsis
|
|
142
|
+
v-else
|
|
143
|
+
:key="item.type"
|
|
144
|
+
:class="[
|
|
145
|
+
style.item({ class: props.ui?.item }),
|
|
146
|
+
style.ellipsis({ class: props.ui?.ellipsis }),
|
|
147
|
+
]"
|
|
148
|
+
:index="index"
|
|
149
|
+
:disabled="props.disabled"
|
|
150
|
+
as-child
|
|
151
|
+
>
|
|
140
152
|
<slot name="ellipsis">
|
|
141
153
|
<Button
|
|
142
154
|
:variant="props.variant"
|
|
143
155
|
:size="props.size"
|
|
144
156
|
:icon="ellipsisIcon"
|
|
145
|
-
:disabled="props.disabled /* TODO: remove after reka-ui update */"
|
|
146
|
-
:class="[
|
|
147
|
-
style.item({ class: props.ui?.item }),
|
|
148
|
-
style.ellipsis({ class: props.ui?.ellipsis }),
|
|
149
|
-
]"
|
|
150
157
|
/>
|
|
151
158
|
</slot>
|
|
152
159
|
</PaginationEllipsis>
|
|
153
160
|
</template>
|
|
154
161
|
|
|
155
|
-
<PaginationNext v-if="props.showControls || !!slots.next" as-child>
|
|
162
|
+
<PaginationNext v-if="props.showControls || !!slots.next" :class="style.next({ class: props.ui?.next })" as-child>
|
|
156
163
|
<slot name="next">
|
|
157
|
-
<Button :
|
|
164
|
+
<Button :variant="props.variant" :size="props.size" :icon="nextIcon" :to="page < pageCount ? props.to?.(page + 1) : undefined" />
|
|
158
165
|
</slot>
|
|
159
166
|
</PaginationNext>
|
|
160
|
-
<PaginationLast v-if="props.showControls || !!slots.last" as-child>
|
|
167
|
+
<PaginationLast v-if="props.showControls || !!slots.last" :class="style.last({ class: props.ui?.last })" as-child>
|
|
161
168
|
<slot name="last">
|
|
162
|
-
<Button :
|
|
169
|
+
<Button :variant="props.variant" :size="props.size" :icon="lastIcon" :to="props.to?.(pageCount)" />
|
|
163
170
|
</slot>
|
|
164
171
|
</PaginationLast>
|
|
165
172
|
</PaginationList>
|
|
@@ -41,11 +41,8 @@ const rootProps = useForwardPropsEmits(reactivePick(props, 'defaultValue', 'disa
|
|
|
41
41
|
|
|
42
42
|
const completed = ref(false)
|
|
43
43
|
|
|
44
|
-
const {
|
|
45
|
-
const style = computed(() =>
|
|
46
|
-
const styler = createStyler(theme.value.pinInput)
|
|
47
|
-
return styler(props)
|
|
48
|
-
})
|
|
44
|
+
const { generateStyle } = useTheme()
|
|
45
|
+
const style = computed(() => generateStyle('pinInput', props))
|
|
49
46
|
|
|
50
47
|
function onComplete(value: string[]) {
|
|
51
48
|
// @ts-expect-error - 'target' does not exist in type 'EventInit'
|
|
@@ -69,11 +69,8 @@ const arrowProps = toRef(() => props.arrow as PopoverArrowProps)
|
|
|
69
69
|
|
|
70
70
|
const Component = computed(() => props.mode === 'hover' ? HoverCard : Popover)
|
|
71
71
|
|
|
72
|
-
const {
|
|
73
|
-
const style = computed(() =>
|
|
74
|
-
const styler = createStyler(theme.value.popover)
|
|
75
|
-
return styler(props)
|
|
76
|
-
})
|
|
72
|
+
const { generateStyle } = useTheme()
|
|
73
|
+
const style = computed(() => generateStyle('popover', props))
|
|
77
74
|
</script>
|
|
78
75
|
|
|
79
76
|
<template>
|
|
@@ -83,11 +83,8 @@ const percent = computed(() => {
|
|
|
83
83
|
})
|
|
84
84
|
|
|
85
85
|
const { dir } = useLocale()
|
|
86
|
-
const {
|
|
87
|
-
const style = computed(() =>
|
|
88
|
-
const styler = createStyler(theme.value.progress)
|
|
89
|
-
return styler(props)
|
|
90
|
-
})
|
|
86
|
+
const { generateStyle } = useTheme()
|
|
87
|
+
const style = computed(() => generateStyle('progress', props))
|
|
91
88
|
|
|
92
89
|
const indicatorStyle = computed(() => {
|
|
93
90
|
if (percent.value === undefined)
|
|
@@ -25,7 +25,7 @@ type NormalizeItem<T> = { id: string } & (
|
|
|
25
25
|
label: string
|
|
26
26
|
value: any
|
|
27
27
|
description: string
|
|
28
|
-
disabled:
|
|
28
|
+
disabled: boolean
|
|
29
29
|
}
|
|
30
30
|
)
|
|
31
31
|
|
|
@@ -90,11 +90,8 @@ const slots = defineSlots<RadioGroupSlots<T>>()
|
|
|
90
90
|
const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'orientation', 'loop', 'required'), emit)
|
|
91
91
|
const id = useId()
|
|
92
92
|
|
|
93
|
-
const {
|
|
94
|
-
const style = computed(() =>
|
|
95
|
-
const styler = createStyler(theme.value.radioGroup)
|
|
96
|
-
return styler(props)
|
|
97
|
-
})
|
|
93
|
+
const { generateStyle } = useTheme()
|
|
94
|
+
const style = computed(() => generateStyle('radioGroup', props))
|
|
98
95
|
|
|
99
96
|
function normalizeItem(item: any): NormalizeItem<T> {
|
|
100
97
|
if (['string', 'number', 'boolean'].includes(typeof item)) {
|
|
@@ -103,6 +100,7 @@ function normalizeItem(item: any): NormalizeItem<T> {
|
|
|
103
100
|
value: item,
|
|
104
101
|
label: item,
|
|
105
102
|
description: '',
|
|
103
|
+
disabled: props.disabled,
|
|
106
104
|
} as any
|
|
107
105
|
}
|
|
108
106
|
|
|
@@ -116,6 +114,7 @@ function normalizeItem(item: any): NormalizeItem<T> {
|
|
|
116
114
|
label,
|
|
117
115
|
description,
|
|
118
116
|
id: `${id}:${value}`,
|
|
117
|
+
disabled: props.disabled || item.disabled,
|
|
119
118
|
}
|
|
120
119
|
}
|
|
121
120
|
|
|
@@ -149,7 +148,7 @@ function onUpdate(value: any) {
|
|
|
149
148
|
{{ props.legend }}
|
|
150
149
|
</slot>
|
|
151
150
|
</legend>
|
|
152
|
-
<div v-for="item in normalizedItems" :key="item.value" :class="style.item({ class: props.ui?.item })">
|
|
151
|
+
<div v-for="item in normalizedItems" :key="item.value" :class="style.item({ class: props.ui?.item, disabled: item.disabled })">
|
|
153
152
|
<div :class="style.container({ class: props.ui?.container })">
|
|
154
153
|
<RadioGroupItem
|
|
155
154
|
:id="item.id"
|
|
@@ -17,12 +17,8 @@ const props = withDefaults(defineProps<ScrollAreaProps>(), {})
|
|
|
17
17
|
const rootRef = ref<InstanceType<typeof ScrollAreaRoot>>()
|
|
18
18
|
const rootProps = reactivePick(props, 'type', 'dir', 'scrollHideDelay')
|
|
19
19
|
|
|
20
|
-
const {
|
|
21
|
-
|
|
22
|
-
const style = computed(() => {
|
|
23
|
-
const styler = createStyler(theme.value.scrollArea)
|
|
24
|
-
return styler(props)
|
|
25
|
-
})
|
|
20
|
+
const { generateStyle } = useTheme()
|
|
21
|
+
const style = computed(() => generateStyle('scrollArea', props))
|
|
26
22
|
|
|
27
23
|
defineExpose({
|
|
28
24
|
scrollTop,
|