@byyuurin/ui 0.0.9 → 0.0.11

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 (215) hide show
  1. package/README.md +2 -5
  2. package/dist/module.json +3 -3
  3. package/dist/module.mjs +1 -1
  4. package/dist/module.mjs.map +1 -1
  5. package/dist/runtime/app/injections.d.ts +9323 -3
  6. package/dist/runtime/app/injections.js +35 -0
  7. package/dist/runtime/components/Accordion.vue +36 -69
  8. package/dist/runtime/components/Accordion.vue.d.ts +52 -0
  9. package/dist/runtime/components/Alert.vue +37 -75
  10. package/dist/runtime/components/Alert.vue.d.ts +59 -0
  11. package/dist/runtime/components/App.vue +25 -40
  12. package/dist/runtime/components/App.vue.d.ts +24 -0
  13. package/dist/runtime/components/Avatar.vue +31 -51
  14. package/dist/runtime/components/Avatar.vue.d.ts +25 -0
  15. package/dist/runtime/components/AvatarGroup.vue +38 -69
  16. package/dist/runtime/components/AvatarGroup.vue.d.ts +27 -0
  17. package/dist/runtime/components/Badge.vue +25 -51
  18. package/dist/runtime/components/Badge.vue.d.ts +44 -0
  19. package/dist/runtime/components/Breadcrumb.vue +35 -77
  20. package/dist/runtime/components/Breadcrumb.vue.d.ts +52 -0
  21. package/dist/runtime/components/Button.vue +62 -51
  22. package/dist/runtime/components/Button.vue.d.ts +29 -0
  23. package/dist/runtime/components/ButtonGroup.vue +17 -37
  24. package/dist/runtime/components/ButtonGroup.vue.d.ts +26 -0
  25. package/dist/runtime/components/Calendar.vue +75 -101
  26. package/dist/runtime/components/Calendar.vue.d.ts +75 -0
  27. package/dist/runtime/components/Card.vue +25 -42
  28. package/dist/runtime/components/Card.vue.d.ts +30 -0
  29. package/dist/runtime/components/Carousel.vue +118 -223
  30. package/dist/runtime/components/Carousel.vue.d.ts +104 -0
  31. package/dist/runtime/components/Checkbox.vue +49 -71
  32. package/dist/runtime/components/Checkbox.vue.d.ts +56 -0
  33. package/dist/runtime/components/Chip.vue +31 -48
  34. package/dist/runtime/components/Chip.vue.d.ts +30 -0
  35. package/dist/runtime/components/Collapsible.vue +22 -30
  36. package/dist/runtime/components/Collapsible.vue.d.ts +26 -0
  37. package/dist/runtime/components/Drawer.vue +52 -102
  38. package/dist/runtime/components/Drawer.vue.d.ts +80 -0
  39. package/dist/runtime/components/DropdownMenu.vue +65 -0
  40. package/dist/runtime/components/DropdownMenu.vue.d.ts +99 -0
  41. package/dist/runtime/components/DropdownMenuContent.vue +192 -0
  42. package/dist/runtime/components/DropdownMenuContent.vue.d.ts +39 -0
  43. package/dist/runtime/components/Form.vue +197 -0
  44. package/dist/runtime/components/Form.vue.d.ts +78 -0
  45. package/dist/runtime/components/FormItem.vue +90 -0
  46. package/dist/runtime/components/FormItem.vue.d.ts +60 -0
  47. package/dist/runtime/components/Input.vue +93 -115
  48. package/dist/runtime/components/Input.vue.d.ts +64 -0
  49. package/dist/runtime/components/InputNumber.vue +81 -116
  50. package/dist/runtime/components/InputNumber.vue.d.ts +245 -0
  51. package/dist/runtime/components/Kbd.vue +18 -39
  52. package/dist/runtime/components/Kbd.vue.d.ts +28 -0
  53. package/dist/runtime/components/Link.vue +170 -244
  54. package/dist/runtime/components/Link.vue.d.ts +95 -0
  55. package/dist/runtime/components/LinkBase.vue +36 -54
  56. package/dist/runtime/components/LinkBase.vue.d.ts +28 -0
  57. package/dist/runtime/components/Modal.vue +50 -85
  58. package/dist/runtime/components/Modal.vue.d.ts +66 -0
  59. package/dist/runtime/components/OverlayProvider.vue +10 -14
  60. package/dist/runtime/components/OverlayProvider.vue.d.ts +2 -0
  61. package/dist/runtime/components/Pagination.vue +55 -121
  62. package/dist/runtime/components/Pagination.vue.d.ts +93 -0
  63. package/dist/runtime/components/PinInput.vue +57 -57
  64. package/dist/runtime/components/PinInput.vue.d.ts +35 -0
  65. package/dist/runtime/components/Popover.vue +39 -68
  66. package/dist/runtime/components/Popover.vue.d.ts +45 -0
  67. package/dist/runtime/components/Progress.vue +68 -120
  68. package/dist/runtime/components/Progress.vue.d.ts +54 -0
  69. package/dist/runtime/components/RadioGroup.vue +75 -129
  70. package/dist/runtime/components/RadioGroup.vue.d.ts +74 -0
  71. package/dist/runtime/components/ScrollArea.vue +31 -31
  72. package/dist/runtime/components/ScrollArea.vue.d.ts +17 -0
  73. package/dist/runtime/components/Select.vue +119 -199
  74. package/dist/runtime/components/Select.vue.d.ts +119 -0
  75. package/dist/runtime/components/Separator.vue +26 -44
  76. package/dist/runtime/components/Separator.vue.d.ts +27 -0
  77. package/dist/runtime/components/Skeleton.vue +12 -21
  78. package/dist/runtime/components/Skeleton.vue.d.ts +19 -0
  79. package/dist/runtime/components/Slider.vue +54 -71
  80. package/dist/runtime/components/Slider.vue.d.ts +36 -0
  81. package/dist/runtime/components/Switch.vue +54 -68
  82. package/dist/runtime/components/Switch.vue.d.ts +49 -0
  83. package/dist/runtime/components/Table.vue +113 -186
  84. package/dist/runtime/components/Table.vue.d.ts +148 -0
  85. package/dist/runtime/components/Tabs.vue +35 -79
  86. package/dist/runtime/components/Tabs.vue.d.ts +65 -0
  87. package/dist/runtime/components/Textarea.vue +82 -123
  88. package/dist/runtime/components/Textarea.vue.d.ts +60 -0
  89. package/dist/runtime/components/Toast.vue +51 -76
  90. package/dist/runtime/components/Toast.vue.d.ts +131 -0
  91. package/dist/runtime/components/ToastProvider.vue +65 -101
  92. package/dist/runtime/components/ToastProvider.vue.d.ts +38 -0
  93. package/dist/runtime/components/Tooltip.vue +36 -47
  94. package/dist/runtime/components/Tooltip.vue.d.ts +31 -0
  95. package/dist/runtime/composables/useAvatarGroup.d.ts +1 -1
  96. package/dist/runtime/composables/useButtonGroup.d.ts +2 -2
  97. package/dist/runtime/composables/useFormItem.d.ts +27 -0
  98. package/dist/runtime/composables/useFormItem.js +64 -0
  99. package/dist/runtime/composables/useKbd.d.ts +1 -1
  100. package/dist/runtime/composables/useLocale.d.ts +3 -3
  101. package/dist/runtime/composables/useTheme.d.ts +1 -1
  102. package/dist/runtime/composables/useTheme.js +2 -1
  103. package/dist/runtime/composables/useToast.d.ts +1 -1
  104. package/dist/runtime/index.d.ts +3 -0
  105. package/dist/runtime/index.js +3 -0
  106. package/dist/runtime/locale/en.d.ts +1 -1
  107. package/dist/runtime/locale/zh-tw.d.ts +1 -1
  108. package/dist/runtime/theme/accordion.d.ts +45 -51
  109. package/dist/runtime/theme/accordion.js +1 -1
  110. package/dist/runtime/theme/alert.d.ts +115 -121
  111. package/dist/runtime/theme/alert.js +1 -1
  112. package/dist/runtime/theme/app.d.ts +1 -0
  113. package/dist/runtime/theme/app.js +2 -1
  114. package/dist/runtime/theme/avatar-group.d.ts +42 -48
  115. package/dist/runtime/theme/avatar-group.js +1 -1
  116. package/dist/runtime/theme/avatar.d.ts +46 -52
  117. package/dist/runtime/theme/avatar.js +1 -1
  118. package/dist/runtime/theme/badge.d.ts +63 -93
  119. package/dist/runtime/theme/badge.js +1 -1
  120. package/dist/runtime/theme/breadcrumb.d.ts +52 -58
  121. package/dist/runtime/theme/breadcrumb.js +1 -1
  122. package/dist/runtime/theme/button-group.d.ts +36 -42
  123. package/dist/runtime/theme/button.d.ts +165 -117
  124. package/dist/runtime/theme/button.js +1 -1
  125. package/dist/runtime/theme/calendar.d.ts +52 -50
  126. package/dist/runtime/theme/calendar.js +20 -3
  127. package/dist/runtime/theme/card.d.ts +52 -58
  128. package/dist/runtime/theme/card.js +1 -1
  129. package/dist/runtime/theme/carousel.d.ts +98 -104
  130. package/dist/runtime/theme/carousel.js +1 -1
  131. package/dist/runtime/theme/checkbox.d.ts +77 -83
  132. package/dist/runtime/theme/checkbox.js +1 -1
  133. package/dist/runtime/theme/chip.d.ts +50 -89
  134. package/dist/runtime/theme/chip.js +1 -1
  135. package/dist/runtime/theme/collapsible.d.ts +29 -35
  136. package/dist/runtime/theme/collapsible.js +1 -1
  137. package/dist/runtime/theme/drawer.d.ts +131 -102
  138. package/dist/runtime/theme/drawer.js +1 -1
  139. package/dist/runtime/theme/dropdown-menu.d.ts +65 -0
  140. package/dist/runtime/theme/dropdown-menu.js +83 -0
  141. package/dist/runtime/theme/form-item.d.ts +70 -0
  142. package/dist/runtime/theme/form-item.js +34 -0
  143. package/dist/runtime/theme/form.d.ts +2 -0
  144. package/dist/runtime/theme/form.js +7 -0
  145. package/dist/runtime/theme/index.d.ts +3 -0
  146. package/dist/runtime/theme/index.js +3 -0
  147. package/dist/runtime/theme/input-number.d.ts +100 -126
  148. package/dist/runtime/theme/input-number.js +1 -1
  149. package/dist/runtime/theme/input.d.ts +153 -131
  150. package/dist/runtime/theme/input.js +3 -3
  151. package/dist/runtime/theme/kbd.d.ts +30 -36
  152. package/dist/runtime/theme/link.d.ts +37 -43
  153. package/dist/runtime/theme/modal.d.ts +35 -69
  154. package/dist/runtime/theme/modal.js +1 -1
  155. package/dist/runtime/theme/pagination.d.ts +71 -77
  156. package/dist/runtime/theme/pagination.js +1 -1
  157. package/dist/runtime/theme/pinInput.d.ts +82 -88
  158. package/dist/runtime/theme/pinInput.js +2 -2
  159. package/dist/runtime/theme/popover.d.ts +29 -35
  160. package/dist/runtime/theme/popover.js +1 -1
  161. package/dist/runtime/theme/progress.d.ts +167 -109
  162. package/dist/runtime/theme/progress.js +1 -1
  163. package/dist/runtime/theme/radio-group.d.ts +99 -105
  164. package/dist/runtime/theme/radio-group.js +1 -1
  165. package/dist/runtime/theme/scroll-area.d.ts +62 -68
  166. package/dist/runtime/theme/scroll-area.js +1 -1
  167. package/dist/runtime/theme/select.d.ts +168 -158
  168. package/dist/runtime/theme/select.js +3 -2
  169. package/dist/runtime/theme/separator.d.ts +64 -85
  170. package/dist/runtime/theme/separator.js +1 -1
  171. package/dist/runtime/theme/skeleton.d.ts +1 -7
  172. package/dist/runtime/theme/slider.d.ts +62 -68
  173. package/dist/runtime/theme/slider.js +1 -1
  174. package/dist/runtime/theme/switch.d.ts +111 -117
  175. package/dist/runtime/theme/switch.js +1 -1
  176. package/dist/runtime/theme/table.d.ts +75 -78
  177. package/dist/runtime/theme/table.js +3 -2
  178. package/dist/runtime/theme/tabs.d.ts +116 -139
  179. package/dist/runtime/theme/tabs.js +1 -1
  180. package/dist/runtime/theme/textarea.d.ts +78 -90
  181. package/dist/runtime/theme/textarea.js +2 -2
  182. package/dist/runtime/theme/toast-provider.d.ts +110 -131
  183. package/dist/runtime/theme/toast-provider.js +1 -1
  184. package/dist/runtime/theme/toast.d.ts +74 -80
  185. package/dist/runtime/theme/toast.js +1 -1
  186. package/dist/runtime/theme/tooltip.d.ts +35 -41
  187. package/dist/runtime/theme/tooltip.js +1 -1
  188. package/dist/runtime/types/components.d.ts +3 -0
  189. package/dist/runtime/types/form.d.ts +45 -0
  190. package/dist/runtime/types/form.js +0 -0
  191. package/dist/runtime/types/index.d.ts +5 -2
  192. package/dist/runtime/types/index.js +1 -0
  193. package/dist/runtime/types/utils.d.ts +37 -16
  194. package/dist/runtime/utils/extend-theme.js +15 -4
  195. package/dist/runtime/utils/form.d.ts +5 -0
  196. package/dist/runtime/utils/form.js +24 -0
  197. package/dist/runtime/utils/index.d.ts +2 -0
  198. package/dist/runtime/utils/index.js +4 -0
  199. package/dist/runtime/utils/link.d.ts +4 -28
  200. package/dist/runtime/utils/link.js +10 -3
  201. package/dist/runtime/utils/styler.d.ts +2 -2
  202. package/dist/runtime/utils/styler.js +2 -2
  203. package/dist/shared/ui.D1BTWZFB.mjs +5 -0
  204. package/dist/shared/ui.D1BTWZFB.mjs.map +1 -0
  205. package/dist/types.d.mts +1 -1
  206. package/dist/unocss.mjs +7 -6
  207. package/dist/unocss.mjs.map +1 -1
  208. package/dist/unplugin.mjs +1 -1
  209. package/dist/unplugin.mjs.map +1 -1
  210. package/dist/vite.mjs +1 -1
  211. package/package.json +78 -74
  212. package/dist/module.cjs +0 -5
  213. package/dist/shared/ui.1a1f119c.mjs +0 -5
  214. package/dist/shared/ui.1a1f119c.mjs.map +0 -1
  215. package/dist/types.d.ts +0 -1
