@nuxt/ui 2.8.0 → 2.9.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.
Files changed (104) hide show
  1. package/README.md +1 -0
  2. package/dist/module.d.mts +1147 -1096
  3. package/dist/module.d.ts +1147 -1096
  4. package/dist/module.json +1 -1
  5. package/dist/module.mjs +35 -10
  6. package/dist/runtime/components/data/Table.vue +42 -29
  7. package/dist/runtime/components/data/Table.vue.d.ts +20 -13
  8. package/dist/runtime/components/elements/Accordion.vue +25 -22
  9. package/dist/runtime/components/elements/Accordion.vue.d.ts +21 -17
  10. package/dist/runtime/components/elements/Alert.vue +22 -18
  11. package/dist/runtime/components/elements/Alert.vue.d.ts +26 -19
  12. package/dist/runtime/components/elements/Avatar.vue +22 -16
  13. package/dist/runtime/components/elements/Avatar.vue.d.ts +28 -19
  14. package/dist/runtime/components/elements/AvatarGroup.d.ts +17 -8
  15. package/dist/runtime/components/elements/AvatarGroup.mjs +18 -13
  16. package/dist/runtime/components/elements/Badge.vue +21 -17
  17. package/dist/runtime/components/elements/Badge.vue.d.ts +28 -19
  18. package/dist/runtime/components/elements/Button.vue +22 -18
  19. package/dist/runtime/components/elements/Button.vue.d.ts +26 -17
  20. package/dist/runtime/components/elements/ButtonGroup.d.ts +17 -8
  21. package/dist/runtime/components/elements/ButtonGroup.mjs +22 -15
  22. package/dist/runtime/components/elements/Dropdown.vue +15 -13
  23. package/dist/runtime/components/elements/Dropdown.vue.d.ts +20 -17
  24. package/dist/runtime/components/elements/Kbd.vue +16 -12
  25. package/dist/runtime/components/elements/Kbd.vue.d.ts +20 -12
  26. package/dist/runtime/components/elements/Link.vue +18 -5
  27. package/dist/runtime/components/forms/Checkbox.vue +27 -17
  28. package/dist/runtime/components/forms/Checkbox.vue.d.ts +33 -15
  29. package/dist/runtime/components/forms/Form.vue +4 -5
  30. package/dist/runtime/components/forms/Form.vue.d.ts +1 -1
  31. package/dist/runtime/components/forms/FormGroup.vue +51 -27
  32. package/dist/runtime/components/forms/FormGroup.vue.d.ts +23 -15
  33. package/dist/runtime/components/forms/Input.vue +36 -28
  34. package/dist/runtime/components/forms/Input.vue.d.ts +41 -23
  35. package/dist/runtime/components/forms/Radio.vue +27 -17
  36. package/dist/runtime/components/forms/Radio.vue.d.ts +35 -17
  37. package/dist/runtime/components/forms/Range.vue +26 -16
  38. package/dist/runtime/components/forms/Range.vue.d.ts +36 -17
  39. package/dist/runtime/components/forms/Select.vue +34 -26
  40. package/dist/runtime/components/forms/Select.vue.d.ts +42 -24
  41. package/dist/runtime/components/forms/SelectMenu.vue +43 -33
  42. package/dist/runtime/components/forms/SelectMenu.vue.d.ts +49 -30
  43. package/dist/runtime/components/forms/Textarea.vue +38 -30
  44. package/dist/runtime/components/forms/Textarea.vue.d.ts +41 -23
  45. package/dist/runtime/components/forms/Toggle.vue +26 -15
  46. package/dist/runtime/components/forms/Toggle.vue.d.ts +31 -12
  47. package/dist/runtime/components/layout/Card.vue +15 -10
  48. package/dist/runtime/components/layout/Card.vue.d.ts +17 -9
  49. package/dist/runtime/components/layout/Container.vue +15 -10
  50. package/dist/runtime/components/layout/Container.vue.d.ts +17 -9
  51. package/dist/runtime/components/layout/Skeleton.vue +15 -10
  52. package/dist/runtime/components/layout/Skeleton.vue.d.ts +17 -9
  53. package/dist/runtime/components/navigation/CommandPalette.vue +50 -38
  54. package/dist/runtime/components/navigation/CommandPalette.vue.d.ts +23 -22
  55. package/dist/runtime/components/navigation/CommandPaletteGroup.vue +1 -1
  56. package/dist/runtime/components/navigation/CommandPaletteGroup.vue.d.ts +3 -4
  57. package/dist/runtime/components/navigation/Pagination.vue +65 -56
  58. package/dist/runtime/components/navigation/Pagination.vue.d.ts +29 -22
  59. package/dist/runtime/components/navigation/Tabs.vue +16 -13
  60. package/dist/runtime/components/navigation/Tabs.vue.d.ts +18 -11
  61. package/dist/runtime/components/navigation/VerticalNavigation.vue +15 -13
  62. package/dist/runtime/components/navigation/VerticalNavigation.vue.d.ts +20 -16
  63. package/dist/runtime/components/overlays/ContextMenu.vue +14 -9
  64. package/dist/runtime/components/overlays/ContextMenu.vue.d.ts +18 -10
  65. package/dist/runtime/components/overlays/Modal.vue +15 -13
  66. package/dist/runtime/components/overlays/Modal.vue.d.ts +17 -10
  67. package/dist/runtime/components/overlays/Notification.vue +18 -14
  68. package/dist/runtime/components/overlays/Notification.vue.d.ts +25 -19
  69. package/dist/runtime/components/overlays/Notifications.vue +18 -12
  70. package/dist/runtime/components/overlays/Notifications.vue.d.ts +22 -14
  71. package/dist/runtime/components/overlays/Popover.vue +18 -16
  72. package/dist/runtime/components/overlays/Popover.vue.d.ts +18 -11
  73. package/dist/runtime/components/overlays/Slideover.vue +15 -13
  74. package/dist/runtime/components/overlays/Slideover.vue.d.ts +17 -10
  75. package/dist/runtime/components/overlays/Tooltip.vue +15 -13
  76. package/dist/runtime/components/overlays/Tooltip.vue.d.ts +18 -11
  77. package/dist/runtime/composables/useFormGroup.d.ts +12 -2
  78. package/dist/runtime/composables/useFormGroup.mjs +10 -4
  79. package/dist/runtime/composables/usePopper.mjs +40 -30
  80. package/dist/runtime/composables/useToast.d.ts +3 -3
  81. package/dist/runtime/composables/useUI.d.ts +10 -0
  82. package/dist/runtime/composables/useUI.mjs +24 -0
  83. package/dist/runtime/types/avatar.d.ts +10 -4
  84. package/dist/runtime/types/badge.d.ts +14 -0
  85. package/dist/runtime/types/button.d.ts +10 -3
  86. package/dist/runtime/types/command-palette.d.ts +2 -1
  87. package/dist/runtime/types/form.d.ts +8 -1
  88. package/dist/runtime/types/index.d.ts +2 -0
  89. package/dist/runtime/types/link.d.ts +1 -0
  90. package/dist/runtime/types/notification.d.ts +5 -3
  91. package/dist/runtime/types/tabs.d.ts +1 -0
  92. package/dist/runtime/types/utils.d.ts +11 -0
  93. package/dist/runtime/ui.config.d.ts +1207 -0
  94. package/dist/runtime/{app.config.mjs → ui.config.mjs} +52 -80
  95. package/dist/runtime/utils/index.d.ts +5 -11
  96. package/dist/runtime/utils/index.mjs +21 -9
  97. package/dist/runtime/utils/lodash.d.ts +2 -0
  98. package/dist/runtime/utils/lodash.mjs +23 -0
  99. package/dist/runtime/utils/uid.d.ts +1 -0
  100. package/dist/runtime/utils/uid.mjs +4 -0
  101. package/dist/types.d.mts +1 -1
  102. package/dist/types.d.ts +1 -1
  103. package/package.json +19 -21
  104. package/dist/runtime/app.config.d.ts +0 -1203
