@nuxt/ui 0.4.1 → 2.8.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 (143) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +63 -50
  3. package/dist/module.cjs +5 -0
  4. package/dist/module.d.mts +1234 -0
  5. package/dist/module.d.ts +1234 -0
  6. package/dist/module.json +8 -0
  7. package/dist/module.mjs +407 -0
  8. package/dist/runtime/app.config.d.ts +1203 -0
  9. package/dist/runtime/app.config.mjs +1057 -0
  10. package/dist/runtime/components/data/Table.vue +251 -0
  11. package/dist/runtime/components/data/Table.vue.d.ts +215 -0
  12. package/dist/runtime/components/elements/Accordion.vue +138 -0
  13. package/dist/runtime/components/elements/Accordion.vue.d.ts +80 -0
  14. package/dist/runtime/components/elements/Alert.vue +120 -0
  15. package/dist/runtime/components/elements/Alert.vue.d.ts +107 -0
  16. package/dist/runtime/components/elements/Avatar.vue +149 -0
  17. package/dist/runtime/components/elements/Avatar.vue.d.ts +115 -0
  18. package/dist/runtime/components/elements/AvatarGroup.d.ts +37 -0
  19. package/dist/runtime/components/elements/AvatarGroup.mjs +53 -0
  20. package/dist/runtime/components/elements/Badge.vue +69 -0
  21. package/dist/runtime/components/elements/Badge.vue.d.ts +63 -0
  22. package/dist/runtime/components/elements/Button.vue +182 -0
  23. package/dist/runtime/components/elements/Button.vue.d.ts +187 -0
  24. package/dist/runtime/components/elements/ButtonGroup.d.ts +39 -0
  25. package/dist/runtime/components/elements/ButtonGroup.mjs +70 -0
  26. package/dist/runtime/components/elements/Dropdown.vue +172 -0
  27. package/dist/runtime/components/elements/Dropdown.vue.d.ts +96 -0
  28. package/dist/runtime/components/elements/Icon.vue +15 -0
  29. package/dist/runtime/components/elements/Icon.vue.d.ts +12 -0
  30. package/dist/runtime/components/elements/Kbd.vue +55 -0
  31. package/dist/runtime/components/elements/Kbd.vue.d.ts +42 -0
  32. package/dist/runtime/components/elements/Link.vue +80 -0
  33. package/dist/runtime/components/elements/Link.vue.d.ts +9 -0
  34. package/dist/runtime/components/forms/Checkbox.vue +136 -0
  35. package/dist/runtime/components/forms/Checkbox.vue.d.ts +129 -0
  36. package/dist/runtime/components/forms/Form.vue +185 -0
  37. package/dist/runtime/components/forms/Form.vue.d.ts +50 -0
  38. package/dist/runtime/components/forms/FormGroup.vue +97 -0
  39. package/dist/runtime/components/forms/FormGroup.vue.d.ts +98 -0
  40. package/dist/runtime/components/forms/Input.vue +250 -0
  41. package/dist/runtime/components/forms/Input.vue.d.ts +214 -0
  42. package/dist/runtime/components/forms/Radio.vue +122 -0
  43. package/dist/runtime/components/forms/Radio.vue.d.ts +109 -0
  44. package/dist/runtime/components/forms/Range.vue +163 -0
  45. package/dist/runtime/components/forms/Range.vue.d.ts +119 -0
  46. package/dist/runtime/components/forms/Select.vue +307 -0
  47. package/dist/runtime/components/forms/Select.vue.d.ts +229 -0
  48. package/dist/runtime/components/forms/SelectMenu.vue +429 -0
  49. package/dist/runtime/components/forms/SelectMenu.vue.d.ts +330 -0
  50. package/dist/runtime/components/forms/Textarea.vue +184 -0
  51. package/dist/runtime/components/forms/Textarea.vue.d.ts +161 -0
  52. package/dist/runtime/components/forms/Toggle.vue +113 -0
  53. package/dist/runtime/components/forms/Toggle.vue.d.ts +83 -0
  54. package/dist/runtime/components/layout/Card.vue +58 -0
  55. package/dist/runtime/components/layout/Card.vue.d.ts +31 -0
  56. package/dist/runtime/components/layout/Container.vue +43 -0
  57. package/dist/runtime/components/layout/Container.vue.d.ts +31 -0
  58. package/dist/runtime/components/layout/Skeleton.vue +37 -0
  59. package/dist/runtime/components/layout/Skeleton.vue.d.ts +22 -0
  60. package/dist/runtime/components/navigation/CommandPalette.vue +304 -0
  61. package/dist/runtime/components/navigation/CommandPalette.vue.d.ts +224 -0
  62. package/dist/runtime/components/navigation/CommandPaletteGroup.vue +152 -0
  63. package/dist/runtime/components/navigation/CommandPaletteGroup.vue.d.ts +63 -0
  64. package/dist/runtime/components/navigation/Pagination.vue +197 -0
  65. package/dist/runtime/components/navigation/Pagination.vue.d.ts +125 -0
  66. package/dist/runtime/components/navigation/Tabs.vue +138 -0
  67. package/dist/runtime/components/navigation/Tabs.vue.d.ts +69 -0
  68. package/dist/runtime/components/navigation/VerticalNavigation.vue +79 -0
  69. package/dist/runtime/components/navigation/VerticalNavigation.vue.d.ts +37 -0
  70. package/dist/runtime/components/overlays/ContextMenu.vue +74 -0
  71. package/dist/runtime/components/overlays/ContextMenu.vue.d.ts +54 -0
  72. package/dist/runtime/components/overlays/Modal.vue +113 -0
  73. package/dist/runtime/components/overlays/Modal.vue.d.ts +82 -0
  74. package/dist/runtime/components/overlays/Notification.vue +197 -0
  75. package/dist/runtime/components/overlays/Notification.vue.d.ts +126 -0
  76. package/dist/runtime/components/overlays/Notifications.vue +61 -0
  77. package/dist/runtime/components/overlays/Notifications.vue.d.ts +41 -0
  78. package/dist/runtime/components/overlays/Popover.vue +139 -0
  79. package/dist/runtime/components/overlays/Popover.vue.d.ts +82 -0
  80. package/dist/runtime/components/overlays/Slideover.vue +103 -0
  81. package/dist/runtime/components/overlays/Slideover.vue.d.ts +84 -0
  82. package/dist/runtime/components/overlays/Tooltip.vue +118 -0
  83. package/dist/runtime/components/overlays/Tooltip.vue.d.ts +82 -0
  84. package/dist/runtime/composables/defineShortcuts.d.ts +13 -0
  85. package/dist/runtime/composables/defineShortcuts.mjs +108 -0
  86. package/dist/runtime/composables/useCopyToClipboard.d.ts +10 -0
  87. package/dist/runtime/composables/useCopyToClipboard.mjs +26 -0
  88. package/dist/runtime/composables/useFormGroup.d.ts +6 -0
  89. package/dist/runtime/composables/useFormGroup.mjs +30 -0
  90. package/dist/runtime/composables/usePopper.d.ts +232 -0
  91. package/dist/runtime/composables/usePopper.mjs +78 -0
  92. package/dist/runtime/composables/useShortcuts.d.ts +12 -0
  93. package/dist/runtime/composables/useShortcuts.mjs +24 -0
  94. package/dist/runtime/composables/useTimer.d.ts +8 -0
  95. package/dist/runtime/composables/useTimer.mjs +51 -0
  96. package/dist/runtime/composables/useToast.d.ts +18 -0
  97. package/dist/runtime/composables/useToast.mjs +22 -0
  98. package/dist/runtime/plugins/colors.d.ts +2 -0
  99. package/dist/runtime/plugins/colors.mjs +46 -0
  100. package/dist/runtime/types/accordion.d.ts +9 -0
  101. package/dist/runtime/types/avatar.d.ts +9 -0
  102. package/dist/runtime/types/button.d.ts +23 -0
  103. package/dist/runtime/types/clipboard.d.ts +3 -0
  104. package/dist/runtime/types/command-palette.d.ts +26 -0
  105. package/dist/runtime/types/dropdown.d.ts +13 -0
  106. package/dist/runtime/types/form.d.ts +21 -0
  107. package/dist/runtime/types/index.d.ts +12 -0
  108. package/dist/runtime/types/link.d.ts +8 -0
  109. package/dist/runtime/types/notification.d.ts +22 -0
  110. package/dist/runtime/types/popper.d.ts +14 -0
  111. package/dist/runtime/types/tabs.d.ts +6 -0
  112. package/dist/runtime/types/vertical-navigation.d.ts +11 -0
  113. package/dist/runtime/ui.css +13 -0
  114. package/dist/runtime/utils/StateEmitter.d.ts +17 -0
  115. package/dist/runtime/utils/StateEmitter.mjs +21 -0
  116. package/dist/runtime/utils/index.d.ts +11 -0
  117. package/dist/runtime/utils/index.mjs +33 -0
  118. package/dist/types.d.mts +15 -0
  119. package/dist/types.d.ts +15 -0
  120. package/package.json +56 -39
  121. package/LICENSE +0 -21
  122. package/dist/assets/styles.css +0 -14
  123. package/dist/components/NButton.vue +0 -22
  124. package/dist/components/NCard.vue +0 -5
  125. package/dist/components/NCheckbox.vue +0 -35
  126. package/dist/components/NDarkToggle.vue +0 -28
  127. package/dist/components/NDialog.vue +0 -59
  128. package/dist/components/NDropdown.vue +0 -31
  129. package/dist/components/NIcon.vue +0 -9
  130. package/dist/components/NLink.vue +0 -20
  131. package/dist/components/NRadio.vue +0 -40
  132. package/dist/components/NSwitch.vue +0 -37
  133. package/dist/components/NTextInput.vue +0 -34
  134. package/dist/components/NTip.vue +0 -16
  135. package/dist/components/NuxtContentLogo.vue +0 -7
  136. package/dist/components/NuxtExampleLayout.vue +0 -82
  137. package/dist/components/NuxtLogo.vue +0 -20
  138. package/dist/components/nuxt/NDarkToggle.vue +0 -28
  139. package/dist/nuxt.d.ts +0 -16
  140. package/dist/nuxt.mjs +0 -36
  141. package/dist/unocss.d.ts +0 -7
  142. package/dist/unocss.mjs +0 -127
  143. package/nuxt.cjs +0 -7
