@byyuurin/ui 0.0.5 → 0.0.7

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 (160) hide show
  1. package/README.md +15 -11
  2. package/dist/module.cjs +5 -0
  3. package/dist/module.json +12 -0
  4. package/dist/{nuxt.mjs → module.mjs} +7 -6
  5. package/dist/module.mjs.map +1 -0
  6. package/dist/runtime/components/Accordion.vue +20 -31
  7. package/dist/runtime/components/Alert.vue +1 -1
  8. package/dist/runtime/components/App.vue +1 -1
  9. package/dist/runtime/components/Badge.vue +0 -1
  10. package/dist/runtime/components/Button.vue +14 -12
  11. package/dist/runtime/components/ButtonGroup.vue +47 -0
  12. package/dist/runtime/components/Card.vue +9 -6
  13. package/dist/runtime/components/Carousel.vue +310 -0
  14. package/dist/runtime/components/Checkbox.vue +3 -4
  15. package/dist/runtime/components/Chip.vue +9 -4
  16. package/dist/runtime/components/Collapsible.vue +56 -0
  17. package/dist/runtime/components/Drawer.vue +4 -2
  18. package/dist/runtime/components/Input.vue +12 -8
  19. package/dist/runtime/components/InputNumber.vue +167 -0
  20. package/dist/runtime/components/Link.vue +301 -72
  21. package/dist/runtime/components/LinkBase.vue +88 -0
  22. package/dist/runtime/components/Modal.vue +2 -4
  23. package/dist/runtime/components/Pagination.vue +167 -0
  24. package/dist/runtime/components/PinInput.vue +0 -1
  25. package/dist/runtime/components/RadioGroup.vue +0 -1
  26. package/dist/runtime/components/ScrollArea.vue +1 -1
  27. package/dist/runtime/components/Select.vue +9 -5
  28. package/dist/runtime/components/Separator.vue +63 -0
  29. package/dist/runtime/components/Slider.vue +0 -1
  30. package/dist/runtime/components/Switch.vue +4 -6
  31. package/dist/runtime/components/Table.vue +292 -0
  32. package/dist/runtime/components/Tabs.vue +17 -18
  33. package/dist/runtime/components/Textarea.vue +0 -1
  34. package/dist/runtime/components/Toast.vue +21 -10
  35. package/dist/runtime/components/Toaster.vue +4 -39
  36. package/dist/runtime/composables/useButtonGroup.d.ts +13 -0
  37. package/dist/runtime/composables/useButtonGroup.js +14 -0
  38. package/dist/runtime/composables/{useComponentIcons.mjs → useComponentIcons.js} +1 -1
  39. package/dist/runtime/composables/useModal.d.ts +1 -1
  40. package/dist/runtime/composables/{useModal.mjs → useModal.js} +1 -1
  41. package/dist/runtime/composables/useTheme.d.ts +4 -4
  42. package/dist/runtime/composables/{useTheme.mjs → useTheme.js} +4 -4
  43. package/dist/runtime/composables/useToast.d.ts +4 -4
  44. package/dist/runtime/composables/{useToast.mjs → useToast.js} +19 -6
  45. package/dist/runtime/index.d.ts +34 -0
  46. package/dist/runtime/index.js +34 -0
  47. package/dist/runtime/theme/accordion.d.ts +22 -5
  48. package/dist/runtime/theme/{accordion.mjs → accordion.js} +2 -2
  49. package/dist/runtime/theme/alert.d.ts +41 -1
  50. package/dist/runtime/theme/{alert.mjs → alert.js} +4 -4
  51. package/dist/runtime/theme/app.d.ts +8 -0
  52. package/dist/runtime/theme/app.js +18 -0
  53. package/dist/runtime/theme/badge.d.ts +48 -21
  54. package/dist/runtime/theme/{badge.mjs → badge.js} +5 -2
  55. package/dist/runtime/theme/button-group.d.ts +66 -0
  56. package/dist/runtime/theme/button-group.js +42 -0
  57. package/dist/runtime/theme/button.d.ts +68 -111
  58. package/dist/runtime/theme/button.js +164 -0
  59. package/dist/runtime/theme/card.d.ts +38 -19
  60. package/dist/runtime/theme/card.js +37 -0
  61. package/dist/runtime/theme/carousel.d.ts +113 -0
  62. package/dist/runtime/theme/carousel.js +43 -0
  63. package/dist/runtime/theme/checkbox.d.ts +4 -1
  64. package/dist/runtime/theme/{checkbox.mjs → checkbox.js} +7 -4
  65. package/dist/runtime/theme/chip.d.ts +56 -12
  66. package/dist/runtime/theme/{chip.mjs → chip.js} +10 -7
  67. package/dist/runtime/theme/collapsible.d.ts +38 -0
  68. package/dist/runtime/theme/collapsible.js +10 -0
  69. package/dist/runtime/theme/drawer.d.ts +71 -33
  70. package/dist/runtime/theme/{drawer.mjs → drawer.js} +33 -22
  71. package/dist/runtime/theme/index.d.ts +31 -24
  72. package/dist/runtime/theme/index.js +31 -0
  73. package/dist/runtime/theme/input-number.d.ts +135 -0
  74. package/dist/runtime/theme/input-number.js +92 -0
  75. package/dist/runtime/theme/input.d.ts +94 -111
  76. package/dist/runtime/theme/input.js +151 -0
  77. package/dist/runtime/theme/link.d.ts +14 -1
  78. package/dist/runtime/theme/{link.mjs → link.js} +1 -1
  79. package/dist/runtime/theme/modal.d.ts +33 -7
  80. package/dist/runtime/theme/{modal.mjs → modal.js} +8 -10
  81. package/dist/runtime/theme/pagination.d.ts +56 -0
  82. package/dist/runtime/theme/pagination.js +13 -0
  83. package/dist/runtime/theme/pinInput.d.ts +45 -42
  84. package/dist/runtime/theme/{pinInput.mjs → pinInput.js} +14 -11
  85. package/dist/runtime/theme/popover.d.ts +16 -5
  86. package/dist/runtime/theme/{radioGroup.d.ts → radio-group.d.ts} +4 -1
  87. package/dist/runtime/theme/{radioGroup.mjs → radio-group.js} +3 -0
  88. package/dist/runtime/theme/scroll-area.d.ts +73 -0
  89. package/dist/runtime/theme/{scrollArea.mjs → scroll-area.js} +2 -2
  90. package/dist/runtime/theme/select.d.ts +95 -99
  91. package/dist/runtime/theme/{select.mjs → select.js} +22 -17
  92. package/dist/runtime/theme/separator.d.ts +95 -0
  93. package/dist/runtime/theme/separator.js +53 -0
  94. package/dist/runtime/theme/slider.d.ts +4 -1
  95. package/dist/runtime/theme/{slider.mjs → slider.js} +6 -3
  96. package/dist/runtime/theme/switch.d.ts +4 -1
  97. package/dist/runtime/theme/{switch.mjs → switch.js} +5 -2
  98. package/dist/runtime/theme/table.d.ts +89 -0
  99. package/dist/runtime/theme/table.js +35 -0
  100. package/dist/runtime/theme/tabs.d.ts +72 -52
  101. package/dist/runtime/theme/{tabs.mjs → tabs.js} +15 -12
  102. package/dist/runtime/theme/textarea.d.ts +46 -37
  103. package/dist/runtime/theme/{textarea.mjs → textarea.js} +14 -11
  104. package/dist/runtime/theme/toast.d.ts +45 -7
  105. package/dist/runtime/theme/{toast.mjs → toast.js} +12 -7
  106. package/dist/runtime/theme/toaster.d.ts +89 -25
  107. package/dist/runtime/theme/{toaster.mjs → toaster.js} +5 -0
  108. package/dist/runtime/theme/tooltip.d.ts +20 -7
  109. package/dist/runtime/theme/{tooltip.mjs → tooltip.js} +2 -2
  110. package/dist/runtime/types/components.d.ts +7 -1
  111. package/dist/runtime/types/index.d.ts +4 -4
  112. package/dist/runtime/types/index.js +2 -0
  113. package/dist/runtime/types/utils.d.ts +1 -1
  114. package/dist/runtime/utils/index.d.ts +3 -3
  115. package/dist/runtime/utils/{index.mjs → index.js} +3 -3
  116. package/dist/runtime/utils/link.d.ts +22 -7
  117. package/dist/runtime/utils/link.js +30 -0
  118. package/dist/runtime/utils/styler.d.ts +2 -2
  119. package/dist/runtime/vue/stubs.d.ts +9 -0
  120. package/dist/runtime/vue/stubs.js +16 -0
  121. package/dist/shared/ui.d1728164.mjs +4 -0
  122. package/dist/shared/ui.d1728164.mjs.map +1 -0
  123. package/dist/types.d.mts +1 -0
  124. package/dist/types.d.ts +1 -0
  125. package/dist/{unocss-preset.d.ts → unocss.d.mts} +10 -15
  126. package/dist/{unocss-preset.d.mts → unocss.d.ts} +10 -15
  127. package/dist/{unocss-preset.mjs → unocss.mjs} +53 -21
  128. package/dist/unocss.mjs.map +1 -0
  129. package/dist/unplugin.d.mts +4 -3
  130. package/dist/unplugin.d.ts +4 -3
  131. package/dist/unplugin.mjs +49 -5
  132. package/dist/unplugin.mjs.map +1 -1
  133. package/dist/vite.d.mts +1 -1
  134. package/dist/vite.d.ts +1 -1
  135. package/dist/vite.mjs +7 -5
  136. package/dist/vite.mjs.map +1 -1
  137. package/package.json +59 -45
  138. package/dist/index.d.ts +0 -26
  139. package/dist/index.mjs +0 -26
  140. package/dist/nuxt.mjs.map +0 -1
  141. package/dist/runtime/theme/app.mjs +0 -10
  142. package/dist/runtime/theme/button.mjs +0 -143
  143. package/dist/runtime/theme/card.mjs +0 -14
  144. package/dist/runtime/theme/index.mjs +0 -24
  145. package/dist/runtime/theme/input.mjs +0 -146
  146. package/dist/runtime/theme/scrollArea.d.ts +0 -51
  147. package/dist/runtime/types/index.mjs +0 -2
  148. package/dist/runtime/utils/link.mjs +0 -4
  149. package/dist/shared/ui.CzDyI29e.mjs +0 -8
  150. package/dist/shared/ui.CzDyI29e.mjs.map +0 -1
  151. package/dist/unocss-preset.mjs.map +0 -1
  152. /package/{LICENSE.md → LICENSE} +0 -0
  153. /package/dist/{nuxt.d.mts → module.d.mts} +0 -0
  154. /package/dist/{nuxt.d.ts → module.d.ts} +0 -0
  155. /package/dist/runtime/composables/{defineInjection.mjs → defineInjection.js} +0 -0
  156. /package/dist/runtime/theme/{popover.mjs → popover.js} +0 -0
  157. /package/dist/runtime/types/{components.mjs → components.js} +0 -0
  158. /package/dist/runtime/types/{utils.mjs → utils.js} +0 -0
  159. /package/dist/runtime/utils/{extend-theme.mjs → extend-theme.js} +0 -0
  160. /package/dist/runtime/utils/{styler.mjs → styler.js} +0 -0
