@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
@@ -0,0 +1,108 @@
1
+ <script lang="ts">
2
+ import type { PrimitiveProps } from 'reka-ui'
3
+ import type { breadcrumb } from '../theme'
4
+ import type { ComponentAttrs, LinkProps } from '../types'
5
+
6
+ type SlotProps<T> = (props: { item: T, index: number, active?: boolean }) => any
7
+
8
+ type DynamicSlots<T extends { slot?: string }, SlotProps, Slot = T['slot']> =
9
+ Slot extends string
10
+ ? Record<Slot | `${Slot}-${'leading' | 'label' | 'trailing'}`, SlotProps>
11
+ : Record<string, never>
12
+
13
+ export type BreadcrumbSlots<T extends { slot?: string }> = {
14
+ 'item'?: SlotProps<T>
15
+ 'item-leading'?: SlotProps<T>
16
+ 'item-label'?: SlotProps<T>
17
+ 'item-trailing'?: SlotProps<T>
18
+ 'separator'?: (props?: {}) => any
19
+ } & DynamicSlots<T, SlotProps<T>>
20
+
21
+ export interface BreadcrumbItem extends Omit<LinkProps, 'raw' | 'custom'> {
22
+ label?: string
23
+ icon?: string
24
+ slot?: string
25
+ }
26
+
27
+ export interface BreadcrumbProps<T> extends ComponentAttrs<typeof breadcrumb> {
28
+ /**
29
+ * The element or component this component should render as.
30
+ * @default "nav"
31
+ */
32
+ as?: PrimitiveProps['as']
33
+ items?: T[]
34
+ /**
35
+ * The icon to use as a separator.
36
+ * @default app.icons.chevronRight
37
+ */
38
+ separatorIcon?: string
39
+ /**
40
+ * The key used to get the label from the item.
41
+ * @default "label"
42
+ */
43
+ labelKey?: string
44
+ }
45
+ </script>
46
+
47
+ <script setup lang="ts" generic="T extends BreadcrumbItem">
48
+ import { Primitive } from 'reka-ui'
49
+ import { computed } from 'vue'
50
+ import { useLocale } from '../composables/useLocale'
51
+ import { useTheme } from '../composables/useTheme'
52
+ import { get, pickLinkProps } from '../utils'
53
+ import Link from './Link.vue'
54
+ import LinkBase from './LinkBase.vue'
55
+
56
+ const props = withDefaults(defineProps<BreadcrumbProps<T>>(), {
57
+ as: 'nav',
58
+ labelKey: 'label',
59
+ })
60
+
61
+ const slots = defineSlots<BreadcrumbSlots<T>>()
62
+
63
+ const { dir } = useLocale()
64
+ const { theme, generateStyle } = useTheme()
65
+
66
+ const separatorIcon = computed(() => props.separatorIcon || (dir.value === 'rtl' ? theme.value.app.icons.chevronLeft : theme.value.app.icons.chevronRight))
67
+
68
+ const style = computed(() => generateStyle('breadcrumb', props))
69
+ </script>
70
+
71
+ <template>
72
+ <Primitive :as="props.as" aria-label="breadcrumb" :class="style.root({ class: [props.class, props.ui?.root] })">
73
+ <ol :class="style.list({ class: props.ui?.list })">
74
+ <template v-for="(item, index) in props.items" :key="index">
75
+ <li :class="style.item({ class: props.ui?.item })">
76
+ <Link v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
77
+ <LinkBase
78
+ v-bind="slotProps"
79
+ as="span"
80
+ :aria-current="active && (index === items!.length - 1) ? 'page' : undefined"
81
+ :class="style.link({ class: props.ui?.link, active: index === items!.length - 1, disabled: item.disabled, to: !!item.to })"
82
+ >
83
+ <slot :name="item.slot || 'item'" :item="item" :index="index">
84
+ <slot :name="`${item.slot || 'item'}-leading`" :item="item" :active="index === items!.length - 1" :index="index">
85
+ <span v-if="item.icon" :class="style.linkLeadingIcon({ class: [item.icon, props.ui?.linkLeadingIcon] })"></span>
86
+ </slot>
87
+
88
+ <span v-if="get(item, props.labelKey) || slots[`${item.slot || 'item'}-label`]" :class="style.linkLabel({ class: props.ui?.linkLabel })">
89
+ <slot :name="`${item.slot || 'item'}-label`" :item="item" :active="index === items!.length - 1" :index="index">
90
+ {{ get(item, props.labelKey) }}
91
+ </slot>
92
+ </span>
93
+
94
+ <slot :name="`${item.slot || 'item'}-trailing`" :item="item" :active="index === items!.length - 1" :index="index"></slot>
95
+ </slot>
96
+ </LinkBase>
97
+ </Link>
98
+ </li>
99
+
100
+ <li v-if="index < items!.length - 1" role="presentation" aria-hidden="true" :class="style.separator({ class: props.ui?.separator })">
101
+ <slot name="separator">
102
+ <span :class="style.separatorIcon({ class: [separatorIcon, props.ui?.separatorIcon] })"></span>
103
+ </slot>
104
+ </li>
105
+ </template>
106
+ </ol>
107
+ </Primitive>
108
+ </template>
@@ -6,14 +6,14 @@ import type { ComponentAttrs } from '../types'
6
6
  import type { LinkProps } from './Link.vue'