@@ -0,0 +1,63 @@
1
+ import type { PropType } from 'vue';
2
+ import type { Group } from '../../types/command-palette';
3
+ declare const _default: import("vue").DefineComponent<{
4
+ group: {
5
+ type: PropType<Group>;
6
+ required: true;
7
+ };
8
+ query: {
9
+ type: StringConstructor;
10
+ default: string;
11
+ };
12
+ groupAttribute: {
13
+ type: StringConstructor;
14
+ required: true;
15
+ };
16
+ commandAttribute: {
17
+ type: StringConstructor;
18
+ required: true;
19
+ };
20
+ selectedIcon: {
21
+ type: StringConstructor;
22
+ required: true;
23
+ };
24
+ ui: {
25
+ type: PropType<any>;
26
+ default: () => {};
27
+ };
28
+ }, {
29
+ label: import("vue").ComputedRef<any>;
30
+ highlight: (text: string, { indices, value }: {
31
+ indices: number[][];
32
+ value: string;
33
+ }) => string;
34
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
35
+ group: {
36
+ type: PropType<Group>;
37
+ required: true;
38
+ };
39
+ query: {
40
+ type: StringConstructor;
41
+ default: string;
42
+ };
43
+ groupAttribute: {
44
+ type: StringConstructor;
45
+ required: true;
46
+ };
47
+ commandAttribute: {
48
+ type: StringConstructor;
49
+ required: true;
50
+ };
51
+ selectedIcon: {
52
+ type: StringConstructor;
53
+ required: true;
54
+ };
55
+ ui: {
56
+ type: PropType<any>;
57
+ default: () => {};
58
+ };
59
+ }>>, {
60
+ ui: any;
61
+ query: string;
62
+ }, {}>;
63
+ export default _default;
@@ -0,0 +1,197 @@
1
+ <template>
2
+ <div :class="wrapperClass" v-bind="attrs">
3
+ <slot name="prev" :on-click="onClickPrev">
4
+ <UButton
5
+ v-if="prevButton"
6
+ :size="size"
7
+ :disabled="!canGoPrev"
8
+ :class="[ui.base, ui.rounded]"
9
+ v-bind="{ ...ui.default.prevButton, ...prevButton }"
10
+ :ui="{ rounded: '' }"
11
+ @click="onClickPrev"
12
+ />
13
+ </slot>
14
+
15
+ <UButton
16
+ v-for="(page, index) of displayedPages"
17
+ :key="`${page}-${index}`"
18
+ :size="size"
19
+ :label="`${page}`"
20
+ v-bind="page === currentPage ? { ...ui.default.activeButton, ...activeButton } : { ...ui.default.inactiveButton, ...inactiveButton }"
21
+ :class="[{ 'pointer-events-none': typeof page === 'string', 'z-[1]': page === currentPage }, ui.base, ui.rounded]"
22
+ :ui="{ rounded: '' }"
23
+ @click="() => onClickPage(page)"
24
+ />
25
+
26
+ <slot name="next" :on-click="onClickNext">
27
+ <UButton
28
+ v-if="nextButton"
29
+ :size="size"
30
+ :disabled="!canGoNext"
31
+ :class="[ui.base, ui.rounded]"
32
+ v-bind="{ ...ui.default.nextButton, ...nextButton }"
33
+ :ui="{ rounded: '' }"
34
+ @click="onClickNext"
35
+ />
36
+ </slot>
37
+ </div>
38
+ </template>
39
+
40
+ <script>
41
+ import { computed, defineComponent } from "vue";
42
+ import { omit } from "lodash-es";
43
+ import { twMerge } from "tailwind-merge";
44
+ import UButton from "../elements/Button.vue";
45
+ import { defuTwMerge } from "../../utils";
46
+ import { useAppConfig } from "#imports";
47
+ import appConfig from "#build/app.config";
48
+ export default defineComponent({
49
+ components: {
50
+ UButton
51
+ },
52
+ inheritAttrs: false,
53
+ props: {
54
+ modelValue: {
55
+ type: Number,
56
+ required: true
57
+ },
58
+ pageCount: {
59
+ type: Number,
60
+ default: 10
61
+ },
62
+ total: {
63
+ type: Number,
64
+ required: true
65
+ },
66
+ max: {
67
+ type: Number,
68
+ default: 7,
69
+ validate(value) {
70
+ return value >= 7 && value < Number.MAX_VALUE;
71
+ }
72
+ },
73
+ size: {
74
+ type: String,
75
+ default: () => appConfig.ui.pagination.default.size,
76
+ validator(value) {
77
+ return Object.keys(appConfig.ui.button.size).includes(value);
78
+ }
79
+ },
80
+ activeButton: {
81
+ type: Object,
82
+ default: () => appConfig.ui.pagination.default.activeButton
83
+ },
84
+ inactiveButton: {
85
+ type: Object,
86
+ default: () => appConfig.ui.pagination.default.inactiveButton
87
+ },
88
+ prevButton: {
89
+ type: Object,
90
+ default: () => appConfig.ui.pagination.default.prevButton
91
+ },
92
+ nextButton: {
93
+ type: Object,
94
+ default: () => appConfig.ui.pagination.default.nextButton
95
+ },
96
+ divider: {
97
+ type: String,
98
+ default: "\u2026"
99
+ },
100
+ ui: {
101
+ type: Object,
102
+ default: () => ({})
103
+ }
104
+ },
105
+ emits: ["update:modelValue"],
106
+ setup(props, { attrs, emit }) {
107
+ const appConfig2 = useAppConfig();
108
+ const ui = computed(() => defuTwMerge({}, props.ui, appConfig2.ui.pagination));
109
+ const currentPage = computed({
110
+ get() {
111
+ return props.modelValue;
112
+ },
113
+ set(value) {
114
+ emit("update:modelValue", value);
115
+ }
116
+ });
117
+ const pages = computed(() => Array.from({ length: Math.ceil(props.total / props.pageCount) }, (_, i) => i + 1));
118
+ const displayedPages = computed(() => {
119
+ if (!props.max || pages.value.length <= 5) {
120
+ return pages.value;
121
+ } else {
122
+ const current = currentPage.value;
123
+ const max = pages.value.length;
124
+ const r = Math.floor((Math.min(props.max, max) - 5) / 2);
125
+ const r1 = current - r;
126
+ const r2 = current + r;
127
+ const beforeWrapped = r1 - 1 > 1;
128
+ const afterWrapped = r2 + 1 < max;
129
+ const items = [1];
130
+ if (beforeWrapped)
131
+ items.push(props.divider);
132
+ if (!afterWrapped) {
133
+ const addedItems = current + r + 2 - max;
134
+ for (let i = current - r - addedItems; i <= current - r - 1; i++) {
135
+ items.push(i);
136
+ }
137
+ }
138
+ for (let i = r1 > 2 ? r1 : 2; i <= Math.min(max, r2); i++) {
139
+ items.push(i);
140
+ }
141
+ if (!beforeWrapped) {
142
+ const addedItems = 1 - (current - r - 2);
143
+ for (let i = current + r + 1; i <= current + r + addedItems; i++) {
144
+ items.push(i);
145
+ }
146
+ }
147
+ if (afterWrapped)
148
+ items.push(props.divider);
149
+ if (r2 < max)
150
+ items.push(max);
151
+ if (items.length >= 3 && items[1] === props.divider && items[2] === 3) {
152
+ items[1] = 2;
153
+ }
154
+ if (items.length >= 3 && items[items.length - 2] === props.divider && items[items.length - 1] === items.length) {
155
+ items[items.length - 2] = items.length - 1;
156
+ }
157
+ return items;
158
+ }
159
+ });
160
+ const canGoPrev = computed(() => currentPage.value > 1);
161
+ const canGoNext = computed(() => currentPage.value < pages.value.length);
162
+ const wrapperClass = computed(() => twMerge(ui.value.wrapper, attrs.class));
163
+ function onClickPage(page) {
164
+ if (typeof page === "string") {
165
+ return;
166
+ }
167
+ currentPage.value = page;
168
+ }
169
+ function onClickPrev() {
170
+ if (!canGoPrev.value) {
171
+ return;
172
+ }
173
+ currentPage.value--;
174
+ }
175
+ function onClickNext() {
176
+ if (!canGoNext.value) {
177
+ return;
178
+ }
179
+ currentPage.value++;
180
+ }
181
+ return {
182
+ attrs: omit(attrs, ["class"]),
183
+ // eslint-disable-next-line vue/no-dupe-keys
184
+ ui,
185
+ currentPage,
186
+ pages,
187
+ displayedPages,
188
+ canGoPrev,
189
+ canGoNext,
190
+ wrapperClass,
191
+ onClickPrev,
192
+ onClickNext,
193
+ onClickPage
194
+ };
195
+ }
196
+ });
197
+ </script>
@@ -0,0 +1,125 @@
1
+ /// <reference types="lodash" />
2
+ import type { PropType } from 'vue';
3
+ import type { Button } from '../../types/button';
4
+ declare const _default: import("vue").DefineComponent<{
5
+ modelValue: {
6
+ type: NumberConstructor;
7
+ required: true;
8
+ };
9
+ pageCount: {
10
+ type: NumberConstructor;
11
+ default: number;
12
+ };
13
+ total: {
14
+ type: NumberConstructor;
15
+ required: true;
16
+ };
17
+ max: {
18
+ type: NumberConstructor;
19
+ default: number;
20
+ validate(value: any): boolean;
21
+ };
22
+ size: {
23
+ type: StringConstructor;
24
+ default: () => any;
25
+ validator(value: string): boolean;
26
+ };
27
+ activeButton: {
28
+ type: PropType<Button>;
29
+ default: () => any;
30
+ };
31
+ inactiveButton: {
32
+ type: PropType<Button>;
33
+ default: () => any;
34
+ };
35
+ prevButton: {
36
+ type: PropType<Button>;
37
+ default: () => any;
38
+ };
39
+ nextButton: {
40
+ type: PropType<Button>;
41
+ default: () => any;
42
+ };
43
+ divider: {
44
+ type: StringConstructor;
45
+ default: string;
46
+ };
47
+ ui: {
48
+ type: PropType<any>;
49
+ default: () => {};
50
+ };
51
+ }, {
52
+ attrs: import("lodash").Omit<{
53
+ [x: string]: unknown;
54
+ }, "class">;
55
+ ui: import("vue").ComputedRef<any>;
56
+ currentPage: import("vue").WritableComputedRef<number>;
57
+ pages: import("vue").ComputedRef<number[]>;
58
+ displayedPages: import("vue").ComputedRef<(string | number)[]>;
59
+ canGoPrev: import("vue").ComputedRef<boolean>;
60
+ canGoNext: import("vue").ComputedRef<boolean>;
61
+ wrapperClass: import("vue").ComputedRef<string>;
62
+ onClickPrev: () => void;
63
+ onClickNext: () => void;
64
+ onClickPage: (page: number | string) => void;
65
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "update:modelValue"[], "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
66
+ modelValue: {
67
+ type: NumberConstructor;
68
+ required: true;
69
+ };
70
+ pageCount: {
71
+ type: NumberConstructor;
72
+ default: number;
73
+ };
74
+ total: {
75
+ type: NumberConstructor;
76
+ required: true;
77
+ };
78
+ max: {
79
+ type: NumberConstructor;
80
+ default: number;
81
+ validate(value: any): boolean;
82
+ };
83
+ size: {
84
+ type: StringConstructor;
85
+ default: () => any;
86
+ validator(value: string): boolean;
87
+ };
88
+ activeButton: {
89
+ type: PropType<Button>;
90
+ default: () => any;
91
+ };
92
+ inactiveButton: {
93
+ type: PropType<Button>;
94
+ default: () => any;
95
+ };
96
+ prevButton: {
97
+ type: PropType<Button>;
98
+ default: () => any;
99
+ };
100
+ nextButton: {
101
+ type: PropType<Button>;
102
+ default: () => any;
103
+ };
104
+ divider: {
105
+ type: StringConstructor;
106
+ default: string;
107
+ };
108
+ ui: {
109
+ type: PropType<any>;
110
+ default: () => {};
111
+ };
112
+ }>> & {
113
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
114
+ }, {
115
+ ui: any;
116
+ size: string;
117
+ max: number;
118
+ pageCount: number;
119
+ activeButton: Button;
120
+ inactiveButton: Button;
121
+ prevButton: Button;
122
+ nextButton: Button;
123
+ divider: string;
124
+ }, {}>;
125
+ export default _default;
@@ -0,0 +1,138 @@
1
+ <template>
2
+ <HTabGroup
3
+ :vertical="orientation === 'vertical'"
4
+ :selected-index="selectedIndex"
5
+ as="div"
6
+ :class="wrapperClass"
7
+ v-bind="attrs"
8
+ @change="onChange"
9
+ >
10
+ <HTabList
11
+ ref="listRef"
12
+ :class="[ui.list.base, ui.list.background, ui.list.rounded, ui.list.shadow, ui.list.padding, ui.list.width, orientation === 'horizontal' && ui.list.height, orientation === 'horizontal' && 'inline-grid items-center']"
13
+ :style="[orientation === 'horizontal' && `grid-template-columns: repeat(${items.length}, minmax(0, 1fr))`]"
14
+ >
15
+ <div ref="markerRef" :class="ui.list.marker.wrapper">
16
+ <div :class="[ui.list.marker.base, ui.list.marker.background, ui.list.marker.rounded, ui.list.marker.shadow]" />
17
+ </div>
18
+
19
+ <HTab
20
+ v-for="(item, index) of items"
21
+ :key="index"
22
+ ref="itemRefs"
23
+ v-slot="{ selected, disabled }"
24
+ :disabled="item.disabled"
25
+ as="template"
26
+ >
27
+ <button :class="[ui.list.tab.base, ui.list.tab.background, ui.list.tab.height, ui.list.tab.padding, ui.list.tab.size, ui.list.tab.font, ui.list.tab.rounded, ui.list.tab.shadow, selected ? ui.list.tab.active : ui.list.tab.inactive]">
28
+ <slot :item="item" :index="index" :selected="selected" :disabled="disabled">
29
+ {{ item.label }}
30
+ </slot>
31
+ </button>
32
+ </HTab>
33
+ </HTabList>
34
+
35
+ <HTabPanels :class="ui.container">
36
+ <HTabPanel
37
+ v-for="(item, index) of items"
38
+ :key="index"
39
+ v-slot="{ selected }"
40
+ :class="ui.base"
41
+ >
42
+ <slot :name="item.slot || 'item'" :item="item" :index="index" :selected="selected">
43
+ {{ item.content }}
44
+ </slot>
45
+ </HTabPanel>
46
+ </HTabPanels>
47
+ </HTabGroup>
48
+ </template>
49
+
50
+ <script>
51
+ import { ref, computed, watch, onMounted, defineComponent } from "vue";
52
+ import { TabGroup as HTabGroup, TabList as HTabList, Tab as HTab, TabPanels as HTabPanels, TabPanel as HTabPanel } from "@headlessui/vue";
53
+ import { useResizeObserver } from "@vueuse/core";
54
+ import { omit } from "lodash-es";
55
+ import { twMerge } from "tailwind-merge";
56
+ import { defuTwMerge } from "../../utils";
57
+ import { useAppConfig } from "#imports";
58
+ export default defineComponent({
59
+ components: {
60
+ HTabGroup,
61
+ HTabList,
62
+ HTab,
63
+ HTabPanels,
64
+ HTabPanel
65
+ },
66
+ inheritAttrs: false,
67
+ props: {
68
+ modelValue: {
69
+ type: Number,
70
+ default: void 0
71
+ },
72
+ orientation: {
73
+ type: String,
74
+ default: "horizontal",
75
+ validator: (value) => ["horizontal", "vertical"].includes(value)
76
+ },
77
+ defaultIndex: {
78
+ type: Number,
79
+ default: 0
80
+ },
81
+ items: {
82
+ type: Array,
83
+ default: () => []
84
+ },
85
+ ui: {
86
+ type: Object,
87
+ default: () => ({})
88
+ }
89
+ },
90
+ emits: ["update:modelValue", "change"],
91
+ setup(props, { attrs, emit }) {
92
+ const appConfig2 = useAppConfig();
93
+ const ui = computed(() => defuTwMerge({}, props.ui, appConfig2.ui.tabs));
94
+ const listRef = ref();
95
+ const itemRefs = ref([]);
96
+ const markerRef = ref();
97
+ const selectedIndex = ref(props.modelValue || props.defaultIndex);
98
+ const wrapperClass = computed(() => twMerge(ui.value.wrapper, attrs.class));
99
+ function calcMarkerSize(index) {
100
+ const tab = itemRefs.value[index]?.$el;
101
+ if (!tab) {
102
+ return;
103
+ }
104
+ markerRef.value.style.top = `${tab.offsetTop}px`;
105
+ markerRef.value.style.left = `${tab.offsetLeft}px`;
106
+ markerRef.value.style.width = `${tab.offsetWidth}px`;
107
+ markerRef.value.style.height = `${tab.offsetHeight}px`;
108
+ }
109
+ function onChange(index) {
110
+ selectedIndex.value = index;
111
+ emit("change", index);
112
+ if (props.modelValue !== void 0) {
113
+ emit("update:modelValue", index);
114
+ }
115
+ calcMarkerSize(index);
116
+ }
117
+ useResizeObserver(listRef, () => {
118
+ calcMarkerSize(selectedIndex.value);
119
+ });
120
+ watch(() => props.modelValue, (value) => {
121
+ selectedIndex.value = value;
122
+ calcMarkerSize(value);
123
+ });
124
+ onMounted(() => calcMarkerSize(selectedIndex.value));
125
+ return {
126
+ attrs: omit(attrs, ["class"]),
127
+ // eslint-disable-next-line vue/no-dupe-keys
128
+ ui,
129
+ listRef,
130
+ itemRefs,
131
+ markerRef,
132
+ selectedIndex,
133
+ wrapperClass,
134
+ onChange
135
+ };
136
+ }
137
+ });
138
+ </script>
@@ -0,0 +1,69 @@
1
+ /// <reference types="lodash" />
2
+ import type { PropType } from 'vue';
3
+ import type { TabItem } from '../../types/tabs';
4
+ declare const _default: import("vue").DefineComponent<{
5
+ modelValue: {
6
+ type: NumberConstructor;
7
+ default: undefined;
8
+ };
9
+ orientation: {
10
+ type: PropType<"horizontal" | "vertical">;
11
+ default: string;
12
+ validator: (value: string) => boolean;
13
+ };
14
+ defaultIndex: {
15
+ type: NumberConstructor;
16
+ default: number;
17
+ };
18
+ items: {
19
+ type: PropType<TabItem[]>;
20
+ default: () => never[];
21
+ };
22
+ ui: {
23
+ type: PropType<any>;
24
+ default: () => {};
25
+ };
26
+ }, {
27
+ attrs: import("lodash").Omit<{
28
+ [x: string]: unknown;
29
+ }, "class">;
30
+ ui: import("vue").ComputedRef<any>;
31
+ listRef: import("vue").Ref<HTMLElement | undefined>;
32
+ itemRefs: import("vue").Ref<HTMLElement[]>;
33
+ markerRef: import("vue").Ref<HTMLElement | undefined>;
34
+ selectedIndex: import("vue").Ref<number>;
35
+ wrapperClass: import("vue").ComputedRef<string>;
36
+ onChange: (index: any) => void;
37
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("change" | "update:modelValue")[], "change" | "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
38
+ modelValue: {
39
+ type: NumberConstructor;
40
+ default: undefined;
41
+ };
42
+ orientation: {
43
+ type: PropType<"horizontal" | "vertical">;
44
+ default: string;
45
+ validator: (value: string) => boolean;
46
+ };
47
+ defaultIndex: {
48
+ type: NumberConstructor;
49
+ default: number;
50
+ };
51
+ items: {
52
+ type: PropType<TabItem[]>;
53
+ default: () => never[];
54
+ };
55
+ ui: {
56
+ type: PropType<any>;
57
+ default: () => {};
58
+ };
59
+ }>> & {
60
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
61
+ onChange?: ((...args: any[]) => any) | undefined;
62
+ }, {
63
+ ui: any;
64
+ modelValue: number;
65
+ items: TabItem[];
66
+ orientation: "horizontal" | "vertical";
67
+ defaultIndex: number;
68
+ }, {}>;
69
+ export default _default;
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <nav :class="wrapperClass" v-bind="attrs">
3
+ <ULink
4
+ v-for="(link, index) of links"
5
+ v-slot="{ isActive }"
6
+ :key="index"
7
+ v-bind="omit(link, ['label', 'icon', 'iconClass', 'avatar', 'badge', 'click'])"
8
+ :class="[ui.base, ui.padding, ui.width, ui.ring, ui.rounded, ui.font, ui.size]"
9
+ :active-class="ui.active"
10
+ :inactive-class="ui.inactive"
11
+ @click="link.click"
12
+ @keyup.enter="$event.target.blur()"
13
+ >
14
+ <slot name="avatar" :link="link" :is-active="isActive">
15
+ <UAvatar
16
+ v-if="link.avatar"
17
+ v-bind="{ size: ui.avatar.size, ...link.avatar }"
18
+ :class="[ui.avatar.base]"
19
+ />
20
+ </slot>
21
+ <slot name="icon" :link="link" :is-active="isActive">
22
+ <UIcon
23
+ v-if="link.icon"
24
+ :name="link.icon"
25
+ :class="[ui.icon.base, isActive ? ui.icon.active : ui.icon.inactive, link.iconClass]"
26
+ />
27
+ </slot>
28
+ <slot :link="link" :is-active="isActive">
29
+ <span v-if="link.label" :class="ui.label">{{ link.label }}</span>
30
+ </slot>
31
+ <slot name="badge" :link="link" :is-active="isActive">
32
+ <span v-if="link.badge" :class="[ui.badge.base, isActive ? ui.badge.active : ui.badge.inactive]">
33
+ {{ link.badge }}
34
+ </span>
35
+ </slot>
36
+ </ULink>
37
+ </nav>
38
+ </template>
39
+
40
+ <script>
41
+ import { computed, defineComponent } from "vue";
42
+ import { omit } from "lodash-es";
43
+ import { twMerge } from "tailwind-merge";
44
+ import UIcon from "../elements/Icon.vue";
45
+ import UAvatar from "../elements/Avatar.vue";
46
+ import ULink from "../elements/Link.vue";
47
+ import { defuTwMerge } from "../../utils";
48
+ import { useAppConfig } from "#imports";
49
+ export default defineComponent({
50
+ components: {
51
+ UIcon,
52
+ UAvatar,
53
+ ULink
54
+ },
55
+ inheritAttrs: false,
56
+ props: {
57
+ links: {
58
+ type: Array,
59
+ default: () => []
60
+ },
61
+ ui: {
62
+ type: Object,
63
+ default: () => ({})
64
+ }
65
+ },
66
+ setup(props, { attrs }) {
67
+ const appConfig2 = useAppConfig();
68
+ const ui = computed(() => defuTwMerge({}, props.ui, appConfig2.ui.verticalNavigation));
69
+ const wrapperClass = computed(() => twMerge(ui.value.wrapper, attrs.class));
70
+ return {
71
+ attrs: omit(attrs, ["class"]),
72
+ // eslint-disable-next-line vue/no-dupe-keys
73
+ ui,
74
+ wrapperClass,
75
+ omit
76
+ };
77
+ }
78
+ });
79
+ </script>