@byyuurin/ui 0.0.2 → 0.0.4

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 (109) hide show
  1. package/README.md +76 -4
  2. package/dist/index.d.ts +3 -3
  3. package/dist/index.mjs +3 -3
  4. package/dist/nuxt.d.mts +13 -0
  5. package/dist/nuxt.d.ts +6 -3
  6. package/dist/nuxt.mjs +6 -3
  7. package/dist/resolver.d.mts +13 -0
  8. package/dist/resolver.d.ts +6 -3
  9. package/dist/resolver.mjs +5 -2
  10. package/dist/{components → runtime/components}/Accordion.vue +19 -3
  11. package/dist/{components → runtime/components}/App.vue +5 -1
  12. package/dist/{components → runtime/components}/Button.vue +92 -94
  13. package/dist/{components → runtime/components}/Checkbox.vue +101 -104
  14. package/dist/{components → runtime/components}/Input.vue +5 -1
  15. package/dist/{components → runtime/components}/ModalProvider.vue +1 -1
  16. package/dist/{components → runtime/components}/RadioGroup.vue +174 -180
  17. package/dist/runtime/components/ScrollArea.vue +72 -0
  18. package/dist/{components → runtime/components}/Select.vue +262 -258
  19. package/dist/{components → runtime/components}/Switch.vue +98 -99
  20. package/dist/{components → runtime/components}/Tabs.vue +117 -117
  21. package/dist/runtime/components/Textarea.vue +173 -0
  22. package/dist/{components → runtime/components}/Toast.vue +1 -1
  23. package/dist/{components → runtime/components}/Toaster.vue +35 -1
  24. package/dist/{components → runtime/components}/index.d.ts +2 -0
  25. package/dist/{components → runtime/components}/index.mjs +2 -0
  26. package/dist/runtime/composables/defineInjection.d.ts +11 -0
  27. package/dist/runtime/composables/defineInjection.mjs +9 -0
  28. package/dist/{composables → runtime/composables}/index.d.ts +1 -0
  29. package/dist/{composables → runtime/composables}/index.mjs +1 -0
  30. package/dist/{composables → runtime/composables}/useModal.d.ts +1 -1
  31. package/dist/{composables → runtime/composables}/useModal.mjs +3 -2
  32. package/dist/{composables → runtime/composables}/useTheme.d.ts +3 -2
  33. package/dist/runtime/composables/useTheme.mjs +26 -0
  34. package/dist/{composables → runtime/composables}/useToast.d.ts +1 -1
  35. package/dist/{theme → runtime/theme}/button.d.ts +0 -8
  36. package/dist/{theme → runtime/theme}/button.mjs +1 -9
  37. package/dist/{theme → runtime/theme}/checkbox.d.ts +0 -12
  38. package/dist/{theme → runtime/theme}/checkbox.mjs +4 -9
  39. package/dist/{theme → runtime/theme}/index.d.ts +2 -0
  40. package/dist/{theme → runtime/theme}/index.mjs +2 -0
  41. package/dist/{theme → runtime/theme}/radioGroup.d.ts +0 -24
  42. package/dist/{theme → runtime/theme}/radioGroup.mjs +8 -20
  43. package/dist/runtime/theme/scrollArea.d.ts +51 -0
  44. package/dist/runtime/theme/scrollArea.mjs +30 -0
  45. package/dist/{theme → runtime/theme}/switch.d.ts +0 -12
  46. package/dist/{theme → runtime/theme}/switch.mjs +2 -8
  47. package/dist/{theme → runtime/theme}/tabs.d.ts +32 -11
  48. package/dist/{theme → runtime/theme}/tabs.mjs +19 -12
  49. package/dist/runtime/theme/textarea.d.ts +90 -0
  50. package/dist/runtime/theme/textarea.mjs +100 -0
  51. package/dist/{theme → runtime/theme}/toast.mjs +1 -1
  52. package/dist/{types → runtime/types}/components.d.ts +2 -0
  53. package/dist/{types → runtime/types}/index.d.ts +1 -1
  54. package/dist/{utils → runtime/utils}/index.d.ts +3 -12
  55. package/dist/{utils → runtime/utils}/index.mjs +3 -12
  56. package/dist/{internal → runtime/utils}/styler.d.ts +0 -1
  57. package/dist/runtime/utils/styler.mjs +10 -0
  58. package/dist/{internal/constants.mjs → shared/ui.Cmq14xN9.mjs} +6 -2
  59. package/dist/unocss-preset.d.mts +57 -0
  60. package/dist/unocss-preset.d.ts +29 -9
  61. package/dist/unocss-preset.mjs +164 -110
  62. package/package.json +18 -12
  63. package/dist/composables/useTheme.mjs +0 -18
  64. package/dist/internal/constants.d.ts +0 -3
  65. package/dist/internal/index.d.ts +0 -4
  66. package/dist/internal/index.mjs +0 -4
  67. package/dist/internal/styler.mjs +0 -236
  68. package/dist/utils/unocss.d.ts +0 -3
  69. package/dist/utils/unocss.mjs +0 -50
  70. /package/dist/{components → runtime/components}/Card.vue +0 -0
  71. /package/dist/{components → runtime/components}/Drawer.vue +0 -0
  72. /package/dist/{components → runtime/components}/Link.vue +0 -0
  73. /package/dist/{components → runtime/components}/Modal.vue +0 -0
  74. /package/dist/{components → runtime/components}/Popover.vue +0 -0
  75. /package/dist/{components → runtime/components}/Tooltip.vue +0 -0
  76. /package/dist/{composables → runtime/composables}/useComponentIcons.d.ts +0 -0
  77. /package/dist/{composables → runtime/composables}/useComponentIcons.mjs +0 -0
  78. /package/dist/{composables → runtime/composables}/useToast.mjs +0 -0
  79. /package/dist/{theme → runtime/theme}/accordion.d.ts +0 -0
  80. /package/dist/{theme → runtime/theme}/accordion.mjs +0 -0
  81. /package/dist/{theme → runtime/theme}/app.d.ts +0 -0
  82. /package/dist/{theme → runtime/theme}/app.mjs +0 -0
  83. /package/dist/{theme → runtime/theme}/card.d.ts +0 -0
  84. /package/dist/{theme → runtime/theme}/card.mjs +0 -0
  85. /package/dist/{theme → runtime/theme}/drawer.d.ts +0 -0
  86. /package/dist/{theme → runtime/theme}/drawer.mjs +0 -0
  87. /package/dist/{theme → runtime/theme}/input.d.ts +0 -0
  88. /package/dist/{theme → runtime/theme}/input.mjs +0 -0
  89. /package/dist/{theme → runtime/theme}/link.d.ts +0 -0
  90. /package/dist/{theme → runtime/theme}/link.mjs +0 -0
  91. /package/dist/{theme → runtime/theme}/modal.d.ts +0 -0
  92. /package/dist/{theme → runtime/theme}/modal.mjs +0 -0
  93. /package/dist/{theme → runtime/theme}/popover.d.ts +0 -0
  94. /package/dist/{theme → runtime/theme}/popover.mjs +0 -0
  95. /package/dist/{theme → runtime/theme}/select.d.ts +0 -0
  96. /package/dist/{theme → runtime/theme}/select.mjs +0 -0
  97. /package/dist/{theme → runtime/theme}/toast.d.ts +0 -0
  98. /package/dist/{theme → runtime/theme}/toaster.d.ts +0 -0
  99. /package/dist/{theme → runtime/theme}/toaster.mjs +0 -0
  100. /package/dist/{theme → runtime/theme}/tooltip.d.ts +0 -0
  101. /package/dist/{theme → runtime/theme}/tooltip.mjs +0 -0
  102. /package/dist/{types → runtime/types}/components.mjs +0 -0
  103. /package/dist/{types → runtime/types}/index.mjs +0 -0
  104. /package/dist/{types → runtime/types}/utils.d.ts +0 -0
  105. /package/dist/{types → runtime/types}/utils.mjs +0 -0
  106. /package/dist/{internal → runtime/utils}/extend-theme.d.ts +0 -0
  107. /package/dist/{internal → runtime/utils}/extend-theme.mjs +0 -0
  108. /package/dist/{internal → runtime/utils}/link.d.ts +0 -0
  109. /package/dist/{internal → runtime/utils}/link.mjs +0 -0
