@nuxt/ui 3.0.2 → 3.1.1

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 (221) hide show
  1. package/.nuxt/ui/accordion.ts +2 -2
  2. package/.nuxt/ui/alert.ts +29 -29
  3. package/.nuxt/ui/avatar-group.ts +1 -1
  4. package/.nuxt/ui/avatar.ts +3 -3
  5. package/.nuxt/ui/badge.ts +33 -33
  6. package/.nuxt/ui/breadcrumb.ts +5 -5
  7. package/.nuxt/ui/button.ts +43 -43
  8. package/.nuxt/ui/calendar.ts +17 -17
  9. package/.nuxt/ui/card.ts +5 -5
  10. package/.nuxt/ui/carousel.ts +6 -6
  11. package/.nuxt/ui/checkbox-group.ts +61 -0
  12. package/.nuxt/ui/checkbox.ts +140 -27
  13. package/.nuxt/ui/chip.ts +8 -8
  14. package/.nuxt/ui/color-picker.ts +3 -3
  15. package/.nuxt/ui/command-palette.ts +14 -14
  16. package/.nuxt/ui/context-menu.ts +33 -33
  17. package/.nuxt/ui/drawer.ts +10 -10
  18. package/.nuxt/ui/dropdown-menu.ts +34 -34
  19. package/.nuxt/ui/form-field.ts +6 -6
  20. package/.nuxt/ui/index.ts +1 -0
  21. package/.nuxt/ui/input-menu.ts +42 -42
  22. package/.nuxt/ui/input-number.ts +20 -20
  23. package/.nuxt/ui/input.ts +23 -23
  24. package/.nuxt/ui/kbd.ts +4 -4
  25. package/.nuxt/ui/link.ts +3 -3
  26. package/.nuxt/ui/modal.ts +5 -5
  27. package/.nuxt/ui/navigation-menu.ts +78 -80
  28. package/.nuxt/ui/pin-input.ts +20 -20
  29. package/.nuxt/ui/popover.ts +2 -2
  30. package/.nuxt/ui/progress.ts +17 -17
  31. package/.nuxt/ui/radio-group.ts +250 -35
  32. package/.nuxt/ui/select-menu.ts +36 -33
  33. package/.nuxt/ui/select.ts +32 -32
  34. package/.nuxt/ui/separator.ts +8 -8
  35. package/.nuxt/ui/skeleton.ts +1 -1
  36. package/.nuxt/ui/slideover.ts +4 -4
  37. package/.nuxt/ui/slider.ts +16 -16
  38. package/.nuxt/ui/stepper.ts +18 -18
  39. package/.nuxt/ui/switch.ts +20 -20
  40. package/.nuxt/ui/table.ts +15 -15
  41. package/.nuxt/ui/tabs.ts +32 -32
  42. package/.nuxt/ui/textarea.ts +40 -35
  43. package/.nuxt/ui/toast.ts +24 -24
  44. package/.nuxt/ui/tooltip.ts +2 -2
  45. package/.nuxt/ui/tree.ts +18 -18
  46. package/.nuxt/ui.css +63 -12
  47. package/README.md +15 -0
  48. package/cli/templates.mjs +18 -17
  49. package/dist/module.json +5 -5
  50. package/dist/module.mjs +12 -7
  51. package/dist/runtime/components/Accordion.vue +36 -93
  52. package/dist/runtime/components/Accordion.vue.d.ts +75 -0
  53. package/dist/runtime/components/Alert.vue +37 -100
  54. package/dist/runtime/components/Alert.vue.d.ts +81 -0
  55. package/dist/runtime/components/App.vue +28 -34
  56. package/dist/runtime/components/App.vue.d.ts +24 -0
  57. package/dist/runtime/components/Avatar.vue +42 -75
  58. package/dist/runtime/components/Avatar.vue.d.ts +39 -0
  59. package/dist/runtime/components/AvatarGroup.vue +40 -77
  60. package/dist/runtime/components/AvatarGroup.vue.d.ts +31 -0
  61. package/dist/runtime/components/Badge.vue +33 -62
  62. package/dist/runtime/components/Badge.vue.d.ts +41 -0
  63. package/dist/runtime/components/Breadcrumb.vue +37 -90
  64. package/dist/runtime/components/Breadcrumb.vue.d.ts +64 -0
  65. package/dist/runtime/components/Button.vue +95 -104
  66. package/dist/runtime/components/Button.vue.d.ts +48 -0
  67. package/dist/runtime/components/ButtonGroup.vue +20 -46
  68. package/dist/runtime/components/ButtonGroup.vue.d.ts +34 -0
  69. package/dist/runtime/components/Calendar.vue +67 -150
  70. package/dist/runtime/components/Calendar.vue.d.ts +111 -0
  71. package/dist/runtime/components/Card.vue +18 -40
  72. package/dist/runtime/components/Card.vue.d.ts +29 -0
  73. package/dist/runtime/components/Carousel.vue +112 -234
  74. package/dist/runtime/components/Carousel.vue.d.ts +122 -0
  75. package/dist/runtime/components/Checkbox.vue +52 -93
  76. package/dist/runtime/components/Checkbox.vue.d.ts +73 -0
  77. package/dist/runtime/components/CheckboxGroup.vue +121 -0
  78. package/dist/runtime/components/CheckboxGroup.vue.d.ts +78 -0
  79. package/dist/runtime/components/Chip.vue +26 -69
  80. package/dist/runtime/components/Chip.vue.d.ts +57 -0
  81. package/dist/runtime/components/Collapsible.vue +22 -41
  82. package/dist/runtime/components/Collapsible.vue.d.ts +35 -0
  83. package/dist/runtime/components/ColorPicker.vue +111 -197
  84. package/dist/runtime/components/ColorPicker.vue.d.ts +48 -0
  85. package/dist/runtime/components/CommandPalette.vue +96 -237
  86. package/dist/runtime/components/CommandPalette.vue.d.ts +161 -0
  87. package/dist/runtime/components/Container.vue +15 -28
  88. package/dist/runtime/components/Container.vue.d.ts +18 -0
  89. package/dist/runtime/components/ContextMenu.vue +34 -133
  90. package/dist/runtime/components/ContextMenu.vue.d.ts +107 -0
  91. package/dist/runtime/components/ContextMenuContent.vue +73 -81
  92. package/dist/runtime/components/ContextMenuContent.vue.d.ts +65 -0
  93. package/dist/runtime/components/Drawer.vue +49 -83
  94. package/dist/runtime/components/Drawer.vue.d.ts +78 -0
  95. package/dist/runtime/components/DropdownMenu.vue +39 -142
  96. package/dist/runtime/components/DropdownMenu.vue.d.ts +117 -0
  97. package/dist/runtime/components/DropdownMenuContent.vue +78 -88
  98. package/dist/runtime/components/DropdownMenuContent.vue.d.ts +68 -0
  99. package/dist/runtime/components/Form.vue +135 -220
  100. package/dist/runtime/components/Form.vue.d.ts +69 -0
  101. package/dist/runtime/components/FormField.vue +35 -77
  102. package/dist/runtime/components/FormField.vue.d.ts +61 -0
  103. package/dist/runtime/components/Icon.vue +12 -19
  104. package/dist/runtime/components/Icon.vue.d.ts +8 -0
  105. package/dist/runtime/components/Input.vue +82 -140
  106. package/dist/runtime/components/Input.vue.d.ts +76 -0
  107. package/dist/runtime/components/InputMenu.vue +185 -332
  108. package/dist/runtime/components/InputMenu.vue.d.ts +324 -0
  109. package/dist/runtime/components/InputNumber.vue +71 -133
  110. package/dist/runtime/components/InputNumber.vue.d.ts +182 -0
  111. package/dist/runtime/components/Kbd.vue +20 -46
  112. package/dist/runtime/components/Kbd.vue.d.ts +34 -0
  113. package/dist/runtime/components/Link.vue +98 -176
  114. package/dist/runtime/components/Link.vue.d.ts +93 -0
  115. package/dist/runtime/components/LinkBase.vue +33 -42
  116. package/dist/runtime/components/LinkBase.vue.d.ts +25 -0
  117. package/dist/runtime/components/Modal.vue +53 -116
  118. package/dist/runtime/components/Modal.vue.d.ts +93 -0
  119. package/dist/runtime/components/NavigationMenu.vue +77 -209
  120. package/dist/runtime/components/NavigationMenu.vue.d.ts +139 -0
  121. package/dist/runtime/components/OverlayProvider.vue +14 -18
  122. package/dist/runtime/components/OverlayProvider.vue.d.ts +2 -0
  123. package/dist/runtime/components/Pagination.vue +46 -140
  124. package/dist/runtime/components/Pagination.vue.d.ts +119 -0
  125. package/dist/runtime/components/PinInput.vue +61 -78
  126. package/dist/runtime/components/PinInput.vue.d.ts +57 -0
  127. package/dist/runtime/components/Popover.vue +47 -84
  128. package/dist/runtime/components/Popover.vue.d.ts +63 -0
  129. package/dist/runtime/components/Progress.vue +70 -131
  130. package/dist/runtime/components/Progress.vue.d.ts +66 -0
  131. package/dist/runtime/components/RadioGroup.vue +70 -132
  132. package/dist/runtime/components/RadioGroup.vue.d.ts +91 -0
  133. package/dist/runtime/components/Select.vue +110 -224
  134. package/dist/runtime/components/Select.vue.d.ts +145 -0
  135. package/dist/runtime/components/SelectMenu.vue +161 -310
  136. package/dist/runtime/components/SelectMenu.vue.d.ts +196 -0
  137. package/dist/runtime/components/Separator.vue +29 -71
  138. package/dist/runtime/components/Separator.vue.d.ts +54 -0
  139. package/dist/runtime/components/Skeleton.vue +21 -23
  140. package/dist/runtime/components/Skeleton.vue.d.ts +17 -0
  141. package/dist/runtime/components/Slideover.vue +53 -120
  142. package/dist/runtime/components/Slideover.vue.d.ts +94 -0
  143. package/dist/runtime/components/Slider.vue +46 -84
  144. package/dist/runtime/components/Slider.vue.d.ts +52 -0
  145. package/dist/runtime/components/Stepper.vue +45 -115
  146. package/dist/runtime/components/Stepper.vue.d.ts +83 -0
  147. package/dist/runtime/components/Switch.vue +45 -93
  148. package/dist/runtime/components/Switch.vue.d.ts +70 -0
  149. package/dist/runtime/components/Table.vue +163 -267
  150. package/dist/runtime/components/Table.vue.d.ts +183 -0
  151. package/dist/runtime/components/Tabs.vue +41 -107
  152. package/dist/runtime/components/Tabs.vue.d.ts +88 -0
  153. package/dist/runtime/components/Textarea.vue +113 -158
  154. package/dist/runtime/components/Textarea.vue.d.ts +78 -0
  155. package/dist/runtime/components/Toast.vue +49 -110
  156. package/dist/runtime/components/Toast.vue.d.ts +157 -0
  157. package/dist/runtime/components/Toaster.vue +70 -107
  158. package/dist/runtime/components/Toaster.vue.d.ts +38 -0
  159. package/dist/runtime/components/Tooltip.vue +38 -65
  160. package/dist/runtime/components/Tooltip.vue.d.ts +50 -0
  161. package/dist/runtime/components/Tree.vue +59 -166
  162. package/dist/runtime/components/Tree.vue.d.ts +111 -0
  163. package/dist/runtime/composables/defineShortcuts.d.ts +1 -1
  164. package/dist/runtime/composables/defineShortcuts.js +6 -0
  165. package/dist/runtime/composables/useAvatarGroup.d.ts +1 -1
  166. package/dist/runtime/composables/useButtonGroup.d.ts +2 -2
  167. package/dist/runtime/composables/useFormField.d.ts +2 -2
  168. package/dist/runtime/composables/useKbd.d.ts +1 -0
  169. package/dist/runtime/composables/useKbd.js +4 -3
  170. package/dist/runtime/composables/useOverlay.d.ts +14 -8
  171. package/dist/runtime/composables/useOverlay.js +20 -7
  172. package/dist/runtime/composables/usePortal.d.ts +6 -0
  173. package/dist/runtime/composables/usePortal.js +17 -0
  174. package/dist/runtime/index.css +1 -1
  175. package/dist/runtime/inertia/components/Link.vue +146 -0
  176. package/dist/runtime/inertia/components/Link.vue.d.ts +63 -0
  177. package/dist/runtime/inertia/stubs.d.ts +43 -0
  178. package/dist/runtime/inertia/stubs.js +82 -0
  179. package/dist/runtime/locale/bg.d.ts +3 -0
  180. package/dist/runtime/locale/bg.js +54 -0
  181. package/dist/runtime/locale/index.d.ts +5 -1
  182. package/dist/runtime/locale/index.js +5 -1
  183. package/dist/runtime/locale/kk.d.ts +3 -0
  184. package/dist/runtime/locale/kk.js +54 -0
  185. package/dist/runtime/locale/tj.d.ts +3 -0
  186. package/dist/runtime/locale/tj.js +54 -0
  187. package/dist/runtime/locale/ug_cn.d.ts +3 -0
  188. package/dist/runtime/locale/ug_cn.js +55 -0
  189. package/dist/runtime/types/form.d.ts +4 -1
  190. package/dist/runtime/types/index.d.ts +1 -0
  191. package/dist/runtime/types/index.js +1 -0
  192. package/dist/runtime/types/tv.d.ts +53 -0
  193. package/dist/runtime/types/tv.js +0 -0
  194. package/dist/runtime/types/utils.d.ts +7 -17
  195. package/dist/runtime/types/utils.js +1 -0
  196. package/dist/runtime/utils/link.d.ts +3 -3
  197. package/dist/runtime/utils/link.js +1 -0
  198. package/dist/runtime/utils/tv.js +2 -2
  199. package/dist/runtime/vue/components/Icon.vue +7 -8
  200. package/dist/runtime/vue/components/Icon.vue.d.ts +5 -0
  201. package/dist/runtime/vue/components/Link.vue +118 -202
  202. package/dist/runtime/vue/components/Link.vue.d.ts +93 -0
  203. package/dist/runtime/vue/stubs.d.ts +2 -2
  204. package/dist/shared/{ui.BkNUP964.mjs → ui.CbtTMMzt.mjs} +631 -366
  205. package/dist/types.d.mts +3 -5
  206. package/dist/unplugin.d.mts +6 -2
  207. package/dist/unplugin.mjs +25 -4
  208. package/dist/vite.d.mts +1 -1
  209. package/dist/vite.mjs +2 -2
  210. package/package.json +96 -54
  211. package/dist/module.cjs +0 -62
  212. package/dist/module.d.cts +0 -45
  213. package/dist/module.d.ts +0 -45
  214. package/dist/shared/ui.BL-XB3u1.cjs +0 -3555
  215. package/dist/types.d.ts +0 -7
  216. package/dist/unplugin.cjs +0 -232
  217. package/dist/unplugin.d.cts +0 -62
  218. package/dist/unplugin.d.ts +0 -62
  219. package/dist/vite.cjs +0 -23
  220. package/dist/vite.d.cts +0 -15
  221. package/dist/vite.d.ts +0 -15
