@byyuurin/ui 0.0.7 → 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.
Files changed (151) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +8 -7
  3. package/dist/module.mjs.map +1 -1
  4. package/dist/runtime/app/injections.d.ts +11 -0
  5. package/dist/runtime/app/injections.js +26 -0
  6. package/dist/runtime/components/Accordion.vue +28 -26
  7. package/dist/runtime/components/Alert.vue +27 -23
  8. package/dist/runtime/components/App.vue +21 -26
  9. package/dist/runtime/components/Avatar.vue +70 -0
  10. package/dist/runtime/components/AvatarGroup.vue +87 -0
  11. package/dist/runtime/components/Badge.vue +17 -15
  12. package/dist/runtime/components/Breadcrumb.vue +108 -0
  13. package/dist/runtime/components/Button.vue +15 -16
  14. package/dist/runtime/components/ButtonGroup.vue +14 -15
  15. package/dist/runtime/components/Calendar.vue +176 -0
  16. package/dist/runtime/components/Card.vue +9 -7
  17. package/dist/runtime/components/Carousel.vue +22 -22
  18. package/dist/runtime/components/Checkbox.vue +15 -14
  19. package/dist/runtime/components/Chip.vue +23 -21
  20. package/dist/runtime/components/Collapsible.vue +5 -8
  21. package/dist/runtime/components/Drawer.vue +91 -49
  22. package/dist/runtime/components/Input.vue +33 -36
  23. package/dist/runtime/components/InputNumber.vue +9 -10
  24. package/dist/runtime/components/Kbd.vue +47 -0
  25. package/dist/runtime/components/Link.vue +15 -12
  26. package/dist/runtime/components/LinkBase.vue +1 -1
  27. package/dist/runtime/components/Modal.vue +31 -19
  28. package/dist/runtime/components/OverlayProvider.vue +29 -0
  29. package/dist/runtime/components/Pagination.vue +60 -53
  30. package/dist/runtime/components/PinInput.vue +9 -12
  31. package/dist/runtime/components/Popover.vue +9 -12
  32. package/dist/runtime/components/Progress.vue +162 -0
  33. package/dist/runtime/components/RadioGroup.vue +38 -35
  34. package/dist/runtime/components/ScrollArea.vue +2 -6
  35. package/dist/runtime/components/Select.vue +48 -51
  36. package/dist/runtime/components/Separator.vue +2 -6
  37. package/dist/runtime/components/Skeleton.vue +30 -0
  38. package/dist/runtime/components/Slider.vue +8 -11
  39. package/dist/runtime/components/Switch.vue +17 -17
  40. package/dist/runtime/components/Table.vue +21 -16
  41. package/dist/runtime/components/Tabs.vue +24 -23
  42. package/dist/runtime/components/Textarea.vue +13 -16
  43. package/dist/runtime/components/Toast.vue +21 -24
  44. package/dist/runtime/components/{Toaster.vue → ToastProvider.vue} +22 -20
  45. package/dist/runtime/components/Tooltip.vue +9 -12
  46. package/dist/runtime/composables/useAvatarGroup.d.ts +4 -0
  47. package/dist/runtime/composables/useAvatarGroup.js +8 -0
  48. package/dist/runtime/composables/useButtonGroup.d.ts +4 -12
  49. package/dist/runtime/composables/useButtonGroup.js +1 -6
  50. package/dist/runtime/composables/useComponentIcons.d.ts +9 -9
  51. package/dist/runtime/composables/useComponentIcons.js +11 -11
  52. package/dist/runtime/composables/useKbd.d.ts +35 -0
  53. package/dist/runtime/composables/useKbd.js +49 -0
  54. package/dist/runtime/composables/useLocale.d.ts +8 -0
  55. package/dist/runtime/composables/useLocale.js +22 -0
  56. package/dist/runtime/composables/useOverlay.d.ts +29 -0
  57. package/dist/runtime/composables/useOverlay.js +69 -0
  58. package/dist/runtime/composables/useTheme.d.ts +6 -6
  59. package/dist/runtime/composables/useTheme.js +11 -15
  60. package/dist/runtime/composables/useToast.d.ts +4 -20
  61. package/dist/runtime/composables/useToast.js +6 -5
  62. package/dist/runtime/index.d.ts +9 -2
  63. package/dist/runtime/index.js +9 -2
  64. package/dist/runtime/locale/en.d.ts +2 -0
  65. package/dist/runtime/locale/en.js +34 -0
  66. package/dist/runtime/locale/index.d.ts +2 -0
  67. package/dist/runtime/locale/index.js +2 -0
  68. package/dist/runtime/locale/zh-tw.d.ts +2 -0
  69. package/dist/runtime/locale/zh-tw.js +34 -0
  70. package/dist/runtime/theme/accordion.d.ts +6 -6
  71. package/dist/runtime/theme/accordion.js +5 -5
  72. package/dist/runtime/theme/alert.js +3 -3
  73. package/dist/runtime/theme/app.d.ts +6 -6
  74. package/dist/runtime/theme/app.js +7 -7
  75. package/dist/runtime/theme/avatar-group.d.ts +52 -0
  76. package/dist/runtime/theme/avatar-group.js +32 -0
  77. package/dist/runtime/theme/avatar.d.ts +56 -0
  78. package/dist/runtime/theme/avatar.js +34 -0
  79. package/dist/runtime/theme/breadcrumb.d.ts +67 -0
  80. package/dist/runtime/theme/breadcrumb.js +44 -0
  81. package/dist/runtime/theme/button.d.ts +8 -8
  82. package/dist/runtime/theme/button.js +22 -22
  83. package/dist/runtime/theme/calendar.d.ts +56 -0
  84. package/dist/runtime/theme/calendar.js +69 -0
  85. package/dist/runtime/theme/card.js +6 -6
  86. package/dist/runtime/theme/carousel.js +1 -1
  87. package/dist/runtime/theme/checkbox.js +5 -5
  88. package/dist/runtime/theme/chip.d.ts +4 -4
  89. package/dist/runtime/theme/chip.js +5 -5
  90. package/dist/runtime/theme/drawer.d.ts +24 -21
  91. package/dist/runtime/theme/drawer.js +47 -20
  92. package/dist/runtime/theme/index.d.ts +8 -1
  93. package/dist/runtime/theme/index.js +8 -1
  94. package/dist/runtime/theme/input-number.d.ts +6 -0
  95. package/dist/runtime/theme/input-number.js +6 -3
  96. package/dist/runtime/theme/input.d.ts +12 -12
  97. package/dist/runtime/theme/input.js +26 -26
  98. package/dist/runtime/theme/kbd.d.ts +39 -0
  99. package/dist/runtime/theme/kbd.js +26 -0
  100. package/dist/runtime/theme/link.d.ts +1 -1
  101. package/dist/runtime/theme/link.js +3 -3
  102. package/dist/runtime/theme/modal.js +5 -5
  103. package/dist/runtime/theme/pagination.d.ts +27 -3
  104. package/dist/runtime/theme/pagination.js +6 -2
  105. package/dist/runtime/theme/pinInput.js +13 -13
  106. package/dist/runtime/theme/popover.js +1 -1
  107. package/dist/runtime/theme/progress.d.ts +122 -0
  108. package/dist/runtime/theme/progress.js +95 -0
  109. package/dist/runtime/theme/radio-group.d.ts +2 -2
  110. package/dist/runtime/theme/radio-group.js +7 -7
  111. package/dist/runtime/theme/select.d.ts +18 -18
  112. package/dist/runtime/theme/select.js +34 -34
  113. package/dist/runtime/theme/separator.js +1 -1
  114. package/dist/runtime/theme/skeleton.d.ts +8 -0
  115. package/dist/runtime/theme/skeleton.js +7 -0
  116. package/dist/runtime/theme/slider.js +1 -1
  117. package/dist/runtime/theme/switch.js +6 -6
  118. package/dist/runtime/theme/table.js +7 -7
  119. package/dist/runtime/theme/tabs.d.ts +2 -2
  120. package/dist/runtime/theme/tabs.js +11 -11
  121. package/dist/runtime/theme/textarea.js +13 -13
  122. package/dist/runtime/theme/toast.js +6 -6
  123. package/dist/runtime/theme/tooltip.js +1 -1
  124. package/dist/runtime/types/components.d.ts +9 -1
  125. package/dist/runtime/types/index.d.ts +1 -0
  126. package/dist/runtime/types/index.js +1 -0
  127. package/dist/runtime/types/locale.d.ts +29 -0
  128. package/dist/runtime/types/locale.js +0 -0
  129. package/dist/runtime/types/utils.d.ts +5 -3
  130. package/dist/runtime/utils/index.d.ts +6 -1
  131. package/dist/runtime/utils/index.js +6 -4
  132. package/dist/runtime/utils/link.d.ts +1 -1
  133. package/dist/runtime/utils/translator.d.ts +18 -0
  134. package/dist/runtime/utils/translator.js +8 -0
  135. package/dist/shared/ui.1a1f119c.mjs +5 -0
  136. package/dist/shared/ui.1a1f119c.mjs.map +1 -0
  137. package/dist/unocss.mjs +19 -14
  138. package/dist/unocss.mjs.map +1 -1
  139. package/dist/unplugin.mjs +3 -12
  140. package/dist/unplugin.mjs.map +1 -1
  141. package/dist/vite.mjs +1 -1
  142. package/package.json +30 -19
  143. package/dist/runtime/components/ModalProvider.vue +0 -10
  144. package/dist/runtime/composables/useModal.d.ts +0 -15
  145. package/dist/runtime/composables/useModal.js +0 -52
  146. package/dist/shared/ui.d1728164.mjs +0 -4
  147. package/dist/shared/ui.d1728164.mjs.map +0 -1
  148. /package/dist/runtime/theme/{toaster.d.ts → toast-provider.d.ts} +0 -0
  149. /package/dist/runtime/theme/{toaster.js → toast-provider.js} +0 -0
  150. /package/dist/runtime/{composables/defineInjection.d.ts → utils/vue.d.ts} +0 -0
  151. /package/dist/runtime/{composables/defineInjection.js → utils/vue.js} +0 -0
