@byyuurin/ui 0.0.4 → 0.0.6

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 (129) hide show
  1. package/README.md +23 -29
  2. package/dist/index.d.ts +28 -2
  3. package/dist/index.mjs +28 -2
  4. package/dist/nuxt.d.mts +1 -1
  5. package/dist/nuxt.d.ts +1 -1
  6. package/dist/nuxt.mjs +15 -10
  7. package/dist/nuxt.mjs.map +1 -0
  8. package/dist/runtime/components/Accordion.vue +1 -1
  9. package/dist/runtime/components/Alert.vue +120 -0
  10. package/dist/runtime/components/App.vue +1 -1
  11. package/dist/runtime/components/Badge.vue +70 -0
  12. package/dist/runtime/components/Button.vue +7 -3
  13. package/dist/runtime/components/ButtonGroup.vue +47 -0
  14. package/dist/runtime/components/Card.vue +4 -4
  15. package/dist/runtime/components/Carousel.vue +310 -0
  16. package/dist/runtime/components/Checkbox.vue +1 -2
  17. package/dist/runtime/components/Chip.vue +64 -0
  18. package/dist/runtime/components/Drawer.vue +2 -2
  19. package/dist/runtime/components/Input.vue +10 -5
  20. package/dist/runtime/components/Link.vue +1 -1
  21. package/dist/runtime/components/Modal.vue +4 -5
  22. package/dist/runtime/components/Pagination.vue +167 -0
  23. package/dist/runtime/components/PinInput.vue +85 -0
  24. package/dist/runtime/components/Popover.vue +1 -1
  25. package/dist/runtime/components/RadioGroup.vue +1 -2
  26. package/dist/runtime/components/ScrollArea.vue +2 -2
  27. package/dist/runtime/components/Select.vue +7 -2
  28. package/dist/runtime/components/Slider.vue +96 -0
  29. package/dist/runtime/components/Switch.vue +2 -4
  30. package/dist/runtime/components/Tabs.vue +1 -2
  31. package/dist/runtime/components/Textarea.vue +2 -4
  32. package/dist/runtime/components/Toast.vue +21 -10
  33. package/dist/runtime/components/Toaster.vue +5 -5
  34. package/dist/runtime/components/Tooltip.vue +1 -1
  35. package/dist/runtime/composables/useButtonGroup.d.ts +13 -0
  36. package/dist/runtime/composables/useButtonGroup.mjs +14 -0
  37. package/dist/runtime/composables/useTheme.d.ts +2 -2
  38. package/dist/runtime/composables/useTheme.mjs +1 -1
  39. package/dist/runtime/composables/useToast.d.ts +4 -4
  40. package/dist/runtime/composables/useToast.mjs +19 -6
  41. package/dist/runtime/theme/accordion.d.ts +17 -0
  42. package/dist/runtime/theme/accordion.mjs +24 -21
  43. package/dist/runtime/theme/alert.d.ts +125 -0
  44. package/dist/runtime/theme/alert.mjs +47 -0
  45. package/dist/runtime/theme/app.d.ts +5 -0
  46. package/dist/runtime/theme/app.mjs +7 -1
  47. package/dist/runtime/theme/badge.d.ts +82 -0
  48. package/dist/runtime/theme/badge.mjs +92 -0
  49. package/dist/runtime/theme/button-group.d.ts +66 -0
  50. package/dist/runtime/theme/button-group.mjs +42 -0
  51. package/dist/runtime/theme/button.d.ts +15 -1
  52. package/dist/runtime/theme/button.mjs +135 -119
  53. package/dist/runtime/theme/card.d.ts +21 -2
  54. package/dist/runtime/theme/card.mjs +12 -9
  55. package/dist/runtime/theme/carousel.d.ts +113 -0
  56. package/dist/runtime/theme/carousel.mjs +43 -0
  57. package/dist/runtime/theme/checkbox.d.ts +3 -0
  58. package/dist/runtime/theme/checkbox.mjs +47 -41
  59. package/dist/runtime/theme/chip.d.ts +67 -0
  60. package/dist/runtime/theme/chip.mjs +68 -0
  61. package/dist/runtime/theme/drawer.d.ts +38 -0
  62. package/dist/runtime/theme/drawer.mjs +69 -66
  63. package/dist/runtime/theme/index.d.ts +10 -2
  64. package/dist/runtime/theme/index.mjs +10 -2
  65. package/dist/runtime/theme/input.d.ts +41 -22
  66. package/dist/runtime/theme/input.mjs +139 -121
  67. package/dist/runtime/theme/link.d.ts +14 -1
  68. package/dist/runtime/theme/link.mjs +23 -20
  69. package/dist/runtime/theme/modal.d.ts +3 -0
  70. package/dist/runtime/theme/modal.mjs +53 -47
  71. package/dist/runtime/theme/pagination.d.ts +56 -0
  72. package/dist/runtime/theme/pagination.mjs +13 -0
  73. package/dist/runtime/theme/pinInput.d.ts +100 -0
  74. package/dist/runtime/theme/pinInput.mjs +111 -0
  75. package/dist/runtime/theme/popover.d.ts +11 -0
  76. package/dist/runtime/theme/popover.mjs +11 -8
  77. package/dist/runtime/theme/{radioGroup.d.ts → radio-group.d.ts} +3 -0
  78. package/dist/runtime/theme/radio-group.mjs +61 -0
  79. package/dist/runtime/theme/{scrollArea.d.ts → scroll-area.d.ts} +22 -0
  80. package/dist/runtime/theme/scroll-area.mjs +33 -0
  81. package/dist/runtime/theme/select.d.ts +16 -2
  82. package/dist/runtime/theme/select.mjs +160 -142
  83. package/dist/runtime/theme/slider.d.ts +76 -0
  84. package/dist/runtime/theme/slider.mjs +52 -0
  85. package/dist/runtime/theme/switch.d.ts +3 -0
  86. package/dist/runtime/theme/switch.mjs +69 -63
  87. package/dist/runtime/theme/tabs.d.ts +15 -2
  88. package/dist/runtime/theme/tabs.mjs +134 -112
  89. package/dist/runtime/theme/textarea.d.ts +8 -2
  90. package/dist/runtime/theme/textarea.mjs +105 -89
  91. package/dist/runtime/theme/toast.d.ts +44 -6
  92. package/dist/runtime/theme/toast.mjs +30 -22
  93. package/dist/runtime/theme/toaster.d.ts +51 -2
  94. package/dist/runtime/theme/toaster.mjs +88 -80
  95. package/dist/runtime/theme/tooltip.d.ts +13 -0
  96. package/dist/runtime/theme/tooltip.mjs +9 -6
  97. package/dist/runtime/types/components.d.ts +27 -20
  98. package/dist/runtime/types/components.mjs +27 -0
  99. package/dist/runtime/types/index.d.ts +1 -3
  100. package/dist/runtime/types/utils.d.ts +1 -1
  101. package/dist/runtime/utils/extend-theme.mjs +1 -1
  102. package/dist/runtime/utils/link.d.ts +1 -1
  103. package/dist/runtime/utils/styler.d.ts +2 -2
  104. package/dist/shared/ui.D4zm1r0C.mjs +4 -0
  105. package/dist/shared/ui.D4zm1r0C.mjs.map +1 -0
  106. package/dist/{unocss-preset.d.mts → unocss.d.mts} +4 -4
  107. package/dist/{unocss-preset.d.ts → unocss.d.ts} +4 -4
  108. package/dist/{unocss-preset.mjs → unocss.mjs} +58 -36
  109. package/dist/unocss.mjs.map +1 -0
  110. package/dist/unplugin.d.mts +26 -0
  111. package/dist/unplugin.d.ts +26 -0
  112. package/dist/unplugin.mjs +72 -0
  113. package/dist/unplugin.mjs.map +1 -0
  114. package/dist/vite.d.mts +10 -0
  115. package/dist/vite.d.ts +10 -0
  116. package/dist/vite.mjs +14 -0
  117. package/dist/vite.mjs.map +1 -0
  118. package/package.json +46 -26
  119. package/dist/resolver.d.mts +0 -13
  120. package/dist/resolver.d.ts +0 -13
  121. package/dist/resolver.mjs +0 -21
  122. package/dist/runtime/components/index.d.ts +0 -20
  123. package/dist/runtime/components/index.mjs +0 -20
  124. package/dist/runtime/composables/index.d.ts +0 -5
  125. package/dist/runtime/composables/index.mjs +0 -5
  126. package/dist/runtime/theme/radioGroup.mjs +0 -55
  127. package/dist/runtime/theme/scrollArea.mjs +0 -30
  128. package/dist/shared/ui.Cmq14xN9.mjs +0 -25
  129. /package/{LICENSE.md → LICENSE} +0 -0