@@ -1,137 +1,38 @@
1
- <!-- eslint-disable vue/block-tag-newline -->
2
- <script lang="ts">
3
- import type { VariantProps } from 'tailwind-variants'
4
- import type { ContextMenuRootProps, ContextMenuRootEmits, ContextMenuContentProps, ContextMenuContentEmits } from 'reka-ui'
5
- import type { AppConfig } from '@nuxt/schema'
6
- import _appConfig from '#build/app.config'
7
- import theme from '#build/ui/context-menu'
8
- import { tv } from '../utils/tv'
9
- import type { AvatarProps, KbdProps, LinkProps } from '../types'
10
- import type {
11
- ArrayOrNested,
12
- DynamicSlots,
13
- MergeTypes,
14
- NestedItem,
15
- PartialString,
16
- EmitsToProps
17
- } from '../types/utils'
18
-
19
- const appConfigContextMenu = _appConfig as AppConfig & { ui: { contextMenu: Partial<typeof theme> } }
20
-
21
- const contextMenu = tv({ extend: tv(theme), ...(appConfigContextMenu.ui?.contextMenu || {}) })
22
-
23
- type ContextMenuVariants = VariantProps<typeof contextMenu>
24
-
25
- export interface ContextMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'custom'> {
26
- label?: string
27
- /**
28
- * @IconifyIcon
29
- */
30
- icon?: string
31
- color?: ContextMenuVariants['color']
32
- avatar?: AvatarProps
33
- content?: Omit<ContextMenuContentProps, 'as' | 'asChild' | 'forceMount'> & Partial<EmitsToProps<ContextMenuContentEmits>>
34
- kbds?: KbdProps['value'][] | KbdProps[]
35
- /**
36
- * The item type.
37
- * @defaultValue 'link'
38
- */
39
- type?: 'label' | 'separator' | 'link' | 'checkbox'
40
- slot?: string
41
- loading?: boolean
42
- disabled?: boolean
43
- checked?: boolean
44
- open?: boolean
45
- defaultOpen?: boolean
46
- children?: ArrayOrNested<ContextMenuItem>
47
- onSelect?(e: Event): void
48
- onUpdateChecked?(checked: boolean): void
49
- [key: string]: any
50
- }
51
-
52
- export interface ContextMenuProps<T extends ArrayOrNested<ContextMenuItem> = ArrayOrNested<ContextMenuItem>> extends Omit<ContextMenuRootProps, 'dir'> {
53
- /**
54
- * @defaultValue 'md'
55
- */
56
- size?: ContextMenuVariants['size']
57
- items?: T
58
- /**
59
- * The icon displayed when an item is checked.
60
- * @defaultValue appConfig.ui.icons.check
61
- * @IconifyIcon
62
- */
63
- checkedIcon?: string
64
- /**
65
- * The icon displayed when an item is loading.
66
- * @defaultValue appConfig.ui.icons.loading
67
- * @IconifyIcon
68
- */
69
- loadingIcon?: string
70
- /**
71
- * The icon displayed when the item is an external link.
72
- * Set to `false` to hide the external icon.
73
- * @defaultValue appConfig.ui.icons.external
74
- * @IconifyIcon
75
- */
76
- externalIcon?: boolean | string
77
- /** The content of the menu. */
78
- content?: Omit<ContextMenuContentProps, 'as' | 'asChild' | 'forceMount'> & Partial<EmitsToProps<ContextMenuContentEmits>>
79
- /**
80
- * Render the menu in a portal.
81
- * @defaultValue true
82
- */
83
- portal?: boolean
84
- /**
85
- * The key used to get the label from the item.
86
- * @defaultValue 'label'
87
- */
88
- labelKey?: keyof NestedItem<T>
89
- disabled?: boolean
90
- class?: any
91
- ui?: PartialString<typeof contextMenu.slots>
92
- }
93
-
94
- export interface ContextMenuEmits extends ContextMenuRootEmits {}
95
-
96
- type SlotProps<T extends ContextMenuItem> = (props: { item: T, active?: boolean, index: number }) => any
97
-
98
- export type ContextMenuSlots<
99
- A extends ArrayOrNested<ContextMenuItem> = ArrayOrNested<ContextMenuItem>,
100
- T extends NestedItem<A> = NestedItem<A>
101
- > = {
102
- 'default'(props?: {}): any
103
- 'item': SlotProps<T>
104
- 'item-leading': SlotProps<T>
105
- 'item-label': SlotProps<T>
106
- 'item-trailing': SlotProps<T>
107
- } & DynamicSlots<MergeTypes<T>, 'leading' | 'label' | 'trailing', { active?: boolean, index: number }>
108
-
1
+ <script>
2
+ import theme from "#build/ui/context-menu";
109
3
  </script>