@@ -5,19 +5,24 @@ import type { UseComponentIconsProps } from '../composables/useComponentIcons'
5
5
  import type { chip } from '../theme'
6
6
  import type { ComponentAttrs } from '../types'
7
7
 
8
+ export interface ChipSlots {
9
+ leading?: (props?: {}) => any
10
+ default?: (props?: {}) => any
11
+ trailing?: (props?: {}) => any
12
+ }
13
+
8
14
  type ChipVariants = VariantProps<typeof chip>
9
15
 
10
- export interface ChipProps extends ComponentAttrs<typeof chip>, Pick<PrimitiveProps, 'as'>, Omit<UseComponentIconsProps, 'loading' | 'loadingIcon'> {
16
+ export interface ChipProps extends ComponentAttrs<typeof chip>, Omit<UseComponentIconsProps, 'loading' | 'loadingIcon'> {
17
+ /**
18
+ * The element or component this component should render as.
19
+ * @default "div"
20
+ */
21
+ as?: PrimitiveProps['as']
11
22
  variant?: ChipVariants['variant']
12
23
  size?: ChipVariants['size']
13
24
  label?: string
14
25
  }
15
-
16
- export interface ChipSlots {
17
- prefix?: (props?: {}) => any
18
- default?: (props?: {}) => any
19
- suffix?: (props?: {}) => any
20
- }
21
26
  </script>
22
27
 
23
28
  <script setup lang="ts">
@@ -34,31 +39,28 @@ const props = withDefaults(defineProps<ChipProps>(), {
34
39
  const slots = defineSlots<ChipSlots>()
35
40
 
36
41
  const { size, orientation } = useButtonGroup(props)
37
- const { isPrefix, prefixIconName, isSuffix, suffixIconName } = useComponentIcons(props)
42
+ const { isLeading, leadingIconName, isTrailing, trailingIconName } = useComponentIcons(props)
38
43
 
39
- const { theme, createStyler } = useTheme()
40
- const style = computed(() => {
41
- const styler = createStyler(theme.value.chip)
42
- return styler({
43
- ...props,
44
- size: size.value,
45
- groupOrientation: orientation.value,
46
- })
47
- })
44
+ const { generateStyle } = useTheme()
45
+ const style = computed(() => generateStyle('chip', {
46
+ ...props,
47
+ size: size.value,
48
+ groupOrientation: orientation.value,
49
+ }))
48
50
  </script>
49
51
 
50
52
  <template>
51
53
  <Primitive :as="props.as" :class="style.base({ class: [props.class, props.ui?.base] })">
52
- <slot name="prefix">
53
- <span v-if="isPrefix && prefixIconName" :class="style.prefixIcon({ class: [prefixIconName, props.ui?.prefixIcon] })"></span>
54
+ <slot name="leading">
55
+ <span v-if="isLeading && leadingIconName" :class="style.leadingIcon({ class: [leadingIconName, props.ui?.leadingIcon] })"></span>
54
56
  </slot>
55
57
 
56
58
  <span v-if="props.label || slots.default" :class="style.label({ class: props.ui?.label })">
57
59
  <slot>{{ props.label }}</slot>
58
60
  </span>
59
61
 
60
- <slot name="suffix">
61
- <span v-if="isSuffix && suffixIconName" :class="style.suffixIcon({ class: [suffixIconName, props.ui?.suffixIcon] })"></span>
62
+ <slot name="trailing">
63
+ <span v-if="isTrailing && trailingIconName" :class="style.trailingIcon({ class: [trailingIconName, props.ui?.trailingIcon] })"></span>
62
64
  </slot>
63
65
  </Primitive>
64
66
  </template>
@@ -3,15 +3,15 @@ import type { CollapsibleRootEmits, CollapsibleRootProps } from 'reka-ui'
3
3
  import type { collapsible } from '../theme'
4
4
  import type { ComponentAttrs } from '../types'
5
5
 
6
- export interface CollapsibleProps extends ComponentAttrs<typeof collapsible>, Pick<CollapsibleRootProps, 'as' | 'defaultOpen' | 'open' | 'disabled' | 'unmountOnHide'> {
7
- }
8
-
9
6
  export interface CollapsibleEmits extends CollapsibleRootEmits {}
10
7
 
11
8
  export interface CollapsibleSlots {
12
9
  default?: (props: { open: boolean }) => any
13
10
  content?: (props?: {}) => any
14
11
  }
12
+
13
+ export interface CollapsibleProps extends ComponentAttrs<typeof collapsible>, Pick<CollapsibleRootProps, 'as' | 'defaultOpen' | 'open' | 'disabled' | 'unmountOnHide'> {
14
+ }
15
15
  </script>
16
16
 
17
17
  <script setup lang="ts">
@@ -28,11 +28,8 @@ const slots = defineSlots<CollapsibleSlots>()
28
28
 
29
29
  const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultOpen', 'open', 'disabled', 'unmountOnHide'), emit)
30
30
 
31
- const { theme, createStyler } = useTheme()
32
- const style = computed(() => {
33
- const styler = createStyler(theme.value.collapsible)
34
- return styler(props)
35
- })
31
+ const { generateStyle } = useTheme()
32
+ const style = computed(() => generateStyle('collapsible', props))
36
33
  </script>
37
34
 
38
35
  <template>
@@ -1,11 +1,27 @@
1
1
  <script lang="ts">
2
- import type { DialogContentProps, PrimitiveProps } from 'reka-ui'
3
- import type { DrawerRootEmits, DrawerRootProps } from 'vaul-vue'
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 DrawerProps extends ComponentAttrs<typeof drawer>, Pick<DrawerRootProps, 'activeSnapPoint' | 'closeThreshold' | 'defaultOpen' | 'direction' | 'fadeFromIndex' | 'fixed' | 'modal' | 'nested' | 'direction' | 'open' | 'scrollLockTimeout' | 'shouldScaleBackground' | 'snapPoints'> {
8
- as?: PrimitiveProps['as']
7
+ export interface DrawerEmits extends DialogRootEmits {
8
+ 'after-leave': []
9
+ }
10
+
11
+ export interface DrawerSlots {
12
+ default?: (props?: {}) => any
13
+ content?: (props?: {}) => any
14
+ header?: (props?: {}) => any
15
+ title?: (props?: {}) => any
16
+ description?: (props?: {}) => any
17
+ close?: (props?: {}) => any
18
+ body?: (props?: {}) => any
19
+ footer?: (props?: {}) => any
20
+ }
21
+
22
+ type DrawerVariants = VariantProps<typeof drawer>
23
+
24
+ export interface DrawerProps extends ComponentAttrs<typeof drawer>, DialogRootProps {
9
25
  title?: string
10
26
  description?: string
11
27
  /** The content of the drawer. */
@@ -15,108 +31,134 @@ export interface DrawerProps extends ComponentAttrs<typeof drawer>, Pick<DrawerR
15
31
  * @default true
16
32
  */
17
33
  overlay?: boolean
34
+ /** @default true */
35
+ transition?: boolean
36
+ /**
37
+ * The direction of the drawer.
38
+ * @default "bottom"
39
+ */
40
+ direction?: DrawerVariants['direction']
18
41
  /**
19
42
  * Whether to inset the drawer from the edges.
20
43
  */
21
44
  inset?: boolean
22
45
  /**
23
- * Render a handle on the drawer.
46
+ * Render the drawer in a portal.
24
47
  * @default true
25
48
  */
26
- handle?: boolean
49
+ portal?: boolean
27
50
  /**
28
- * Render the drawer in a portal.
51
+ * Display a close button to dismiss the drawer.
29
52
  * @default true
30
53
  */
31
- portal?: boolean
54
+ close?: ButtonProps | boolean
55
+ /** @default app.icons.close */
56
+ closeIcon?: string
32
57
  /**
33
58
  * When `false`, the drawer will not close when clicking outside or pressing escape.
34
59
  * @default true
35
60
  */
36
61
  dismissible?: boolean
37
62
  }
38
-
39
- export interface DrawerEmits extends DrawerRootEmits {}
40
-
41
- export interface DrawerSlots {
42
- default?: (props?: {}) => any
43
- handle?: (props?: {}) => any
44
- content?: (props?: {}) => any
45
- header?: (props?: {}) => any
46
- title?: (props?: {}) => any
47
- description?: (props?: {}) => any
48
- body?: (props?: {}) => any
49
- footer?: (props?: {}) => any
50
- }
51
63
  </script>
52
64
 
53
65
  <script setup lang="ts">
54
66
  import { reactivePick } from '@vueuse/core'
55
- import { useForwardPropsEmits } from 'reka-ui'
56
- 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'
57
68
  import { computed, toRef } from 'vue'
69
+ import { useLocale } from '../composables/useLocale'
58
70
  import { useTheme } from '../composables/useTheme'
71
+ import Button from './Button.vue'
59
72
 
60
73
  const props = withDefaults(defineProps<DrawerProps>(), {
61
74
  direction: 'bottom',
75
+ modal: true,
62
76
  portal: true,
63
77
  overlay: true,
64
- handle: true,
78
+ transition: true,
79
+ dismissible: true,
80
+ close: true,
65
81
  })
66
82
  const emit = defineEmits<DrawerEmits>()
67
83
  const slots = defineSlots<DrawerSlots>()
68
84
 
69
- const rootProps = useForwardPropsEmits(reactivePick(props, 'activeSnapPoint', 'closeThreshold', 'defaultOpen', 'dismissible', 'fadeFromIndex', 'fixed', 'modal', 'nested', 'direction', 'open', 'scrollLockTimeout', 'shouldScaleBackground', 'snapPoints'), emit)
70
- const contentProps = toRef(() => props.content)
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 {}
71
93
 
72
- const { theme, createStyler } = useTheme()
73
- const style = computed(() => {
74
- const styler = createStyler(theme.value.drawer)
75
- return styler(props)
94
+ return {
95
+ pointerDownOutside: (e: Event) => e.preventDefault(),
96
+ interactOutside: (e: Event) => e.preventDefault(),
97
+ escapeKeyDown: (e: Event) => e.preventDefault(),
98
+ }
76
99
  })
100
+
101
+ const { t } = useLocale()
102
+ const { theme, generateStyle } = useTheme()
103
+ const style = computed(() => generateStyle('drawer', props))
77
104
  </script>
78
105
 
79
106
  <template>
80
- <DrawerRoot v-bind="rootProps">
81
- <DrawerTrigger v-if="slots.default" as-child :class="props.class">
82
- <slot></slot>
83
- </DrawerTrigger>
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>
84
111
 
85
- <DrawerPortal :disabled="!props.portal">
86
- <DrawerOverlay v-if="props.overlay" :class="style.overlay({ class: props.ui?.overlay })" />
112
+ <DialogPortal :disabled="!props.portal">
113
+ <DialogOverlay v-if="props.overlay" :class="style.overlay({ class: props.ui?.overlay })" />
87
114
 
88
- <DrawerContent
115
+ <DialogContent
89
116
  :class="style.content({ class: [!slots.default && props.class, props.ui?.content] })"
117
+ :data-direction="props.direction"
90
118
  v-bind="contentProps"
119
+ v-on="contentEvents"
120
+ @after-leave="emit('after-leave')"
91
121
  >
92
- <slot name="handle">
93
- <div v-if="props.handle" :class="style.handle({ class: props.ui?.handle })"></div>
94
- </slot>
122
+ <VisuallyHidden v-if="slots.content || slots.header || (!props.title && !slots.title)">
123
+ <DialogTitle />
124
+ </VisuallyHidden>
95
125
 
96
126
  <slot name="content">
97
127
  <div :class="style.container({ class: props.ui?.container })">
98
128
  <div
99
- 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"
100
130
  :class="style.header({ class: props.ui?.header })"
101
131
  >
102
132
  <slot name="header">
103
- <DrawerTitle
133
+ <DialogTitle
104
134
  v-if="props.title || slots.title"
105
135
  :class="style.title({ class: props.ui?.title })"
106
136
  >
107
137
  <slot name="title">
108
138
  {{ props.title }}
109
139
  </slot>
110
- </DrawerTitle>
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>
111
153
 
112
- <DrawerDescription
154
+ <DialogDescription
113
155
  v-if="props.description || slots.description"
114
156
  :class="style.description({ class: props.ui?.description })"
115
157
  >
116
158
  <slot name="description">
117
159
  {{ props.description }}
118
160
  </slot>
119
- </DrawerDescription>
161
+ </DialogDescription>
120
162
  </slot>
121
163
  </div>
122
164
 
@@ -129,7 +171,7 @@ const style = computed(() => {
129
171
  </div>
130
172
  </div>
131
173
  </slot>
132
- </DrawerContent>
133
- </DrawerPortal>
134
- </DrawerRoot>
174
+ </DialogContent>
175
+ </DialogPortal>
176
+ </DialogRoot>
135
177
  </template>
@@ -6,12 +6,24 @@ import type { UseComponentIconsProps } from '../composables/useComponentIcons'
6
6
  import type { input } from '../theme'
7
7
  import type { ComponentAttrs } from '../types'
8
8
 
9
+ export interface InputEmits {
10
+ (e: 'update:modelValue', payload: string | number): void
11
+ (e: 'blur', event: FocusEvent): void
12
+ (e: 'change', event: Event): void
13
+ }
14
+
15
+ export interface InputSlots {
16
+ leading?: (props?: {}) => any
17
+ default?: (props?: {}) => any
18
+ trailing?: (props?: {}) => any
19
+ }
20
+
9
21
  type InputVariants = VariantProps<typeof input>
10
22
 
11
23
  export interface InputProps extends ComponentAttrs<typeof input>, UseComponentIconsProps {
12
24
  /**
13
25
  * The element or component this component should render as.
14
- * @defaultValue 'div'
26
+ * @default "div"
15
27
  */
16
28
  as?: PrimitiveProps['as']
17
29
  id?: string
@@ -29,18 +41,6 @@ export interface InputProps extends ComponentAttrs<typeof input>, UseComponentIc
29
41
  autofocusDelay?: number
30
42
  disabled?: boolean
31
43
  }
32
-
33
- export interface InputEmits {
34
- (e: 'update:modelValue', payload: string | number): void
35
- (e: 'blur', event: FocusEvent): void
36
- (e: 'change', event: Event): void
37
- }
38
-
39
- export interface InputSlots {
40
- prefix?: (props?: {}) => any
41
- default?: (props?: {}) => any
42
- suffix?: (props?: {}) => any
43
- }
44
44
  </script>
45
45
 
46
46
  <script setup lang="ts">
@@ -69,21 +69,18 @@ const [modelValue, modelModifiers] = defineModel<string | number>()
69
69
  const inputRef = ref<HTMLInputElement | null>(null)
70
70
 
71
71
  const { size, orientation } = useButtonGroup(props)
72
- const { isPrefix, prefixIconName, isSuffix, suffixIconName } = useComponentIcons(props)
73
-
74
- const { theme, createStyler } = useTheme()
75
- const style = computed(() => {
76
- const styler = createStyler(theme.value.input)
77
- return styler({
78
- ...props,
79
- // @ts-expect-error ignore type
80
- type: props.type,
81
- size: size.value,
82
- groupOrientation: orientation.value,
83
- prefix: isPrefix.value || !!slots.prefix,
84
- suffix: isSuffix.value || !!slots.suffix,
85
- })
86
- })
72
+ const { isLeading, leadingIconName, isTrailing, trailingIconName } = useComponentIcons(props)
73
+
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)
@@ -138,11 +135,11 @@ onMounted(() => {
138
135
  :class="style.base({ class: [props.class, props.ui?.base] })"
139
136
  :aria-disabled="props.disabled ? true : undefined"
140
137
  >
141
- <span v-if="isPrefix || slots.prefix" :class="style.prefix({ class: props.ui?.prefix })">
142
- <slot name="prefix">
138
+ <span v-if="isLeading || slots.leading" :class="style.leading({ class: props.ui?.leading })">
139
+ <slot name="leading">
143
140
  <span
144
- v-if="isPrefix && prefixIconName"
145
- :class="style.prefixIcon({ class: [prefixIconName, props.ui?.prefixIcon] })"
141
+ v-if="isLeading && leadingIconName"
142
+ :class="style.leadingIcon({ class: [leadingIconName, props.ui?.leadingIcon] })"
146
143
  ></span>
147
144
  </slot>
148
145
  </span>
@@ -166,11 +163,11 @@ onMounted(() => {
166
163
 
167
164
  <slot></slot>
168
165
 
169
- <span v-if="isSuffix || slots.suffix" :class="style.suffix({ class: props.ui?.suffix })">
170
- <slot name="suffix">
166
+ <span v-if="isTrailing || slots.trailing" :class="style.trailing({ class: props.ui?.trailing })">
167
+ <slot name="trailing">
171
168
  <span
172
- v-if="isSuffix && suffixIconName"
173
- :class="style.suffixIcon({ class: [suffixIconName, props.ui?.suffixIcon] })"
169
+ v-if="isTrailing && trailingIconName"
170
+ :class="style.trailingIcon({ class: [trailingIconName, props.ui?.trailingIcon] })"
174
171
  ></span>
175
172
  </slot>
176
173
  </span>
@@ -27,7 +27,7 @@ export interface InputNumberProps extends ComponentAttrs<typeof inputNumber>, Pi
27
27
  highlight?: boolean
28
28
  /**
29
29
  * The orientation of the input menu.
30
- * @default 'horizontal'
30
+ * @default "horizontal"
31
31
  */
32
32
  orientation?: InputNumberVariants['orientation']
33
33
  /**
@@ -63,6 +63,7 @@ export interface InputNumberProps extends ComponentAttrs<typeof inputNumber>, Pi
63
63
  import { reactivePick } from '@vueuse/core'
64
64
  import { NumberFieldDecrement, NumberFieldIncrement, NumberFieldInput, NumberFieldRoot, useForwardPropsEmits } from 'reka-ui'
65
65
  import { computed, onMounted, ref } from 'vue'
66
+ import { useLocale } from '../composables/useLocale'
66
67
  import { useTheme } from '../composables/useTheme'
67
68
  import Button from './Button.vue'
68
69
 
@@ -81,14 +82,12 @@ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', '
81
82
 
82
83
  const inputRef = ref<InstanceType<typeof NumberFieldInput> | null>(null)
83
84
 
84
- const { theme, createStyler } = useTheme()
85
- const incrementIcon = computed(() => props.incrementIcon || (props.orientation === 'horizontal' ? theme.value.app.icons.plus : theme.value.app.icons.up))
86
- const decrementIcon = computed(() => props.decrementIcon || (props.orientation === 'horizontal' ? theme.value.app.icons.minus : theme.value.app.icons.down))
85
+ const { t } = useLocale()
86
+ const { theme, generateStyle } = useTheme()
87
+ const incrementIcon = computed(() => props.incrementIcon || (props.orientation === 'horizontal' ? theme.value.app.icons.plus : theme.value.app.icons.chevronUp))
88
+ const decrementIcon = computed(() => props.decrementIcon || (props.orientation === 'horizontal' ? theme.value.app.icons.minus : theme.value.app.icons.chevronDown))
87
89
 
88
- const style = computed(() => {
89
- const styler = createStyler(theme.value.inputNumber)
90
- return styler(props)
91
- })
90
+ const style = computed(() => generateStyle('inputNumber', props))
92
91
 
93
92
  onMounted(() => {
94
93
  setTimeout(() => {
@@ -143,7 +142,7 @@ function onBlur(event: FocusEvent) {
143
142
  :icon="incrementIcon"
144
143
  :size="props.size"
145
144
  variant="link"
146
- aria-label="increment"
145
+ :aria-label="t('inputNumber.increment')"
147
146
  v-bind="typeof props.increment === 'object' ? props.increment : undefined"
148
147
  />
149
148
  </slot>
@@ -157,7 +156,7 @@ function onBlur(event: FocusEvent) {
157
156
  :icon="decrementIcon"
158
157
  :size="props.size"
159
158
  variant="link"
160
- aria-label="decrement"
159
+ :aria-label="t('inputNumber.decrement')"
161
160
  v-bind="typeof props.decrement === 'object' ? props.decrement : undefined"
162
161
  />
163
162
  </slot>
@@ -0,0 +1,47 @@
1
+ <script lang="ts">
2
+ import type { VariantProps } from '@byyuurin/ui-kit'
3
+ import type { PrimitiveProps } from 'reka-ui'
4
+ import { computed } from 'vue'
5
+ import type { KbdKey } from '../composables/useKbd'
6
+ import type { kbd } from '../theme'
7
+ import type { ComponentAttrs } from '../types'
8
+
9
+ export interface KbdSlots {
10
+ default?: (props?: {}) => any
11
+ }
12
+
13
+ type KbdVariants = VariantProps<typeof kbd>
14
+
15
+ export interface KbdProps extends Omit<ComponentAttrs<typeof kbd>, 'ui'> {
16
+ /**
17
+ * The element or component this component should render as.
18
+ * @default "kbd"
19
+ */
20
+ as?: PrimitiveProps['as']
21
+ variant?: KbdVariants['variant']
22
+ size?: KbdVariants['size']
23
+ value?: KbdKey | (string & {})
24
+ }
25
+ </script>
26
+
27
+ <script setup lang="ts">
28
+ import { Primitive } from 'reka-ui'
29
+ import { useKbd } from '../composables/useKbd'
30
+ import { useTheme } from '../composables/useTheme'
31
+
32
+ const props = withDefaults(defineProps<KbdProps>(), {
33
+ as: 'kbd',
34
+ })
35
+
36
+ defineSlots<KbdSlots>()
37
+
38
+ const { getKbdKey } = useKbd()
39
+ const { generateStyle } = useTheme()
40
+ const style = computed(() => generateStyle('kbd', props))
41
+ </script>
42
+
43
+ <template>
44
+ <Primitive :as="props.as" :class="style">
45
+ <slot>{{ getKbdKey(props.value) }}</slot>
46
+ </Primitive>
47
+ </template>
@@ -5,6 +5,10 @@ import type { RouteLocationRaw, RouterLinkProps } from 'vue-router'
5
5
  import type { link } from '../theme'
6
6
  import type { ComponentAttrs } from '../types'
7
7
 
8
+ export interface LinkSlots {
9
+ default?: (props: { active: boolean }) => any
10
+ }
11
+
8
12
  interface NuxtLinkProps extends Omit<RouterLinkProps, 'to'> {
9
13
  /**
10
14
  * Route Location the link should navigate to when clicked on.
@@ -54,12 +58,12 @@ interface NuxtLinkProps extends Omit<RouterLinkProps, 'to'> {
54
58
  export interface LinkProps extends Omit<ComponentAttrs<typeof link>, 'ui'>, NuxtLinkProps {
55
59
  /**
56
60
  * The element or component this component should render as when not a link.
57
- * @default 'button'
61
+ * @default "button"
58
62
  */
59
63
  as?: PrimitiveProps['as']
60
64
  /**
61
65
  * The type of the button when not a link.
62
- * @default 'button'
66
+ * @default "button"
63
67
  */
64
68
  type?: ButtonHTMLAttributes['type']
65
69
  label?: string
@@ -81,10 +85,6 @@ export interface LinkProps extends Omit<ComponentAttrs<typeof link>, 'ui'>, Nuxt
81
85
  /** When `true`, only styles from `class`, `ui.active`, and `ui.inactive` will be applied. */
82
86
  raw?: boolean
83
87
  }
84
-
85
- export interface LinkSlots {
86
- default?: (props: { active: boolean }) => any
87
- }
88
88
  </script>
89
89
 
90
90
  <script setup lang="ts">
@@ -163,10 +163,12 @@ function isPartiallyEqual(item1: any, item2: any) {
163
163
  }
164
164
 
165
165
  const isExternalLink = computed(() => {
166
- if (!props.to)
166
+ const to = props.to || props.href
167
+
168
+ if (!to)
167
169
  return false
168
170
 
169
- return typeof props.to === 'string' && hasProtocol(props.to, { acceptRelative: true })
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 })">
@@ -317,8 +320,8 @@ function resolveLinkClass({ route, isActive, isExactActive }: any = {}) {
317
320
  as,
318
321
  type,
319
322
  disabled,
320
- href: to,
321
- target: isExternalLink ? '_blank' : undefined,
323
+ href: to || href,
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 as string),
336
- target: isExternalLink ? '_blank' : undefined,
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,7 @@ import type { PrimitiveProps } from 'reka-ui'
4
4
  export interface LinkBaseProps {
5
5
  /**
6
6
  * The element or component this component should render as.
7
- * @default 'button'
7
+ * @default "button"
8
8
  */
9
9
  as?: PrimitiveProps['as']
10
10
  type?: string