@nuxt/ui 3.1.3 → 3.3.0
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.
- package/.nuxt/ui/avatar.ts +1 -1
- package/.nuxt/ui/button.ts +42 -42
- package/.nuxt/ui/card.ts +1 -1
- package/.nuxt/ui/carousel.ts +1 -1
- package/.nuxt/ui/command-palette.ts +3 -1
- package/.nuxt/ui/drawer.ts +1 -1
- package/.nuxt/ui/file-upload.ts +290 -0
- package/.nuxt/ui/index.ts +3 -0
- package/.nuxt/ui/input-menu.ts +24 -10
- package/.nuxt/ui/input-tags.ts +310 -0
- package/.nuxt/ui/kbd.ts +167 -3
- package/.nuxt/ui/modal.ts +1 -1
- package/.nuxt/ui/navigation-menu.ts +1 -1
- package/.nuxt/ui/select-menu.ts +11 -6
- package/.nuxt/ui/select.ts +11 -6
- package/.nuxt/ui/table.ts +11 -2
- package/.nuxt/ui/tabs.ts +4 -2
- package/.nuxt/ui/timeline.ts +321 -0
- package/.nuxt/ui/toast.ts +8 -15
- package/.nuxt/ui/toaster.ts +1 -1
- package/.nuxt/ui/tooltip.ts +1 -1
- package/cli/templates.mjs +11 -7
- package/dist/module.d.mts +15 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +3 -3
- package/dist/runtime/components/Accordion.vue.d.ts +1 -1
- package/dist/runtime/components/Alert.vue +0 -1
- package/dist/runtime/components/Alert.vue.d.ts +2 -2
- package/dist/runtime/components/App.vue.d.ts +1 -1
- package/dist/runtime/components/Avatar.vue +10 -2
- package/dist/runtime/components/Avatar.vue.d.ts +3 -1
- package/dist/runtime/components/AvatarGroup.vue.d.ts +1 -1
- package/dist/runtime/components/Badge.vue.d.ts +1 -1
- package/dist/runtime/components/Breadcrumb.vue.d.ts +1 -1
- package/dist/runtime/components/Button.vue +6 -6
- package/dist/runtime/components/Button.vue.d.ts +1 -5
- package/dist/runtime/components/ButtonGroup.vue.d.ts +1 -1
- package/dist/runtime/components/Calendar.vue +4 -1
- package/dist/runtime/components/Calendar.vue.d.ts +1 -1
- package/dist/runtime/components/Card.vue.d.ts +1 -1
- package/dist/runtime/components/Carousel.vue +19 -16
- package/dist/runtime/components/Carousel.vue.d.ts +1 -1
- package/dist/runtime/components/Checkbox.vue +1 -1
- package/dist/runtime/components/Checkbox.vue.d.ts +1 -1
- package/dist/runtime/components/CheckboxGroup.vue.d.ts +1 -1
- package/dist/runtime/components/Chip.vue.d.ts +2 -2
- package/dist/runtime/components/Collapsible.vue.d.ts +1 -1
- package/dist/runtime/components/ColorPicker.vue +1 -2
- package/dist/runtime/components/ColorPicker.vue.d.ts +1 -1
- package/dist/runtime/components/CommandPalette.vue +84 -16
- package/dist/runtime/components/CommandPalette.vue.d.ts +38 -9
- package/dist/runtime/components/Container.vue.d.ts +1 -1
- package/dist/runtime/components/ContextMenu.vue.d.ts +1 -1
- package/dist/runtime/components/ContextMenuContent.vue.d.ts +5 -21
- package/dist/runtime/components/Drawer.vue +4 -4
- package/dist/runtime/components/Drawer.vue.d.ts +6 -1
- package/dist/runtime/components/DropdownMenu.vue.d.ts +1 -1
- package/dist/runtime/components/DropdownMenuContent.vue.d.ts +12 -25
- package/dist/runtime/components/FileUpload.vue +242 -0
- package/dist/runtime/components/FileUpload.vue.d.ts +167 -0
- package/dist/runtime/components/Form.vue +6 -6
- package/dist/runtime/components/Form.vue.d.ts +15 -13
- package/dist/runtime/components/FormField.vue +2 -2
- package/dist/runtime/components/FormField.vue.d.ts +4 -4
- package/dist/runtime/components/Icon.vue.d.ts +1 -1
- package/dist/runtime/components/Input.vue +10 -7
- package/dist/runtime/components/Input.vue.d.ts +9 -9
- package/dist/runtime/components/InputMenu.vue +17 -10
- package/dist/runtime/components/InputMenu.vue.d.ts +19 -16
- package/dist/runtime/components/InputNumber.vue +3 -2
- package/dist/runtime/components/InputNumber.vue.d.ts +5 -5
- package/dist/runtime/components/InputTags.vue +161 -0
- package/dist/runtime/components/InputTags.vue.d.ts +185 -0
- package/dist/runtime/components/Kbd.vue +2 -1
- package/dist/runtime/components/Kbd.vue.d.ts +5 -1
- package/dist/runtime/components/Link.vue +6 -5
- package/dist/runtime/components/Link.vue.d.ts +1 -3
- package/dist/runtime/components/LinkBase.vue.d.ts +1 -1
- package/dist/runtime/components/Modal.vue +14 -13
- package/dist/runtime/components/Modal.vue.d.ts +16 -6
- package/dist/runtime/components/NavigationMenu.vue +19 -17
- package/dist/runtime/components/NavigationMenu.vue.d.ts +1 -1
- package/dist/runtime/components/OverlayProvider.vue +2 -2
- package/dist/runtime/components/OverlayProvider.vue.d.ts +1 -1
- package/dist/runtime/components/Pagination.vue +1 -1
- package/dist/runtime/components/Pagination.vue.d.ts +1 -2
- package/dist/runtime/components/PinInput.vue +4 -3
- package/dist/runtime/components/PinInput.vue.d.ts +22 -19
- package/dist/runtime/components/Popover.vue +2 -1
- package/dist/runtime/components/Popover.vue.d.ts +8 -2
- package/dist/runtime/components/Progress.vue +2 -1
- package/dist/runtime/components/Progress.vue.d.ts +2 -2
- package/dist/runtime/components/RadioGroup.vue +3 -3
- package/dist/runtime/components/RadioGroup.vue.d.ts +5 -4
- package/dist/runtime/components/Select.vue +23 -4
- package/dist/runtime/components/Select.vue.d.ts +108 -2
- package/dist/runtime/components/SelectMenu.vue +33 -11
- package/dist/runtime/components/SelectMenu.vue.d.ts +106 -2
- package/dist/runtime/components/Separator.vue.d.ts +1 -1
- package/dist/runtime/components/Skeleton.vue.d.ts +1 -1
- package/dist/runtime/components/Slideover.vue +14 -13
- package/dist/runtime/components/Slideover.vue.d.ts +16 -6
- package/dist/runtime/components/Slider.vue.d.ts +5 -5
- package/dist/runtime/components/Stepper.vue.d.ts +1 -1
- package/dist/runtime/components/Switch.vue.d.ts +1 -1
- package/dist/runtime/components/Table.vue +90 -9
- package/dist/runtime/components/Table.vue.d.ts +30 -12
- package/dist/runtime/components/Tabs.vue +24 -4
- package/dist/runtime/components/Tabs.vue.d.ts +12 -4
- package/dist/runtime/components/Textarea.vue +10 -7
- package/dist/runtime/components/Textarea.vue.d.ts +14 -12
- package/dist/runtime/components/Timeline.vue +92 -0
- package/dist/runtime/components/Timeline.vue.d.ts +70 -0
- package/dist/runtime/components/Toast.vue +16 -9
- package/dist/runtime/components/Toast.vue.d.ts +14 -13
- package/dist/runtime/components/Toaster.vue.d.ts +1 -1
- package/dist/runtime/components/Tooltip.vue +2 -1
- package/dist/runtime/components/Tooltip.vue.d.ts +8 -2
- package/dist/runtime/components/Tree.vue +6 -4
- package/dist/runtime/components/Tree.vue.d.ts +2 -2
- package/dist/runtime/composables/defineLocale.d.ts +2 -0
- package/dist/runtime/composables/defineLocale.js +4 -0
- package/dist/runtime/composables/defineShortcuts.js +7 -5
- package/dist/runtime/composables/useAvatarGroup.d.ts +1 -1
- package/dist/runtime/composables/useComponentIcons.d.ts +1 -1
- package/dist/runtime/composables/useFileUpload.d.ts +19 -0
- package/dist/runtime/composables/useFileUpload.js +63 -0
- package/dist/runtime/composables/useFormField.d.ts +3 -6
- package/dist/runtime/composables/useFormField.js +5 -2
- package/dist/runtime/composables/useKbd.d.ts +1 -1
- package/dist/runtime/composables/useLocale.js +2 -2
- package/dist/runtime/composables/useOverlay.d.ts +30 -2
- package/dist/runtime/composables/useOverlay.js +8 -7
- package/dist/runtime/composables/usePortal.d.ts +1 -1
- package/dist/runtime/inertia/components/Link.vue.d.ts +1 -1
- package/dist/runtime/inertia/components/LinkBase.vue.d.ts +1 -1
- package/dist/runtime/inertia/stubs.d.ts +1 -0
- package/dist/runtime/inertia/stubs.js +4 -2
- package/dist/runtime/locale/ar.js +4 -2
- package/dist/runtime/locale/az.js +3 -1
- package/dist/runtime/locale/bg.js +3 -1
- package/dist/runtime/locale/bn.js +3 -1
- package/dist/runtime/locale/ca.js +3 -1
- package/dist/runtime/locale/ckb.js +4 -2
- package/dist/runtime/locale/cs.js +3 -1
- package/dist/runtime/locale/da.js +3 -1
- package/dist/runtime/locale/de.js +3 -1
- package/dist/runtime/locale/el.js +3 -1
- package/dist/runtime/locale/en.js +3 -1
- package/dist/runtime/locale/es.js +3 -1
- package/dist/runtime/locale/et.js +3 -1
- package/dist/runtime/locale/fa_ir.js +3 -1
- package/dist/runtime/locale/fi.js +3 -1
- package/dist/runtime/locale/fr.js +3 -1
- package/dist/runtime/locale/he.js +3 -1
- package/dist/runtime/locale/hi.js +4 -2
- package/dist/runtime/locale/hu.js +3 -1
- package/dist/runtime/locale/hy.js +3 -1
- package/dist/runtime/locale/id.js +3 -1
- package/dist/runtime/locale/index.d.ts +1 -0
- package/dist/runtime/locale/index.js +1 -0
- package/dist/runtime/locale/it.js +3 -1
- package/dist/runtime/locale/ja.js +3 -1
- package/dist/runtime/locale/kk.js +3 -1
- package/dist/runtime/locale/km.js +4 -2
- package/dist/runtime/locale/ko.js +3 -1
- package/dist/runtime/locale/ky.js +3 -1
- package/dist/runtime/locale/lb.d.ts +3 -0
- package/dist/runtime/locale/lb.js +56 -0
- package/dist/runtime/locale/lt.js +3 -1
- package/dist/runtime/locale/mn.js +3 -1
- package/dist/runtime/locale/ms.js +3 -1
- package/dist/runtime/locale/nb_no.js +3 -1
- package/dist/runtime/locale/nl.js +3 -1
- package/dist/runtime/locale/pl.js +3 -1
- package/dist/runtime/locale/pt.js +3 -1
- package/dist/runtime/locale/pt_br.js +3 -1
- package/dist/runtime/locale/ro.js +3 -1
- package/dist/runtime/locale/ru.js +3 -1
- package/dist/runtime/locale/sk.js +3 -1
- package/dist/runtime/locale/sl.js +3 -1
- package/dist/runtime/locale/sv.js +3 -1
- package/dist/runtime/locale/th.js +3 -1
- package/dist/runtime/locale/tj.js +3 -1
- package/dist/runtime/locale/tr.js +3 -1
- package/dist/runtime/locale/ug_cn.js +3 -1
- package/dist/runtime/locale/uk.js +3 -1
- package/dist/runtime/locale/ur.js +3 -1
- package/dist/runtime/locale/uz.js +3 -1
- package/dist/runtime/locale/vi.js +3 -1
- package/dist/runtime/locale/zh_cn.js +3 -1
- package/dist/runtime/locale/zh_tw.js +3 -1
- package/dist/runtime/types/form.d.ts +11 -10
- package/dist/runtime/types/index.d.ts +3 -0
- package/dist/runtime/types/index.js +3 -0
- package/dist/runtime/types/locale.d.ts +2 -0
- package/dist/runtime/types/utils.d.ts +3 -0
- package/dist/runtime/utils/index.d.ts +1 -0
- package/dist/runtime/utils/index.js +9 -0
- package/dist/runtime/vue/components/Icon.vue.d.ts +1 -1
- package/dist/runtime/vue/components/Link.vue.d.ts +1 -1
- package/dist/runtime/vue/stubs.d.ts +1 -0
- package/dist/runtime/vue/stubs.js +3 -1
- package/dist/shared/{ui.Bix4DSU4.mjs → ui.BkSj2DmF.mjs} +560 -55
- package/dist/unplugin.d.mts +2 -0
- package/dist/unplugin.mjs +6 -3
- package/dist/vite.mjs +1 -1
- package/package.json +37 -38
|
@@ -21,12 +21,17 @@ export interface CommandPaletteItem extends Omit<LinkProps, 'type' | 'raw' | 'cu
|
|
|
21
21
|
loading?: boolean;
|
|
22
22
|
disabled?: boolean;
|
|
23
23
|
slot?: string;
|
|
24
|
+
/**
|
|
25
|
+
* The placeholder to display when the item has children.
|
|
26
|
+
*/
|
|
27
|
+
placeholder?: string;
|
|
28
|
+
children?: CommandPaletteItem[];
|
|
24
29
|
onSelect?(e?: Event): void;
|
|
25
30
|
class?: any;
|
|
26
31
|
ui?: Pick<CommandPalette['slots'], 'item' | 'itemLeadingIcon' | 'itemLeadingAvatarSize' | 'itemLeadingAvatar' | 'itemLeadingChipSize' | 'itemLeadingChip' | 'itemLabel' | 'itemLabelPrefix' | 'itemLabelBase' | 'itemLabelSuffix' | 'itemTrailing' | 'itemTrailingKbds' | 'itemTrailingKbdsSize' | 'itemTrailingHighlightedIcon' | 'itemTrailingIcon'>;
|
|
27
32
|
[key: string]: any;
|
|
28
33
|
}
|
|
29
|
-
export interface CommandPaletteGroup<T> {
|
|
34
|
+
export interface CommandPaletteGroup<T extends CommandPaletteItem = CommandPaletteItem> {
|
|
30
35
|
id: string;
|
|
31
36
|
label?: string;
|
|
32
37
|
slot?: string;
|
|
@@ -45,7 +50,7 @@ export interface CommandPaletteGroup<T> {
|
|
|
45
50
|
*/
|
|
46
51
|
highlightedIcon?: string;
|
|
47
52
|
}
|
|
48
|
-
export interface CommandPaletteProps<G
|
|
53
|
+
export interface CommandPaletteProps<G extends CommandPaletteGroup<T> = CommandPaletteGroup<any>, T extends CommandPaletteItem = CommandPaletteItem> extends Pick<ListboxRootProps, 'multiple' | 'disabled' | 'modelValue' | 'defaultValue' | 'highlightOnHover' | 'selectionBehavior'>, Pick<UseComponentIconsProps, 'loading' | 'loadingIcon'> {
|
|
49
54
|
/**
|
|
50
55
|
* The element or component this component should render as.
|
|
51
56
|
* @defaultValue 'div'
|
|
@@ -63,6 +68,12 @@ export interface CommandPaletteProps<G, T> extends Pick<ListboxRootProps, 'multi
|
|
|
63
68
|
* @IconifyIcon
|
|
64
69
|
*/
|
|
65
70
|
selectedIcon?: string;
|
|
71
|
+
/**
|
|
72
|
+
* The icon displayed when an item has children.
|
|
73
|
+
* @defaultValue appConfig.ui.icons.chevronRight
|
|
74
|
+
* @IconifyIcon
|
|
75
|
+
*/
|
|
76
|
+
trailingIcon?: string;
|
|
66
77
|
/**
|
|
67
78
|
* The placeholder text for the input.
|
|
68
79
|
* @defaultValue t('commandPalette.placeholder')
|
|
@@ -86,6 +97,18 @@ export interface CommandPaletteProps<G, T> extends Pick<ListboxRootProps, 'multi
|
|
|
86
97
|
* @IconifyIcon
|
|
87
98
|
*/
|
|
88
99
|
closeIcon?: string;
|
|
100
|
+
/**
|
|
101
|
+
* Display a button to navigate back in history.
|
|
102
|
+
* `{ size: 'md', color: 'neutral', variant: 'link' }`{lang="ts-type"}
|
|
103
|
+
* @defaultValue true
|
|
104
|
+
*/
|
|
105
|
+
back?: boolean | ButtonProps;
|
|
106
|
+
/**
|
|
107
|
+
* The icon displayed in the back button.
|
|
108
|
+
* @defaultValue appConfig.ui.icons.arrowLeft
|
|
109
|
+
* @IconifyIcon
|
|
110
|
+
*/
|
|
111
|
+
backIcon?: string;
|
|
89
112
|
groups?: G[];
|
|
90
113
|
/**
|
|
91
114
|
* Options for [useFuse](https://vueuse.org/integrations/useFuse).
|
|
@@ -108,21 +131,27 @@ export interface CommandPaletteProps<G, T> extends Pick<ListboxRootProps, 'multi
|
|
|
108
131
|
class?: any;
|
|
109
132
|
ui?: CommandPalette['slots'];
|
|
110
133
|
}
|
|
111
|
-
export type CommandPaletteEmits<T> = ListboxRootEmits<T> & {
|
|
134
|
+
export type CommandPaletteEmits<T extends CommandPaletteItem = CommandPaletteItem> = ListboxRootEmits<T> & {
|
|
112
135
|
'update:open': [value: boolean];
|
|
113
136
|
};
|
|
114
137
|
type SlotProps<T> = (props: {
|
|
115
138
|
item: T;
|
|
116
139
|
index: number;
|
|
117
140
|
}) => any;
|
|
118
|
-
export type CommandPaletteSlots<G extends {
|
|
119
|
-
slot?: string;
|
|
120
|
-
}, T extends {
|
|
121
|
-
slot?: string;
|
|
122
|
-
}> = {
|
|
141
|
+
export type CommandPaletteSlots<G extends CommandPaletteGroup<T> = CommandPaletteGroup<any>, T extends CommandPaletteItem = CommandPaletteItem> = {
|
|
123
142
|
'empty'(props: {
|
|
124
143
|
searchTerm?: string;
|
|
125
144
|
}): any;
|
|
145
|
+
'footer'(props: {
|
|
146
|
+
ui: {
|
|
147
|
+
[K in keyof Required<CommandPalette['slots']>]: (props?: Record<string, any>) => string;
|
|
148
|
+
};
|
|
149
|
+
}): any;
|
|
150
|
+
'back'(props: {
|
|
151
|
+
ui: {
|
|
152
|
+
[K in keyof Required<CommandPalette['slots']>]: (props?: Record<string, any>) => string;
|
|
153
|
+
};
|
|
154
|
+
}): any;
|
|
126
155
|
'close'(props: {
|
|
127
156
|
ui: {
|
|
128
157
|
[K in keyof Required<CommandPalette['slots']>]: (props?: Record<string, any>) => string;
|
|
@@ -159,5 +188,5 @@ declare const _default: <G extends CommandPaletteGroup<T>, T extends CommandPale
|
|
|
159
188
|
};
|
|
160
189
|
export default _default;
|
|
161
190
|
type __VLS_PrettifyLocal<T> = {
|
|
162
|
-
[K in keyof T]: T[K];
|
|
191
|
+
[K in keyof T as K]: T[K];
|
|
163
192
|
} & {};
|
|
@@ -9,7 +9,7 @@ export interface ContainerProps {
|
|
|
9
9
|
export interface ContainerSlots {
|
|
10
10
|
default(props?: {}): any;
|
|
11
11
|
}
|
|
12
|
-
declare const _default: __VLS_WithSlots<import("vue").DefineComponent<ContainerProps,
|
|
12
|
+
declare const _default: __VLS_WithSlots<import("vue").DefineComponent<ContainerProps, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ContainerProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ContainerSlots>;
|
|
13
13
|
export default _default;
|
|
14
14
|
type __VLS_WithSlots<T, S> = T & {
|
|
15
15
|
new (): {
|
|
@@ -31,35 +31,19 @@ interface ContextMenuContentProps<T extends ArrayOrNested<ContextMenuItem>> exte
|
|
|
31
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
32
|
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
33
33
|
readonly onEscapeKeyDown?: ((event: KeyboardEvent) => any) | undefined;
|
|
34
|
-
readonly onPointerDownOutside?: ((event:
|
|
35
|
-
|
|
36
|
-
|
|
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;
|
|
34
|
+
readonly onPointerDownOutside?: ((event: import("reka-ui").PointerDownOutsideEvent) => any) | undefined;
|
|
35
|
+
readonly onFocusOutside?: ((event: import("reka-ui").FocusOutsideEvent) => any) | undefined;
|
|
36
|
+
readonly onInteractOutside?: ((event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => any) | undefined;
|
|
45
37
|
readonly onCloseAutoFocus?: ((event: Event) => any) | undefined;
|
|
46
38
|
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onEscapeKeyDown" | "onPointerDownOutside" | "onFocusOutside" | "onInteractOutside" | "onCloseAutoFocus"> & ContextMenuContentProps<T> & Partial<{}>> & import("vue").PublicProps;
|
|
47
39
|
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
|
|
48
40
|
attrs: any;
|
|
49
41
|
slots: ContextMenuSlots<T>;
|
|
50
|
-
emit: ((evt: "escapeKeyDown", event: KeyboardEvent) => void) & ((evt: "pointerDownOutside", event:
|
|
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);
|
|
42
|
+
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);
|
|
59
43
|
}>) => import("vue").VNode & {
|
|
60
44
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
61
45
|
};
|
|
62
46
|
export default _default;
|
|
63
47
|
type __VLS_PrettifyLocal<T> = {
|
|
64
|
-
[K in keyof T]: T[K];
|
|
48
|
+
[K in keyof T as K]: T[K];
|
|
65
49
|
} & {};
|
|
@@ -5,7 +5,7 @@ import theme from "#build/ui/drawer";
|
|
|
5
5
|
<script setup>
|
|
6
6
|
import { computed, toRef } from "vue";
|
|
7
7
|
import { VisuallyHidden, useForwardPropsEmits } from "reka-ui";
|
|
8
|
-
import { DrawerRoot, DrawerTrigger, DrawerPortal, DrawerOverlay, DrawerContent, DrawerTitle, DrawerDescription, DrawerHandle } from "vaul-vue";
|
|
8
|
+
import { DrawerRoot, DrawerRootNested, DrawerTrigger, DrawerPortal, DrawerOverlay, DrawerContent, DrawerTitle, DrawerDescription, DrawerHandle } from "vaul-vue";
|
|
9
9
|
import { reactivePick } from "@vueuse/core";
|
|
10
10
|
import { useAppConfig } from "#imports";
|
|
11
11
|
import { usePortal } from "../composables/usePortal";
|
|
@@ -19,6 +19,7 @@ const props = defineProps({
|
|
|
19
19
|
overlay: { type: Boolean, required: false, default: true },
|
|
20
20
|
handle: { type: Boolean, required: false, default: true },
|
|
21
21
|
portal: { type: [Boolean, String], required: false, skipCheck: true, default: true },
|
|
22
|
+
nested: { type: Boolean, required: false },
|
|
22
23
|
class: { type: null, required: false },
|
|
23
24
|
ui: { type: null, required: false },
|
|
24
25
|
activeSnapPoint: { type: [Number, String, null], required: false },
|
|
@@ -31,7 +32,6 @@ const props = defineProps({
|
|
|
31
32
|
modal: { type: Boolean, required: false, default: true },
|
|
32
33
|
open: { type: Boolean, required: false },
|
|
33
34
|
defaultOpen: { type: Boolean, required: false },
|
|
34
|
-
nested: { type: Boolean, required: false },
|
|
35
35
|
direction: { type: String, required: false, default: "bottom" },
|
|
36
36
|
noBodyStyles: { type: Boolean, required: false },
|
|
37
37
|
handleOnly: { type: Boolean, required: false },
|
|
@@ -54,7 +54,7 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.drawer || {}
|
|
|
54
54
|
</script>
|
|
55
55
|
|
|
56
56
|
<template>
|
|
57
|
-
<DrawerRoot v-bind="rootProps">
|
|
57
|
+
<component :is="nested ? DrawerRootNested : DrawerRoot" v-bind="rootProps">
|
|
58
58
|
<DrawerTrigger v-if="!!slots.default" as-child :class="props.class">
|
|
59
59
|
<slot />
|
|
60
60
|
</DrawerTrigger>
|
|
@@ -108,5 +108,5 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.drawer || {}
|
|
|
108
108
|
</slot>
|
|
109
109
|
</DrawerContent>
|
|
110
110
|
</DrawerPortal>
|
|
111
|
-
</
|
|
111
|
+
</component>
|
|
112
112
|
</template>
|
|
@@ -34,6 +34,11 @@ export interface DrawerProps extends Pick<DrawerRootProps, 'activeSnapPoint' | '
|
|
|
34
34
|
* @defaultValue true
|
|
35
35
|
*/
|
|
36
36
|
portal?: boolean | string | HTMLElement;
|
|
37
|
+
/**
|
|
38
|
+
* Whether the drawer is nested in another drawer.
|
|
39
|
+
* @defaultValue false
|
|
40
|
+
*/
|
|
41
|
+
nested?: boolean;
|
|
37
42
|
class?: any;
|
|
38
43
|
ui?: Drawer['slots'];
|
|
39
44
|
}
|
|
@@ -48,7 +53,7 @@ export interface DrawerSlots {
|
|
|
48
53
|
body(props?: {}): any;
|
|
49
54
|
footer(props?: {}): any;
|
|
50
55
|
}
|
|
51
|
-
declare const _default: __VLS_WithSlots<import("vue").DefineComponent<DrawerProps,
|
|
56
|
+
declare const _default: __VLS_WithSlots<import("vue").DefineComponent<DrawerProps, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
52
57
|
close: () => any;
|
|
53
58
|
drag: (percentageDragged: number) => any;
|
|
54
59
|
"update:open": (open: boolean) => any;
|
|
@@ -2,7 +2,7 @@ import { DropdownMenu } from 'reka-ui/namespaced';
|
|
|
2
2
|
import type { DropdownMenuContentProps as RekaDropdownMenuContentProps } from 'reka-ui';
|
|
3
3
|
import type { AppConfig } from '@nuxt/schema';
|
|
4
4
|
import type theme from '#build/ui/dropdown-menu';
|
|
5
|
-
import type { DropdownMenuItem, DropdownMenuSlots } from '../types';
|
|
5
|
+
import type { DropdownMenuItem, DropdownMenuSlots, DynamicSlots, MergeTypes } from '../types';
|
|
6
6
|
import type { ArrayOrNested, NestedItem, ComponentConfig } from '../types/utils';
|
|
7
7
|
type DropdownMenu = ComponentConfig<typeof theme, AppConfig, 'dropdownMenu'>;
|
|
8
8
|
interface DropdownMenuContentProps<T extends ArrayOrNested<DropdownMenuItem>> extends Omit<RekaDropdownMenuContentProps, 'as' | 'asChild' | 'forceMount'> {
|
|
@@ -28,41 +28,28 @@ interface DropdownMenuContentProps<T extends ArrayOrNested<DropdownMenuItem>> ex
|
|
|
28
28
|
};
|
|
29
29
|
uiOverride?: DropdownMenu['slots'];
|
|
30
30
|
}
|
|
31
|
-
type DropdownMenuContentSlots<
|
|
31
|
+
type DropdownMenuContentSlots<A extends ArrayOrNested<DropdownMenuItem> = ArrayOrNested<DropdownMenuItem>, T extends NestedItem<A> = NestedItem<A>> = Pick<DropdownMenuSlots<A>, 'item' | 'item-leading' | 'item-label' | 'item-trailing' | 'content-top' | 'content-bottom'> & {
|
|
32
32
|
default(props?: {}): any;
|
|
33
|
-
}
|
|
33
|
+
} & DynamicSlots<MergeTypes<T>, 'leading' | 'label' | 'trailing', {
|
|
34
|
+
active?: boolean;
|
|
35
|
+
index: number;
|
|
36
|
+
}>;
|
|
34
37
|
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<{
|
|
35
38
|
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
36
39
|
readonly onEscapeKeyDown?: ((event: KeyboardEvent) => any) | undefined;
|
|
37
|
-
readonly onPointerDownOutside?: ((event:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
readonly onFocusOutside?: ((event: CustomEvent<{
|
|
41
|
-
originalEvent: FocusEvent;
|
|
42
|
-
}>) => any) | undefined;
|
|
43
|
-
readonly onInteractOutside?: ((event: CustomEvent<{
|
|
44
|
-
originalEvent: PointerEvent;
|
|
45
|
-
}> | CustomEvent<{
|
|
46
|
-
originalEvent: FocusEvent;
|
|
47
|
-
}>) => any) | undefined;
|
|
40
|
+
readonly onPointerDownOutside?: ((event: import("reka-ui").PointerDownOutsideEvent) => any) | undefined;
|
|
41
|
+
readonly onFocusOutside?: ((event: import("reka-ui").FocusOutsideEvent) => any) | undefined;
|
|
42
|
+
readonly onInteractOutside?: ((event: import("reka-ui").PointerDownOutsideEvent | import("reka-ui").FocusOutsideEvent) => any) | undefined;
|
|
48
43
|
readonly onCloseAutoFocus?: ((event: Event) => any) | undefined;
|
|
49
44
|
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onEscapeKeyDown" | "onPointerDownOutside" | "onFocusOutside" | "onInteractOutside" | "onCloseAutoFocus"> & DropdownMenuContentProps<T> & Partial<{}>> & import("vue").PublicProps;
|
|
50
45
|
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
|
|
51
46
|
attrs: any;
|
|
52
|
-
slots: DropdownMenuContentSlots<T
|
|
53
|
-
emit: ((evt: "escapeKeyDown", event: KeyboardEvent) => void) & ((evt: "pointerDownOutside", event:
|
|
54
|
-
originalEvent: PointerEvent;
|
|
55
|
-
}>) => void) & ((evt: "focusOutside", event: CustomEvent<{
|
|
56
|
-
originalEvent: FocusEvent;
|
|
57
|
-
}>) => void) & ((evt: "interactOutside", event: CustomEvent<{
|
|
58
|
-
originalEvent: PointerEvent;
|
|
59
|
-
}> | CustomEvent<{
|
|
60
|
-
originalEvent: FocusEvent;
|
|
61
|
-
}>) => void) & ((evt: "closeAutoFocus", event: Event) => void);
|
|
47
|
+
slots: DropdownMenuContentSlots<T, NestedItem<T>>;
|
|
48
|
+
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);
|
|
62
49
|
}>) => import("vue").VNode & {
|
|
63
50
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
64
51
|
};
|
|
65
52
|
export default _default;
|
|
66
53
|
type __VLS_PrettifyLocal<T> = {
|
|
67
|
-
[K in keyof T]: T[K];
|
|
54
|
+
[K in keyof T as K]: T[K];
|
|
68
55
|
} & {};
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import theme from "#build/ui/file-upload";
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script setup>
|
|
6
|
+
import { computed, watch } from "vue";
|
|
7
|
+
import { Primitive } from "reka-ui";
|
|
8
|
+
import { createReusableTemplate } from "@vueuse/core";
|
|
9
|
+
import { useAppConfig } from "#imports";
|
|
10
|
+
import { useFormField } from "../composables/useFormField";
|
|
11
|
+
import { useFileUpload } from "../composables/useFileUpload";
|
|
12
|
+
import { tv } from "../utils/tv";
|
|
13
|
+
import UAvatar from "./Avatar.vue";
|
|
14
|
+
import UButton from "./Button.vue";
|
|
15
|
+
import UIcon from "./Icon.vue";
|
|
16
|
+
defineOptions({ inheritAttrs: false });
|
|
17
|
+
const props = defineProps({
|
|
18
|
+
as: { type: null, required: false },
|
|
19
|
+
id: { type: String, required: false },
|
|
20
|
+
name: { type: String, required: false },
|
|
21
|
+
icon: { type: String, required: false },
|
|
22
|
+
label: { type: String, required: false },
|
|
23
|
+
description: { type: String, required: false },
|
|
24
|
+
color: { type: null, required: false },
|
|
25
|
+
variant: { type: null, required: false },
|
|
26
|
+
size: { type: null, required: false },
|
|
27
|
+
layout: { type: null, required: false, default: "grid" },
|
|
28
|
+
position: { type: null, required: false, default: "outside" },
|
|
29
|
+
highlight: { type: Boolean, required: false },
|
|
30
|
+
accept: { type: String, required: false, default: "*" },
|
|
31
|
+
multiple: { type: Boolean, required: false, default: false },
|
|
32
|
+
reset: { type: Boolean, required: false, default: false },
|
|
33
|
+
dropzone: { type: Boolean, required: false, default: true },
|
|
34
|
+
interactive: { type: Boolean, required: false, default: true },
|
|
35
|
+
required: { type: Boolean, required: false },
|
|
36
|
+
disabled: { type: Boolean, required: false },
|
|
37
|
+
fileIcon: { type: String, required: false },
|
|
38
|
+
fileDelete: { type: [Boolean, Object], required: false },
|
|
39
|
+
fileDeleteIcon: { type: String, required: false },
|
|
40
|
+
class: { type: null, required: false },
|
|
41
|
+
ui: { type: null, required: false }
|
|
42
|
+
});
|
|
43
|
+
const emits = defineEmits(["update:modelValue", "change"]);
|
|
44
|
+
const slots = defineSlots();
|
|
45
|
+
const modelValue = defineModel({ type: null });
|
|
46
|
+
const appConfig = useAppConfig();
|
|
47
|
+
const [DefineFilesTemplate, ReuseFilesTemplate] = createReusableTemplate();
|
|
48
|
+
const { isDragging, open, inputRef, dropzoneRef } = useFileUpload({
|
|
49
|
+
accept: props.accept,
|
|
50
|
+
reset: props.reset,
|
|
51
|
+
multiple: props.multiple,
|
|
52
|
+
dropzone: props.dropzone,
|
|
53
|
+
onUpdate
|
|
54
|
+
});
|
|
55
|
+
const { emitFormInput, emitFormChange, id, name, disabled, ariaAttrs } = useFormField(props);
|
|
56
|
+
const variant = computed(() => props.multiple ? "area" : props.variant);
|
|
57
|
+
const layout = computed(() => props.variant === "button" && !props.multiple ? "grid" : props.layout);
|
|
58
|
+
const position = computed(() => {
|
|
59
|
+
if (layout.value === "grid" && props.multiple) {
|
|
60
|
+
return "inside";
|
|
61
|
+
}
|
|
62
|
+
if (variant.value === "button") {
|
|
63
|
+
return "outside";
|
|
64
|
+
}
|
|
65
|
+
return props.position;
|
|
66
|
+
});
|
|
67
|
+
const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.fileUpload || {} })({
|
|
68
|
+
dropzone: props.dropzone,
|
|
69
|
+
interactive: props.interactive,
|
|
70
|
+
color: props.color,
|
|
71
|
+
size: props.size,
|
|
72
|
+
variant: variant.value,
|
|
73
|
+
layout: layout.value,
|
|
74
|
+
position: position.value,
|
|
75
|
+
multiple: props.multiple,
|
|
76
|
+
highlight: props.highlight,
|
|
77
|
+
disabled: props.disabled
|
|
78
|
+
}));
|
|
79
|
+
function createObjectUrl(file) {
|
|
80
|
+
return URL.createObjectURL(file);
|
|
81
|
+
}
|
|
82
|
+
function formatFileSize(bytes) {
|
|
83
|
+
if (bytes === 0) {
|
|
84
|
+
return "0B";
|
|
85
|
+
}
|
|
86
|
+
const k = 1024;
|
|
87
|
+
const sizes = ["B", "KB", "MB", "GB"];
|
|
88
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
89
|
+
const size = bytes / Math.pow(k, i);
|
|
90
|
+
const formattedSize = i === 0 ? size.toString() : size.toFixed(0);
|
|
91
|
+
return `${formattedSize}${sizes[i]}`;
|
|
92
|
+
}
|
|
93
|
+
function onUpdate(files, reset = false) {
|
|
94
|
+
if (props.multiple) {
|
|
95
|
+
if (reset) {
|
|
96
|
+
modelValue.value = files;
|
|
97
|
+
} else {
|
|
98
|
+
const existingFiles = modelValue.value || [];
|
|
99
|
+
modelValue.value = [...existingFiles, ...files || []];
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
modelValue.value = files?.[0];
|
|
103
|
+
}
|
|
104
|
+
const event = new Event("change", { target: { value: modelValue.value } });
|
|
105
|
+
emits("change", event);
|
|
106
|
+
emitFormChange();
|
|
107
|
+
emitFormInput();
|
|
108
|
+
}
|
|
109
|
+
function removeFile(index) {
|
|
110
|
+
if (!modelValue.value) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (!props.multiple || index === void 0) {
|
|
114
|
+
onUpdate([], true);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const files = [...modelValue.value];
|
|
118
|
+
files.splice(index, 1);
|
|
119
|
+
onUpdate(files, true);
|
|
120
|
+
}
|
|
121
|
+
watch(modelValue, (newValue) => {
|
|
122
|
+
const hasModelReset = !Array.isArray(newValue) || !newValue.length;
|
|
123
|
+
if (hasModelReset && inputRef.value) {
|
|
124
|
+
inputRef.value.value = "";
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
defineExpose({
|
|
128
|
+
inputRef,
|
|
129
|
+
dropzoneRef
|
|
130
|
+
});
|
|
131
|
+
</script>
|
|
132
|
+
|
|
133
|
+
<template>
|
|
134
|
+
<DefineFilesTemplate>
|
|
135
|
+
<template v-if="modelValue && (Array.isArray(modelValue) ? modelValue.length : true)">
|
|
136
|
+
<slot name="files-top" :files="modelValue" :open="open" :remove-file="removeFile" />
|
|
137
|
+
|
|
138
|
+
<div :class="ui.files({ class: props.ui?.files })">
|
|
139
|
+
<slot name="files" :files="modelValue">
|
|
140
|
+
<div v-for="(file, index) in Array.isArray(modelValue) ? modelValue : [modelValue]" :key="file.name" :class="ui.file({ class: props.ui?.file })">
|
|
141
|
+
<slot name="file" :file="file" :index="index">
|
|
142
|
+
<slot name="file-leading" :file="file" :index="index">
|
|
143
|
+
<UAvatar :src="createObjectUrl(file)" :icon="fileIcon || appConfig.ui.icons.file" :size="props.size" :class="ui.fileLeadingAvatar({ class: props.ui?.fileLeadingAvatar })" />
|
|
144
|
+
</slot>
|
|
145
|
+
|
|
146
|
+
<div :class="ui.fileWrapper({ class: props.ui?.fileWrapper })">
|
|
147
|
+
<span :class="ui.fileName({ class: props.ui?.fileName })">
|
|
148
|
+
<slot name="file-name" :file="file" :index="index">
|
|
149
|
+
{{ file.name }}
|
|
150
|
+
</slot>
|
|
151
|
+
</span>
|
|
152
|
+
|
|
153
|
+
<span :class="ui.fileSize({ class: props.ui?.fileSize })">
|
|
154
|
+
<slot name="file-size" :file="file" :index="index">
|
|
155
|
+
{{ formatFileSize(file.size) }}
|
|
156
|
+
</slot>
|
|
157
|
+
</span>
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
<slot name="file-trailing" :file="file" :index="index">
|
|
161
|
+
<UButton
|
|
162
|
+
color="neutral"
|
|
163
|
+
v-bind="{
|
|
164
|
+
...layout === 'grid' ? {
|
|
165
|
+
variant: 'solid',
|
|
166
|
+
size: 'xs'
|
|
167
|
+
} : {
|
|
168
|
+
variant: 'link',
|
|
169
|
+
size
|
|
170
|
+
},
|
|
171
|
+
...typeof fileDelete === 'object' ? fileDelete : void 0
|
|
172
|
+
}"
|
|
173
|
+
:trailing-icon="fileDeleteIcon || appConfig.ui.icons.close"
|
|
174
|
+
:class="ui.fileTrailingButton({ class: props.ui?.fileTrailingButton })"
|
|
175
|
+
@click.stop.prevent="removeFile(index)"
|
|
176
|
+
/>
|
|
177
|
+
</slot>
|
|
178
|
+
</slot>
|
|
179
|
+
</div>
|
|
180
|
+
</slot>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<slot name="files-bottom" :files="modelValue" :open="open" :remove-file="removeFile" />
|
|
184
|
+
</template>
|
|
185
|
+
</DefineFilesTemplate>
|
|
186
|
+
|
|
187
|
+
<Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })">
|
|
188
|
+
<slot :open="open" :remove-file="removeFile">
|
|
189
|
+
<component
|
|
190
|
+
:is="variant === 'button' ? 'button' : 'div'"
|
|
191
|
+
ref="dropzoneRef"
|
|
192
|
+
:role="variant === 'button' ? void 0 : 'button'"
|
|
193
|
+
:data-dragging="isDragging"
|
|
194
|
+
:class="ui.base({ class: props.ui?.base })"
|
|
195
|
+
:tabindex="interactive && !disabled ? 0 : -1"
|
|
196
|
+
@click="interactive && !disabled && open()"
|
|
197
|
+
>
|
|
198
|
+
<ReuseFilesTemplate v-if="position === 'inside'" />
|
|
199
|
+
|
|
200
|
+
<div v-if="position === 'inside' ? multiple ? !modelValue?.length : !modelValue : true" :class="ui.wrapper({ class: props.ui?.wrapper })">
|
|
201
|
+
<slot name="leading">
|
|
202
|
+
<UIcon v-if="variant === 'button'" :name="icon || appConfig.ui.icons.upload" :class="ui.icon({ class: props.ui?.icon })" />
|
|
203
|
+
<UAvatar v-else :icon="icon || appConfig.ui.icons.upload" :size="props.size" :class="ui.avatar({ class: props.ui?.avatar })" />
|
|
204
|
+
</slot>
|
|
205
|
+
|
|
206
|
+
<template v-if="variant !== 'button'">
|
|
207
|
+
<div v-if="label || !!slots.label" :class="ui.label({ class: props.ui?.label })">
|
|
208
|
+
<slot name="label">
|
|
209
|
+
{{ label }}
|
|
210
|
+
</slot>
|
|
211
|
+
</div>
|
|
212
|
+
<div v-if="description || !!slots.description" :class="ui.description({ class: props.ui?.description })">
|
|
213
|
+
<slot name="description">
|
|
214
|
+
{{ description }}
|
|
215
|
+
</slot>
|
|
216
|
+
</div>
|
|
217
|
+
|
|
218
|
+
<div v-if="!!slots.actions" :class="ui.actions({ class: props.ui?.actions })">
|
|
219
|
+
<slot name="actions" :files="modelValue" :open="open" :remove-file="removeFile" />
|
|
220
|
+
</div>
|
|
221
|
+
</template>
|
|
222
|
+
</div>
|
|
223
|
+
</component>
|
|
224
|
+
|
|
225
|
+
<ReuseFilesTemplate v-if="position === 'outside'" />
|
|
226
|
+
</slot>
|
|
227
|
+
|
|
228
|
+
<input
|
|
229
|
+
:id="id"
|
|
230
|
+
ref="inputRef"
|
|
231
|
+
type="file"
|
|
232
|
+
:name="name"
|
|
233
|
+
:accept="accept"
|
|
234
|
+
:multiple="multiple"
|
|
235
|
+
:required="required"
|
|
236
|
+
:disabled="disabled"
|
|
237
|
+
v-bind="{ ...$attrs, ...ariaAttrs }"
|
|
238
|
+
class="sr-only"
|
|
239
|
+
tabindex="-1"
|
|
240
|
+
>
|
|
241
|
+
</Primitive>
|
|
242
|
+
</template>
|