@@ -1,99 +1,98 @@
1
- <script lang="ts">
2
- import type { VariantProps } from '@byyuurin/ui-kit'
3
- import type { PrimitiveProps, SwitchRootProps } from 'reka-ui'
4
- import type { switch as _switch } from '../theme'
5
- import type { ComponentAttrs } from '../types'
6
-
7
- type SwitchVariants = VariantProps<typeof _switch>
8
-
9
- export interface SwitchProps extends ComponentAttrs<typeof _switch>, Pick<SwitchRootProps, 'disabled' | 'id' | 'name' | 'required' | 'value' | 'defaultValue'> {
10
- as?: PrimitiveProps['as']
11
- size?: SwitchVariants['size']
12
- /** When `true`, the loading icon will be displayed. */
13
- loading?: boolean
14
- /**
15
- * The icon when the `loading` prop is `true`.
16
- * @default app.icons.loading
17
- */
18
- loadingIcon?: string
19
- /** Display an icon when the switch is checked. */
20
- checkedIcon?: string
21
- /** Display an icon when the switch is unchecked. */
22
- uncheckedIcon?: string
23
- label?: string
24
- description?: string
25
- round?: boolean
26
- }
27
-
28
- export interface SwitchEmits {
29
- (event: 'change', payload: Event): void
30
- }
31
-
32
- export interface SwitchSlots {
33
- label?: (props: { label?: string }) => any
34
- description?: (props: { description?: string }) => any
35
- }
36
- </script>
37
-
38
- <script lang="ts" setup>
39
- import { reactivePick } from '@vueuse/core'
40
- import { Label, Primitive, SwitchRoot, SwitchThumb, useForwardProps } from 'reka-ui'
41
- import { computed, useId } from 'vue'
42
- import { useTheme } from '../composables'
43
-
44
- const props = withDefaults(defineProps<SwitchProps>(), {
45
- size: 'md',
46
- })
47
- const emit = defineEmits<SwitchEmits>()
48
- const slots = defineSlots<SwitchSlots>()
49
- const modelValue = defineModel<boolean>({ default: undefined })
50
-
51
- const rootProps = useForwardProps(reactivePick(props, 'required', 'value', 'defaultValue'))
52
- const id = useId()
53
-
54
- const { theme, createStyler } = useTheme()
55
- const style = computed(() => {
56
- const styler = createStyler(theme.value.switch)
57
- return styler({ ...props, checked: false, unchecked: false })
58
- })
59
-
60
- function onUpdate(value: any) {
61
- // @ts-expect-error - 'target' does not exist in type 'EventInit'
62
- const event = new Event('change', { target: { value } })
63
- emit('change', event)
64
- }
65
- </script>
66
-
67
- <template>
68
- <Primitive :as="props.as" :class="style.root({ class: [props.class, props.ui?.root] })">
69
- <div :class="style.container({ class: props.ui?.container })">
70
- <SwitchRoot
71
- :id="id"
72
- v-bind="rootProps"
73
- v-model="modelValue"
74
- :name="props.name"
75
- :disabled="props.disabled || props.loading"
76
- :class="style.base({ class: props.ui?.base })"
77
- @update:model-value="onUpdate"
78
- >
79
- <SwitchThumb :class="style.thumb({ class: props.ui?.thumb })">
80
- <i v-if="props.loading" :class="style.icon({ class: [theme.app.icons.loading, props.ui?.icon], checked: true, unchecked: true })"></i>
81
- <template v-else>
82
- <i v-if="props.checkedIcon" :class="style.icon({ class: [props.checkedIcon, props.ui?.icon], checked: true })"></i>
83
- <i v-if="props.uncheckedIcon" :class="style.icon({ class: [props.uncheckedIcon, props.ui?.icon], unchecked: true })"></i>
84
- </template>
85
- </SwitchThumb>
86
- </SwitchRoot>
87
- </div>
88
- <div v-if="props.label || slots.label || props.description || slots.description" :class="style.wrapper({ class: props.ui?.wrapper })">
89
- <Label v-if="props.label || slots.label" :for="id" :class="style.label({ class: props.ui?.label })">
90
- <slot name="label" :label="props.label">{{ props.label }}</slot>
91
- </Label>
92
- <p v-if="props.description || slots.description" :class="style.description({ class: props.ui?.description })">
93
- <slot name="description" :description="props.description">
94
- {{ props.description }}
95
- </slot>
96
- </p>
97
- </div>
98
- </Primitive>
99
- </template>
1
+ <script lang="ts">
2
+ import type { VariantProps } from '@byyuurin/ui-kit'
3
+ import type { PrimitiveProps, SwitchRootProps } from 'reka-ui'
4
+ import type { switch as _switch } from '../theme'
5
+ import type { ComponentAttrs } from '../types'
6
+
7
+ type SwitchVariants = VariantProps<typeof _switch>
8
+
9
+ export interface SwitchProps extends ComponentAttrs<typeof _switch>, Pick<SwitchRootProps, 'disabled' | 'id' | 'name' | 'required' | 'value' | 'defaultValue'> {
10
+ as?: PrimitiveProps['as']
11
+ size?: SwitchVariants['size']
12
+ /** When `true`, the loading icon will be displayed. */
13
+ loading?: boolean
14
+ /**
15
+ * The icon when the `loading` prop is `true`.
16
+ * @default app.icons.loading
17
+ */
18
+ loadingIcon?: string
19
+ /** Display an icon when the switch is checked. */
20
+ checkedIcon?: string
21
+ /** Display an icon when the switch is unchecked. */
22
+ uncheckedIcon?: string
23
+ label?: string
24
+ description?: string
25
+ }
26
+
27
+ export interface SwitchEmits {
28
+ (event: 'change', payload: Event): void
29
+ }
30
+
31
+ export interface SwitchSlots {
32
+ label?: (props: { label?: string }) => any
33
+ description?: (props: { description?: string }) => any
34
+ }
35
+ </script>
36
+
37
+ <script lang="ts" setup>
38
+ import { reactivePick } from '@vueuse/core'
39
+ import { Label, Primitive, SwitchRoot, SwitchThumb, useForwardProps } from 'reka-ui'
40
+ import { computed, useId } from 'vue'
41
+ import { useTheme } from '../composables'
42
+
43
+ const props = withDefaults(defineProps<SwitchProps>(), {
44
+ size: 'md',
45
+ })
46
+ const emit = defineEmits<SwitchEmits>()
47
+ const slots = defineSlots<SwitchSlots>()
48
+ const modelValue = defineModel<boolean>({ default: undefined })
49
+
50
+ const rootProps = useForwardProps(reactivePick(props, 'required', 'value', 'defaultValue'))
51
+ const id = useId()
52
+
53
+ const { theme, createStyler } = useTheme()
54
+ const style = computed(() => {
55
+ const styler = createStyler(theme.value.switch)
56
+ return styler({ ...props, checked: false, unchecked: false })
57
+ })
58
+
59
+ function onUpdate(value: any) {
60
+ // @ts-expect-error - 'target' does not exist in type 'EventInit'
61
+ const event = new Event('change', { target: { value } })
62
+ emit('change', event)
63
+ }
64
+ </script>
65
+
66
+ <template>
67
+ <Primitive :as="props.as" :class="style.root({ class: [props.class, props.ui?.root] })">
68
+ <div :class="style.container({ class: props.ui?.container })">
69
+ <SwitchRoot
70
+ :id="id"
71
+ v-bind="rootProps"
72
+ v-model="modelValue"
73
+ :name="props.name"
74
+ :disabled="props.disabled || props.loading"
75
+ :class="style.base({ class: props.ui?.base })"
76
+ @update:model-value="onUpdate"
77
+ >
78
+ <SwitchThumb :class="style.thumb({ class: props.ui?.thumb })">
79
+ <i v-if="props.loading" :class="style.icon({ class: [theme.app.icons.loading, props.ui?.icon], checked: true, unchecked: true })"></i>
80
+ <template v-else>
81
+ <i v-if="props.checkedIcon" :class="style.icon({ class: [props.checkedIcon, props.ui?.icon], checked: true })"></i>
82
+ <i v-if="props.uncheckedIcon" :class="style.icon({ class: [props.uncheckedIcon, props.ui?.icon], unchecked: true })"></i>
83
+ </template>
84
+ </SwitchThumb>
85
+ </SwitchRoot>
86
+ </div>
87
+ <div v-if="props.label || slots.label || props.description || slots.description" :class="style.wrapper({ class: props.ui?.wrapper })">
88
+ <Label v-if="props.label || slots.label" :for="id" :class="style.label({ class: props.ui?.label })">
89
+ <slot name="label" :label="props.label">{{ props.label }}</slot>
90
+ </Label>
91
+ <p v-if="props.description || slots.description" :class="style.description({ class: props.ui?.description })">
92
+ <slot name="description" :description="props.description">
93
+ {{ props.description }}
94
+ </slot>
95
+ </p>
96
+ </div>
97
+ </Primitive>
98
+ </template>
@@ -1,117 +1,117 @@
1
- <script lang="ts">
2
- import type { VariantProps } from '@byyuurin/ui-kit'
3
- import type { PrimitiveProps, TabsRootEmits, TabsRootProps } from 'reka-ui'
4
- import type { tabs } from '../theme'
5
- import type { ComponentAttrs, DynamicSlots } from '../types'
6
-
7
- export interface TabsItem {
8
- label?: string
9
- icon?: string
10
- slot?: string
11
- content?: string
12
- /** A unique value for the tab item. Defaults to the index. */
13
- value?: string | number
14
- disabled?: boolean
15
- }
16
-
17
- type TabsVariants = VariantProps<typeof tabs>
18
-
19
- export interface TabsProps<T> extends ComponentAttrs<typeof tabs>, Pick<TabsRootProps<string | number>, 'defaultValue' | 'modelValue' | 'activationMode' | 'unmountOnHide'> {
20
- as?: PrimitiveProps['as']
21
- items?: T[]
22
- variant?: TabsVariants['variant']
23
- orientation?: TabsVariants['orientation']
24
- size?: TabsVariants['size']
25
- /** @default true */
26
- full?: boolean
27
- /**
28
- * The content of the tabs, can be disabled to prevent rendering the content.
29
- * @default true
30
- */
31
- content?: boolean
32
- /**
33
- * The key used to get the label from the item.
34
- * @default 'label'
35
- */
36
- labelKey?: string
37
- }
38
-
39
- export interface TabsEmits extends TabsRootEmits<string | number> {}
40
-
41
- type SlotProps<T> = (props: { item: T, index: number }) => any
42
-
43
- export type TabsSlots<T extends { slot?: string }> = {
44
- leading?: SlotProps<T>
45
- default?: SlotProps<T>
46
- trailing?: SlotProps<T>
47
- content?: SlotProps<T>
48
- } & DynamicSlots<T, SlotProps<T>>
49
- </script>
50
-
51
- <script lang="ts" setup generic="T extends TabsItem">
52
- import { reactivePick } from '@vueuse/core'
53
- import { TabsContent, TabsIndicator, TabsList, TabsRoot, TabsTrigger, useForwardPropsEmits } from 'reka-ui'
54
- import { computed } from 'vue'
55
- import { useTheme } from '../composables'
56
- import { get } from '../utils'
57
-
58
- const props = withDefaults(defineProps<TabsProps<T>>(), {
59
- defaultValue: '0',
60
- variant: 'solid',
61
- orientation: 'horizontal',
62
- size: 'md',
63
- full: true,
64
- content: true,
65
- labelKey: 'label',
66
- })
67
-
68
- const emits = defineEmits<TabsEmits>()
69
- const slots = defineSlots<TabsSlots<T>>()
70
-
71
- const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'orientation', 'activationMode', 'unmountOnHide'), emits)
72
-
73
- const { theme, createStyler } = useTheme()
74
- const style = computed(() => {
75
- const styler = createStyler(theme.value.tabs)
76
- return styler(props)
77
- })
78
- </script>
79
-
80
- <template>
81
- <TabsRoot v-bind="rootProps" :class="style.root({ class: [props.class, props.ui?.root] })">
82
- <TabsList :class="style.list({ class: props.ui?.list })">
83
- <TabsIndicator :class="style.indicator({ class: props.ui?.indicator })" />
84
-
85
- <TabsTrigger
86
- v-for="(item, index) of items"
87
- :key="index"
88
- :value="item.value || String(index)"
89
- :disabled="item.disabled"
90
- :class="style.trigger({ class: props.ui?.trigger })"
91
- >
92
- <slot name="leading" :item="item" :index="index">
93
- <i v-if="item.icon" :class="style.leadingIcon({ class: [item.icon, props.ui?.leadingIcon] })"></i>
94
- </slot>
95
-
96
- <span v-if="get(item, props.labelKey) || slots.default" :class="style.label({ class: props.ui?.label })">
97
- <slot :item="item" :index="index">{{ get(item, props.labelKey) }}</slot>
98
- </span>
99
-
100
- <slot name="trailing" :item="item" :index="index"></slot>
101
- </TabsTrigger>
102
- </TabsList>
103
-
104
- <template v-if="props.content">
105
- <TabsContent
106
- v-for="(item, index) of items"
107
- :key="index"
108
- :value="item.value || String(index)"
109
- :class="style.content({ class: props.ui?.content })"
110
- >
111
- <slot :name="item.slot || 'content'" :item="item" :index="index">
112
- {{ item.content }}
113
- </slot>
114
- </TabsContent>
115
- </template>
116
- </TabsRoot>
117
- </template>
1
+ <script lang="ts">
2
+ import type { VariantProps } from '@byyuurin/ui-kit'
3
+ import type { PrimitiveProps, TabsRootEmits, TabsRootProps } from 'reka-ui'
4
+ import type { tabs } from '../theme'
5
+ import type { ComponentAttrs, DynamicSlots } from '../types'
6
+
7
+ export interface TabsItem {
8
+ label?: string
9
+ icon?: string
10
+ slot?: string
11
+ content?: string
12
+ /** A unique value for the tab item. Defaults to the index. */
13
+ value?: string | number
14
+ disabled?: boolean
15
+ }
16
+
17
+ type TabsVariants = VariantProps<typeof tabs>
18
+
19
+ export interface TabsProps<T> extends ComponentAttrs<typeof tabs>, Pick<TabsRootProps<string | number>, 'defaultValue' | 'modelValue' | 'activationMode' | 'unmountOnHide'> {
20
+ as?: PrimitiveProps['as']
21
+ items?: T[]
22
+ variant?: TabsVariants['variant']
23
+ orientation?: TabsVariants['orientation']
24
+ size?: TabsVariants['size']
25
+ /** @default true */
26
+ full?: boolean
27
+ /**
28
+ * The content of the tabs, can be disabled to prevent rendering the content.
29
+ * @default true
30
+ */
31
+ content?: boolean
32
+ /**
33
+ * The key used to get the label from the item.
34
+ * @default 'label'
35
+ */
36
+ labelKey?: string
37
+ }
38
+
39
+ export interface TabsEmits extends TabsRootEmits<string | number> {}
40
+
41
+ type SlotProps<T> = (props: { item: T, index: number }) => any
42
+
43
+ export type TabsSlots<T extends { slot?: string }> = {
44
+ prefix?: SlotProps<T>
45
+ default?: SlotProps<T>
46
+ suffix?: SlotProps<T>
47
+ content?: SlotProps<T>
48
+ } & DynamicSlots<T, SlotProps<T>>
49
+ </script>
50
+
51
+ <script lang="ts" setup generic="T extends TabsItem">
52
+ import { reactivePick } from '@vueuse/core'
53
+ import { TabsContent, TabsIndicator, TabsList, TabsRoot, TabsTrigger, useForwardPropsEmits } from 'reka-ui'
54
+ import { computed } from 'vue'
55
+ import { useTheme } from '../composables'
56
+ import { get } from '../utils'
57
+
58
+ const props = withDefaults(defineProps<TabsProps<T>>(), {
59
+ defaultValue: '0',
60
+ variant: 'solid',
61
+ orientation: 'horizontal',
62
+ size: 'md',
63
+ full: true,
64
+ content: true,
65
+ labelKey: 'label',
66
+ })
67
+
68
+ const emits = defineEmits<TabsEmits>()
69
+ const slots = defineSlots<TabsSlots<T>>()
70
+
71
+ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'orientation', 'activationMode', 'unmountOnHide'), emits)
72
+
73
+ const { theme, createStyler } = useTheme()
74
+ const style = computed(() => {
75
+ const styler = createStyler(theme.value.tabs)
76
+ return styler(props)
77
+ })
78
+ </script>
79
+
80
+ <template>
81
+ <TabsRoot v-bind="rootProps" :class="style.root({ class: [props.class, props.ui?.root] })">
82
+ <TabsList :class="style.list({ class: props.ui?.list })">
83
+ <TabsIndicator :class="style.indicator({ class: props.ui?.indicator })" />
84
+
85
+ <TabsTrigger
86
+ v-for="(item, index) of items"
87
+ :key="index"
88
+ :value="item.value || String(index)"
89
+ :disabled="item.disabled"
90
+ :class="style.trigger({ class: props.ui?.trigger })"
91
+ >
92
+ <slot name="prefix" :item="item" :index="index">
93
+ <i v-if="item.icon" :class="style.prefixIcon({ class: [item.icon, props.ui?.prefixIcon] })"></i>
94
+ </slot>
95
+
96
+ <span v-if="get(item, props.labelKey) || slots.default" :class="style.label({ class: props.ui?.label })">
97
+ <slot :item="item" :index="index">{{ get(item, props.labelKey) }}</slot>
98
+ </span>
99
+
100
+ <slot name="suffix" :item="item" :index="index"></slot>
101
+ </TabsTrigger>
102
+ </TabsList>
103
+
104
+ <template v-if="props.content">
105
+ <TabsContent
106
+ v-for="(item, index) of items"
107
+ :key="index"
108
+ :value="item.value || String(index)"
109
+ :class="style.content({ class: props.ui?.content })"
110
+ >
111
+ <slot :name="item.slot || 'content'" :item="item" :index="index">
112
+ {{ item.content }}
113
+ </slot>
114
+ </TabsContent>
115
+ </template>
116
+ </TabsRoot>
117
+ </template>
@@ -0,0 +1,173 @@
1
+ <script lang="ts">
2
+ import type { VariantProps } from '@byyuurin/ui-kit'
3
+ import type { PrimitiveProps } from 'reka-ui'
4
+ import type { textarea } from '../theme'
5
+ import type { ComponentAttrs } from '../types'
6
+
7
+ type TextareaVariants = VariantProps<typeof textarea>
8
+
9
+ export interface TextareaProps extends ComponentAttrs<typeof textarea> {
10
+ /**
11
+ * The element or component this component should render as.
12
+ * @defaultValue 'div'
13
+ */
14
+ as?: PrimitiveProps['as']
15
+ id?: string
16
+ name?: string
17
+ placeholder?: string
18
+ size?: TextareaVariants['size']
19
+ variant?: TextareaVariants['variant']
20
+ highlight?: boolean
21
+ underline?: boolean
22
+ required?: boolean
23
+ autofocus?: boolean
24
+ autofocusDelay?: number
25
+ disabled?: boolean
26
+ rows?: number
27
+ maxRows?: number
28
+ autoResize?: boolean
29
+ }
30
+
31
+ export interface TextareaEmits {
32
+ (e: 'update:modelValue', payload: string): void
33
+ (e: 'blur', event: FocusEvent): void
34
+ (e: 'change', event: Event): void
35
+ }
36
+
37
+ export interface TextareaSlots {
38
+ default?: (props?: {}) => any
39
+ }
40
+ </script>
41
+
42
+ <script setup lang="ts">
43
+ import { Primitive } from 'reka-ui'
44
+ import { computed, nextTick, onMounted, ref, watch } from 'vue'
45
+ import { useTheme } from '../composables'
46
+
47
+ defineOptions({
48
+ inheritAttrs: false,
49
+ })
50
+
51
+ const props = withDefaults(defineProps<TextareaProps>(), {
52
+ size: 'md',
53
+ variant: 'outline',
54
+ rows: 3,
55
+ maxRows: 0,
56
+ autofocusDelay: 0,
57
+ })
58
+
59
+ const emit = defineEmits<TextareaEmits>()
60
+ defineSlots<TextareaSlots>()
61
+ const [modelValue, modelModifiers] = defineModel<string | number>()
62
+
63
+ const textareaRef = ref<HTMLTextAreaElement | null>(null)
64
+
65
+ const { theme, createStyler } = useTheme()
66
+ const style = computed(() => {
67
+ const styler = createStyler(theme.value.textarea)
68
+ return styler(props)
69
+ })
70
+
71
+ function autoFocus() {
72
+ if (props.autofocus)
73
+ textareaRef.value?.focus()
74
+ }
75
+
76
+ function updateInput(value: string) {
77
+ if (modelModifiers.trim)
78
+ value = value.trim()
79
+
80
+ modelValue.value = value
81
+ }
82
+
83
+ function onInput(event: Event) {
84
+ autoResize()
85
+
86
+ if (!modelModifiers.lazy)
87
+ updateInput((event.target as HTMLInputElement).value)
88
+ }
89
+
90
+ function onChange(event: Event) {
91
+ const value = (event.target as HTMLInputElement).value
92
+
93
+ if (modelModifiers.lazy)
94
+ updateInput(value)
95
+
96
+ if (modelModifiers.trim)
97
+ (event.target as HTMLInputElement).value = value.trim()
98
+
99
+ emit('change', event)
100
+ }
101
+
102
+ function onBlur(event: FocusEvent) {
103
+ emit('blur', event)
104
+ }
105
+
106
+ function autoResize() {
107
+ if (!props.autoResize)
108
+ return
109
+
110
+ if (!textareaRef.value)
111
+ return
112
+
113
+ textareaRef.value.rows = props.rows
114
+
115
+ const overflow = textareaRef.value.style.overflow
116
+ textareaRef.value.style.overflow = 'hidden'
117
+
118
+ const styles = window.getComputedStyle(textareaRef.value)
119
+ const paddingTop = Number.parseInt(styles.paddingTop)
120
+ const paddingBottom = Number.parseInt(styles.paddingBottom)
121
+ const padding = paddingTop + paddingBottom
122
+ const lineHeight = Number.parseInt(styles.lineHeight)
123
+ const { scrollHeight } = textareaRef.value
124
+ const newRows = Math.ceil((scrollHeight - padding) / lineHeight)
125
+
126
+ if (newRows > props.rows)
127
+ textareaRef.value.rows = props.maxRows ? Math.min(newRows, props.maxRows) : newRows
128
+
129
+ textareaRef.value.style.overflow = overflow
130
+ }
131
+
132
+ watch(modelValue, () => {
133
+ nextTick(autoResize)
134
+ })
135
+
136
+ defineExpose({
137
+ textareaRef,
138
+ })
139
+
140
+ onMounted(() => {
141
+ setTimeout(() => {
142
+ autoFocus()
143
+ }, props.autofocusDelay)
144
+ })
145
+ </script>
146
+
147
+ <template>
148
+ <Primitive
149
+ :as="props.as"
150
+ :class="style.root({ class: [props.class, props.ui?.root] })"
151
+ :aria-disabled="props.disabled ? true : undefined"
152
+ >
153
+ <textarea
154
+ :id="props.id"
155
+ ref="textareaRef"
156
+ :value="modelValue"
157
+ :name="props.name"
158
+ :rows="props.rows"
159
+ :placeholder="props.placeholder"
160
+ :class="style.base({ class: props.ui?.base })"
161
+ :disabled="props.disabled"
162
+ :required="props.required"
163
+ v-bind="$attrs"
164
+ @input="onInput"
165
+ @blur="onBlur"
166
+ @change="onChange"
167
+ @focus="autoResize"
168
+ >
169
+ </textarea>
170
+
171
+ <slot></slot>
172
+ </Primitive>
173
+ </template>
@@ -121,6 +121,6 @@ defineExpose({
121
121
  </ToastClose>
122
122
  </div>
123
123
 
124
- <div v-if="remaining > 0 && duration" :class="style.progress({ class: props.ui?.progress })" :style="{ width: `${remaining / duration * 100}%` }"></div>
124
+ <div v-if="remaining >= 0 && duration" :class="style.progress({ class: props.ui?.progress })" :style="{ width: `${remaining / duration * 100}%` }"></div>
125
125
  </ToastRoot>
126
126
  </template>
@@ -139,5 +139,39 @@ function getOffset(index: number) {
139
139
  </template>
140
140
 
141
141
  <style>
142
- @keyframes toast-collapsed-closed{0%{transform:var(--transform)}to{transform:translateY(calc((var(--before) - var(--height))*var(--gap))) scale(var(--scale))}}@keyframes toast-closed{0%{transform:var(--transform)}to{transform:translateY(calc((var(--offset) - var(--height))*var(--translate-factor)))}}@keyframes toast-slide-left{0%{transform:translateX(0) translateY(var(--translate))}to{transform:translateX(-100%) translateY(var(--translate))}}@keyframes toast-slide-right{0%{transform:translateX(0) translateY(var(--translate))}to{transform:translateX(100%) translateY(var(--translate))}}
142
+ @keyframes toast-collapsed-closed {
143
+ from {
144
+ transform: var(--transform);
145
+ }
146
+ to {
147
+ transform: translateY(calc((var(--before) - var(--height)) * var(--gap)))
148
+ scale(var(--scale));
149
+ }
150
+ }
151
+ @keyframes toast-closed {
152
+ from {
153
+ transform: var(--transform);
154
+ }
155
+ to {
156
+ transform: translateY(
157
+ calc((var(--offset) - var(--height)) * var(--translate-factor))
158
+ );
159
+ }
160
+ }
161
+ @keyframes toast-slide-left {
162
+ from {
163
+ transform: translateX(0) translateY(var(--translate));
164
+ }
165
+ to {
166
+ transform: translateX(-100%) translateY(var(--translate));
167
+ }
168
+ }
169
+ @keyframes toast-slide-right {
170
+ from {
171
+ transform: translateX(0) translateY(var(--translate));
172
+ }
173
+ to {
174
+ transform: translateX(100%) translateY(var(--translate));
175
+ }
176
+ }
143
177
  </style>