7
7
 
8
8
  export interface ButtonSlots {
9
- default?: (props?: any) => any
10
- prefix?: (props?: any) => any
11
- suffix?: (props?: any) => any
9
+ default?: (props?: {}) => any
10
+ leading?: (props?: {}) => any
11
+ trailing?: (props?: {}) => any
12
12
  }
13
13
 
14
14
  type ButtonVariants = VariantProps<typeof button>
15
15
 
16
- export interface ButtonProps extends ComponentAttrs<typeof button>, UseComponentIconsProps, Omit<LinkProps, 'raw' | 'custom'> {
16
+ export interface ButtonProps extends ComponentAttrs<typeof button>, UseComponentIconsProps, Omit<LinkProps, 'raw' | 'custom' | 'underline'> {
17
17
  icon?: string
18
18
  label?: string
19
19
  variant?: ButtonVariants['variant']
@@ -40,22 +40,21 @@ const props = withDefaults(defineProps<ButtonProps>(), {
40
40
  const slots = defineSlots<ButtonSlots>()
41
41
 
42
42
  const { size, orientation } = useButtonGroup(props)
43
- const { isPrefix, isSuffix, prefixIconName, suffixIconName } = useComponentIcons(
43
+ const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(
44
44
  computed(() => ({ ...props, loading: props.loading })),
45
45
  )
46
46
 
47
47
  const linkProps = useForwardProps(pickLinkProps(props))
48
48
 
49
- const { theme, createStyler } = useTheme()
49
+ const { generateStyle } = useTheme()
50
50
 
51
51
  const style = computed(() => {
52
- const styler = createStyler(theme.value.button)
53
- return styler({
52
+ return generateStyle('button', {
54
53
  ...props,
55
54
  size: size.value,
56
55
  groupOrientation: orientation.value,
57
- prefix: isPrefix.value,
58
- suffix: isSuffix.value,
56
+ leading: isLeading.value,
57
+ trailing: isTrailing.value,
59
58
  class: [
60
59
  props.class,
61
60
  props.active ? props.activeClass : props.inactiveClass,
@@ -73,10 +72,10 @@ const style = computed(() => {
73
72
  v-bind="omit(linkProps, ['type', 'disabled', 'activeClass', 'inactiveClass', 'disableClass'])"
74
73
  raw
75
74
  >
76
- <slot name="prefix">
75
+ <slot name="leading">
77
76
  <span
78
- v-if="isPrefix && prefixIconName"
79
- :class="style.prefixIcon({ class: [prefixIconName, props.ui?.prefixIcon] })"
77
+ v-if="isLeading && leadingIconName"
78
+ :class="style.leadingIcon({ class: [leadingIconName, props.ui?.leadingIcon] })"
80
79
  ></span>
81
80
  </slot>
82
81
  <span
@@ -85,10 +84,10 @@ const style = computed(() => {
85
84
  >
86
85
  <slot>{{ label }}</slot>
87
86
  </span>
88
- <slot name="suffix">
87
+ <slot name="trailing">
89
88
  <span
90
- v-if="isSuffix && suffixIconName"
91
- :class="style.suffixIcon({ class: [suffixIconName, props.ui?.suffixIcon] })"
89
+ v-if="isTrailing && trailingIconName"
90
+ :class="style.trailingIcon({ class: [trailingIconName, props.ui?.trailingIcon] })"
92
91
  ></span>
93
92
  </slot>
94
93
  </Link>
@@ -4,22 +4,27 @@ import type { PrimitiveProps } from 'reka-ui'
4
4
  import type { buttonGroup } from '../theme'
5
5
  import type { ComponentAttrs } from '../types'
6
6
 
7
+ export interface ButtonGroupSlots {
8
+ default?: (props?: {}) => any
9
+ }
10
+
7
11
  type ButtonGroupVariant = VariantProps<typeof buttonGroup>
8
12
 
9
- export interface ButtonGroupProps extends Omit<ComponentAttrs<typeof buttonGroup>, 'ui'>, Pick<PrimitiveProps, 'as'> {
13
+ export interface ButtonGroupProps extends Omit<ComponentAttrs<typeof buttonGroup>, 'ui'> {
14
+ /**
15
+ * The element or component this component should render as.
16
+ * @default "div"
17
+ */
18
+ as?: PrimitiveProps['as']
10
19
  size?: ButtonGroupVariant['size']
11
20
  orientation?: ButtonGroupVariant['orientation']
12
21
  }
13
-
14
- export interface ButtonGroupSlots {
15
- default?: (props?: any) => any
16
- }
17
22
  </script>
18
23
 
19
24
  <script setup lang="ts">
20
25
  import { Primitive } from 'reka-ui'
21
26
  import { computed } from 'vue'
22
- import { provideButtonGroup } from '../composables/useButtonGroup'
27
+ import { provideButtonGroup } from '../app/injections'
23
28
  import { useTheme } from '../composables/useTheme'
24
29
 
25
30
  const props = withDefaults(defineProps<ButtonGroupProps>(), {
@@ -28,16 +33,10 @@ const props = withDefaults(defineProps<ButtonGroupProps>(), {
28
33
 
29
34
  defineSlots<ButtonGroupSlots>()
30
35
 
31
- provideButtonGroup(computed(() => ({
32
- size: props.size,
33
- orientation: props.orientation,
34
- })))
36
+ provideButtonGroup(computed(() => props))
35
37
 
36
- const { theme, createStyler } = useTheme()
37
- const style = computed(() => {
38
- const styler = createStyler(theme.value.buttonGroup)
39
- return styler(props)
40
- })
38
+ const { generateStyle } = useTheme()
39
+ const style = computed(() => generateStyle('buttonGroup', props))
41
40
  </script>
42
41
 
43
42
  <template>
@@ -0,0 +1,176 @@
1
+ <script lang="ts">
2
+ import type { VariantProps } from '@byyuurin/ui-kit'
3
+ import type { DateValue } from '@internationalized/date'
4
+ import type { CalendarCellTriggerProps, CalendarRootEmits, CalendarRootProps, DateRange, RangeCalendarRootEmits } from 'reka-ui'
5
+ import type { calendar } from '../theme'
6
+ import type { ComponentAttrs } from '../types'
7
+
8
+ export interface CalendarEmits<R extends boolean, M extends boolean> extends Omit<CalendarRootEmits & RangeCalendarRootEmits, 'update:modelValue'> {
9
+ 'update:modelValue': [date: CalendarModelValue<R, M>]
10
+ }
11
+
12
+ export interface CalendarSlots {
13
+ 'heading'?: (props: { value: string }) => any
14
+ 'day'?: (props: Pick<CalendarCellTriggerProps, 'day'>) => any
15
+ 'week-day'?: (props: { day: string }) => any
16
+ }
17
+
18
+ type CalendarVariants = VariantProps<typeof calendar>
19
+
20
+ type CalendarModelValue<R extends boolean = false, M extends boolean = false> = R extends true
21
+ ? DateRange
22
+ : M extends true ? DateValue[] : DateValue
23
+
24
+ export interface CalendarProps<R extends boolean, M extends boolean> extends ComponentAttrs<typeof calendar>, Omit<CalendarRootProps, 'modelValue' | 'defaultValue' | 'dir' | 'locale' | 'calendarLabel' | 'multiple'> {
25
+ /**
26
+ * The icon to use for the next year control.
27
+ * @default app.icons.chevronDoubleRight
28
+ */
29
+ nextYearIcon?: string
30
+ /**
31
+ * The icon to use for the next month control.
32
+ * @default app.icons.chevronRight
33
+ */
34
+ nextMonthIcon?: string
35
+ /**
36
+ * The icon to use for the previous year control.
37
+ * @default app.icons.chevronDoubleLeft
38
+ */
39
+ prevYearIcon?: string
40
+ /**
41
+ * The icon to use for the previous month control.
42
+ * @default app.icons.chevronLeft
43
+ */
44
+ prevMonthIcon?: string
45
+ /**
46
+ * @default "md"
47
+ */
48
+ size?: CalendarVariants['size']
49
+ /** Whether or not a range of dates can be selected */
50
+ range?: R & boolean
51
+ /** Whether or not multiple dates can be selected */
52
+ multiple?: M & boolean
53
+ /** Show month controls */
54
+ monthControls?: boolean
55
+ /** Show year controls */
56
+ yearControls?: boolean
57
+ defaultValue?: CalendarModelValue<R, M>
58
+ modelValue?: CalendarModelValue<R, M>
59
+ }
60
+ </script>
61
+
62
+ <script setup lang="ts" generic="R extends boolean = false, M extends boolean = false">
63
+ import { reactiveOmit } from '@vueuse/core'
64
+ import { useForwardPropsEmits } from 'reka-ui'
65
+ import { Calendar as BaseCalendar, RangeCalendar } from 'reka-ui/namespaced'
66
+ import { computed } from 'vue'
67
+ import { useLocale } from '../composables/useLocale'
68
+ import { useTheme } from '../composables/useTheme'
69
+ import Button from './Button.vue'
70
+
71
+ const props = withDefaults(defineProps<CalendarProps<R, M>>(), {
72
+ fixedWeeks: true,
73
+ monthControls: true,
74
+ yearControls: true,
75
+ })
76
+ const emit = defineEmits<CalendarEmits<R, M>>()
77
+ defineSlots<CalendarSlots>()
78
+
79
+ const rootProps = useForwardPropsEmits(reactiveOmit(props, 'range', 'modelValue', 'defaultValue', 'size', 'monthControls', 'yearControls', 'class', 'ui'), emit)
80
+
81
+ const { code: locale, dir, t } = useLocale()
82
+ const { theme, generateStyle } = useTheme()
83
+
84
+ const nextYearIcon = computed(() => props.nextYearIcon || (dir.value === 'rtl' ? theme.value.app.icons.chevronDoubleLeft : theme.value.app.icons.chevronDoubleRight))
85
+ const nextMonthIcon = computed(() => props.nextMonthIcon || (dir.value === 'rtl' ? theme.value.app.icons.chevronLeft : theme.value.app.icons.chevronRight))
86
+ const prevYearIcon = computed(() => props.prevYearIcon || (dir.value === 'rtl' ? theme.value.app.icons.chevronDoubleRight : theme.value.app.icons.chevronDoubleLeft))
87
+ const prevMonthIcon = computed(() => props.prevMonthIcon || (dir.value === 'rtl' ? theme.value.app.icons.chevronRight : theme.value.app.icons.chevronLeft))
88
+
89
+ function paginateYear(date: DateValue, sign: -1 | 1) {
90
+ if (sign === -1)
91
+ return date.subtract({ years: 1 })
92
+
93
+ return date.add({ years: 1 })
94
+ }
95
+
96
+ const Calendar = computed(() => props.range ? RangeCalendar : BaseCalendar)
97
+
98
+ const style = computed(() => generateStyle('calendar', props))
99
+ </script>
100
+
101
+ <template>
102
+ <Calendar.Root
103
+ v-slot="{ weekDays, grid }"
104
+ v-bind="rootProps"
105
+ :model-value="props.modelValue"
106
+ :default-value="props.defaultValue"
107
+ :locale="locale"
108
+ :dir="dir"
109
+ :class="style.root({ class: [props.class, props.ui?.root] })"
110
+ >
111
+ <Calendar.Header :class="style.header({ class: props.ui?.header })">
112
+ <Calendar.Prev v-if="props.yearControls" :prev-page="date => paginateYear(date, -1)" :aria-label="t('calendar.prevYear')" as-child>
113
+ <Button :icon="prevYearIcon" :size="props.size" variant="ghost" />
114
+ </Calendar.Prev>
115
+ <Calendar.Prev v-if="props.monthControls" :aria-label="t('calendar.prevMonth')" as-child>
116
+ <Button :icon="prevMonthIcon" :size="props.size" variant="ghost" />
117
+ </Calendar.Prev>
118
+
119
+ <Calendar.Heading v-slot="{ headingValue }" :class="style.heading({ class: props.ui?.heading })">
120
+ <slot name="heading" :value="headingValue">
121
+ {{ headingValue }}
122
+ </slot>
123
+ </Calendar.Heading>
124
+ <Calendar.Next v-if="props.monthControls" :aria-label="t('calendar.nextMonth')" as-child>
125
+ <Button :icon="nextMonthIcon" :size="props.size" variant="ghost" />
126
+ </Calendar.Next>
127
+ <Calendar.Next v-if="props.yearControls" :next-page="(date) => paginateYear(date, 1)" :aria-label="t('calendar.nextYear')" as-child>
128
+ <Button :icon="nextYearIcon" :size="props.size" variant="ghost" />
129
+ </Calendar.Next>
130
+ </Calendar.Header>
131
+ <div :class="style.body({ class: props.ui?.body })">
132
+ <Calendar.Grid
133
+ v-for="month in grid"
134
+ :key="month.value.toString()"
135
+ :class="style.grid({ class: props.ui?.grid })"
136
+ >
137
+ <Calendar.GridHead>
138
+ <Calendar.GridRow :class="style.gridWeekDaysRow({ class: props.ui?.gridWeekDaysRow })">
139
+ <Calendar.HeadCell v-for="day in weekDays" :key="day" :class="style.headCell({ class: props.ui?.headCell })">
140
+ <slot name="week-day" :day="day">
141
+ {{ day }}
142
+ </slot>
143
+ </Calendar.HeadCell>
144
+ </Calendar.GridRow>
145
+ </Calendar.GridHead>
146
+ <Calendar.GridBody :class="style.gridBody({ class: props.ui?.gridBody })">
147
+ <Calendar.GridRow
148
+ v-for="(weekDates, index) in month.rows"
149
+ :key="`weekDates-${index}`"
150
+ :class="style.gridRow({ class: props.ui?.gridRow })"
151
+ >
152
+ <Calendar.Cell
153
+ v-for="weekDate in weekDates"
154
+ :key="weekDate.toString()"
155
+ :date="weekDate"
156
+ :class="style.cell({ class: props.ui?.cell })"
157
+ >
158
+ <Calendar.CellTrigger
159
+ v-slot="{ disabled, unavailable }"
160
+ :day="weekDate"
161
+ :month="month.value"
162
+ as-child
163
+ >
164
+ <div :class="style.cellTrigger({ class: props.ui?.cellTrigger, disabled: disabled || unavailable })">
165
+ <slot name="day" :day="weekDate">
166
+ {{ weekDate.day }}
167
+ </slot>
168
+ </div>
169
+ </Calendar.CellTrigger>
170
+ </Calendar.Cell>
171
+ </Calendar.GridRow>
172
+ </Calendar.GridBody>
173
+ </Calendar.Grid>
174
+ </div>
175
+ </Calendar.Root>
176
+ </template>
@@ -8,13 +8,18 @@ export interface CardSlots {
8
8
  default?: (props?: {}) => any
9
9
  content?: (props?: {}) => any
10
10
  header?: (props?: {}) => any
11
- title?: (props?: any) => any
12
- description?: (props?: any) => any
11
+ title?: (props?: {}) => any
12
+ description?: (props?: {}) => any
13
13
  footer?: (props?: {}) => any
14
14
  }
15
15
 
16
16
  type CardVariants = VariantProps<typeof card>
17
+
17
18
  export interface CardProps extends ComponentAttrs<typeof card> {
19
+ /**
20
+ * The element or component this component should render as.
21
+ * @default "div"
22
+ */
18
23
  as?: PrimitiveProps['as']
19
24
  variant?: CardVariants['variant']
20
25
  title?: string
@@ -30,11 +35,8 @@ import { useTheme } from '../composables/useTheme'
30
35
  const props = withDefaults(defineProps<CardProps>(), {})
31
36
  const slots = defineSlots<CardSlots>()
32
37
 
33
- const { theme, createStyler } = useTheme()
34
- const style = computed(() => {
35
- const styler = createStyler(theme.value.card)
36
- return styler(props)
37
- })
38
+ const { generateStyle } = useTheme()
39
+ const style = computed(() => generateStyle('card', props))
38
40
  </script>
39
41
 
40
42
  <template>
@@ -11,9 +11,18 @@ import type { AcceptableValue, PrimitiveProps } from 'reka-ui'
11
11
  import type { carousel } from '../theme'
12
12
  import type { ButtonProps, ComponentAttrs } from '../types'
13
13
 
14
+ export interface CarouselSlots<T> {
15
+ default?: (props: { item: T, index: number }) => any
16
+ }
17
+
14
18
  type CarouselVariants = VariantProps<typeof carousel>
15
19
 
16
- export interface CarouselProps<T> extends ComponentAttrs<typeof carousel>, Pick<PrimitiveProps, 'as'>, Omit<EmblaOptionsType, 'axis' | 'container' | 'slides' | 'direction'> {
20
+ export interface CarouselProps<T> extends ComponentAttrs<typeof carousel>, Omit<EmblaOptionsType, 'axis' | 'container' | 'slides' | 'direction'> {
21
+ /**
22
+ * The element or component this component should render as.
23
+ * @default "div"
24
+ */
25
+ as?: PrimitiveProps['as']
17
26
  /**
18
27
  * Configure the prev button when arrows are enabled.
19
28
  * @default { size: 'md', variant: 'link' }
@@ -21,7 +30,7 @@ export interface CarouselProps<T> extends ComponentAttrs<typeof carousel>, Pick<
21
30
  prev?: ButtonProps
22
31
  /**
23
32
  * The icon displayed in the prev button.
24
- * @default `app.icons.arrowLeft`
33
+ * @default app.icons.chevronLeft
25
34
  */
26
35
  prevIcon?: string
27
36
  /**
@@ -31,7 +40,7 @@ export interface CarouselProps<T> extends ComponentAttrs<typeof carousel>, Pick<
31
40
  next?: ButtonProps
32
41
  /**
33
42
  * The icon displayed in the next button.
34
- * @default `app.icons.arrowRight`
43
+ * @default app.icons.chevronRight
35
44
  */
36
45
  nextIcon?: string
37
46
  /**
@@ -46,7 +55,6 @@ export interface CarouselProps<T> extends ComponentAttrs<typeof carousel>, Pick<
46
55
  dots?: boolean
47
56
  orientation?: CarouselVariants['orientation']
48
57
  items?: T[]
49
- dir?: 'rtl' | 'ltr'
50
58
  /**
51
59
  * Enable Autoplay plugin
52
60
  * @link https://www.embla-carousel.com/plugins/autoplay/
@@ -78,10 +86,6 @@ export interface CarouselProps<T> extends ComponentAttrs<typeof carousel>, Pick<
78
86
  */
79
87
  wheelGestures?: boolean | WheelGesturesPluginOptions
80
88
  }
81
-
82
- export interface CarouselSlots<T> {
83
- default?: (props: { item: T, index: number }) => any
84
- }
85
89
  </script>
86
90
 
87
91
  <script setup lang="ts" generic="T extends AcceptableValue">
@@ -89,6 +93,7 @@ import { computedAsync, reactivePick } from '@vueuse/core'
89
93
  import useEmblaCarousel from 'embla-carousel-vue'
90
94
  import { Primitive, useForwardProps } from 'reka-ui'
91
95
  import { computed, onMounted, ref, watch } from 'vue'
96
+ import { useLocale } from '../composables/useLocale'
92
97
  import { useTheme } from '../composables/useTheme'
93
98
  import Button from './Button.vue'
94
99
 
@@ -97,8 +102,6 @@ const props = withDefaults(defineProps<CarouselProps<T>>(), {
97
102
  arrows: false,
98
103
  dots: false,
99
104
 
100
- dir: 'ltr',
101
-
102
105
  // Embla Options
103
106
  active: true,
104
107
  align: 'center',
@@ -129,20 +132,18 @@ defineSlots<CarouselSlots<T>>()
129
132
 
130
133
  const rootProps = useForwardProps(reactivePick(props, 'active', 'align', 'breakpoints', 'containScroll', 'dragFree', 'dragThreshold', 'duration', 'inViewThreshold', 'loop', 'skipSnaps', 'slidesToScroll', 'startIndex', 'watchDrag', 'watchResize', 'watchSlides', 'watchFocus'))
131
134
 
132
- const { theme, createStyler } = useTheme()
133
- const style = computed(() => {
134
- const styler = createStyler(theme.value.carousel)
135
- return styler(props)
136
- })
135
+ const { t, dir } = useLocale()
136
+ const { theme, generateStyle } = useTheme()
137
+ const style = computed(() => generateStyle('carousel', props))
137
138
 
138
- const prevIcon = computed(() => props.prevIcon || (props.dir === 'rtl' ? theme.value.app.icons.arrowRight : theme.value.app.icons.arrowLeft))
139
- const nextIcon = computed(() => props.nextIcon || (props.dir === 'rtl' ? theme.value.app.icons.arrowLeft : theme.value.app.icons.arrowRight))
139
+ const prevIcon = computed(() => props.prevIcon || (dir.value === 'rtl' ? theme.value.app.icons.chevronRight : theme.value.app.icons.chevronLeft))
140
+ const nextIcon = computed(() => props.nextIcon || (dir.value === 'rtl' ? theme.value.app.icons.chevronLeft : theme.value.app.icons.chevronRight))
140
141
 
141
142
  const options = computed<EmblaOptionsType>(() => ({
142
143
  ...(props.fade ? { align: 'center', containScroll: false } : {}),
143
144
  ...rootProps.value,
144
145
  axis: props.orientation === 'horizontal' ? 'x' : 'y',
145
- direction: props.dir === 'rtl' ? 'rtl' : 'ltr',
146
+ direction: dir.value === 'rtl' ? 'rtl' : 'ltr',
146
147
  }))
147
148
 
148
149
  const plugins = computedAsync<EmblaPluginType[]>(async () => {
@@ -254,7 +255,6 @@ defineExpose({
254
255
  role="region"
255
256
  aria-roledescription="carousel"
256
257
  tabindex="0"
257
- :dir="props.dir"
258
258
  :class="style.root({ class: [props.class, props.ui?.root] })"
259
259
  @keydown="onKeyDown"
260
260
  >
@@ -279,7 +279,7 @@ defineExpose({
279
279
  :icon="prevIcon"
280
280
  size="md"
281
281
  variant="outline"
282
- aria-label="prev"
282
+ :aria-label="t('carousel.prev')"
283
283
  v-bind="typeof props.prev === 'object' ? props.prev : undefined"
284
284
  :class="style.prev({ class: props.ui?.prev })"
285
285
  @click="scrollPrev"
@@ -289,7 +289,7 @@ defineExpose({
289
289
  :icon="nextIcon"
290
290
  size="md"
291
291
  variant="outline"
292
- aria-label="next"
292
+ :aria-label="t('carousel.next')"
293
293
  v-bind="typeof props.next === 'object' ? props.next : undefined"
294
294
  :class="style.next({ class: props.ui?.next })"
295
295
  @click="scrollNext"
@@ -299,7 +299,7 @@ defineExpose({
299
299
  <div v-if="props.dots" :class="style.dots({ class: props.ui?.dots })">
300
300
  <template v-for="(_, index) in scrollSnaps" :key="index">
301
301
  <button
302
- :aria-label="`Go to ${index + 1}`"
302
+ :aria-label="t('carousel.goto', { page: index + 1 })"
303
303
  :class="style.dot({ class: props.ui?.dot, active: selectedIndex === index })"
304
304
  @click="scrollTo(index)"
305
305
  ></button>
@@ -4,9 +4,22 @@ import type { CheckboxRootProps, PrimitiveProps } from 'reka-ui'
4
4
  import type { checkbox } from '../theme'
5
5
  import type { ComponentAttrs } from '../types'
6
6
 
7
+ export interface CheckboxEmits {
8
+ (event: 'change', payload: Event): void
9
+ }
10
+
11
+ export interface CheckboxSlots {
12
+ label?: (props: { label?: string }) => any
13
+ description?: (props: { description?: string }) => any
14
+ }
15
+
7
16
  type CheckboxVariants = VariantProps<typeof checkbox>
8
17
 
9
18
  export interface CheckboxProps extends ComponentAttrs<typeof checkbox>, Pick<CheckboxRootProps, 'disabled' | 'required' | 'name' | 'value' | 'id' | 'defaultValue'> {
19
+ /**
20
+ * The element or component this component should render as.
21
+ * @default "div"
22
+ */
10
23
  as?: PrimitiveProps['as']
11
24
  label?: string
12
25
  description?: string
@@ -22,15 +35,6 @@ export interface CheckboxProps extends ComponentAttrs<typeof checkbox>, Pick<Che
22
35
  */
23
36
  indeterminateIcon?: string
24
37
  }
25
-
26
- export interface CheckboxEmits {
27
- (event: 'change', payload: Event): void
28
- }
29
-
30
- export interface CheckboxSlots {
31
- label?: (props: { label?: string }) => any
32
- description?: (props: { description?: string }) => any
33
- }
34
38
  </script>
35
39
 
36
40
  <script lang="ts" setup>
@@ -51,11 +55,8 @@ const rootProps = useForwardProps(reactivePick(props, 'required', 'value', 'defa
51
55
 
52
56
  const id = props.id ?? useId()
53
57
 
54
- const { theme, createStyler } = useTheme()
55
- const style = computed(() => {
56
- const styler = createStyler(theme.value.checkbox)
57
- return styler(props)
58
- })
58
+ const { theme, generateStyle } = useTheme()
59
+ const style = computed(() => generateStyle('checkbox', props))
59
60
 
60
61
  function onUpdate(value: any) {
61
62
  // @ts-expect-error - 'target' does not exist in type 'EventInit'