110
4
 
111
- <script setup lang="ts" generic="T extends ArrayOrNested<ContextMenuItem>">
112
- import { computed, toRef } from 'vue'
113
- import { ContextMenuRoot, ContextMenuTrigger, useForwardPropsEmits } from 'reka-ui'
114
- import { reactivePick } from '@vueuse/core'
115
- import { omit } from '../utils'
116
- import UContextMenuContent from './ContextMenuContent.vue'
117
-
118
- const props = withDefaults(defineProps<ContextMenuProps<T>>(), {
119
- portal: true,
120
- modal: true,
121
- externalIcon: true,
122
- labelKey: 'label'
123
- })
124
- const emits = defineEmits<ContextMenuEmits>()
125
- const slots = defineSlots<ContextMenuSlots<T>>()
126
-
127
- const rootProps = useForwardPropsEmits(reactivePick(props, 'modal'), emits)
128
-
129
- const contentProps = toRef(() => props.content)
130
- const proxySlots = omit(slots, ['default'])
131
-
132
- const ui = computed(() => contextMenu({
5
+ <script setup>
6
+ import { computed, toRef } from "vue";
7
+ import { ContextMenuRoot, ContextMenuTrigger, useForwardPropsEmits } from "reka-ui";
8
+ import { reactivePick } from "@vueuse/core";
9
+ import { useAppConfig } from "#imports";
10
+ import { omit } from "../utils";
11
+ import { tv } from "../utils/tv";
12
+ import UContextMenuContent from "./ContextMenuContent.vue";
13
+ const props = defineProps({
14
+ size: { type: null, required: false },
15
+ items: { type: null, required: false },
16
+ checkedIcon: { type: String, required: false },
17
+ loadingIcon: { type: String, required: false },
18
+ externalIcon: { type: [Boolean, String], required: false, default: true },
19
+ content: { type: Object, required: false },
20
+ portal: { type: [Boolean, String], required: false, skipCheck: true, 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
+ modal: { type: Boolean, required: false, default: true }
26
+ });
27
+ const emits = defineEmits(["update:open"]);
28
+ const slots = defineSlots();
29
+ const appConfig = useAppConfig();
30
+ const rootProps = useForwardPropsEmits(reactivePick(props, "modal"), emits);
31
+ const contentProps = toRef(() => props.content);
32
+ const proxySlots = omit(slots, ["default"]);
33
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.contextMenu || {} })({
133
34
  size: props.size
134
- }))
35
+ }));
135
36
  </script>
