@nuxt/ui 4.10.0 → 4.11.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 (97) hide show
  1. package/.nuxt/ui.static.css +11 -11
  2. package/README.md +1 -0
  3. package/cli/commands/make/locale.mjs +40 -11
  4. package/cli/templates.mjs +2 -2
  5. package/dist/module.d.mts +1 -1
  6. package/dist/module.json +2 -2
  7. package/dist/module.mjs +5 -2
  8. package/dist/runtime/components/AuthForm.d.vue.ts +7 -7
  9. package/dist/runtime/components/AuthForm.vue.d.ts +7 -7
  10. package/dist/runtime/components/Button.vue +11 -2
  11. package/dist/runtime/components/ChatPromptSubmit.d.vue.ts +2 -2
  12. package/dist/runtime/components/ChatPromptSubmit.vue.d.ts +2 -2
  13. package/dist/runtime/components/Checkbox.d.vue.ts +1 -1
  14. package/dist/runtime/components/Checkbox.vue +12 -6
  15. package/dist/runtime/components/Checkbox.vue.d.ts +1 -1
  16. package/dist/runtime/components/CheckboxGroup.d.vue.ts +6 -0
  17. package/dist/runtime/components/CheckboxGroup.vue +10 -4
  18. package/dist/runtime/components/CheckboxGroup.vue.d.ts +6 -0
  19. package/dist/runtime/components/Editor.vue +4 -1
  20. package/dist/runtime/components/Error.d.vue.ts +1 -1
  21. package/dist/runtime/components/Error.vue.d.ts +1 -1
  22. package/dist/runtime/components/FileUpload.vue +17 -10
  23. package/dist/runtime/components/Input.vue +12 -7
  24. package/dist/runtime/components/InputDate.vue +12 -8
  25. package/dist/runtime/components/InputMenu.vue +25 -11
  26. package/dist/runtime/components/InputNumber.vue +14 -9
  27. package/dist/runtime/components/InputRating.vue +10 -7
  28. package/dist/runtime/components/InputTags.vue +12 -7
  29. package/dist/runtime/components/InputTime.vue +12 -7
  30. package/dist/runtime/components/Listbox.vue +10 -6
  31. package/dist/runtime/components/Modal.vue +12 -5
  32. package/dist/runtime/components/PinInput.vue +13 -8
  33. package/dist/runtime/components/Popover.vue +0 -1
  34. package/dist/runtime/components/PricingTable.d.vue.ts +1 -1
  35. package/dist/runtime/components/PricingTable.vue.d.ts +1 -1
  36. package/dist/runtime/components/Progress.d.vue.ts +2 -1
  37. package/dist/runtime/components/Progress.vue +5 -6
  38. package/dist/runtime/components/Progress.vue.d.ts +2 -1
  39. package/dist/runtime/components/ProgressGroup.d.vue.ts +91 -0
  40. package/dist/runtime/components/ProgressGroup.vue +99 -0
  41. package/dist/runtime/components/ProgressGroup.vue.d.ts +91 -0
  42. package/dist/runtime/components/RadioGroup.d.vue.ts +7 -1
  43. package/dist/runtime/components/RadioGroup.vue +14 -5
  44. package/dist/runtime/components/RadioGroup.vue.d.ts +7 -1
  45. package/dist/runtime/components/Select.vue +21 -8
  46. package/dist/runtime/components/SelectMenu.vue +26 -12
  47. package/dist/runtime/components/Slider.vue +14 -7
  48. package/dist/runtime/components/Splitter.d.vue.ts +266 -0
  49. package/dist/runtime/components/Splitter.vue +99 -0
  50. package/dist/runtime/components/Splitter.vue.d.ts +266 -0
  51. package/dist/runtime/components/Switch.vue +8 -4
  52. package/dist/runtime/components/Textarea.vue +17 -7
  53. package/dist/runtime/components/Theme.d.vue.ts +1 -1
  54. package/dist/runtime/components/Theme.vue +4 -3
  55. package/dist/runtime/components/Theme.vue.d.ts +1 -1
  56. package/dist/runtime/components/Tree.vue +1 -1
  57. package/dist/runtime/components/content/ContentNavigation.vue +8 -1
  58. package/dist/runtime/components/content/ContentToc.vue +4 -1
  59. package/dist/runtime/composables/useComponentProps.d.ts +1 -1
  60. package/dist/runtime/composables/useComponentProps.js +6 -0
  61. package/dist/runtime/composables/useFormField.d.ts +10 -4
  62. package/dist/runtime/composables/useFormField.js +10 -3
  63. package/dist/runtime/keyframes.css +1 -1
  64. package/dist/runtime/locale/da.js +1 -1
  65. package/dist/runtime/locale/de_at.js +7 -0
  66. package/dist/runtime/locale/de_ch.js +1 -1
  67. package/dist/runtime/locale/eu.js +1 -1
  68. package/dist/runtime/locale/fi.js +1 -1
  69. package/dist/runtime/locale/he.js +1 -1
  70. package/dist/runtime/locale/hi.js +1 -1
  71. package/dist/runtime/locale/index.d.ts +2 -1
  72. package/dist/runtime/locale/index.js +2 -1
  73. package/dist/runtime/locale/is.js +1 -1
  74. package/dist/runtime/locale/lb.js +1 -1
  75. package/dist/runtime/locale/tg.d.ts +3 -0
  76. package/dist/runtime/locale/{tj.js → tg.js} +1 -1
  77. package/dist/runtime/locale/ur.js +1 -1
  78. package/dist/runtime/types/form.d.ts +1 -1
  79. package/dist/runtime/types/html.d.ts +3 -1
  80. package/dist/runtime/types/index.d.ts +2 -0
  81. package/dist/runtime/types/index.js +2 -0
  82. package/dist/runtime/types/theme.d.ts +2 -0
  83. package/dist/runtime/types/tv.d.ts +6 -2
  84. package/dist/runtime/utils/link-keys.d.ts +1 -0
  85. package/dist/runtime/utils/link-keys.js +40 -0
  86. package/dist/runtime/utils/link.d.ts +2 -1
  87. package/dist/runtime/utils/link.js +2 -40
  88. package/dist/runtime/utils/search.js +3 -12
  89. package/dist/runtime/utils/tv.d.ts +1 -1
  90. package/dist/runtime/utils/tv.js +103 -25
  91. package/dist/runtime/vue/components/Icon.vue +5 -2
  92. package/dist/shared/{ui.XkBrgXFP.mjs → ui.DNq7CNkE.mjs} +589 -213
  93. package/dist/unplugin.d.mts +1 -1
  94. package/dist/unplugin.mjs +22 -6
  95. package/dist/vite.mjs +4 -4
  96. package/package.json +51 -50
  97. /package/dist/runtime/locale/{tj.d.ts → de_at.d.ts} +0 -0