@@ -0,0 +1,85 @@
1
+ <script lang="ts">
2
+ import type { VariantProps } from '@byyuurin/ui-kit'
3
+ import type { PinInputRootProps } from 'reka-ui'
4
+ import type { pinInput } from '../theme'
5
+ import type { ComponentAttrs } from '../types'
6
+
7
+ type PinInputVariants = VariantProps<typeof pinInput>
8
+
9
+ export interface PinInputProps extends ComponentAttrs<typeof pinInput>, Pick<PinInputRootProps, 'as' | 'defaultValue' | 'disabled' | 'id' | 'mask' | 'modelValue' | 'name' | 'otp' | 'placeholder' | 'required' | 'type'> {
10
+ variant?: PinInputVariants['variant']
11
+ size?: PinInputVariants['size']
12
+ length?: number | string
13
+ underline?: boolean
14
+ highlight?: boolean
15
+ }
16
+
17
+ export interface PinInputEmits {
18
+ (event: 'update:modelValue', value: string[]): void
19
+ (event: 'complete', value: string[]): void
20
+ (event: 'change', payload: Event): void
21
+ (event: 'blur', payload: Event): void
22
+ }
23
+ </script>
24
+
25
+ <script setup lang="ts">
26
+ import { reactivePick } from '@vueuse/core'
27
+ import { PinInputInput, PinInputRoot, useForwardPropsEmits } from 'reka-ui'
28
+ import { computed, ref } from 'vue'
29
+ import { useTheme } from '../composables/useTheme'
30
+ import { looseToNumber } from '../utils'
31
+
32
+ const props = withDefaults(defineProps<PinInputProps>(), {
33
+ variant: 'outline',
34
+ length: 5,
35
+ type: 'text',
36
+ })
37
+
38
+ const emit = defineEmits<PinInputEmits>()
39
+
40
+ const rootProps = useForwardPropsEmits(reactivePick(props, 'defaultValue', 'disabled', 'id', 'mask', 'modelValue', 'name', 'otp', 'placeholder', 'required', 'type'), emit)
41
+
42
+ const completed = ref(false)
43
+
44
+ const { theme, createStyler } = useTheme()
45
+ const style = computed(() => {
46
+ const styler = createStyler(theme.value.pinInput)
47
+ return styler(props)
48
+ })
49
+
50
+ function onComplete(value: string[]) {
51
+ // @ts-expect-error - 'target' does not exist in type 'EventInit'
52
+ const event = new Event('change', { target: { value } })
53
+ emit('change', event)
54
+ }
55
+
56
+ function onBlur(event: FocusEvent) {
57
+ if (!event.relatedTarget || completed.value)
58
+ emit('blur', event)
59
+ }
60
+ </script>
61
+
62
+ <template>
63
+ <PinInputRoot
64
+ v-bind="rootProps"
65
+ :id="props.id"
66
+ :name="props.name"
67
+ :class="style.root({ class: [props.class, props.ui?.root] })"
68
+ @complete="onComplete"
69
+ >
70
+ <span
71
+ v-for="(ids, index) in looseToNumber(props.length)"
72
+ :key="ids"
73
+ :class="style.container({ class: props.ui?.container })"
74
+ :aria-disabled="props.disabled ? true : undefined"
75
+ >
76
+ <PinInputInput
77
+ :index="index"
78
+ :class="style.base({ class: props.ui?.base })"
79
+ v-bind="$attrs"
80
+ :disabled="props.disabled"
81
+ @blur="onBlur"
82
+ />
83
+ </span>
84
+ </PinInputRoot>
85
+ </template>
@@ -35,7 +35,7 @@ import { defu } from 'defu'
35
35
  import { useForwardPropsEmits } from 'reka-ui'