@@ -31,7 +31,6 @@ import { looseToNumber } from '../utils'
31
31
 
32
32
  const props = withDefaults(defineProps<PinInputProps>(), {
33
33
  variant: 'outline',
34
- size: 'md',
35
34
  length: 5,
36
35
  type: 'text',
37
36
  })
@@ -74,7 +74,6 @@ 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'> {}
@@ -105,13 +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 { useButtonGroup } from '../composables/useButtonGroup'
108
109
  import { useComponentIcons } from '../composables/useComponentIcons'
109
110
  import { useTheme } from '../composables/useTheme'
110
111
  import { compare, get } from '../utils'
111
112
 
112
113
  const props = withDefaults(defineProps<SelectProps<T, I, V, M>>(), {
113
114
  variant: 'outline',
114
- size: 'md',
115
115
  valueKey: 'value' as never,
116
116
  labelKey: 'label' as never,
117
117
  portal: true,
@@ -125,6 +125,8 @@ const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffse
125
125
  const arrowProps = toRef(() => props.arrow as SelectArrowProps)
126
126
 
127
127
  const { theme, createStyler } = useTheme()
128
+
129
+ const { size, orientation } = useButtonGroup(props)
128
130
  const { isPrefix, isSuffix, prefixIconName, suffixIconName } = useComponentIcons(toRef(() => defu(props, {
129
131
  suffixIcon: theme.value.app.icons.down,
130
132
  })))
@@ -136,6 +138,8 @@ const style = computed(() => {
136
138
  const styler = createStyler(theme.value.select)
137
139
  return styler({
138
140
  ...props,
141
+ size: size.value,
142
+ groupOrientation: orientation.value,
139
143
  prefix: isPrefix.value,
140
144
  suffix: isSuffix.value,
141
145
  })
@@ -194,7 +198,7 @@ function onUpdateOpen(value: boolean) {
194
198
  <SelectTrigger :id="props.id" :class="style.base({ class: [props.class, props.ui?.base] })">
195
199
  <span v-if="isPrefix || slots.prefix" :class="style.prefix({ class: props.ui?.prefix })">
196
200
  <slot name="prefix" :model-value="typedValue(innerValue)" :open="open" :ui="props.ui">
197
- <i v-if="isPrefix && prefixIconName" :class="style.prefixIcon({ class: [prefixIconName, props.ui?.prefixIcon] })"></i>
201
+ <span v-if="isPrefix && prefixIconName" :class="style.prefixIcon({ class: [prefixIconName, props.ui?.prefixIcon] })"></span>
198
202
  </slot>
199
203
  </span>
200
204
 
@@ -211,7 +215,7 @@ function onUpdateOpen(value: boolean) {
211
215
 
212
216
  <span v-if="isSuffix || !!slots.suffix" :class="style.suffix({ class: props.ui?.suffix })">
213
217
  <slot name="suffix" :model-value="typedValue(innerValue)" :open="open" :ui="props.ui">
214
- <i v-if="suffixIconName" :class="style.suffixIcon({ class: [suffixIconName, props.ui?.suffixIcon] })"></i>
218
+ <span v-if="suffixIconName" :class="style.suffixIcon({ class: [suffixIconName, props.ui?.suffixIcon] })"></span>
215
219
  </slot>
216
220
  </span>
217
221
  </SelectTrigger>
@@ -234,7 +238,7 @@ function onUpdateOpen(value: boolean) {
234
238
  >
235
239
  <slot name="item" :item="typedItem(item)" :index="index">
236
240
  <slot name="itemPrefix" :item="typedItem(item)" :index="index">
237
- <i v-if="item.icon" :class="style.itemPrefixIcon({ class: [item.icon, props.ui?.itemPrefixIcon] })"></i>
241
+ <span v-if="item.icon" :class="style.itemPrefixIcon({ class: [item.icon, props.ui?.itemPrefixIcon] })"></span>
238
242
  </slot>
239
243
 
240
244
  <SelectItemText :class="style.itemLabel({ class: props.ui?.itemLabel })">
@@ -247,7 +251,7 @@ function onUpdateOpen(value: boolean) {
247
251
  <slot name="itemSuffix" :item="typedItem(item)" :index="index"></slot>
248
252
 
249
253
  <SelectItemIndicator as-child>
250
- <i :class="style.itemSuffixIcon({ class: [props.selectedIcon || theme.app.icons.check, props.ui?.itemSuffixIcon] })"></i>
254
+ <span :class="style.itemSuffixIcon({ class: [props.selectedIcon || theme.app.icons.check, props.ui?.itemSuffixIcon] })"></span>
251
255
  </SelectItemIndicator>
252
256
  </span>
253
257
  </slot>
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ import type { VariantProps } from '@byyuurin/ui-kit'
3
+ import type { SeparatorProps as RekaSeparatorProps } from 'reka-ui'
4
+ import type { separator } from '../theme'
5
+ import type { ComponentAttrs } from '../types'
6
+
7
+ export interface SeparatorSlots {
8
+ default?: (props: {}) => any
9
+ }
10
+
11
+ type SeparatorVariants = VariantProps<typeof separator>
12
+
13
+ export interface SeparatorProps extends ComponentAttrs<typeof separator>, Pick<RekaSeparatorProps, 'as' | 'decorative'> {
14
+ orientation?: SeparatorVariants['orientation']
15
+ align?: 'start' | 'end' | 'center'
16
+ /** Display a label in the middle. */
17
+ label?: string
18
+ /**
19
+ * Display an icon in the middle.
20
+ */
21
+ icon?: string
22
+ }
23
+ </script>
24
+
25
+ <script setup lang="ts">
26
+ import { reactivePick } from '@vueuse/core'
27
+ import { Separator, useForwardProps } from 'reka-ui'
28
+ import { computed } from 'vue'
29
+ import { useTheme } from '../composables/useTheme'
30
+
31
+ const props = withDefaults(defineProps<SeparatorProps>(), {
32
+ orientation: 'horizontal',
33
+ position: 'center',
34
+ })
35
+
36
+ const slots = defineSlots<SeparatorSlots>()
37
+
38
+ const rootProps = useForwardProps(reactivePick(props, 'as', 'decorative', 'orientation'))
39
+
40
+ const { theme, createStyler } = useTheme()
41
+
42
+ const style = computed(() => {
43
+ const styler = createStyler(theme.value.separator)
44
+ return styler(props)
45
+ })
46
+ </script>
47
+
48
+ <template>
49
+ <Separator v-bind="rootProps" :class="style.root({ class: [props.class, props.ui?.root] })">
50
+ <div :class="style.line({ class: props.ui?.line, start: props.align === 'start' })"></div>
51
+
52
+ <template v-if="props.label || props.icon || slots.default">
53
+ <div :class="style.container({ class: props.ui?.container })">
54
+ <slot>
55
+ <span v-if="props.label" :class="style.label({ class: props.ui?.label })">{{ props.label }}</span>
56
+ <span v-else-if="props.icon" :class="style.icon({ class: [props.icon, props.ui?.icon] })"></span>
57
+ </slot>
58
+ </div>
59
+
60
+ <div :class="style.line({ class: props.ui?.line, end: props.align === 'end' })"></div>
61
+ </template>
62
+ </Separator>
63
+ </template>
@@ -31,7 +31,6 @@ import { computed } from 'vue'
31
31
  import { useTheme } from '../composables/useTheme'
32
32
 
33
33
  const props = withDefaults(defineProps<SliderProps>(), {
34
- size: 'md',
35
34
  orientation: 'horizontal',
36
35
  step: 1,
37
36
  max: 100,
@@ -40,9 +40,7 @@ import { Label, Primitive, SwitchRoot, SwitchThumb, useForwardProps } from 'reka
40
40
  import { computed, useId } from 'vue'
41
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 })
@@ -76,10 +74,10 @@ function onUpdate(value: any) {
76
74
  @update:model-value="onUpdate"
77
75
  >
78
76
  <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>
77
+ <span v-if="props.loading" :class="style.icon({ class: [theme.app.icons.loading, props.ui?.icon], checked: true, unchecked: true })"></span>
80
78
  <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>
79
+ <span v-if="props.checkedIcon" :class="style.icon({ class: [props.checkedIcon, props.ui?.icon], checked: true })"></span>
80
+ <span v-if="props.uncheckedIcon" :class="style.icon({ class: [props.uncheckedIcon, props.ui?.icon], unchecked: true })"></span>
83
81
  </template>
84
82
  </SwitchThumb>
85
83
  </SwitchRoot>
@@ -0,0 +1,292 @@
1
+ <script lang="ts">
2
+ import type { CellContext, ColumnDef, ColumnFiltersOptions, ColumnFiltersState, ColumnOrderState, ColumnPinningOptions, ColumnPinningState, ColumnSizingInfoState, ColumnSizingOptions, ColumnSizingState, CoreOptions, ExpandedOptions, ExpandedState, FacetedOptions, GlobalFilterOptions, GroupingOptions, GroupingState, HeaderContext, PaginationOptions, PaginationState, Row, RowData, RowPinningOptions, RowPinningState, RowSelectionOptions, RowSelectionState, SortingOptions, SortingState, Updater, VisibilityOptions, VisibilityState } from '@tanstack/vue-table'
3
+ import type { PrimitiveProps } from 'reka-ui'
4
+ import type { Ref } from 'vue'
5
+ import type { table } from '../theme'
6
+ import type { ComponentAttrs } from '../types'
7
+
8
+ export type TableData = RowData
9
+ export type TableColumn<T extends TableData, D = unknown> = ColumnDef<T, D> & { title?: string }
10
+
11
+ export interface TableOptions<T extends TableData> extends Omit<CoreOptions<T>, 'data' | 'columns' | 'getCoreRowModel' | 'state' | 'onStateChange' | 'renderFallbackValue'> {
12
+ state?: CoreOptions<T>['state']
13
+ onStateChange?: CoreOptions<T>['onStateChange']
14
+ renderFallbackValue?: CoreOptions<T>['renderFallbackValue']
15
+ }
16
+
17
+ type DynamicHeaderSlots<T, K = keyof T> = Record<string, (props: HeaderContext<T, unknown>) => any> & Record<`${K extends string ? K : never}-header`, (props: HeaderContext<T, unknown>) => any>
18
+ type DynamicCellSlots<T, K = keyof T> = Record<string, (props: CellContext<T, unknown>) => any> & Record<`${K extends string ? K : never}-cell`, (props: CellContext<T, unknown>) => any>
19
+
20
+ export type TableSlots<T> = {
21
+ expanded: (props: { row: Row<T> }) => any
22
+ empty: (props?: {}) => any
23
+ caption: (props?: {}) => any
24
+ } & DynamicHeaderSlots<T> & DynamicCellSlots<T>
25
+
26
+ export interface TableProps<T extends TableData> extends ComponentAttrs<typeof table>, Pick<PrimitiveProps, 'as'>, TableOptions<T> {
27
+ data?: T[]
28
+ columns?: TableColumn<T>[]
29
+ caption?: string
30
+ /**
31
+ * Whether the table should have a sticky header.
32
+ * @default false
33
+ */
34
+ sticky?: boolean
35
+ /**
36
+ * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/global-filtering#table-options)
37
+ * @link [Guide](https://tanstack.com/table/v8/docs/guide/global-filtering)
38
+ */
39
+ globalFilterOptions?: Omit<GlobalFilterOptions<T>, 'onGlobalFilterChange'>
40
+ /**
41
+ * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-filtering#table-options)
42
+ * @link [Guide](https://tanstack.com/table/v8/docs/guide/column-filtering)
43
+ */
44
+ columnFiltersOptions?: Omit<ColumnFiltersOptions<T>, 'getFilteredRowModel' | 'onColumnFiltersChange'>
45
+ /**
46
+ * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-pinning#table-options)
47
+ * @link [Guide](https://tanstack.com/table/v8/docs/guide/column-pinning)
48
+ */
49
+ columnPinningOptions?: Omit<ColumnPinningOptions, 'onColumnPinningChange'>
50
+ /**
51
+ * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-sizing#table-options)
52
+ * @link [Guide](https://tanstack.com/table/v8/docs/guide/column-sizing)
53
+ */
54
+ columnSizingOptions?: Omit<ColumnSizingOptions, 'onColumnSizingChange' | 'onColumnSizingInfoChange'>
55
+ /**
56
+ * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-visibility#table-options)
57
+ * @link [Guide](https://tanstack.com/table/v8/docs/guide/column-visibility)
58
+ */
59
+ visibilityOptions?: Omit<VisibilityOptions, 'onColumnVisibilityChange'>
60
+ /**
61
+ * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/sorting#table-options)
62
+ * @link [Guide](https://tanstack.com/table/v8/docs/guide/sorting)
63
+ */
64
+ sortingOptions?: Omit<SortingOptions<T>, 'getSortedRowModel' | 'onSortingChange'>
65
+ /**
66
+ * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/grouping#table-options)
67
+ * @link [Guide](https://tanstack.com/table/v8/docs/guide/grouping)
68
+ */
69
+ groupingOptions?: Omit<GroupingOptions, 'onGroupingChange'>
70
+ /**
71
+ * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/expanding#table-options)
72
+ * @link [Guide](https://tanstack.com/table/v8/docs/guide/expanding)
73
+ */
74
+ expandedOptions?: Omit<ExpandedOptions<T>, 'getExpandedRowModel' | 'onExpandedChange'>
75
+ /**
76
+ * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/row-selection#table-options)
77
+ * @link [Guide](https://tanstack.com/table/v8/docs/guide/row-selection)
78
+ */
79
+ rowSelectionOptions?: Omit<RowSelectionOptions<T>, 'onRowSelectionChange'>
80
+ /**
81
+ * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/row-pinning#table-options)
82
+ * @link [Guide](https://tanstack.com/table/v8/docs/guide/row-pinning)
83
+ */
84
+ rowPinningOptions?: Omit<RowPinningOptions<T>, 'onRowPinningChange'>
85
+ /**
86
+ * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/pagination#table-options)
87
+ * @link [Guide](https://tanstack.com/table/v8/docs/guide/pagination)
88
+ */
89
+ paginationOptions?: Omit<PaginationOptions, 'onPaginationChange'>
90
+ /**
91
+ * @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-faceting#table-options)
92
+ * @link [Guide](https://tanstack.com/table/v8/docs/guide/column-faceting)
93
+ */
94
+ facetedOptions?: FacetedOptions<T>
95
+ }
96
+ </script>
97
+
98
+ <script setup lang="ts" generic="T extends TableData">
99
+ import { FlexRender, getCoreRowModel, getExpandedRowModel, getFilteredRowModel, getSortedRowModel, useVueTable } from '@tanstack/vue-table'
100
+ import { reactiveOmit } from '@vueuse/core'
101
+ import { Primitive } from 'reka-ui'
102
+ import { upperFirst } from 'scule'
103
+ import { computed } from 'vue'
104
+ import { useTheme } from '../composables/useTheme'
105
+
106
+ const props = defineProps<TableProps<T>>()
107
+
108
+ defineSlots<TableSlots<T>>()
109
+
110
+ const globalFilterState = defineModel<string>('globalFilter', { default: undefined })
111
+ const columnFiltersState = defineModel<ColumnFiltersState>('columnFilters', { default: [] })
112
+ const columnOrderState = defineModel<ColumnOrderState>('columnOrder', { default: [] })
113
+ const columnVisibilityState = defineModel<VisibilityState>('columnVisibility', { default: {} })
114
+ const columnPinningState = defineModel<ColumnPinningState>('columnPinning', { default: {} })
115
+ const columnSizingState = defineModel<ColumnSizingState>('columnSizing', { default: {} })
116
+ const columnSizingInfoState = defineModel<ColumnSizingInfoState>('columnSizingInfo', { default: {} })
117
+ const rowSelectionState = defineModel<RowSelectionState>('rowSelection', { default: {} })
118
+ const rowPinningState = defineModel<RowPinningState>('rowPinning', { default: {} })
119
+ const sortingState = defineModel<SortingState>('sorting', { default: [] })
120
+ const groupingState = defineModel<GroupingState>('grouping', { default: [] })
121
+ const expandedState = defineModel<ExpandedState>('expanded', { default: {} })
122
+ const paginationState = defineModel<PaginationState>('pagination', { default: {} })
123
+
124
+ const data = computed(() => props.data ?? [])
125
+ const columns = computed<TableColumn<T>[]>(
126
+ () =>
127
+ props.columns ?? Object.keys(data.value[0] ?? {}).map(
128
+ (accessorKey: string) => ({ accessorKey, header: upperFirst(accessorKey) }),
129
+ ),
130
+ )
131
+
132
+ const tableApi = useVueTable({
133
+ ...reactiveOmit(props, 'data', 'columns', 'caption', 'sticky', 'class', 'ui'),
134
+ data,
135
+ columns: columns.value,
136
+ getCoreRowModel: getCoreRowModel(),
137
+
138
+ ...props.globalFilterOptions,
139
+ onGlobalFilterChange: (updaterOrValue) => valueUpdater(updaterOrValue, globalFilterState),
140
+
141
+ ...props.columnFiltersOptions,
142
+ getFilteredRowModel: getFilteredRowModel(),
143
+ onColumnFiltersChange: (updaterOrValue) => valueUpdater(updaterOrValue, columnFiltersState),
144
+ onColumnOrderChange: (updaterOrValue) => valueUpdater(updaterOrValue, columnOrderState),
145
+
146
+ ...props.visibilityOptions,
147
+ onColumnVisibilityChange: (updaterOrValue) => valueUpdater(updaterOrValue, columnVisibilityState),
148
+
149
+ ...props.columnPinningOptions,
150
+ onColumnPinningChange: (updaterOrValue) => valueUpdater(updaterOrValue, columnPinningState),
151
+
152
+ ...props.columnSizingOptions,
153
+ onColumnSizingChange: (updaterOrValue) => valueUpdater(updaterOrValue, columnSizingState),
154
+ onColumnSizingInfoChange: (updaterOrValue) => valueUpdater(updaterOrValue, columnSizingInfoState),
155
+
156
+ ...props.rowSelectionOptions,
157
+ onRowSelectionChange: (updaterOrValue) => valueUpdater(updaterOrValue, rowSelectionState),
158
+
159
+ ...props.rowPinningOptions,
160
+ onRowPinningChange: (updaterOrValue) => valueUpdater(updaterOrValue, rowPinningState),
161
+
162
+ ...props.sortingOptions,
163
+ getSortedRowModel: getSortedRowModel(),
164
+ onSortingChange: (updaterOrValue) => valueUpdater(updaterOrValue, sortingState),
165
+
166
+ ...props.groupingOptions,
167
+ onGroupingChange: (updaterOrValue) => valueUpdater(updaterOrValue, groupingState),
168
+
169
+ ...props.expandedOptions,
170
+ getExpandedRowModel: getExpandedRowModel(),
171
+ onExpandedChange: (updaterOrValue) => valueUpdater(updaterOrValue, expandedState),
172
+
173
+ ...props.paginationOptions,
174
+ onPaginationChange: (updaterOrValue) => valueUpdater(updaterOrValue, paginationState),
175
+
176
+ ...props.facetedOptions,
177
+ state: {
178
+ get globalFilter() {
179
+ return globalFilterState.value
180
+ },
181
+ get columnFilters() {
182
+ return columnFiltersState.value
183
+ },
184
+ get columnOrder() {
185
+ return columnOrderState.value
186
+ },
187
+ get columnVisibility() {
188
+ return columnVisibilityState.value
189
+ },
190
+ get columnPinning() {
191
+ return columnPinningState.value
192
+ },
193
+ get expanded() {
194
+ return expandedState.value
195
+ },
196
+ get rowSelection() {
197
+ return rowSelectionState.value
198
+ },
199
+ get sorting() {
200
+ return sortingState.value
201
+ },
202
+ get grouping() {
203
+ return groupingState.value
204
+ },
205
+ get rowPinning() {
206
+ return rowPinningState.value
207
+ },
208
+ get columnSizing() {
209
+ return columnSizingState.value
210
+ },
211
+ get columnSizingInfo() {
212
+ return columnSizingInfoState.value
213
+ },
214
+ get pagination() {
215
+ return paginationState.value
216
+ },
217
+ },
218
+ })
219
+
220
+ function valueUpdater<T extends Updater<any>>(updaterOrValue: T, ref: Ref) {
221
+ ref.value = typeof updaterOrValue === 'function' ? updaterOrValue(ref.value) : updaterOrValue
222
+ }
223
+
224
+ const { theme, createStyler } = useTheme()
225
+ const style = computed(() => {
226
+ const styler = createStyler(theme.value.table)
227
+ return styler(props)
228
+ })
229
+
230
+ defineExpose({
231
+ tableApi,
232
+ })
233
+ </script>
234
+
235
+ <template>
236
+ <Primitive :as="props.as" :class="style.root({ class: [props.class, props.ui?.root] })">
237
+ <table :class="style.base({ class: props.ui?.base })">
238
+ <caption v-if="props.caption" :class="style.caption({ class: props.caption })">
239
+ <slot name="caption">
240
+ {{ props.caption }}
241
+ </slot>
242
+ </caption>
243
+
244
+ <thead :class="style.thead({ class: props.ui?.thead })">
245
+ <tr v-for="headerGroup in tableApi.getHeaderGroups()" :key="headerGroup.id" :class="style.tr({ class: props.ui?.tr })">
246
+ <th
247
+ v-for="header in headerGroup.headers"
248
+ :key="header.id"
249
+ :data-pinned="header.column.getIsPinned()"
250
+ :class="style.th({ class: props.ui?.th, pinned: !!header.column.getIsPinned() })"
251
+ >
252
+ <slot :name="`${header.id}-header`" v-bind="header.getContext()">
253
+ <FlexRender v-if="!header.isPlaceholder" :render="header.column.columnDef.header" :props="header.getContext" />
254
+ </slot>
255
+ </th>
256
+ </tr>
257
+ </thead>
258
+
259
+ <tbody :class="style.tbody({ class: props.ui?.tbody })">
260
+ <template v-if="tableApi.getRowModel().rows.length > 0">
261
+ <template v-for="row in tableApi.getRowModel().rows" :key="row.id">
262
+ <tr :data-selected="row.getIsSelected()" :data-expanded="row.getIsExpanded()" :class="style.tr({ class: props.ui?.tr })">
263
+ <td
264
+ v-for="cell in row.getVisibleCells()"
265
+ :key="cell.id"
266
+ :data-pinned="cell.column.getIsPinned()"
267
+ :class="style.td({ class: props.ui?.td, pinned: !!cell.column.getIsPinned() })"
268
+ >
269
+ <slot :name="`${cell.column.id}-cell`" v-bind="cell.getContext()">
270
+ <FlexRender :render="cell.column.columnDef.cell" :props="cell.getContext()" />
271
+ </slot>
272
+ </td>
273
+ </tr>
274
+ <tr v-if="row.getIsExpanded()" :class="style.tr({ class: props.ui?.tr, expanded: true })">
275
+ <td :colspan="row.getAllCells().length" :class="style.td({ class: props.ui?.td })">
276
+ <slot name="expanded" :row="row"></slot>
277
+ </td>
278
+ </tr>
279
+ </template>
280
+ </template>
281
+
282
+ <tr v-else :class="style.tr({ class: props.ui?.tr })">
283
+ <td :colspan="columns.length" :class="style.empty({ class: props.ui?.empty })">
284
+ <slot name="empty">
285
+ Empty
286
+ </slot>
287
+ </td>
288
+ </tr>
289
+ </tbody>
290
+ </table>
291
+ </Primitive>
292
+ </template>
@@ -2,7 +2,7 @@
2
2
  import type { VariantProps } from '@byyuurin/ui-kit'
3
3
  import type { PrimitiveProps, TabsRootEmits, TabsRootProps } from 'reka-ui'
4
4
  import type { tabs } from '../theme'
5
- import type { ComponentAttrs, DynamicSlots } from '../types'
5
+ import type { ComponentAttrs } from '../types'
6
6
 
7
7
  export interface TabsItem {
8
8
  label?: string
@@ -14,6 +14,17 @@ export interface TabsItem {
14
14
  disabled?: boolean
15
15
  }
16
16
 
17
+ export interface TabsEmits extends TabsRootEmits<string | number> {}
18
+
19
+ type SlotProps<T> = (props: { item: T, index: number }) => any
20
+
21
+ export type TabsSlots<T extends { slot?: string }> = {
22
+ prefix?: SlotProps<T>
23
+ default?: SlotProps<T>
24
+ suffix?: SlotProps<T>
25
+ content?: SlotProps<T>
26
+ } & Record<string, SlotProps<T>>
27
+
17
28
  type TabsVariants = VariantProps<typeof tabs>
18
29
 
19
30
  export interface TabsProps<T> extends ComponentAttrs<typeof tabs>, Pick<TabsRootProps<string | number>, 'defaultValue' | 'modelValue' | 'activationMode' | 'unmountOnHide'> {
@@ -23,7 +34,7 @@ export interface TabsProps<T> extends ComponentAttrs<typeof tabs>, Pick<TabsRoot
23
34
  orientation?: TabsVariants['orientation']
24
35
  size?: TabsVariants['size']
25
36
  /** @default true */
26
- full?: boolean
37
+ evenly?: boolean
27
38
  /**
28
39
  * The content of the tabs, can be disabled to prevent rendering the content.
29
40
  * @default true
@@ -35,17 +46,6 @@ export interface TabsProps<T> extends ComponentAttrs<typeof tabs>, Pick<TabsRoot
35
46
  */
36
47
  labelKey?: string
37
48
  }
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
49
  </script>
50
50
 
51
51
  <script lang="ts" setup generic="T extends TabsItem">
@@ -59,16 +59,15 @@ const props = withDefaults(defineProps<TabsProps<T>>(), {
59
59
  defaultValue: '0',
60
60
  variant: 'solid',
61
61
  orientation: 'horizontal',
62
- size: 'md',
63
- full: true,
62
+ evenly: true,
64
63
  content: true,
65
64
  labelKey: 'label',
66
65
  })
67
66
 
68
- const emits = defineEmits<TabsEmits>()
67
+ const emit = defineEmits<TabsEmits>()
69
68
  const slots = defineSlots<TabsSlots<T>>()
70
69
 
71
- const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'orientation', 'activationMode', 'unmountOnHide'), emits)
70
+ const rootProps = useForwardPropsEmits(reactivePick(props, 'as', 'modelValue', 'defaultValue', 'orientation', 'activationMode', 'unmountOnHide'), emit)
72
71
 
73
72
  const { theme, createStyler } = useTheme()
74
73
  const style = computed(() => {
@@ -90,7 +89,7 @@ const style = computed(() => {
90
89
  :class="style.trigger({ class: props.ui?.trigger })"
91
90
  >
92
91
  <slot name="prefix" :item="item" :index="index">
93
- <i v-if="item.icon" :class="style.prefixIcon({ class: [item.icon, props.ui?.prefixIcon] })"></i>
92
+ <span v-if="item.icon" :class="style.prefixIcon({ class: [item.icon, props.ui?.prefixIcon] })"></span>
94
93
  </slot>
95
94
 
96
95
  <span v-if="get(item, props.labelKey) || slots.default" :class="style.label({ class: props.ui?.label })">
@@ -49,7 +49,6 @@ defineOptions({
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,