package/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/ui",
3
- "version": "2.8.0",
3
+ "version": "2.9.0",
4
4
  "configKey": "ui",
5
5
  "compatibility": {
6
6
  "nuxt": "^3.0.0-rc.8"
package/dist/module.mjs CHANGED
@@ -1,8 +1,9 @@
1
- import { defineNuxtModule, createResolver, resolvePath, installModule, addPlugin, addComponentsDir, addImportsDir } from '@nuxt/kit';
1
+ import { addTemplate, useNuxt, defineNuxtModule, createResolver, installModule, addPlugin, addComponentsDir, addImportsDir } from '@nuxt/kit';
2
2
  import defaultColors from 'tailwindcss/colors.js';
3
3
  import { defaultExtractor as defaultExtractor$1 } from 'tailwindcss/lib/lib/defaultExtractor.js';
4
4
  import { iconsPlugin, getIconCollections } from '@egoist/tailwindcss-icons';
5
- import { omit, kebabCase, upperFirst, camelCase } from 'lodash-es';
5
+ import { kebabCase, upperFirst, camelCase } from 'scule';
6
+ import { dirname } from 'pathe';
6
7
 
7
8
 
8
9
 
@@ -14,7 +15,15 @@ const __filename = __cjs_url__.fileURLToPath(import.meta.url);
14
15
  const __dirname = __cjs_path__.dirname(__filename);
15
16
  const require = __cjs_mod__.createRequire(import.meta.url);
16
17
  const name = "@nuxt/ui";
17
- const version = "2.8.0";
18
+ const version = "2.9.0";
19
+
20
+ function omit(object, keysToOmit) {
21
+ const result = { ...object };
22
+ for (const key of keysToOmit) {
23
+ delete result[key];
24
+ }
25
+ return result;
26
+ }
18
27
 
19
28
  const colorsToExclude = [
20
29
  "inherit",
@@ -251,6 +260,23 @@ const customSafelistExtractor = (prefix, content, colors, safelistColors) => {
251
260
  return classes;
252
261
  };
253
262
 
263
+ function createTemplates(nuxt = useNuxt()) {
264
+ const template = addTemplate({
265
+ filename: "ui.colors.mjs",
266
+ getContents: () => `export default ${JSON.stringify(nuxt.options.appConfig.ui.colors)};`,
267
+ write: true
268
+ });
269
+ const typesTemplate = addTemplate({
270
+ filename: "ui.colors.d.ts",
271
+ getContents: () => `declare module '#ui-colors' { const defaultExport: ${JSON.stringify(nuxt.options.appConfig.ui.colors)}; export default defaultExport; }`,
272
+ write: true
273
+ });
274
+ nuxt.options.alias["#ui-colors"] = dirname(template.dst);
275
+ nuxt.hook("prepare:types", (opts) => {
276
+ opts.references.push({ path: typesTemplate.dst });
277
+ });
278
+ }
279
+
254
280
  const defaultExtractor = defaultExtractor$1({ tailwindConfig: { separator: ":" } });
255
281
  delete defaultColors.lightBlue;
256
282
  delete defaultColors.warmGray;
@@ -276,11 +302,8 @@ const module = defineNuxtModule({
276
302
  const runtimeDir = resolve("./runtime");
277
303
  nuxt.options.build.transpile.push(runtimeDir);
278
304
  nuxt.options.build.transpile.push("@popperjs/core", "@headlessui/vue");
305
+ nuxt.options.alias["#ui"] = runtimeDir;
279
306
  nuxt.options.css.push(resolve(runtimeDir, "ui.css"));
280
- const appConfigFile = await resolvePath(resolve(runtimeDir, "app.config"));
281
- nuxt.hook("app:resolve", (app) => {
282
- app.configs.push(appConfigFile);
283
- });
284
307
  nuxt.hook("tailwindcss:config", function(tailwindConfig) {
285
308
  const globalColors = {
286
309
  ...tailwindConfig.theme.colors || defaultColors,
@@ -319,16 +342,17 @@ const module = defineNuxtModule({
319
342
  };
320
343
  const colors = excludeColors(globalColors);
321
344
  nuxt.options.appConfig.ui = {
322
- ...nuxt.options.appConfig.ui,
323
345
  primary: "green",
324
346
  gray: "cool",
325
- colors
347
+ colors,
348
+ strategy: "merge"
326
349
  };
327
350
  tailwindConfig.safelist = tailwindConfig.safelist || [];
328
351
  tailwindConfig.safelist.push(...generateSafelist(options.safelistColors, colors));
329
352
  tailwindConfig.plugins = tailwindConfig.plugins || [];
330
353
  tailwindConfig.plugins.push(iconsPlugin({ collections: getIconCollections(options.icons) }));
331
354
  });
355
+ createTemplates(nuxt);
332
356
  await installModule("@nuxtjs/color-mode", { classSuffix: "" });
333
357
  await installModule("@nuxtjs/tailwindcss", {
334
358
  exposeConfig: true,
@@ -338,7 +362,8 @@ const module = defineNuxtModule({
338
362
  require("@tailwindcss/forms")({ strategy: "class" }),
339
363
  require("@tailwindcss/aspect-ratio"),
340
364
  require("@tailwindcss/typography"),
341
- require("@tailwindcss/container-queries")
365
+ require("@tailwindcss/container-queries"),
366
+ require("@headlessui/tailwindcss")
342
367
  ],
343
368
  content: {
344
369
  files: [
@@ -1,10 +1,10 @@
1
1
  <template>
2
- <div :class="wrapperClass" v-bind="attrs">
2
+ <div :class="ui.wrapper" v-bind="attrs">
3
3
  <table :class="[ui.base, ui.divide]">
4
4
  <thead :class="ui.thead">
5
5
  <tr :class="ui.tr.base">
6
- <th v-if="modelValue" scope="col" class="ps-4">
7
- <UCheckbox :checked="indeterminate || selected.length === rows.length" :indeterminate="indeterminate" @change="onChange" />
6
+ <th v-if="modelValue" scope="col" :class="ui.checkbox.padding">
7
+ <UCheckbox :checked="indeterminate || selected.length === rows.length" :indeterminate="indeterminate" aria-label="Select all" @change="onChange" />
8
8
  </th>
9
9
 
10
10
  <th v-for="(column, index) in columns" :key="index" scope="col" :class="[ui.th.base, ui.th.padding, ui.th.color, ui.th.font, ui.th.size, column.class]">
@@ -49,12 +49,12 @@
49
49
  </tr>
50
50
 
51
51
  <template v-else>
52
- <tr v-for="(row, index) in rows" :key="index" :class="[ui.tr.base, isSelected(row) && ui.tr.selected, $attrs.onSelect && ui.tr.active]" @click="() => onSelect(row)">
53
- <td v-if="modelValue" class="ps-4">
54
- <UCheckbox v-model="selected" :value="row" @click.stop />
52
+ <tr v-for="(row, index) in rows" :key="index" :class="[ui.tr.base, isSelected(row) && ui.tr.selected, $attrs.onSelect && ui.tr.active, row?.class]" @click="() => onSelect(row)">
53
+ <td v-if="modelValue" :class="ui.checkbox.padding">
54
+ <UCheckbox v-model="selected" :value="row" aria-label="Select row" @click.stop />
55
55
  </td>
56
56
 
57
- <td v-for="(column, subIndex) in columns" :key="subIndex" :class="[ui.td.base, ui.td.padding, ui.td.color, ui.td.font, ui.td.size]">
57
+ <td v-for="(column, subIndex) in columns" :key="subIndex" :class="[ui.td.base, ui.td.padding, ui.td.color, ui.td.font, ui.td.size, row[column.key]?.class]">
58
58
  <slot :name="`${column.key}-data`" :column="column" :row="row" :index="index" :get-row-data="(defaultValue) => getRowData(row, column.key, defaultValue)">
59
59
  {{ getRowData(row, column.key) }}
60
60
  </slot>
@@ -67,16 +67,17 @@
67
67
  </template>
68
68
 
69
69
  <script>
70
- import { ref, computed, defineComponent, toRaw } from "vue";
71
- import { omit, capitalize, orderBy, get } from "lodash-es";
70
+ import { ref, computed, defineComponent, toRaw, toRef } from "vue";
71
+ import { upperFirst } from "scule";
72
72
  import { defu } from "defu";
73
- import { twMerge } from "tailwind-merge";
74
- import { defuTwMerge } from "../../utils";
75
73
  import UButton from "../elements/Button.vue";
76
74
  import UIcon from "../elements/Icon.vue";
77
75
  import UCheckbox from "../forms/Checkbox.vue";
78
- import { useAppConfig } from "#imports";
76
+ import { useUI } from "../../composables/useUI";
77
+ import { mergeConfig, omit, get } from "../../utils";
79
78
  import appConfig from "#build/app.config";
79
+ import { table } from "#ui/ui.config";
80
+ const config = mergeConfig(appConfig.ui.strategy, appConfig.ui.table, table);
80
81
  function defaultComparator(a, z) {
81
82
  return a === z;
82
83
  }
@@ -114,15 +115,15 @@ export default defineComponent({
114
115
  },
115
116
  sortButton: {
116
117
  type: Object,
117
- default: () => appConfig.ui.table.default.sortButton
118
+ default: () => config.default.sortButton
118
119
  },
119
120
  sortAscIcon: {
120
121
  type: String,
121
- default: () => appConfig.ui.table.default.sortAscIcon
122
+ default: () => config.default.sortAscIcon
122
123
  },
123
124
  sortDescIcon: {
124
125
  type: String,
125
- default: () => appConfig.ui.table.default.sortDescIcon
126
+ default: () => config.default.sortDescIcon
126
127
  },
127
128
  loading: {
128
129
  type: Boolean,
@@ -130,30 +131,43 @@ export default defineComponent({
130
131
  },
131
132
  loadingState: {
132
133
  type: Object,
133
- default: () => appConfig.ui.table.default.loadingState
134
+ default: () => config.default.loadingState
134
135
  },
135
136
  emptyState: {
136
137
  type: Object,
137
- default: () => appConfig.ui.table.default.emptyState
138
+ default: () => config.default.emptyState
139
+ },
140
+ class: {
141
+ type: [String, Object, Array],
142
+ default: void 0
138
143
  },
139
144
  ui: {
140
145
  type: Object,
141
- default: () => ({})
146
+ default: void 0
142
147
  }
143
148
  },
144
149
  emits: ["update:modelValue"],
145
- setup(props, { emit, attrs }) {
146
- const appConfig2 = useAppConfig();
147
- const ui = computed(() => defuTwMerge({}, props.ui, appConfig2.ui.table));
148
- const wrapperClass = computed(() => twMerge(ui.value.wrapper, attrs.class));
149
- const columns = computed(() => props.columns ?? Object.keys(omit(props.rows[0] ?? {}, ["click"])).map((key) => ({ key, label: capitalize(key), sortable: false })));
150
+ setup(props, { emit, attrs: $attrs }) {
151
+ const { ui, attrs } = useUI("table", toRef(props, "ui"), config, toRef(props, "class"));
152
+ const columns = computed(() => props.columns ?? Object.keys(omit(props.rows[0] ?? {}, ["click"])).map((key) => ({ key, label: upperFirst(key), sortable: false })));
150
153
  const sort = ref(defu({}, props.sort, { column: null, direction: "asc" }));
151
154
  const rows = computed(() => {
152
155
  if (!sort.value?.column) {
153
156
  return props.rows;
154
157
  }
155
158
  const { column, direction } = sort.value;
156
- return orderBy(props.rows, column, direction);
159
+ return props.rows.slice().sort((a, b) => {
160
+ const aValue = a[column];
161
+ const bValue = b[column];
162
+ if (aValue === bValue) {
163
+ return 0;
164
+ }
165
+ if (direction === "asc") {
166
+ return aValue < bValue ? -1 : 1;
167
+ } else {
168
+ return aValue > bValue ? -1 : 1;
169
+ }
170
+ });
157
171
  });
158
172
  const selected = computed({
159
173
  get() {
@@ -200,17 +214,17 @@ export default defineComponent({
200
214
  }
201
215
  }
202
216
  function onSelect(row) {
203
- if (!attrs.onSelect) {
217
+ if (!$attrs.onSelect) {
204
218
  return;
205
219
  }
206
- attrs.onSelect(row);
220
+ $attrs.onSelect(row);
207
221
  }
208
222
  function selectAllRows() {
209
223
  props.rows.forEach((row) => {
210
224
  if (selected.value.some((item) => compare(toRaw(item), toRaw(row)))) {
211
225
  return;
212
226
  }
213
- onSelect(row);
227
+ $attrs.onSelect ? $attrs.onSelect(row) : selected.value.push(row);
214
228
  });
215
229
  }
216
230
  function onChange(event) {
@@ -224,10 +238,9 @@ export default defineComponent({
224
238
  return get(row, rowKey, defaultValue);
225
239
  }
226
240
  return {
227
- attrs: omit(attrs, ["class"]),
228
241
  // eslint-disable-next-line vue/no-dupe-keys
229
242
  ui,
230
- wrapperClass,
243
+ attrs,
231
244
  // eslint-disable-next-line vue/no-dupe-keys
232
245
  sort,
233
246
  // eslint-disable-next-line vue/no-dupe-keys
@@ -1,6 +1,5 @@
1
- /// <reference types="lodash" />
2
1
  import type { PropType } from 'vue';
3
- import type { Button } from '../../types/button';
2
+ import type { Button } from '../../types';
4
3
  declare function defaultComparator<T>(a: T, z: T): boolean;
5
4
  declare const _default: import("vue").DefineComponent<{
6
5
  modelValue: {
@@ -41,7 +40,7 @@ declare const _default: import("vue").DefineComponent<{
41
40
  };
42
41
  sortButton: {
43
42
  type: PropType<Button>;
44
- default: () => any;
43
+ default: () => Button;
45
44
  };
46
45
  sortAscIcon: {
47
46
  type: StringConstructor;
@@ -69,16 +68,19 @@ declare const _default: import("vue").DefineComponent<{
69
68
  }>;
70
69
  default: () => any;
71
70
  };
72
- ui: {
71
+ class: {
73
72
  type: PropType<any>;
74
- default: () => {};
73
+ default: undefined;
74
+ };
75
+ ui: {
76
+ type: PropType<Partial<any>>;
77
+ default: undefined;
75
78
  };
76
79
  }, {
77
- attrs: import("lodash").Omit<{
78
- [x: string]: unknown;
79
- }, "class">;
80
80
  ui: import("vue").ComputedRef<any>;
81
- wrapperClass: import("vue").ComputedRef<string>;
81
+ attrs: import("vue").ComputedRef<Pick<{
82
+ [x: string]: unknown;
83
+ }, string>>;
82
84
  sort: import("vue").Ref<{
83
85
  direction: string;
84
86
  column: string;
@@ -145,7 +147,7 @@ declare const _default: import("vue").DefineComponent<{
145
147
  };
146
148
  sortButton: {
147
149
  type: PropType<Button>;
148
- default: () => any;
150
+ default: () => Button;
149
151
  };
150
152
  sortAscIcon: {
151
153
  type: StringConstructor;
@@ -173,9 +175,13 @@ declare const _default: import("vue").DefineComponent<{
173
175
  }>;
174
176
  default: () => any;
175
177
  };
176
- ui: {
178
+ class: {
177
179
  type: PropType<any>;
178
- default: () => {};
180
+ default: undefined;
181
+ };
182
+ ui: {
183
+ type: PropType<Partial<any>>;
184
+ default: undefined;
179
185
  };
180
186
  }>> & {
181
187
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
@@ -184,7 +190,8 @@ declare const _default: import("vue").DefineComponent<{
184
190
  column: string;
185
191
  direction: 'asc' | 'desc';
186
192
  };
187
- ui: any;
193
+ ui: Partial<any>;
194
+ class: any;
188
195
  modelValue: unknown[];
189
196
  by: string | Function;
190
197
  rows: {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div :class="wrapperClass">
2
+ <div :class="ui.wrapper">
3
3
  <HDisclosure v-for="(item, index) in items" v-slot="{ open, close }" :key="index" :default-open="defaultOpen || item.defaultOpen">
4
4
  <HDisclosureButton :ref="() => buttonRefs[index] = close" as="template" :disabled="item.disabled">
5
5
  <slot :item="item" :index="index" :open="open" :close="close">
@@ -40,16 +40,17 @@
40
40
  </template>
41
41
 
42
42
  <script>
43
- import { ref, computed, defineComponent } from "vue";
43
+ import { ref, computed, toRef, defineComponent } from "vue";
44
44
  import { Disclosure as HDisclosure, DisclosureButton as HDisclosureButton, DisclosurePanel as HDisclosurePanel } from "@headlessui/vue";
45
- import { omit } from "lodash-es";
46
- import { twMerge } from "tailwind-merge";
47
45
  import UIcon from "../elements/Icon.vue";
48
46
  import UButton from "../elements/Button.vue";
49
- import { defuTwMerge } from "../../utils";
47
+ import { useUI } from "../../composables/useUI";
48
+ import { mergeConfig, omit } from "../../utils";
50
49
  import StateEmitter from "../../utils/StateEmitter";
51
- import { useAppConfig } from "#imports";
52
50
  import appConfig from "#build/app.config";
51
+ import { accordion, button } from "#ui/ui.config";
52
+ const config = mergeConfig(appConfig.ui.strategy, appConfig.ui.accordion, accordion);
53
+ const configButton = mergeConfig(appConfig.ui.strategy, appConfig.ui.button, button);
53
54
  export default defineComponent({
54
55
  components: {
55
56
  HDisclosure,
@@ -71,36 +72,39 @@ export default defineComponent({
71
72
  },
72
73
  openIcon: {
73
74
  type: String,
74
- default: () => appConfig.ui.accordion.default.openIcon
75
+ default: () => config.default.openIcon
75
76
  },
76
77
  closeIcon: {
77
78
  type: String,
78
- default: () => appConfig.ui.accordion.default.closeIcon
79
+ default: () => config.default.closeIcon
79
80
  },
80
81
  multiple: {
81
82
  type: Boolean,
82
83
  default: false
83
84
  },
85
+ class: {
86
+ type: [String, Object, Array],
87
+ default: void 0
88
+ },
84
89
  ui: {
85
90
  type: Object,
86
- default: () => ({})
91
+ default: void 0
87
92
  }
88
93
  },
89
- setup(props, { attrs }) {
90
- const appConfig2 = useAppConfig();
91
- const ui = computed(() => defuTwMerge({}, props.ui, appConfig2.ui.accordion));
92
- const uiButton = computed(() => appConfig2.ui.button);
93
- const wrapperClass = computed(() => twMerge(ui.value.wrapper, attrs.class));
94
+ setup(props) {
95
+ const { ui, attrs } = useUI("accordion", toRef(props, "ui"), config, toRef(props, "class"));
96
+ const uiButton = computed(() => configButton);
94
97
  const buttonRefs = ref([]);
95
- function closeOthers(itemIndex) {
96
- if (!props.items[itemIndex].closeOthers && props.multiple) {
98
+ function closeOthers(currentIndex) {
99
+ if (!props.items[currentIndex].closeOthers && props.multiple) {
97
100
  return;
98
101
  }
99
- buttonRefs.value.forEach((close, index) => {
100
- if (index === itemIndex)
101
- return;
102
+ const totalItems = buttonRefs.value.length;
103
+ const order = Array.from({ length: totalItems }, (_, i) => (currentIndex + i) % totalItems).filter((index) => index !== currentIndex).reverse();
104
+ for (const index of order) {
105
+ const close = buttonRefs.value[index];
102
106
  close();
103
- });
107
+ }
104
108
  }
105
109
  function onEnter(el, done) {
106
110
  el.style.height = "0";
@@ -120,11 +124,10 @@ export default defineComponent({
120
124
  el.addEventListener("transitionend", done, { once: true });
121
125
  }
122
126
  return {
123
- attrs: omit(attrs, ["class"]),
124
127
  // eslint-disable-next-line vue/no-dupe-keys
125
128
  ui,
126
129
  uiButton,
127
- wrapperClass,
130
+ attrs,
128
131
  buttonRefs,
129
132
  closeOthers,
130
133
  omit,
@@ -1,6 +1,6 @@
1
- /// <reference types="lodash" />
2
1
  import type { PropType } from 'vue';
3
- import type { AccordionItem } from '../../types/accordion';
2
+ import { omit } from '../../utils';
3
+ import type { AccordionItem } from '../../types';
4
4
  declare const _default: import("vue").DefineComponent<{
5
5
  items: {
6
6
  type: PropType<AccordionItem[]>;
@@ -22,24 +22,23 @@ declare const _default: import("vue").DefineComponent<{
22
22
  type: BooleanConstructor;
23
23
  default: boolean;
24
24
  };
25
- ui: {
25
+ class: {
26
26
  type: PropType<any>;
27
- default: () => {};
27
+ default: undefined;
28
+ };
29
+ ui: {
30
+ type: PropType<Partial<any>>;
31
+ default: undefined;
28
32
  };
29
33
  }, {
30
- attrs: import("lodash").Omit<{
31
- [x: string]: unknown;
32
- }, "class">;
33
34
  ui: import("vue").ComputedRef<any>;
34
35
  uiButton: import("vue").ComputedRef<any>;
35
- wrapperClass: import("vue").ComputedRef<string>;
36
+ attrs: import("vue").ComputedRef<Pick<{
37
+ [x: string]: unknown;
38
+ }, string>>;
36
39
  buttonRefs: import("vue").Ref<Function[]>;
37
- closeOthers: (itemIndex: number) => void;
38
- omit: {
39
- <T extends object, K extends import("lodash").PropertyName[]>(object: T | null | undefined, ...paths: K): Pick<T, Exclude<keyof T, K[number]>>;
40
- <T_1 extends object, K_1 extends keyof T_1>(object: T_1 | null | undefined, ...paths: import("lodash").Many<K_1>[]): import("lodash").Omit<T_1, K_1>;
41
- <T_2 extends object>(object: T_2 | null | undefined, ...paths: import("lodash").Many<import("lodash").PropertyName>[]): Partial<T_2>;
42
- };
40
+ closeOthers: (currentIndex: number) => void;
41
+ omit: typeof omit;
43
42
  onEnter: (el: HTMLElement, done: any) => void;
44
43
  onBeforeLeave: (el: HTMLElement) => void;
45
44
  onAfterEnter: (el: HTMLElement) => void;
@@ -65,12 +64,17 @@ declare const _default: import("vue").DefineComponent<{
65
64
  type: BooleanConstructor;
66
65
  default: boolean;
67
66
  };
68
- ui: {
67
+ class: {
69
68
  type: PropType<any>;
70
- default: () => {};
69
+ default: undefined;
70
+ };
71
+ ui: {
72
+ type: PropType<Partial<any>>;
73
+ default: undefined;
71
74
  };
72
75
  }>>, {
73
- ui: any;
76
+ ui: Partial<any>;
77
+ class: any;
74
78
  defaultOpen: boolean;
75
79
  items: AccordionItem[];
76
80
  openIcon: string;
@@ -25,22 +25,23 @@
25
25
  <UButton v-for="(action, index) of actions" :key="index" v-bind="{ ...ui.default.actionButton, ...action }" @click.stop="action.click" />
26
26
  </div>
27
27
 
28
- <UButton v-if="closeButton" v-bind="{ ...ui.default.closeButton, ...closeButton }" @click.stop="$emit('close')" />
28
+ <UButton v-if="closeButton" aria-label="Close" v-bind="{ ...ui.default.closeButton, ...closeButton }" @click.stop="$emit('close')" />
29
29
  </div>
30
30
  </div>
31
31
  </div>
32
32
  </template>
33
33
 
34
34
  <script>
35
- import { computed, defineComponent } from "vue";
35
+ import { computed, toRef, defineComponent } from "vue";
36
36
  import { twMerge, twJoin } from "tailwind-merge";
37
37
  import UIcon from "../elements/Icon.vue";
38
38
  import UAvatar from "../elements/Avatar.vue";
39
39
  import UButton from "../elements/Button.vue";
40
- import { defuTwMerge } from "../../utils";
41
- import { useAppConfig } from "#imports";
40
+ import { useUI } from "../../composables/useUI";
41
+ import { mergeConfig } from "../../utils";
42
42
  import appConfig from "#build/app.config";
43
- import { omit } from "lodash-es";
43
+ import { alert } from "#ui/ui.config";
44
+ const config = mergeConfig(appConfig.ui.strategy, appConfig.ui.alert, alert);
44
45
  export default defineComponent({
45
46
  components: {
46
47
  UIcon,
@@ -59,7 +60,7 @@ export default defineComponent({
59
60
  },
60
61
  icon: {
61
62
  type: String,
62
- default: () => appConfig.ui.alert.default.icon
63
+ default: () => config.default.icon
63
64
  },
64
65
  avatar: {
65
66
  type: Object,
@@ -67,7 +68,7 @@ export default defineComponent({
67
68
  },
68
69
  closeButton: {
69
70
  type: Object,
70
- default: () => appConfig.ui.alert.default.closeButton
71
+ default: () => config.default.closeButton
71
72
  },
72
73
  actions: {
73
74
  type: Array,
@@ -75,30 +76,33 @@ export default defineComponent({
75
76
  },
76
77
  color: {
77
78
  type: String,
78
- default: () => appConfig.ui.alert.default.color,
79
+ default: () => config.default.color,
79
80
  validator(value) {
80
- return [...appConfig.ui.colors, ...Object.keys(appConfig.ui.alert.color)].includes(value);
81
+ return [...appConfig.ui.colors, ...Object.keys(config.color)].includes(value);
81
82
  }
82
83
  },
83
84
  variant: {
84
85
  type: String,
85
- default: () => appConfig.ui.alert.default.variant,
86
+ default: () => config.default.variant,
86
87
  validator(value) {
87
88
  return [
88
- ...Object.keys(appConfig.ui.alert.variant),
89
- ...Object.values(appConfig.ui.alert.color).flatMap((value2) => Object.keys(value2))
89
+ ...Object.keys(config.variant),
90
+ ...Object.values(config.color).flatMap((value2) => Object.keys(value2))
90
91
  ].includes(value);
91
92
  }
92
93
  },
94
+ class: {
95
+ type: [String, Object, Array],
96
+ default: void 0
97
+ },
93
98
  ui: {
94
99
  type: Object,
95
- default: () => ({})
100
+ default: void 0
96
101
  }
97
102
  },
98
103
  emits: ["close"],
99
- setup(props, { attrs }) {
100
- const appConfig2 = useAppConfig();
101
- const ui = computed(() => defuTwMerge({}, props.ui, appConfig2.ui.alert));
104
+ setup(props) {
105
+ const { ui, attrs } = useUI("alert", toRef(props, "ui"), config);
102
106
  const alertClass = computed(() => {
103
107
  const variant = ui.value.color?.[props.color]?.[props.variant] || ui.value.variant[props.variant];
104
108
  return twMerge(twJoin(
@@ -107,12 +111,12 @@ export default defineComponent({
107
111
  ui.value.shadow,
108
112
  ui.value.padding,
109
113
  variant?.replaceAll("{color}", props.color)
110
- ), attrs.class);
114
+ ), props.class);
111
115
  });
112
116
  return {
113
- attrs: omit(attrs, ["class"]),
114
117
  // eslint-disable-next-line vue/no-dupe-keys
115
118
  ui,
119
+ attrs,
116
120
  alertClass
117
121
  };
118
122
  }