36
36
  import { HoverCard, Popover } from 'reka-ui/namespaced'
37
37
  import { computed, toRef } from 'vue'
38
- import { useTheme } from '../composables'
38
+ import { useTheme } from '../composables/useTheme'
39
39
 
40
40
  const props = withDefaults(defineProps<PopoverProps>(), {
41
41
  mode: 'click',
@@ -70,11 +70,10 @@ type NormalizeItem<T> = { id: string } & (
70
70
  import { reactivePick } from '@vueuse/core'
71
71
  import { Label, RadioGroupIndicator, RadioGroupItem, RadioGroupRoot, useForwardPropsEmits } from 'reka-ui'
72
72
  import { computed, useId } from 'vue'
73
- import { useTheme } from '../composables'
73
+ import { useTheme } from '../composables/useTheme'
74
74
  import { get } from '../utils'
75
75
 
76
76
  const props = withDefaults(defineProps<RadioGroupProps<T>>(), {
77
- size: 'md',
78
77
  valueKey: 'value',
79
78
  labelKey: 'label',
80
79
  descriptionKey: 'description',
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { ScrollAreaRootProps } from 'reka-ui'
3
3
  import type { scrollArea } from '../theme'
4
- import { transitionProps } from '../theme/scrollArea'
4
+ import { transitionProps } from '../theme/scroll-area'
5
5
  import type { ComponentAttrs } from '../types'
6
6
 
7
7
  export interface ScrollAreaProps extends ComponentAttrs<typeof scrollArea>, Pick<ScrollAreaRootProps, 'type' | 'dir' | 'scrollHideDelay'> {}
@@ -11,7 +11,7 @@ export interface ScrollAreaProps extends ComponentAttrs<typeof scrollArea>, Pick
11
11
  import { reactivePick } from '@vueuse/core'
12
12
  import { ScrollAreaCorner, ScrollAreaRoot, ScrollAreaScrollbar, ScrollAreaThumb, ScrollAreaViewport } from 'reka-ui'
13
13
  import { computed, ref } from 'vue'
14
- import { useTheme } from '../composables'
14
+ import { useTheme } from '../composables/useTheme'
15
15
 
16
16
  const props = withDefaults(defineProps<ScrollAreaProps>(), {})
17
17
  const rootRef = ref<InstanceType<typeof ScrollAreaRoot>>()
@@ -105,12 +105,13 @@ import { reactivePick } from '@vueuse/core'
105
105
  import { defu } from 'defu'
106
106
  import { SelectArrow, SelectContent, SelectGroup, SelectItem, SelectItemIndicator, SelectItemText, SelectLabel, SelectPortal, SelectRoot, SelectSeparator, SelectTrigger, SelectViewport, useForwardPropsEmits } from 'reka-ui'
107
107
  import { computed, toRef } from 'vue'
108
- import { useComponentIcons, useTheme } from '../composables'
108
+ import { useButtonGroup } from '../composables/useButtonGroup'
109
+ import { useComponentIcons } from '../composables/useComponentIcons'
110
+ import { useTheme } from '../composables/useTheme'
109
111
  import { compare, get } from '../utils'
110
112
 
111
113
  const props = withDefaults(defineProps<SelectProps<T, I, V, M>>(), {
112
114
  variant: 'outline',
113
- size: 'md',
114
115
  valueKey: 'value' as never,
115
116
  labelKey: 'label' as never,
116
117
  portal: true,
@@ -124,6 +125,8 @@ const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffse
124
125
  const arrowProps = toRef(() => props.arrow as SelectArrowProps)
125
126
 
126
127
  const { theme, createStyler } = useTheme()
128
+
129
+ const { size, orientation } = useButtonGroup(props)
127
130
  const { isPrefix, isSuffix, prefixIconName, suffixIconName } = useComponentIcons(toRef(() => defu(props, {
128
131
  suffixIcon: theme.value.app.icons.down,
129
132
  })))
@@ -135,6 +138,8 @@ const style = computed(() => {
135
138
  const styler = createStyler(theme.value.select)
136
139
  return styler({
137
140
  ...props,
141
+ size: size.value,
142
+ groupOrientation: orientation.value,
138
143
  prefix: isPrefix.value,
139
144
  suffix: isSuffix.value,
140
145
  })
@@ -0,0 +1,96 @@
1
+ <script lang="ts">
2
+ import type { VariantProps } from '@byyuurin/ui-kit'
3
+ import type { SliderRootProps } from 'reka-ui'
4
+ import type { slider } from '../theme'
5
+ import type { ComponentAttrs } from '../types'
6
+
7
+ type SliderVariants = VariantProps<typeof slider>
8
+
9
+ export interface SliderProps extends ComponentAttrs<typeof slider>, Pick<SliderRootProps, 'as' | 'name' | 'disabled' | 'inverted' | 'min' | 'max' | 'step' | 'minStepsBetweenThumbs'> {
10
+ modelValue?: number | number[]
11
+ size?: SliderVariants['size']
12
+ /**
13
+ * The orientation of the slider.
14
+ * @default 'horizontal'
15
+ */
16
+ orientation?: SliderVariants['orientation']
17
+ /** The value of the slider when initially rendered. Use when you do not need to control the state of the slider. */
18
+ defaultValue?: number | number[]
19
+ }
20
+
21
+ export interface SliderEmits {
22
+ (event: 'update:modelValue', payload: number | number[]): void
23
+ (event: 'change', payload: Event): void
24
+ }
25
+ </script>
26
+
27
+ <script setup lang="ts">
28
+ import { reactivePick } from '@vueuse/core'
29
+ import { SliderRange, SliderRoot, SliderThumb, SliderTrack, useForwardPropsEmits } from 'reka-ui'
30
+ import { computed } from 'vue'
31
+ import { useTheme } from '../composables/useTheme'
32
+
33
+ const props = withDefaults(defineProps<SliderProps>(), {
34
+ orientation: 'horizontal',
35
+ step: 1,
36
+ max: 100,
37
+ })
38
+
39
+ const emit = defineEmits<SliderEmits>()
40
+
41
+ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'orientation', 'min', 'max', 'step', 'minStepsBetweenThumbs', 'inverted'), emit)
42
+
43
+ const modelValue = defineModel<number | number[]>()
44
+
45
+ const defaultSliderValue = computed(() => {
46
+ if (typeof props.defaultValue === 'number')
47
+ return [props.defaultValue]
48
+
49
+ return props.defaultValue
50
+ })
51
+
52
+ const sliderValue = computed({
53
+ get() {
54
+ if (typeof modelValue.value === 'number')
55
+ return [modelValue.value]
56
+
57
+ return modelValue.value ?? defaultSliderValue.value
58
+ },
59
+ set(value) {
60
+ modelValue.value = value?.length === 1 ? value[0] : value
61
+ },
62
+ })
63
+
64
+ const thumbsCount = computed(() => sliderValue.value?.length ?? 1)
65
+
66
+ const { theme, createStyler } = useTheme()
67
+ const style = computed(() => {
68
+ const styler = createStyler(theme.value.slider)
69
+ return styler(props)
70
+ })
71
+
72
+ function onChange(value: any) {
73
+ // @ts-expect-error - 'target' does not exist in type 'EventInit'
74
+ const event = new Event('change', { target: { value } })
75
+ emit('change', event)
76
+ }
77
+ </script>
78
+
79
+ <template>
80
+ <SliderRoot
81
+ v-bind="rootProps"
82
+ v-model="sliderValue"
83
+ :name="props.name"
84
+ :disabled="props.disabled"
85
+ :class="style.root({ class: [props.class, props.ui?.root] })"
86
+ :default-value="defaultSliderValue"
87
+ :data-steps="thumbsCount"
88
+ @value-commit="onChange"
89
+ >
90
+ <SliderTrack :class="style.track({ class: props.ui?.track })">
91
+ <SliderRange :class="style.range({ class: props.ui?.range })" />
92
+ </SliderTrack>
93
+
94
+ <SliderThumb v-for="count in thumbsCount" :key="count" :class="style.thumb({ class: props.ui?.thumb })" />
95
+ </SliderRoot>
96
+ </template>
@@ -38,11 +38,9 @@ export interface SwitchSlots {
38
38
  import { reactivePick } from '@vueuse/core'
39
39
  import { Label, Primitive, SwitchRoot, SwitchThumb, useForwardProps } from 'reka-ui'
40
40
  import { computed, useId } from 'vue'
41
- import { useTheme } from '../composables'
41
+ import { useTheme } from '../composables/useTheme'
42
42
 
43
- const props = withDefaults(defineProps<SwitchProps>(), {
44
- size: 'md',
45
- })
43
+ const props = withDefaults(defineProps<SwitchProps>(), {})
46
44
  const emit = defineEmits<SwitchEmits>()
47
45
  const slots = defineSlots<SwitchSlots>()
48
46
  const modelValue = defineModel<boolean>({ default: undefined })
@@ -52,14 +52,13 @@ export type TabsSlots<T extends { slot?: string }> = {
52
52
  import { reactivePick } from '@vueuse/core'
53
53
  import { TabsContent, TabsIndicator, TabsList, TabsRoot, TabsTrigger, useForwardPropsEmits } from 'reka-ui'
54
54
  import { computed } from 'vue'
55
- import { useTheme } from '../composables'
55
+ import { useTheme } from '../composables/useTheme'
56
56
  import { get } from '../utils'
57
57
 
58
58
  const props = withDefaults(defineProps<TabsProps<T>>(), {
59
59
  defaultValue: '0',
60
60
  variant: 'solid',
61
61
  orientation: 'horizontal',
62
- size: 'md',
63
62
  full: true,
64
63
  content: true,
65
64
  labelKey: 'label',
@@ -42,14 +42,13 @@ export interface TextareaSlots {
42
42
  <script setup lang="ts">
43
43
  import { Primitive } from 'reka-ui'
44
44
  import { computed, nextTick, onMounted, ref, watch } from 'vue'
45
- import { useTheme } from '../composables'
45
+ import { useTheme } from '../composables/useTheme'
46
46
 
47
47
  defineOptions({
48
48
  inheritAttrs: false,
49
49
  })
50
50
 
51
51
  const props = withDefaults(defineProps<TextareaProps>(), {
52
- size: 'md',
53
52
  variant: 'outline',
54
53
  rows: 3,
55
54
  maxRows: 0,
@@ -165,8 +164,7 @@ onMounted(() => {
165
164
  @blur="onBlur"
166
165
  @change="onChange"
167
166
  @focus="autoResize"
168
- >
169
- </textarea>
167
+ ></textarea>
170
168
 
171
169
  <slot></slot>
172
170
  </Primitive>
@@ -1,21 +1,30 @@
1
1
  <script lang="ts">
2
+ import type { VariantProps } from '@byyuurin/ui-kit'
2
3
  import type { PrimitiveProps, ToastRootEmits, ToastRootProps } from 'reka-ui'
3
4
  import type { toast } from '../theme'
4
5
  import type { ButtonProps, ComponentAttrs } from '../types'
5
6
 
7
+ type ToastVariants = VariantProps<typeof toast>
8
+
6
9
  export interface ToastProps extends ComponentAttrs<typeof toast>, Pick<ToastRootProps, 'defaultOpen' | 'open' | 'type' | 'duration'> {
7
10
  /** @default "li" */
8
11
  as?: PrimitiveProps['as']
9
12
  title?: string
10
13
  description?: string
11
14
  icon?: string
15
+ orientation?: ToastVariants['orientation']
16
+ /**
17
+ * Display a list of actions:
18
+ * - under the title and description when orientation is `vertical`
19
+ * - next to the close button when orientation is `horizontal`
20
+ */
12
21
  actions?: ButtonProps[]
13
22
  /**
14
23
  * Display a close button to dismiss the toast.
15
24
  * @default true
16
25
  */
17
26
  close?: ButtonProps | boolean
18
- /** @default `app.icons.close` */
27
+ /** @default app.icons.close */
19
28
  closeIcon?: string
20
29
  }
21
30
 
@@ -35,10 +44,11 @@ export interface ToastSlots {
35
44
  import { reactivePick, useElementBounding } from '@vueuse/core'
36
45
  import { ToastAction, ToastClose, ToastDescription, ToastRoot, ToastTitle, useForwardPropsEmits } from 'reka-ui'
37
46
  import { computed, ref } from 'vue'
38
- import { useTheme } from '../composables'
47
+ import { useTheme } from '../composables/useTheme'
39
48
  import Button from './Button.vue'
40
49
 
41
50
  const props = withDefaults(defineProps<ToastProps>(), {
51
+ orientation: 'vertical',
42
52
  close: true,
43
53
  })
44
54
 
@@ -50,12 +60,13 @@ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'defaultOpen',
50
60
  const el = ref<InstanceType<typeof ToastRoot>>()
51
61
  const { height } = useElementBounding(() => el.value?.$el.getBoundingClientRect ? el.value.$el : undefined)
52
62
 
53
- const multiline = computed(() => !!props.title && !!props.description)
54
-
55
63
  const { theme, createStyler } = useTheme()
56
64
  const style = computed(() => {
57
65
  const styler = createStyler(theme.value.toast)
58
- return styler({ ...props, multiline: multiline.value })
66
+ return styler({
67
+ ...props,
68
+ title: !!(props.title || slots.title),
69
+ })
59
70
  })
60
71
 
61
72
  defineExpose({
@@ -68,7 +79,7 @@ defineExpose({
68
79
  ref="el"
69
80
  v-slot="{ remaining, duration }"
70
81
  v-bind="rootProps"
71
- :class="style.root({ class: [props.class, props.ui?.root], multiline })"
82
+ :class="style.root({ class: [props.class, props.ui?.root] })"
72
83
  :style="{ '--height': height }"
73
84
  >
74
85
  <slot name="icon">
@@ -87,7 +98,7 @@ defineExpose({
87
98
  </slot>
88
99
  </ToastDescription>
89
100
 
90
- <div v-if="multiline && actions?.length" :class="style.actions({ class: props.ui?.actions, multiline: true })">
101
+ <div v-if="props.orientation === 'vertical' && actions?.length" :class="style.actions({ class: props.ui?.actions })">
91
102
  <slot name="actions">
92
103
  <ToastAction v-for="(action, index) in props.actions" :key="index" :alt-text="action.label || 'Action'" as-child @click.stop>
93
104
  <Button size="xs" v-bind="action" />
@@ -96,8 +107,8 @@ defineExpose({
96
107
  </div>
97
108
  </div>
98
109
 
99
- <div v-if="(!multiline && actions?.length) || props.close !== null" :class="style.actions({ class: props.ui?.actions, multiline: false })">
100
- <template v-if="!multiline">
110
+ <div v-if="(props.orientation === 'horizontal' && actions?.length) || props.close !== null" :class="style.actions({ class: props.ui?.actions })">
111
+ <template v-if="props.orientation === 'horizontal'">
101
112
  <slot name="actions">
102
113
  <ToastAction v-for="(action, index) in props.actions" :key="index" :alt-text="action.label || 'Action'" as-child @click.stop>
103
114
  <Button size="xs" v-bind="action" />
@@ -107,7 +118,7 @@ defineExpose({
107
118
 
108
119
  <ToastClose as-child>
109
120
  <slot name="close" :ui="ui">
110
- <UButton
121
+ <Button
111
122
  v-if="props.close"
112
123
  :icon="props.closeIcon || theme.app.icons.close"
113
124
  size="md"
@@ -30,7 +30,8 @@ export interface ToasterSlots {
30
30
  import { reactivePick } from '@vueuse/core'
31
31
  import { ToastPortal, ToastProvider, ToastViewport, useForwardProps } from 'reka-ui'
32
32
  import { computed, ref } from 'vue'
33
- import { useTheme, useToast } from '../composables'
33
+ import { useTheme } from '../composables/useTheme'
34
+ import { useToast } from '../composables/useToast'
34
35
  import { omit } from '../utils'
35
36
  import Toast from './Toast.vue'
36
37
 
@@ -71,6 +72,7 @@ const style = computed(() => {
71
72
  return styler({
72
73
  ...props,
73
74
  swipeDirection: swipeDirection.value,
75
+ clickable: false,
74
76
  })
75
77
  })
76
78
 
@@ -113,11 +115,9 @@ function getOffset(index: number) {
113
115
  '--translate': expanded ? 'calc(var(--offset) * var(--translate-factor))' : 'calc(var(--before) * var(--gap))',
114
116
  '--transform': 'translateY(var(--translate)) scale(var(--scale))',
115
117
  }"
116
- :class="[style.base(), {
117
- 'cursor-pointer': !!toast.click,
118
- }]"
118
+ :class="style.base({ clickable: !!(toast.onClick) })"
119
119
  @update:open="onUpdateOpen($event, toast.id)"
120
- @click="toast.click && toast.click(toast)"
120
+ @click="toast.onClick && toast.onClick(toast)"
121
121
  />
122
122
 
123
123
  <ToastPortal :disabled="!portal">
@@ -24,7 +24,7 @@ import { reactivePick } from '@vueuse/core'
24
24
  import { defu } from 'defu'
25
25
  import { TooltipArrow, TooltipContent, TooltipPortal, TooltipRoot, TooltipTrigger, useForwardPropsEmits } from 'reka-ui'
26
26
  import { computed, toRef } from 'vue'
27
- import { useTheme } from '../composables'
27
+ import { useTheme } from '../composables/useTheme'
28
28
 
29
29
  const props = withDefaults(defineProps<TooltipProps>(), {
30
30
  portal: true,
@@ -0,0 +1,13 @@
1
+ import type { ComputedRef } from 'vue';
2
+ import type { ButtonGroupProps } from '../components/ButtonGroup.vue';
3
+ interface ButtonGroupInjectData {
4
+ size: ButtonGroupProps['size'];
5
+ orientation: ButtonGroupProps['orientation'];
6
+ }
7
+ export declare const InjectionKeyButtonGroup: import("vue").InjectionKey<ComputedRef<ButtonGroupInjectData>>, injectButtonGroup: () => ComputedRef<ButtonGroupInjectData> | undefined, provideButtonGroup: (value: ComputedRef<ButtonGroupInjectData>) => void;
8
+ type UseButtonGroupProps = Pick<ButtonGroupProps, 'size'>;
9
+ export declare function useButtonGroup(props?: UseButtonGroupProps): {
10
+ size: ComputedRef<any>;
11
+ orientation: ComputedRef<any>;
12
+ };
13
+ export {};
@@ -0,0 +1,14 @@
1
+ import { computed } from "vue";
2
+ import { defineInjection } from "./defineInjection.mjs";
3
+ export const {
4
+ InjectionKey: InjectionKeyButtonGroup,
5
+ inject: injectButtonGroup,
6
+ provide: provideButtonGroup
7
+ } = defineInjection("ui.buttonGroup");
8
+ export function useButtonGroup(props = {}) {
9
+ const buttonGroup = injectButtonGroup();
10
+ return {
11
+ size: computed(() => props.size ?? buttonGroup?.value.size),
12
+ orientation: computed(() => buttonGroup?.value.orientation)
13
+ };
14
+ }
@@ -1,9 +1,9 @@
1
- import type { UserConfig } from 'unocss';
1
+ import type { UserConfig } from '@unocss/core';
2
2
  import type { MaybeRefOrGetter } from 'vue';
3
3
  import * as theme from '../theme';
4
4
  export declare const InjectionKeyThemeExtension: import("vue").InjectionKey<MaybeRefOrGetter<import("../types").PartialTheme<typeof theme>>>, provideThemeExtension: (value: MaybeRefOrGetter<import("../types").PartialTheme<typeof theme>>) => void, injectThemeExtension: () => MaybeRefOrGetter<import("../types").PartialTheme<typeof theme>>;
5
5
  export declare const InjectionKeyUnoConfig: import("vue").InjectionKey<UserConfig<object>>, provideUnoConfig: (value: UserConfig<object>) => void, injectUnoConfig: () => UserConfig<object>;
6
6
  export declare const useTheme: () => {
7
7
  theme: import("vue").ComputedRef<typeof theme>;
8
- createStyler: <V extends import("@byyuurin/ui-kit/index").CVVariants<S, B>, CV extends import("@byyuurin/ui-kit/index").CVCompoundVariants<V, S, B>, B extends import("@byyuurin/ui-kit/index").ClassValue = undefined, S extends import("@byyuurin/ui-kit/index").CVSlots = undefined>(theme: import("@byyuurin/ui-kit/index").CVMeta<V, CV, never, B, S>) => [keyof V] extends string[] ? (props: Required<import("@byyuurin/ui-kit/index").VariantProps<import("@byyuurin/ui-kit/index").CVReturnType<V, S, B>>> & import("../types").StylerBaseProps) => S extends undefined ? string : { [K in keyof S | (B extends undefined ? never : "base")]: import("@byyuurin/ui-kit/index").CVHandler<V, S, string>; } : (props?: import("../types").StylerBaseProps) => S extends undefined ? string : { [K in keyof S | (B extends undefined ? never : "base")]: import("@byyuurin/ui-kit/index").CVHandler<V, S, string>; };
8
+ createStyler: <V extends import("@byyuurin/ui-kit/index").CVVariants<S, B>, CV extends import("@byyuurin/ui-kit/index").CVCompoundVariants<V, S, B>, DV extends import("@byyuurin/ui-kit/index").CVDefaultVariants<V, S>, B extends import("@byyuurin/ui-kit/index").ClassValue = undefined, S extends import("@byyuurin/ui-kit/index").CVSlots = undefined>(theme: import("@byyuurin/ui-kit/index").CVMeta<V, CV, DV, B, S>) => [keyof V] extends string[] ? (props: import("@byyuurin/ui-kit/index").VariantProps<import("@byyuurin/ui-kit/index").CVReturnType<V, S, B>> & import("../types").StylerBaseProps) => S extends undefined ? string : { [K in keyof S | (B extends undefined ? never : "base")]: import("@byyuurin/ui-kit/index").CVHandler<V, S, string>; } : (props?: import("../types").StylerBaseProps) => S extends undefined ? string : { [K in keyof S | (B extends undefined ? never : "base")]: import("@byyuurin/ui-kit/index").CVHandler<V, S, string>; };
9
9
  };
@@ -1,4 +1,4 @@
1
- import { transformUnoRules } from "@byyuurin/ui/unocss-preset";
1
+ import { transformUnoRules } from "@byyuurin/ui/unocss";
2
2
  import { createSharedComposable } from "@vueuse/core";
3
3
  import { computed, toValue } from "vue";
4
4
  import * as theme from "../theme/index.mjs";
@@ -1,7 +1,7 @@
1
- import type { ToastProps } from '@byyuurin/ui';
1
+ import type { ToastProps } from '../types';
2
2
  export interface Toast extends Omit<ToastProps, 'defaultOpen'> {
3
3
  id: string | number;
4
- click?: (toast: Toast) => void;
4
+ onClick?: (toast: Toast) => void;
5
5
  }
6
6
  export declare const useToast: () => {
7
7
  toasts: import("vue").Ref<{
@@ -9,13 +9,13 @@ export declare const useToast: () => {
9
9
  [x: number]: any;
10
10
  [x: symbol]: ToastProps;
11
11
  id: string | number;
12
- click?: ((toast: Toast) => void) | undefined;
12
+ onClick?: ((toast: Toast) => void) | undefined;
13
13
  }[], Toast[] | {
14
14
  [x: string]: any;
15
15
  [x: number]: any;
16
16
  [x: symbol]: ToastProps;
17
17
  id: string | number;
18
- click?: ((toast: Toast) => void) | undefined;
18
+ onClick?: ((toast: Toast) => void) | undefined;
19
19
  }[]>;
20
20
  add: (toast: Partial<Toast>) => Toast;
21
21
  update: (id: string | number, toast: Partial<Omit<Toast, "id">>) => void;
@@ -1,17 +1,30 @@
1
1
  import { createSharedComposable } from "@vueuse/core";
2
- import { ref } from "vue";
2
+ import { nextTick, ref } from "vue";
3
3
  export const useToast = createSharedComposable(() => {
4
4
  const toasts = ref([]);
5
+ const running = ref(false);
6
+ const maxToasts = 5;
7
+ const queue = [];
8
+ const generateId = () => `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
9
+ async function processQueue() {
10
+ if (running.value || queue.length === 0)
11
+ return;
12
+ running.value = true;
13
+ while (queue.length > 0) {
14
+ const toast = queue.shift();
15
+ await nextTick();
16
+ toasts.value = [...toasts.value, toast].slice(-maxToasts);
17
+ }
18
+ running.value = false;
19
+ }
5
20
  function add(toast) {
6
21
  const body = {
7
- id: Date.now().toString(),
22
+ id: generateId(),
8
23
  open: true,
9
24
  ...toast
10
25
  };
11
- const index = toasts.value.findIndex((t) => t.id === body.id);
12
- if (index === -1)
13
- toasts.value.push(body);
14
- toasts.value = toasts.value.slice(-5);
26
+ queue.push(body);
27
+ processQueue();
15
28
  return body;
16
29
  }
17
30
  function update(id, toast) {
@@ -35,5 +35,22 @@ declare const _default: {
35
35
  trailingIcon: string;
36
36
  label: string;
37
37
  }, undefined>;
38
+ defaultVariants: import("@byyuurin/ui-kit/index").CVDefaultVariants<{
39
+ disabled: {
40
+ true: {
41
+ trigger: string;
42
+ };
43
+ };
44
+ }, {
45
+ root: string;
46
+ item: string;
47
+ header: string;
48
+ trigger: string;
49
+ content: string[];
50
+ body: string;
51
+ icon: string;
52
+ trailingIcon: string;
53
+ label: string;
54
+ }>;
38
55
  };
39
56
  export default _default;
@@ -1,25 +1,28 @@
1
1
  import { ct } from "@byyuurin/ui-kit";
2
- export default ct({
3
- slots: {
4
- root: "w-full color-ui-cb",
5
- item: "border-b last:border-b-0",
6
- header: "flex",
7
- trigger: "group flex-1 flex items-center gap-2 font-medium text-sm py-4 focus-visible:outline-ui-fill min-w-0",
8
- content: [
9
- "overflow-hidden focus:outline-none",
10
- "data-[state=open]:animate-[accordion-down_200ms_ease-out]",
11
- "data-[state=closed]:animate-[accordion-up_200ms_ease-out]"
12
- ],
13
- body: "text-sm pb-4 color-ui-cb/80",
14
- icon: "shrink-0 size-5",
15
- trailingIcon: "shrink-0 size-5 ms-auto group-data-[state=open]:rotate-180 transition-transform duration-200",
16
- label: "text-start break-words"
17
- },
18
- variants: {
19
- disabled: {
20
- true: {
21
- trigger: "cursor-not-allowed opacity-50"
2
+ export default ct(
3
+ /* @unocss-include */
4
+ {
5
+ slots: {
6
+ root: "w-full color-ui-cb",
7
+ item: "border-b last:border-b-0",
8
+ header: "flex",
9
+ trigger: "group flex-1 flex items-center gap-2 font-medium text-sm py-4 outline-none focus-visible:outline-ui-cb/80 min-w-0",
10
+ content: [
11
+ "overflow-hidden focus:outline-none",
12
+ "data-[state=open]:animate-[accordion-down_200ms_ease-out]",
13
+ "data-[state=closed]:animate-[accordion-up_200ms_ease-out]"
14
+ ],
15
+ body: "text-sm pb-4 color-ui-cb/80",
16
+ icon: "shrink-0 size-5",
17
+ trailingIcon: "shrink-0 size-5 ms-auto group-data-[state=open]:rotate-180 transition-transform duration-200",
18
+ label: "text-start break-words"
19
+ },
20
+ variants: {
21
+ disabled: {
22
+ true: {
23
+ trigger: "cursor-not-allowed opacity-50"
24
+ }
22
25
  }
23
26
  }
24
27
  }
25
- });
28
+ );