@@ -0,0 +1,80 @@
1
+ import type { VariantProps } from '@byyuurin/ui-kit';
2
+ import type { DialogContentEmits, DialogContentProps, DialogRootEmits, DialogRootProps } from 'reka-ui';
3
+ import type { drawer } from '../theme/index.js';
4
+ import type { ButtonProps, ComponentAttrs, EmitsToProps } from '../types/index.js';
5
+ export interface DrawerEmits extends DialogRootEmits {
6
+ 'after-leave': [];
7
+ }
8
+ export interface DrawerSlots {
9
+ default?: any;
10
+ content?: any;
11
+ header?: any;
12
+ title?: any;
13
+ description?: any;
14
+ close?: (props: {
15
+ ui: ComponentAttrs<typeof drawer>['ui'];
16
+ }) => any;
17
+ body?: any;
18
+ footer?: any;
19
+ }
20
+ type DrawerVariants = VariantProps<typeof drawer>;
21
+ export interface DrawerProps extends ComponentAttrs<typeof drawer>, DialogRootProps {
22
+ title?: string;
23
+ description?: string;
24
+ /** The content of the drawer. */
25
+ content?: Omit<DialogContentProps, 'as' | 'asChild' | 'forceMount'> & Partial<EmitsToProps<DialogContentEmits>>;
26
+ /**
27
+ * Render an overlay behind the drawer.
28
+ * @default true
29
+ */
30
+ overlay?: boolean;
31
+ /** @default true */
32
+ transition?: boolean;
33
+ /**
34
+ * The direction of the drawer.
35
+ * @default "bottom"
36
+ */
37
+ direction?: DrawerVariants['direction'];
38
+ /**
39
+ * Whether to inset the drawer from the edges.
40
+ */
41
+ inset?: boolean;
42
+ /**
43
+ * Render the drawer in a portal.
44
+ * @default true
45
+ */
46
+ portal?: boolean;
47
+ /**
48
+ * Display a close button to dismiss the drawer.
49
+ * @default true
50
+ */
51
+ close?: ButtonProps | boolean;
52
+ /** @default app.icons.close */
53
+ closeIcon?: string;
54
+ /**
55
+ * When `false`, the drawer will not close when clicking outside or pressing escape.
56
+ * @default true
57
+ */
58
+ dismissible?: boolean;
59
+ }
60
+ declare const _default: __VLS_WithSlots<import("vue").DefineComponent<DrawerProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
61
+ "update:open": (value: boolean) => any;
62
+ "after-leave": () => any;
63
+ }, string, import("vue").PublicProps, Readonly<DrawerProps> & Readonly<{
64
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
65
+ "onAfter-leave"?: (() => any) | undefined;
66
+ }>, {
67
+ close: ButtonProps | boolean;
68
+ overlay: boolean;
69
+ direction: "top" | "bottom" | "left" | "right";
70
+ transition: boolean;
71
+ modal: boolean;
72
+ portal: boolean;
73
+ dismissible: boolean;
74
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, DrawerSlots>;
75
+ export default _default;
76
+ type __VLS_WithSlots<T, S> = T & {
77
+ new (): {
78
+ $slots: S;
79
+ };
80
+ };
@@ -0,0 +1,65 @@
1
+ <script>
2
+
3
+ </script>
4
+
5
+ <script setup>
6
+ import { reactivePick } from "@vueuse/core";
7
+ import { DropdownMenuArrow, DropdownMenuRoot, DropdownMenuTrigger, useForwardPropsEmits } from "reka-ui";
8
+ import { computed, toRef } from "vue";
9
+ import { useTheme } from "../composables/useTheme";
10
+ import { omit } from "../utils";
11
+ import DropdownMenuContent from "./DropdownMenuContent.vue";
12
+ const props = defineProps({
13
+ size: { type: null, required: false },
14
+ items: { type: null, required: false },
15
+ checkedIcon: { type: String, required: false },
16
+ loadingIcon: { type: String, required: false },
17
+ externalIcon: { type: [Boolean, String], required: false, default: true },
18
+ content: { type: Object, required: false },
19
+ arrow: { type: [Boolean, Object], required: false },
20
+ portal: { type: Boolean, required: false, default: true },
21
+ labelKey: { type: null, required: false, default: "label" },
22
+ disabled: { type: Boolean, required: false },
23
+ class: { type: null, required: false },
24
+ ui: { type: null, required: false },
25
+ defaultOpen: { type: Boolean, required: false },
26
+ open: { type: Boolean, required: false },
27
+ modal: { type: Boolean, required: false, default: true }
28
+ });
29
+ const emit = defineEmits(["update:open"]);
30
+ const slots = defineSlots();
31
+ const rootProps = useForwardPropsEmits(reactivePick(props, "defaultOpen", "open", "modal"), emit);
32
+ const contentProps = toRef(() => ({ side: "bottom", sideOffset: 8, collisionPadding: 8, ...props.content }));
33
+ const arrowProps = toRef(() => props.arrow);
34
+ const proxySlots = omit(slots, ["default"]);
35
+ const { generateStyle } = useTheme();
36
+ const style = computed(() => generateStyle("dropdownMenu", props));
37
+ </script>
38
+
39
+ <template>
40
+ <DropdownMenuRoot v-slot="{ open }" v-bind="rootProps">
41
+ <DropdownMenuTrigger v-if="slots.default" as-child :class="props.class" :disabled="props.disabled">
42
+ <slot :open="open"></slot>
43
+ </DropdownMenuTrigger>
44
+
45
+ <DropdownMenuContent
46
+ :class="style.content({ class: [!slots.default && props.class, props.ui?.content] })"
47
+ data-part="content"
48
+ :ui="props.ui"
49
+ v-bind="contentProps"
50
+ :size="props.size"
51
+ :items="props.items"
52
+ :portal="props.portal"
53
+ :label-key="props.labelKey"
54
+ :checked-icon="props.checkedIcon"
55
+ :loading-icon="props.loadingIcon"
56
+ :external-icon="props.externalIcon"
57
+ >
58
+ <template v-for="(_, name) in proxySlots" #[name]="slotProps">
59
+ <slot :name="name" v-bind="slotProps"></slot>
60
+ </template>
61
+
62
+ <DropdownMenuArrow v-if="props.arrow" v-bind="arrowProps" :class="style.arrow({ class: props.ui?.arrow })" data-part="arrow" />
63
+ </DropdownMenuContent>
64
+ </DropdownMenuRoot>
65
+ </template>
@@ -0,0 +1,99 @@
1
+ import type { VariantProps } from '@byyuurin/ui-kit';
2
+ import type { DropdownMenuArrowProps, DropdownMenuContentEmits, DropdownMenuContentProps, DropdownMenuRootEmits, DropdownMenuRootProps } from 'reka-ui';
3
+ import type { dropdownMenu } from '../theme/index.js';
4
+ import type { ArrayOrNested, AvatarProps, ComponentAttrs, DynamicSlots, EmitsToProps, KbdProps, LinkProps, MergeTypes, NestedItem } from '../types/index.js';
5
+ export interface DropdownMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'custom' | 'underline'> {
6
+ icon?: string;
7
+ avatar?: AvatarProps;
8
+ content?: Omit<DropdownMenuContentProps, 'as' | 'asChild' | 'forceMount'> & Partial<EmitsToProps<DropdownMenuContentEmits>>;
9
+ kbds?: Array<string | KbdProps['value']>;
10
+ /**
11
+ * The item type.
12
+ * @default 'link'
13
+ */
14
+ type?: 'label' | 'separator' | 'link' | 'checkbox';
15
+ slot?: string;
16
+ loading?: boolean;
17
+ disabled?: boolean;
18
+ checked?: boolean;
19
+ open?: boolean;
20
+ defaultOpen?: boolean;
21
+ children?: ArrayOrNested<DropdownMenuItem>;
22
+ onSelect?: (e: Event) => void;
23
+ onUpdateChecked?: (checked: boolean) => void;
24
+ [key: string]: any;
25
+ }
26
+ type SlotProps<T extends DropdownMenuItem> = (props: {
27
+ item: T;
28
+ active?: boolean;
29
+ index: number;
30
+ }) => any;
31
+ export type DropdownMenuSlots<T extends ArrayOrNested<DropdownMenuItem> = ArrayOrNested<DropdownMenuItem>, I extends NestedItem<T> = NestedItem<T>> = {
32
+ 'default'?: (props: {
33
+ open: boolean;
34
+ }) => any;
35
+ 'item'?: SlotProps<I>;
36
+ 'item-leading'?: SlotProps<I>;
37
+ 'item-label'?: SlotProps<I>;
38
+ 'item-trailing'?: SlotProps<I>;
39
+ } & DynamicSlots<MergeTypes<I>, 'leading' | 'label' | 'trailing', SlotProps<I>>;
40
+ export interface DropdownMenuEmits extends DropdownMenuRootEmits {
41
+ }
42
+ type DropdownMenuVariants = VariantProps<typeof dropdownMenu>;
43
+ export interface DropdownMenuProps<T extends ArrayOrNested<DropdownMenuItem> = ArrayOrNested<DropdownMenuItem>> extends ComponentAttrs<typeof dropdownMenu>, Omit<DropdownMenuRootProps, 'dir'> {
44
+ /** @default "md" */
45
+ size?: DropdownMenuVariants['size'];
46
+ items?: T;
47
+ /**
48
+ * The icon displayed when an item is checked.
49
+ * @default app.icons.check
50
+ */
51
+ checkedIcon?: string;
52
+ /**
53
+ * The icon displayed when an item is loading.
54
+ * @default app.icons.loading
55
+ */
56
+ loadingIcon?: string;
57
+ /**
58
+ * The icon displayed when the item is an external link.
59
+ * Set to `false` to hide the external icon.
60
+ * @default app.icons.external
61
+ */
62
+ externalIcon?: boolean | string;
63
+ /**
64
+ * The content of the menu.
65
+ * @default { side: 'bottom', sideOffset: 8, collisionPadding: 8 }
66
+ */
67
+ content?: Omit<DropdownMenuContentProps, 'as' | 'asChild' | 'forceMount'> & Partial<EmitsToProps<DropdownMenuContentEmits>>;
68
+ /**
69
+ * Display an arrow alongside the menu.
70
+ * @default false
71
+ */
72
+ arrow?: boolean | Omit<DropdownMenuArrowProps, 'as' | 'asChild'>;
73
+ /**
74
+ * Render the menu in a portal.
75
+ * @default true
76
+ */
77
+ portal?: boolean;
78
+ /**
79
+ * The key used to get the label from the item.
80
+ * @default "label"
81
+ */
82
+ labelKey?: keyof NestedItem<T>;
83
+ disabled?: boolean;
84
+ }
85
+ declare const _default: <T extends ArrayOrNested<DropdownMenuItem>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
86
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
87
+ readonly "onUpdate:open"?: ((payload: boolean) => any) | undefined;
88
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onUpdate:open"> & DropdownMenuProps<T> & Partial<{}>> & import("vue").PublicProps;
89
+ expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
90
+ attrs: any;
91
+ slots: DropdownMenuSlots<T, NestedItem<T>>;
92
+ emit: (evt: "update:open", payload: boolean) => void;
93
+ }>) => import("vue").VNode & {
94
+ __ctx?: Awaited<typeof __VLS_setup>;
95
+ };
96
+ export default _default;
97
+ type __VLS_PrettifyLocal<T> = {
98
+ [K in keyof T]: T[K];
99
+ } & {};
@@ -0,0 +1,192 @@
1
+ <script>
2
+
3
+ </script>
4
+
5
+ <script setup>
6
+ import { createReusableTemplate, reactiveOmit } from "@vueuse/core";
7
+ import { useForwardPropsEmits } from "reka-ui";
8
+ import { DropdownMenu } from "reka-ui/namespaced";
9
+ import { computed } from "vue";
10
+ import { useTheme } from "../composables/useTheme";
11
+ import { get, isArrayOfArray, omit } from "../utils";
12
+ import { pickLinkProps } from "../utils/link";
13
+ import Avatar from "./Avatar.vue";
14
+ import DropdownMenuContent from "./DropdownMenuContent.vue";
15
+ import Kbd from "./Kbd.vue";
16
+ import Link from "./Link.vue";
17
+ import LinkBase from "./LinkBase.vue";
18
+ defineOptions({
19
+ inheritAttrs: false
20
+ });
21
+ const props = defineProps({
22
+ size: { type: null, required: false },
23
+ items: { type: null, required: false },
24
+ portal: { type: Boolean, required: false },
25
+ sub: { type: Boolean, required: false },
26
+ labelKey: { type: null, required: true },
27
+ checkedIcon: { type: String, required: false },
28
+ loadingIcon: { type: String, required: false },
29
+ externalIcon: { type: [Boolean, String], required: false },
30
+ class: { type: null, required: false },
31
+ ui: { type: null, required: false },
32
+ loop: { type: Boolean, required: false },
33
+ side: { type: null, required: false },
34
+ sideOffset: { type: Number, required: false },
35
+ align: { type: null, required: false },
36
+ alignOffset: { type: Number, required: false },
37
+ avoidCollisions: { type: Boolean, required: false },
38
+ collisionBoundary: { type: null, required: false },
39
+ collisionPadding: { type: [Number, Object], required: false },
40
+ arrowPadding: { type: Number, required: false },
41
+ sticky: { type: String, required: false },
42
+ hideWhenDetached: { type: Boolean, required: false },
43
+ positionStrategy: { type: String, required: false },
44
+ updatePositionStrategy: { type: String, required: false },
45
+ disableUpdateOnLayoutShift: { type: Boolean, required: false },
46
+ prioritizePosition: { type: Boolean, required: false },
47
+ reference: { type: null, required: false }
48
+ });
49
+ const emit = defineEmits(["escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "closeAutoFocus"]);
50
+ const slots = defineSlots();
51
+ const contentProps = useForwardPropsEmits(reactiveOmit(props, "sub", "items", "portal", "labelKey", "checkedIcon", "loadingIcon", "externalIcon", "class", "ui"), emit);
52
+ const proxySlots = omit(slots, ["default"]);
53
+ const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate();
54
+ const groups = computed(
55
+ () => props.items?.length ? isArrayOfArray(props.items) ? props.items : [props.items] : []
56
+ );
57
+ const { theme, generateStyle } = useTheme();
58
+ const style = computed(() => generateStyle("dropdownMenu", props));
59
+ </script>
60
+
61
+ <template>
62
+ <DefineItemTemplate v-slot="{ item, active, index }">
63
+ <slot :name="item.slot || 'item'" :item="item" :index="index">
64
+ <slot :name="`${item.slot || 'item'}-leading`" :item="item" :active="active" :index="index">
65
+ <span
66
+ v-if="item.loading"
67
+ :class="style.itemLeadingIcon({ class: [loadingIcon || theme.app.icons.loading, props.ui?.itemLeadingIcon], loading: true })"
68
+ data-part="item-leading-icon"
69
+ ></span>
70
+ <span
71
+ v-else-if="item.icon"
72
+ :class="style.itemLeadingIcon({ class: [item.icon, props.ui?.itemLeadingIcon], active })"
73
+ data-part="item-leading-icon"
74
+ ></span>
75
+ <Avatar
76
+ v-else-if="item.avatar"
77
+ v-bind="item.avatar"
78
+ :size="item.avatar.size || props.size"
79
+ :class="style.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar, active })"
80
+ data-part="item-leading-avatar"
81
+ />
82
+ </slot>
83
+
84
+ <span
85
+ v-if="get(item, props.labelKey) || !!slots[`${item.slot || 'item'}-label`]"
86
+ :class="style.itemLabel({ class: props.ui?.itemLabel, active })"
87
+ data-part="item-label"
88
+ >
89
+ <slot :name="`${item.slot || 'item'}-label`" :item="item" :active="active" :index="index">
90
+ {{ get(item, props.labelKey) }}
91
+ </slot>
92
+
93
+ <span
94
+ v-if="item.target === '_blank' && externalIcon !== false"
95
+ :class="style.itemLabelExternalIcon({ class: [typeof externalIcon === 'string' ? externalIcon : theme.app.icons.external, props.ui?.itemLabelExternalIcon], active })"
96
+ data-part="item-label-external-icon"
97
+ ></span>
98
+ </span>
99
+
100
+ <span :class="style.itemTrailing({ class: props.ui?.itemTrailing })" data-part="item-trailing">
101
+ <slot :name="`${item.slot || 'item'}-trailing`" :item="item" :active="active" :index="index">
102
+ <span v-if="item.children?.length" :class="style.itemTrailingIcon({ class: [theme.app.icons.chevronRight, props.ui?.itemTrailingIcon], active })" data-part="item-trailing-icon"></span>
103
+ <span v-else-if="item.kbds?.length" :class="style.itemTrailingKbds({ class: props.ui?.itemTrailingKbds })" data-part="item-trailing-kbds">
104
+ <Kbd
105
+ v-for="(kbd, kbdIndex) in item.kbds"
106
+ :key="kbdIndex"
107
+ v-bind="typeof kbd === 'string' ? { value: kbd } : kbd"
108
+ :size="props.size"
109
+ />
110
+ </span>
111
+ </slot>
112
+
113
+ <DropdownMenu.ItemIndicator as-child>
114
+ <span :class="style.itemTrailingIcon({ class: [checkedIcon || theme.app.icons.check, props.ui?.itemTrailingIcon] })" data-part="item-trailing-icon"></span>
115
+ </DropdownMenu.ItemIndicator>
116
+ </span>
117
+ </slot>
118
+ </DefineItemTemplate>
119
+
120
+ <DropdownMenu.Portal :disabled="!portal">
121
+ <component :is="sub ? DropdownMenu.SubContent : DropdownMenu.Content" :class="props.class" :data-part="$attrs['data-part']" v-bind="contentProps">
122
+ <DropdownMenu.Group v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="style.group({ class: props.ui?.group })" data-part="group">
123
+ <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
124
+ <DropdownMenu.Label v-if="item.type === 'label'" :class="style.label({ class: props.ui?.label })" data-part="label">
125
+ <ReuseItemTemplate :item="item" :index="index" />
126
+ </DropdownMenu.Label>
127
+ <DropdownMenu.Separator v-else-if="item.type === 'separator'" :class="style.separator({ class: props.ui?.separator })" data-part="separator" />
128
+ <DropdownMenu.Sub v-else-if="item?.children?.length" :open="item.open" :default-open="item.defaultOpen">
129
+ <DropdownMenu.SubTrigger
130
+ as="button"
131
+ type="button"
132
+ :disabled="item.disabled"
133
+ :text-value="get(item, props.labelKey)"
134
+ :class="style.item({ class: props.ui?.item })"
135
+ data-part="item"
136
+ >
137
+ <ReuseItemTemplate :item="item" :index="index" />
138
+ </DropdownMenu.SubTrigger>
139
+
140
+ <DropdownMenuContent
141
+ sub
142
+ :class="props.class"
143
+ :ui="props.ui"
144
+ :portal="props.portal"
145
+ :items="item.children"
146
+ side="right"
147
+ align="start"
148
+ :align-offset="-4"
149
+ :side-offset="3"
150
+ :label-key="labelKey"
151
+ :checked-icon="checkedIcon"
152
+ :loading-icon="loadingIcon"
153
+ :external-icon="externalIcon"
154
+ v-bind="item.content"
155
+ >
156
+ <template v-for="(_, name) in proxySlots" #[name]="slotProps">
157
+ <slot :name="name" v-bind="slotProps"></slot>
158
+ </template>
159
+ </DropdownMenuContent>
160
+ </DropdownMenu.Sub>
161
+ <DropdownMenu.CheckboxItem
162
+ v-else-if="item.type === 'checkbox'"
163
+ :model-value="item.checked"
164
+ :disabled="item.disabled"
165
+ :text-value="get(item, props.labelKey)"
166
+ :class="style.item({ class: [props.ui?.item, item.class] })"
167
+ data-part="item"
168
+ @update:model-value="item.onUpdateChecked"
169
+ @select="item.onSelect"
170
+ >
171
+ <ReuseItemTemplate :item="item" :index="index" />
172
+ </DropdownMenu.CheckboxItem>
173
+ <DropdownMenu.Item
174
+ v-else
175
+ as-child
176
+ :disabled="item.disabled"
177
+ :text-value="get(item, props.labelKey)"
178
+ @select="item.onSelect"
179
+ >
180
+ <Link v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
181
+ <LinkBase v-bind="slotProps" :class="style.item({ class: [props.ui?.item, item.class], active })" data-part="item">
182
+ <ReuseItemTemplate :item="item" :active="active" :index="index" />
183
+ </LinkBase>
184
+ </Link>
185
+ </DropdownMenu.Item>
186
+ </template>
187
+ </DropdownMenu.Group>
188
+
189
+ <slot></slot>
190
+ </component>
191
+ </DropdownMenu.Portal>
192
+ </template>
@@ -0,0 +1,39 @@
1
+ import type { VariantProps } from '@byyuurin/ui-kit';
2
+ import type { DropdownMenuContentEmits as RekaDropdownMenuContentEmits, DropdownMenuContentProps as RekaDropdownMenuContentProps } from 'reka-ui';
3
+ import type { dropdownMenu } from '../theme/index.js';
4
+ import type { ArrayOrNested, ComponentAttrs, DropdownMenuItem, DropdownMenuSlots, NestedItem } from '../types/index.js';
5
+ export type DropdownMenuContentSlots<T extends ArrayOrNested<DropdownMenuItem>> = Omit<DropdownMenuSlots<T>, 'default'> & {
6
+ default?: any;
7
+ };
8
+ export interface DropdownMenuContentEmits extends RekaDropdownMenuContentEmits {
9
+ }
10
+ type DropdownMenuVariants = VariantProps<typeof dropdownMenu>;
11
+ export interface DropdownMenuContentProps<T extends ArrayOrNested<DropdownMenuItem>> extends ComponentAttrs<typeof dropdownMenu>, Omit<RekaDropdownMenuContentProps, 'as' | 'asChild' | 'forceMount'> {
12
+ size?: DropdownMenuVariants['size'];
13
+ items?: T;
14
+ portal?: boolean;
15
+ sub?: boolean;
16
+ labelKey: keyof NestedItem<T>;
17
+ checkedIcon?: string;
18
+ loadingIcon?: string;
19
+ externalIcon?: boolean | string;
20
+ }
21
+ declare const _default: <T extends ArrayOrNested<DropdownMenuItem>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
22
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
23
+ readonly onEscapeKeyDown?: ((event: KeyboardEvent) => any) | undefined;
24
+ readonly onPointerDownOutside?: ((event: import("reka-ui").PointerDownOutsideEvent) => any) | undefined;
25
+ readonly onFocusOutside?: ((event: import("reka-ui").FocusOutsideEvent) => any) | undefined;
26
+ readonly onInteractOutside?: ((event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => any) | undefined;
27
+ readonly onCloseAutoFocus?: ((event: Event) => any) | undefined;
28
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onEscapeKeyDown" | "onPointerDownOutside" | "onFocusOutside" | "onInteractOutside" | "onCloseAutoFocus"> & DropdownMenuContentProps<T> & Partial<{}>> & import("vue").PublicProps;
29
+ expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
30
+ attrs: any;
31
+ slots: DropdownMenuContentSlots<T>;
32
+ emit: ((evt: "escapeKeyDown", event: KeyboardEvent) => void) & ((evt: "pointerDownOutside", event: import("reka-ui").PointerDownOutsideEvent) => void) & ((evt: "focusOutside", event: import("reka-ui").FocusOutsideEvent) => void) & ((evt: "interactOutside", event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => void) & ((evt: "closeAutoFocus", event: Event) => void);
33
+ }>) => import("vue").VNode & {
34
+ __ctx?: Awaited<typeof __VLS_setup>;
35
+ };
36
+ export default _default;
37
+ type __VLS_PrettifyLocal<T> = {
38
+ [K in keyof T]: T[K];
39
+ } & {};
@@ -0,0 +1,197 @@
1
+ <script>
2
+ export class FormValidationExceptionError extends Error {
3
+ formId;
4
+ errors;
5
+ children;
6
+ constructor(formId, errors, childErrors) {
7
+ super("Form validation exception");
8
+ this.name = "FormValidationExceptionError";
9
+ this.formId = formId;
10
+ this.errors = errors;
11
+ this.children = childErrors;
12
+ Object.setPrototypeOf(this, FormValidationExceptionError.prototype);
13
+ }
14
+ }
15
+ </script>
16
+
17
+ <script setup>
18
+ import { useEventBus } from "@vueuse/core";
19
+ import { computed, nextTick, onMounted, onUnmounted, readonly, ref, useId } from "vue";
20
+ import { injectFormBus, provideFormBus, provideFormErrors, provideFormInputs, provideFormLoading, provideFormOptions } from "../app/injections";
21
+ import { useTheme } from "../composables/useTheme";
22
+ import { validateSchema } from "../utils";
23
+ const props = defineProps({
24
+ id: { type: [String, Number], required: false },
25
+ schema: { type: null, required: false },
26
+ state: { type: Object, required: true },
27
+ validate: { type: Function, required: false },
28
+ validateOn: { type: Array, required: false, default: () => ["input", "blur", "change"] },
29
+ disabled: { type: Boolean, required: false },
30
+ validateOnInputDelay: { type: Number, required: false, default: 300 },
31
+ transform: { type: Boolean, required: false, default: true },
32
+ onSubmit: { type: Function, required: false },
33
+ class: { type: null, required: false }
34
+ });
35
+ const emit = defineEmits(["submit", "error"]);
36
+ defineSlots();
37
+ const formId = props.id ?? useId();
38
+ const bus = useEventBus(`form-${formId}`);
39
+ const parentBus = injectFormBus();
40
+ provideFormBus(bus);
41
+ const nestedForms = ref(/* @__PURE__ */ new Map());
42
+ onMounted(() => {
43
+ bus.on(async (event) => {
44
+ if (event.type === "attach") {
45
+ nestedForms.value.set(event.formId, { validate: event.validate });
46
+ } else if (event.type === "detach") {
47
+ nestedForms.value.delete(event.formId);
48
+ } else if (props.validateOn?.includes(event.type) && !loading.value) {
49
+ if (event.type !== "input")
50
+ await validateFn({ name: event.name, silent: true, nested: false });
51
+ else if (event.eager || blurredFields.has(event.name))
52
+ await validateFn({ name: event.name, silent: true, nested: false });
53
+ }
54
+ if (event.type === "blur")
55
+ blurredFields.add(event.name);
56
+ if (event.type === "change" || event.type === "input" || event.type === "blur" || event.type === "focus")
57
+ touchedFields.add(event.name);
58
+ if (event.type === "change" || event.type === "input")
59
+ dirtyFields.add(event.name);
60
+ });
61
+ });
62
+ onUnmounted(() => {
63
+ bus.reset();
64
+ });
65
+ onMounted(async () => {
66
+ if (parentBus) {
67
+ await nextTick();
68
+ parentBus.emit({ type: "attach", validate: validateFn, formId });
69
+ }
70
+ });
71
+ onUnmounted(() => {
72
+ if (parentBus)
73
+ parentBus.emit({ type: "detach", formId });
74
+ });
75
+ const errors = ref([]);
76
+ provideFormErrors(errors);
77
+ const inputs = ref({});
78
+ provideFormInputs(inputs);
79
+ const dirtyFields = /* @__PURE__ */ new Set();
80
+ const touchedFields = /* @__PURE__ */ new Set();
81
+ const blurredFields = /* @__PURE__ */ new Set();
82
+ function resolveErrorIds(errs) {
83
+ return errs.map((err) => ({
84
+ ...err,
85
+ id: err?.name ? inputs.value[err.name]?.id : void 0
86
+ }));
87
+ }
88
+ const transformedState = ref(null);
89
+ async function getErrors() {
90
+ let errs = props.validate ? await props.validate(props.state) ?? [] : [];
91
+ if (props.schema) {
92
+ const { errors: errors2, result } = await validateSchema(props.state, props.schema);
93
+ if (errors2)
94
+ errs = errs.concat(errors2);
95
+ else
96
+ transformedState.value = result;
97
+ }
98
+ return resolveErrorIds(errs);
99
+ }
100
+ async function validateFn(options) {
101
+ const _options = {
102
+ silent: false,
103
+ nested: true,
104
+ transform: false,
105
+ ...options
106
+ };
107
+ const names = _options.name && !Array.isArray(_options.name) ? [_options.name] : _options.name;
108
+ const nestedValidatePromises = !names && _options.nested ? Array.from(nestedForms.value.values()).map(
109
+ ({ validate }) => validate(_options).then(() => {
110
+ }).catch((error) => {
111
+ if (!(error instanceof FormValidationExceptionError))
112
+ throw error;
113
+ return error;
114
+ })
115
+ ) : [];
116
+ if (names) {
117
+ const otherErrors = errors.value.filter((error) => !names.some((name) => {
118
+ const pattern = inputs.value?.[name]?.pattern;
119
+ return name === error.name || pattern && error.name?.match(pattern);
120
+ }));
121
+ const pathErrors = (await getErrors()).filter((error) => names.some((name) => {
122
+ const pattern = inputs.value?.[name]?.pattern;
123
+ return name === error.name || pattern && error.name?.match(pattern);
124
+ }));
125
+ errors.value = otherErrors.concat(pathErrors);
126
+ } else {
127
+ errors.value = await getErrors();
128
+ }
129
+ const childErrors = (await Promise.all(nestedValidatePromises)).filter((val) => val !== void 0);
130
+ if (errors.value.length + childErrors.length > 0) {
131
+ if (_options.silent)
132
+ return false;
133
+ throw new FormValidationExceptionError(formId, errors.value, childErrors);
134
+ }
135
+ if (_options.transform)
136
+ Object.assign(props.state, transformedState.value);
137
+ return props.state;
138
+ }
139
+ const loading = ref(false);
140
+ provideFormLoading(readonly(loading));
141
+ async function onSubmitWrapper(payload) {
142
+ loading.value = true;
143
+ const event = payload;
144
+ try {
145
+ event.data = await validateFn({ nested: true, transform: props.transform });
146
+ await props.onSubmit?.(event);
147
+ dirtyFields.clear();
148
+ } catch (error) {
149
+ if (!(error instanceof FormValidationExceptionError))
150
+ throw error;
151
+ const errorEvent = {
152
+ ...event,
153
+ errors: error.errors,
154
+ children: error.children
155
+ };
156
+ emit("error", errorEvent);
157
+ } finally {
158
+ loading.value = false;
159
+ }
160
+ }
161
+ const disabled = computed(() => props.disabled || loading.value);
162
+ provideFormOptions(computed(() => ({
163
+ disabled: disabled.value,
164
+ validateOnInputDelay: props.validateOnInputDelay
165
+ })));
166
+ defineExpose({
167
+ validate: validateFn,
168
+ errors,
169
+ setErrors(errs, name) {
170
+ errors.value = name ? errors.value.filter((error) => error.name !== name).concat(resolveErrorIds(errs)) : resolveErrorIds(errs);
171
+ },
172
+ async submit() {
173
+ await onSubmitWrapper(new Event("submit"));
174
+ },
175
+ getErrors(name) {
176
+ if (name)
177
+ return errors.value.filter((err) => err.name === name);
178
+ return errors.value;
179
+ },
180
+ clear(name) {
181
+ errors.value = name ? errors.value.filter((err) => err.name !== name) : [];
182
+ },
183
+ disabled,
184
+ dirty: computed(() => dirtyFields.size > 0),
185
+ dirtyFields: readonly(dirtyFields),
186
+ blurredFields: readonly(blurredFields),
187
+ touchedFields: readonly(touchedFields)
188
+ });
189
+ const { generateStyle } = useTheme();
190
+ const style = computed(() => generateStyle("form", props));
191
+ </script>
192
+
193
+ <template>
194
+ <component :is="parentBus ? 'div' : 'form'" :id="formId" :class="style.base()" data-part="base" @submit.prevent="onSubmitWrapper">
195
+ <slot :errors="errors"></slot>
196
+ </component>
197
+ </template>