136
37
 
137
38
  <template>
@@ -147,13 +48,13 @@ const ui = computed(() => contextMenu({
147
48
  v-bind="contentProps"
148
49
  :items="items"
149
50
  :portal="portal"
150
- :label-key="(labelKey as keyof NestedItem<T>)"
51
+ :label-key="labelKey"
151
52
  :checked-icon="checkedIcon"
152
53
  :loading-icon="loadingIcon"
153
54
  :external-icon="externalIcon"
154
55
  >
155
56
  <template v-for="(_, name) in proxySlots" #[name]="slotData">
156
- <slot :name="(name as keyof ContextMenuSlots<T>)" v-bind="slotData" />
57
+ <slot :name="name" v-bind="slotData" />
157
58
  </template>
158
59
  </UContextMenuContent>
159
60
  </ContextMenuRoot>
@@ -0,0 +1,107 @@
1
+ import type { ContextMenuRootProps, ContextMenuRootEmits, ContextMenuContentProps, ContextMenuContentEmits } from 'reka-ui';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import theme from '#build/ui/context-menu';
4
+ import type { AvatarProps, KbdProps, LinkProps } from '../types';
5
+ import type { ArrayOrNested, DynamicSlots, MergeTypes, NestedItem, EmitsToProps, ComponentConfig } from '../types/utils';
6
+ type ContextMenu = ComponentConfig<typeof theme, AppConfig, 'contextMenu'>;
7
+ export interface ContextMenuItem extends Omit<LinkProps, 'type' | 'raw' | 'custom'> {
8
+ label?: string;
9
+ /**
10
+ * @IconifyIcon
11
+ */
12
+ icon?: string;
13
+ color?: ContextMenu['variants']['color'];
14
+ avatar?: AvatarProps;
15
+ content?: Omit<ContextMenuContentProps, 'as' | 'asChild' | 'forceMount'> & Partial<EmitsToProps<ContextMenuContentEmits>>;
16
+ kbds?: KbdProps['value'][] | KbdProps[];
17
+ /**
18
+ * The item type.
19
+ * @defaultValue 'link'
20
+ */
21
+ type?: 'label' | 'separator' | 'link' | 'checkbox';
22
+ slot?: string;
23
+ loading?: boolean;
24
+ disabled?: boolean;
25
+ checked?: boolean;
26
+ open?: boolean;
27
+ defaultOpen?: boolean;
28
+ children?: ArrayOrNested<ContextMenuItem>;
29
+ onSelect?(e: Event): void;
30
+ onUpdateChecked?(checked: boolean): void;
31
+ [key: string]: any;
32
+ }
33
+ export interface ContextMenuProps<T extends ArrayOrNested<ContextMenuItem> = ArrayOrNested<ContextMenuItem>> extends Omit<ContextMenuRootProps, 'dir'> {
34
+ /**
35
+ * @defaultValue 'md'
36
+ */
37
+ size?: ContextMenu['variants']['size'];
38
+ items?: T;
39
+ /**
40
+ * The icon displayed when an item is checked.
41
+ * @defaultValue appConfig.ui.icons.check
42
+ * @IconifyIcon
43
+ */
44
+ checkedIcon?: string;
45
+ /**
46
+ * The icon displayed when an item is loading.
47
+ * @defaultValue appConfig.ui.icons.loading
48
+ * @IconifyIcon
49
+ */
50
+ loadingIcon?: string;
51
+ /**
52
+ * The icon displayed when the item is an external link.
53
+ * Set to `false` to hide the external icon.
54
+ * @defaultValue appConfig.ui.icons.external
55
+ * @IconifyIcon
56
+ */
57
+ externalIcon?: boolean | string;
58
+ /** The content of the menu. */
59
+ content?: Omit<ContextMenuContentProps, 'as' | 'asChild' | 'forceMount'> & Partial<EmitsToProps<ContextMenuContentEmits>>;
60
+ /**
61
+ * Render the menu in a portal.
62
+ * @defaultValue true
63
+ */
64
+ portal?: boolean | string | HTMLElement;
65
+ /**
66
+ * The key used to get the label from the item.
67
+ * @defaultValue 'label'
68
+ */
69
+ labelKey?: keyof NestedItem<T>;
70
+ disabled?: boolean;
71
+ class?: any;
72
+ ui?: ContextMenu['slots'];
73
+ }
74
+ export interface ContextMenuEmits extends ContextMenuRootEmits {
75
+ }
76
+ type SlotProps<T extends ContextMenuItem> = (props: {
77
+ item: T;
78
+ active?: boolean;
79
+ index: number;
80
+ }) => any;
81
+ export type ContextMenuSlots<A extends ArrayOrNested<ContextMenuItem> = ArrayOrNested<ContextMenuItem>, T extends NestedItem<A> = NestedItem<A>> = {
82
+ 'default'(props?: {}): any;
83
+ 'item': SlotProps<T>;
84
+ 'item-leading': SlotProps<T>;
85
+ 'item-label': SlotProps<T>;
86
+ 'item-trailing': SlotProps<T>;
87
+ 'content-top': (props?: {}) => any;
88
+ 'content-bottom': (props?: {}) => any;
89
+ } & DynamicSlots<MergeTypes<T>, 'leading' | 'label' | 'trailing', {
90
+ active?: boolean;
91
+ index: number;
92
+ }>;
93
+ declare const _default: <T extends ArrayOrNested<ContextMenuItem>>(__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<{
94
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
95
+ readonly "onUpdate:open"?: ((payload: boolean) => any) | undefined;
96
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onUpdate:open"> & ContextMenuProps<T> & Partial<{}>> & import("vue").PublicProps;
97
+ expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
98
+ attrs: any;
99
+ slots: ContextMenuSlots<T, NestedItem<T>>;
100
+ emit: (evt: "update:open", payload: boolean) => void;
101
+ }>) => import("vue").VNode & {
102
+ __ctx?: Awaited<typeof __VLS_setup>;
103
+ };
104
+ export default _default;
105
+ type __VLS_PrettifyLocal<T> = {
106
+ [K in keyof T]: T[K];
107
+ } & {};
@@ -1,94 +1,82 @@
1
- <script lang="ts">
2
- import type { ContextMenuContentProps as RekaContextMenuContentProps, ContextMenuContentEmits as RekaContextMenuContentEmits } from 'reka-ui'
3
- import theme from '#build/ui/context-menu'
4
- import { tv } from '../utils/tv'
5
- import type { AvatarProps, ContextMenuItem, ContextMenuSlots, KbdProps } from '../types'
6
- import type { ArrayOrNested, NestedItem } from '../types/utils'
1
+ <script>
7
2
 
8
- const _contextMenu = tv(theme)()
9
-
10
- interface ContextMenuContentProps<T extends ArrayOrNested<ContextMenuItem>> extends Omit<RekaContextMenuContentProps, 'as' | 'asChild' | 'forceMount'> {
11
- items?: T
12
- portal?: boolean
13
- sub?: boolean
14
- labelKey: keyof NestedItem<T>
15
- /**
16
- * @IconifyIcon
17
- */
18
- checkedIcon?: string
19
- /**
20
- * @IconifyIcon
21
- */
22
- loadingIcon?: string
23
- /**
24
- * @IconifyIcon
25
- */
26
- externalIcon?: boolean | string
27
- class?: any
28
- ui: typeof _contextMenu
29
- uiOverride?: any
30
- }
31
-
32
- interface ContextMenuContentEmits extends RekaContextMenuContentEmits {}
33
3
  </script>
34
4
 
35
- <script setup lang="ts" generic="T extends ArrayOrNested<ContextMenuItem>">
36
- import { computed } from 'vue'
37
- import { ContextMenu } from 'reka-ui/namespaced'
38
- import { useForwardPropsEmits } from 'reka-ui'
39
- import { reactiveOmit, createReusableTemplate } from '@vueuse/core'
40
- import { useAppConfig } from '#imports'
41
- import { omit, get, isArrayOfArray } from '../utils'
42
- import { pickLinkProps } from '../utils/link'
43
- import ULinkBase from './LinkBase.vue'
44
- import ULink from './Link.vue'
45
- import UAvatar from './Avatar.vue'
46
- import UIcon from './Icon.vue'
47
- import UKbd from './Kbd.vue'
48
- // eslint-disable-next-line import/no-self-import
49
- import UContextMenuContent from './ContextMenuContent.vue'
50
-
51
- const props = defineProps<ContextMenuContentProps<T>>()
52
- const emits = defineEmits<ContextMenuContentEmits>()
53
- const slots = defineSlots<ContextMenuSlots<T>>()
54
-
55
- const appConfig = useAppConfig()
56
- const contentProps = useForwardPropsEmits(reactiveOmit(props, 'sub', 'items', 'portal', 'labelKey', 'checkedIcon', 'loadingIcon', 'externalIcon', 'class', 'ui', 'uiOverride'), emits)
57
- const proxySlots = omit(slots, ['default'])
58
-
59
- const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate<{ item: ContextMenuItem, active?: boolean, index: number }>()
60
-
61
- const groups = computed<ContextMenuItem[][]>(() =>
62
- props.items?.length
63
- ? isArrayOfArray(props.items)
64
- ? props.items
65
- : [props.items]
66
- : []
67
- )
5
+ <script setup>
6
+ import { computed, toRef } from "vue";
7
+ import { ContextMenu } from "reka-ui/namespaced";
8
+ import { useForwardPropsEmits } from "reka-ui";
9
+ import { reactiveOmit, createReusableTemplate } from "@vueuse/core";
10
+ import { useAppConfig } from "#imports";
11
+ import { useLocale } from "../composables/useLocale";
12
+ import { usePortal } from "../composables/usePortal";
13
+ import { omit, get, isArrayOfArray } from "../utils";
14
+ import { pickLinkProps } from "../utils/link";
15
+ import ULinkBase from "./LinkBase.vue";
16
+ import ULink from "./Link.vue";
17
+ import UAvatar from "./Avatar.vue";
18
+ import UIcon from "./Icon.vue";
19
+ import UKbd from "./Kbd.vue";
20
+ import UContextMenuContent from "./ContextMenuContent.vue";
21
+ const props = defineProps({
22
+ items: { type: null, required: false },
23
+ portal: { type: [Boolean, String], required: false, skipCheck: true },
24
+ sub: { type: Boolean, required: false },
25
+ labelKey: { type: null, required: true },
26
+ checkedIcon: { type: String, required: false },
27
+ loadingIcon: { type: String, required: false },
28
+ externalIcon: { type: [Boolean, String], required: false },
29
+ class: { type: null, required: false },
30
+ ui: { type: null, required: true },
31
+ uiOverride: { type: null, required: false },
32
+ loop: { type: Boolean, required: false },
33
+ alignOffset: { type: Number, required: false },
34
+ avoidCollisions: { type: Boolean, required: false },
35
+ collisionBoundary: { type: null, required: false },
36
+ collisionPadding: { type: [Number, Object], required: false },
37
+ sticky: { type: String, required: false },
38
+ hideWhenDetached: { type: Boolean, required: false },
39
+ positionStrategy: { type: String, required: false },
40
+ disableUpdateOnLayoutShift: { type: Boolean, required: false },
41
+ prioritizePosition: { type: Boolean, required: false },
42
+ reference: { type: null, required: false }
43
+ });
44
+ const emits = defineEmits(["escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "closeAutoFocus"]);
45
+ const slots = defineSlots();
46
+ const { dir } = useLocale();
47
+ const appConfig = useAppConfig();
48
+ const portalProps = usePortal(toRef(() => props.portal));
49
+ const contentProps = useForwardPropsEmits(reactiveOmit(props, "sub", "items", "portal", "labelKey", "checkedIcon", "loadingIcon", "externalIcon", "class", "ui", "uiOverride"), emits);
50
+ const proxySlots = omit(slots, ["default"]);
51
+ const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate();
52
+ const childrenIcon = computed(() => dir.value === "rtl" ? appConfig.ui.icons.chevronLeft : appConfig.ui.icons.chevronRight);
53
+ const groups = computed(
54
+ () => props.items?.length ? isArrayOfArray(props.items) ? props.items : [props.items] : []
55
+ );
68
56
  </script>
69
57
 
70
58
  <template>
71
59
  <DefineItemTemplate v-slot="{ item, active, index }">
72
- <slot :name="((item.slot || 'item') as keyof ContextMenuSlots<T>)" :item="item" :index="index">
73
- <slot :name="((item.slot ? `${item.slot}-leading`: 'item-leading') as keyof ContextMenuSlots<T>)" :item="item" :active="active" :index="index">
60
+ <slot :name="item.slot || 'item'" :item="item" :index="index">
61
+ <slot :name="item.slot ? `${item.slot}-leading` : 'item-leading'" :item="item" :active="active" :index="index">
74
62
  <UIcon v-if="item.loading" :name="loadingIcon || appConfig.ui.icons.loading" :class="ui.itemLeadingIcon({ class: uiOverride?.itemLeadingIcon, color: item?.color, loading: true })" />
75
63
  <UIcon v-else-if="item.icon" :name="item.icon" :class="ui.itemLeadingIcon({ class: uiOverride?.itemLeadingIcon, color: item?.color, active })" />
76
- <UAvatar v-else-if="item.avatar" :size="((props.uiOverride?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: uiOverride?.itemLeadingAvatar, active })" />
64
+ <UAvatar v-else-if="item.avatar" :size="props.uiOverride?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: uiOverride?.itemLeadingAvatar, active })" />
77
65
  </slot>
78
66
 
79
- <span v-if="get(item, props.labelKey as string) || !!slots[(item.slot ? `${item.slot}-label`: 'item-label') as keyof ContextMenuSlots<T>]" :class="ui.itemLabel({ class: uiOverride?.itemLabel, active })">
80
- <slot :name="((item.slot ? `${item.slot}-label`: 'item-label') as keyof ContextMenuSlots<T>)" :item="item" :active="active" :index="index">
81
- {{ get(item, props.labelKey as string) }}
67
+ <span v-if="get(item, props.labelKey) || !!slots[item.slot ? `${item.slot}-label` : 'item-label']" :class="ui.itemLabel({ class: uiOverride?.itemLabel, active })">
68
+ <slot :name="item.slot ? `${item.slot}-label` : 'item-label'" :item="item" :active="active" :index="index">
69
+ {{ get(item, props.labelKey) }}
82
70
  </slot>
83
71
 
84
72
  <UIcon v-if="item.target === '_blank' && externalIcon !== false" :name="typeof externalIcon === 'string' ? externalIcon : appConfig.ui.icons.external" :class="ui.itemLabelExternalIcon({ class: uiOverride?.itemLabelExternalIcon, color: item?.color, active })" />
85
73
  </span>
86
74
 
87
75
  <span :class="ui.itemTrailing({ class: uiOverride?.itemTrailing })">
88
- <slot :name="((item.slot ? `${item.slot}-trailing`: 'item-trailing') as keyof ContextMenuSlots<T>)" :item="item" :active="active" :index="index">
89
- <UIcon v-if="item.children?.length" :name="appConfig.ui.icons.chevronRight" :class="ui.itemTrailingIcon({ class: uiOverride?.itemTrailingIcon, color: item?.color, active })" />
76
+ <slot :name="item.slot ? `${item.slot}-trailing` : 'item-trailing'" :item="item" :active="active" :index="index">
77
+ <UIcon v-if="item.children?.length" :name="childrenIcon" :class="ui.itemTrailingIcon({ class: uiOverride?.itemTrailingIcon, color: item?.color, active })" />
90
78
  <span v-else-if="item.kbds?.length" :class="ui.itemTrailingKbds({ class: uiOverride?.itemTrailingKbds })">
91
- <UKbd v-for="(kbd, kbdIndex) in item.kbds" :key="kbdIndex" :size="((props.uiOverride?.itemTrailingKbdsSize || ui.itemTrailingKbdsSize()) as KbdProps['size'])" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
79
+ <UKbd v-for="(kbd, kbdIndex) in item.kbds" :key="kbdIndex" :size="props.uiOverride?.itemTrailingKbdsSize || ui.itemTrailingKbdsSize()" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
92
80
  </span>
93
81
  </slot>
94
82
 
@@ -99,8 +87,10 @@ const groups = computed<ContextMenuItem[][]>(() =>
99
87
  </slot>
100
88
  </DefineItemTemplate>
101
89
 
102
- <ContextMenu.Portal :disabled="!portal">
90
+ <ContextMenu.Portal v-bind="portalProps">
103
91
  <component :is="sub ? ContextMenu.SubContent : ContextMenu.Content" :class="props.class" v-bind="contentProps">
92
+ <slot name="content-top" />
93
+
104
94
  <ContextMenu.Group v-for="(group, groupIndex) in groups" :key="`group-${groupIndex}`" :class="ui.group({ class: uiOverride?.group })">
105
95
  <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
106
96
  <ContextMenu.Label v-if="item.type === 'label'" :class="ui.label({ class: uiOverride?.label })">
@@ -112,7 +102,7 @@ const groups = computed<ContextMenuItem[][]>(() =>
112
102
  as="button"
113
103
  type="button"
114
104
  :disabled="item.disabled"
115
- :text-value="get(item, props.labelKey as string)"
105
+ :text-value="get(item, props.labelKey)"
116
106
  :class="ui.item({ class: uiOverride?.item, color: item?.color })"
117
107
  >
118
108
  <ReuseItemTemplate :item="item" :index="index" />
@@ -124,7 +114,7 @@ const groups = computed<ContextMenuItem[][]>(() =>
124
114
  :ui="ui"
125
115
  :ui-override="uiOverride"
126
116
  :portal="portal"
127
- :items="(item.children as T)"
117
+ :items="item.children"
128
118
  :align-offset="-4"
129
119
  :label-key="labelKey"
130
120
  :checked-icon="checkedIcon"
@@ -132,8 +122,8 @@ const groups = computed<ContextMenuItem[][]>(() =>
132
122
  :external-icon="externalIcon"
133
123
  v-bind="item.content"
134
124
  >
135
- <template v-for="(_, name) in proxySlots" #[name]="slotData: any">
136
- <slot :name="(name as keyof ContextMenuSlots<T>)" v-bind="slotData" />
125
+ <template v-for="(_, name) in proxySlots" #[name]="slotData">
126
+ <slot :name="name" v-bind="slotData" />
137
127
  </template>
138
128
  </UContextMenuContent>
139
129
  </ContextMenu.Sub>
@@ -141,7 +131,7 @@ const groups = computed<ContextMenuItem[][]>(() =>
141
131
  v-else-if="item.type === 'checkbox'"
142
132
  :model-value="item.checked"
143
133
  :disabled="item.disabled"
144
- :text-value="get(item, props.labelKey as string)"
134
+ :text-value="get(item, props.labelKey)"
145
135
  :class="ui.item({ class: [uiOverride?.item, item.class], color: item?.color })"
146
136
  @update:model-value="item.onUpdateChecked"
147
137
  @select="item.onSelect"
@@ -152,10 +142,10 @@ const groups = computed<ContextMenuItem[][]>(() =>
152
142
  v-else
153
143
  as-child
154
144
  :disabled="item.disabled"
155
- :text-value="get(item, props.labelKey as string)"
145
+ :text-value="get(item, props.labelKey)"
156
146
  @select="item.onSelect"
157
147
  >
158
- <ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item as Omit<ContextMenuItem, 'type'>)" custom>
148
+ <ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
159
149
  <ULinkBase v-bind="slotProps" :class="ui.item({ class: [uiOverride?.item, item.class], active, color: item?.color })">
160
150
  <ReuseItemTemplate :item="item" :active="active" :index="index" />
161
151
  </ULinkBase>
@@ -165,6 +155,8 @@ const groups = computed<ContextMenuItem[][]>(() =>
165
155
  </ContextMenu.Group>
166
156
 
167
157
  <slot />
158
+
159
+ <slot name="content-bottom" />
168
160
  </component>
169
161
  </ContextMenu.Portal>
170
162
  </template>
@@ -0,0 +1,65 @@
1
+ import { ContextMenu } from 'reka-ui/namespaced';
2
+ import type { ContextMenuContentProps as RekaContextMenuContentProps } from 'reka-ui';
3
+ import type { AppConfig } from '@nuxt/schema';
4
+ import type theme from '#build/ui/context-menu';
5
+ import type { ContextMenuItem, ContextMenuSlots } from '../types';
6
+ import type { ArrayOrNested, NestedItem, ComponentConfig } from '../types/utils';
7
+ type ContextMenu = ComponentConfig<typeof theme, AppConfig, 'contextMenu'>;
8
+ interface ContextMenuContentProps<T extends ArrayOrNested<ContextMenuItem>> extends Omit<RekaContextMenuContentProps, 'as' | 'asChild' | 'forceMount'> {
9
+ items?: T;
10
+ portal?: boolean | string | HTMLElement;
11
+ sub?: boolean;
12
+ labelKey: keyof NestedItem<T>;
13
+ /**
14
+ * @IconifyIcon
15
+ */
16
+ checkedIcon?: string;
17
+ /**
18
+ * @IconifyIcon
19
+ */
20
+ loadingIcon?: string;
21
+ /**
22
+ * @IconifyIcon
23
+ */
24
+ externalIcon?: boolean | string;
25
+ class?: any;
26
+ ui: {
27
+ [K in keyof Required<ContextMenu['slots']>]: (props?: Record<string, any>) => string;
28
+ };
29
+ uiOverride?: ContextMenu['slots'];
30
+ }
31
+ declare const _default: <T extends ArrayOrNested<ContextMenuItem>>(__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<{
32
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
33
+ readonly onEscapeKeyDown?: ((event: KeyboardEvent) => any) | undefined;
34
+ readonly onPointerDownOutside?: ((event: CustomEvent<{
35
+ originalEvent: PointerEvent;
36
+ }>) => any) | undefined;
37
+ readonly onFocusOutside?: ((event: CustomEvent<{
38
+ originalEvent: FocusEvent;
39
+ }>) => any) | undefined;
40
+ readonly onInteractOutside?: ((event: CustomEvent<{
41
+ originalEvent: PointerEvent;
42
+ }> | CustomEvent<{
43
+ originalEvent: FocusEvent;
44
+ }>) => any) | undefined;
45
+ readonly onCloseAutoFocus?: ((event: Event) => any) | undefined;
46
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onEscapeKeyDown" | "onPointerDownOutside" | "onFocusOutside" | "onInteractOutside" | "onCloseAutoFocus"> & ContextMenuContentProps<T> & Partial<{}>> & import("vue").PublicProps;
47
+ expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
48
+ attrs: any;
49
+ slots: ContextMenuSlots<T>;
50
+ emit: ((evt: "escapeKeyDown", event: KeyboardEvent) => void) & ((evt: "pointerDownOutside", event: CustomEvent<{
51
+ originalEvent: PointerEvent;
52
+ }>) => void) & ((evt: "focusOutside", event: CustomEvent<{
53
+ originalEvent: FocusEvent;
54
+ }>) => void) & ((evt: "interactOutside", event: CustomEvent<{
55
+ originalEvent: PointerEvent;
56
+ }> | CustomEvent<{
57
+ originalEvent: FocusEvent;
58
+ }>) => void) & ((evt: "closeAutoFocus", event: Event) => void);
59
+ }>) => import("vue").VNode & {
60
+ __ctx?: Awaited<typeof __VLS_setup>;
61
+ };
62
+ export default _default;
63
+ type __VLS_PrettifyLocal<T> = {
64
+ [K in keyof T]: T[K];
65
+ } & {};