@@ -34,7 +34,7 @@ type WideTV = {
34
34
  * Wraps `tailwind-variants`' `tv` so slot classes can be **replaced** (not just
35
35
  * merged) through a function form — `(defaults) => classes` — in `:ui`, the
36
36
  * `class` prop and `app.config.ui`. The wrapper is transparent for every other
37
- * usage: it preserves the `TVReturnType` (so `extend: tv(theme)` keeps working
37
+ * usage: it preserves the `TVReturnType` (so `extend: theme` keeps working
38
38
  * via property reads) and only intercepts the slot functions on invocation.
39
39
  */
40
40
  export declare const tv: WideTV;
@@ -29,7 +29,44 @@ function plainClasses(value) {
29
29
  function applyReplacer(replacer, slotProps, resolveDefaults) {
30
30
  return cnMerge(replacer(resolveDefaults()), ...plainClasses(slotProps.class), ...plainClasses(slotProps.className))(config) ?? "";
31
31
  }
32
- function wrapSlots(slots, directives) {
32
+ function isMemoizable(value, depth = 0) {
33
+ if (value === void 0 || value === null) {
34
+ return true;
35
+ }
36
+ const type = typeof value;
37
+ if (type === "string" || type === "boolean") {
38
+ return true;
39
+ }
40
+ if (type === "number") {
41
+ return Number.isFinite(value);
42
+ }
43
+ if (Array.isArray(value)) {
44
+ if (depth >= 4) {
45
+ return false;
46
+ }
47
+ for (const item of value) {
48
+ if (!isMemoizable(item, depth + 1)) {
49
+ return false;
50
+ }
51
+ }
52
+ return true;
53
+ }
54
+ return false;
55
+ }
56
+ function memoKey(slotProps) {
57
+ const proto = Object.getPrototypeOf(slotProps);
58
+ if (proto !== Object.prototype && proto !== null) {
59
+ return void 0;
60
+ }
61
+ for (const key of Object.keys(slotProps)) {
62
+ if (!isMemoizable(slotProps[key])) {
63
+ return void 0;
64
+ }
65
+ }
66
+ return JSON.stringify(slotProps);
67
+ }
68
+ function wrapSlots(slots) {
69
+ const memo = /* @__PURE__ */ new Map();
33
70
  return new Proxy(slots, {
34
71
  get(target, key) {
35
72
  const slot = target[key];
@@ -37,52 +74,93 @@ function wrapSlots(slots, directives) {
37
74
  return slot;
38
75
  }
39
76
  return (slotProps = {}) => {
40
- const replacer = findReplacer(slotProps.class) ?? findReplacer(slotProps.className) ?? directives?.[key];
77
+ const replacer = findReplacer(slotProps.class) ?? findReplacer(slotProps.className);
41
78
  if (!replacer) {
42
- return slot(slotProps);
79
+ const cacheKey = memoKey(slotProps);
80
+ if (cacheKey === void 0) {
81
+ return slot(slotProps);
82
+ }
83
+ let cache = memo.get(key);
84
+ if (!cache) {
85
+ cache = /* @__PURE__ */ new Map();
86
+ memo.set(key, cache);
87
+ }
88
+ let result = cache.get(cacheKey);
89
+ if (result === void 0 && !cache.has(cacheKey)) {
90
+ if (cache.size >= 500) {
91
+ cache.clear();
92
+ }
93
+ result = slot(slotProps);
94
+ cache.set(cacheKey, result);
95
+ }
96
+ return result;
43
97
  }
44
98
  return applyReplacer(replacer, slotProps, () => slot({ ...slotProps, class: void 0, className: void 0 }));
45
99
  };
46
100
  }
47
101
  });
48
102
  }
49
- function extractDirectives(componentConfig) {
103
+ function defaultClasses(value) {
104
+ return cnMerge(value)(config) ?? "";
105
+ }
106
+ function resolveReplacers(componentConfig) {
50
107
  if (!componentConfig || typeof componentConfig !== "object") {
51
- return { config: componentConfig };
52
- }
53
- let config2 = componentConfig;
54
- let directives;
55
- if (typeof componentConfig.base === "function") {
56
- directives = { base: componentConfig.base };
57
- config2 = { ...config2, base: "" };
108
+ return componentConfig;
58
109
  }
59
110
  const slots = componentConfig.slots;
60
- if (slots && typeof slots === "object") {
61
- const replacers = Object.entries(slots).filter(([, value]) => typeof value === "function");
62
- if (replacers.length) {
63
- directives ??= {};
64
- const cleaned = { ...slots };
65
- for (const [slot, replacer] of replacers) {
66
- directives[slot] = replacer;
67
- cleaned[slot] = "";
111
+ const replacers = slots && typeof slots === "object" ? Object.entries(slots).filter((entry) => typeof entry[1] === "function") : [];
112
+ const baseReplacer = typeof componentConfig.base === "function" ? componentConfig.base : void 0;
113
+ if (!replacers.length && !baseReplacer) {
114
+ return componentConfig;
115
+ }
116
+ const extend = componentConfig.extend;
117
+ const resolved = { ...componentConfig };
118
+ let extendSlots;
119
+ let blankExtendBase = false;
120
+ if (baseReplacer) {
121
+ resolved.base = baseReplacer(defaultClasses(extend?.slots?.base ?? extend?.base));
122
+ if (extend?.slots?.base) {
123
+ extendSlots ??= { ...extend.slots };
124
+ extendSlots.base = "";
125
+ }
126
+ if (extend?.base) {
127
+ blankExtendBase = true;
128
+ }
129
+ }
130
+ if (replacers.length) {
131
+ const cleaned = { ...slots };
132
+ for (const [slot, replacer] of replacers) {
133
+ cleaned[slot] = replacer(defaultClasses(extend?.slots?.[slot]));
134
+ if (extend?.slots?.[slot]) {
135
+ extendSlots ??= { ...extend.slots };
136
+ extendSlots[slot] = "";
68
137
  }
69
- config2 = { ...config2, slots: cleaned };
70
138
  }
139
+ resolved.slots = cleaned;
140
+ }
141
+ if (extendSlots || blankExtendBase) {
142
+ const cleanedExtend = { ...extend };
143
+ if (extendSlots) {
144
+ cleanedExtend.slots = extendSlots;
145
+ }
146
+ if (blankExtendBase) {
147
+ cleanedExtend.base = "";
148
+ }
149
+ resolved.extend = cleanedExtend;
71
150
  }
72
- return { config: config2, directives };
151
+ return resolved;
73
152
  }
74
153
  export const tv = ((componentConfig) => {
75
- const { config: cleanConfig, directives } = extractDirectives(componentConfig);
76
- const component = baseTv(cleanConfig);
154
+ const component = baseTv(resolveReplacers(componentConfig));
77
155
  return new Proxy(component, {
78
156
  apply(target, thisArg, args) {
79
157
  const result = Reflect.apply(target, thisArg, args);
80
158
  if (result && typeof result === "object") {
81
- return wrapSlots(result, directives);
159
+ return wrapSlots(result);
82
160
  }
83
161
  if (typeof result === "string") {
84
162
  const slotProps = args[0] ?? {};
85
- const replacer = findReplacer(slotProps.class) ?? findReplacer(slotProps.className) ?? directives?.base;
163
+ const replacer = findReplacer(slotProps.class) ?? findReplacer(slotProps.className);
86
164
  if (replacer) {
87
165
  return applyReplacer(replacer, slotProps, () => Reflect.apply(target, thisArg, [{ ...slotProps, class: void 0, className: void 0 }]));
88
166
  }
@@ -4,7 +4,7 @@
4
4
 
5
5
  <script setup>
6
6
  import { computed } from "vue";
7
- import { Icon as IconifyIcon } from "@iconify/vue";
7
+ import { Icon as IconifyIcon, iconLoaded } from "@iconify/vue";
8
8
  import { useAppConfig } from "#imports";
9
9
  const props = defineProps({
10
10
  name: { type: null, required: true },
@@ -25,16 +25,19 @@ const mode = computed(() => {
25
25
  });
26
26
  const size = computed(() => props.size || appConfig.icon?.size);
27
27
  const customize = computed(() => resolveCustomizeFn(props.customize, appConfig.icon?.customize));
28
+ const icon = computed(() => typeof props.name === "string" ? props.name.replace(/^i-/, "") : "");
29
+ const ssr = computed(() => iconLoaded(icon.value));
28
30
  </script>
29
31
 
30
32
  <template>
31
33
  <IconifyIcon
32
34
  v-if="typeof name === 'string'"
33
- :icon="name.replace(/^i-/, '')"
35
+ :icon="icon"
34
36
  :mode="mode"
35
37
  :width="size"
36
38
  :height="size"
37
39
  :customise="customize"
40
+ :ssr="ssr"
38
41
  />
39
42
  <component :is="name" v-else />
40
43
  </template>