@nuxt/ui 3.1.1 → 3.1.3

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 (126) hide show
  1. package/.nuxt/ui/alert.ts +0 -5
  2. package/.nuxt/ui/badge.ts +30 -7
  3. package/.nuxt/ui/button-group.ts +0 -13
  4. package/.nuxt/ui/button.ts +2 -7
  5. package/.nuxt/ui/calendar.ts +1 -1
  6. package/.nuxt/ui/carousel.ts +0 -5
  7. package/.nuxt/ui/checkbox-group.ts +144 -1
  8. package/.nuxt/ui/color-picker.ts +2 -2
  9. package/.nuxt/ui/context-menu.ts +2 -1
  10. package/.nuxt/ui/dropdown-menu.ts +2 -1
  11. package/.nuxt/ui/input-menu.ts +4 -13
  12. package/.nuxt/ui/input-number.ts +10 -0
  13. package/.nuxt/ui/input.ts +2 -11
  14. package/.nuxt/ui/link.ts +12 -5
  15. package/.nuxt/ui/navigation-menu.ts +43 -34
  16. package/.nuxt/ui/radio-group.ts +1 -1
  17. package/.nuxt/ui/select-menu.ts +4 -13
  18. package/.nuxt/ui/select.ts +4 -13
  19. package/.nuxt/ui/tabs.ts +4 -3
  20. package/.nuxt/ui/textarea.ts +2 -11
  21. package/.nuxt/ui/toast.ts +0 -5
  22. package/.nuxt/ui/tooltip.ts +1 -1
  23. package/.nuxt/ui.css +4 -1
  24. package/cli/templates.mjs +2 -2
  25. package/dist/module.json +1 -1
  26. package/dist/module.mjs +14 -5
  27. package/dist/runtime/components/Accordion.vue +9 -9
  28. package/dist/runtime/components/Accordion.vue.d.ts +2 -0
  29. package/dist/runtime/components/Alert.vue +1 -1
  30. package/dist/runtime/components/Avatar.vue +2 -2
  31. package/dist/runtime/components/AvatarGroup.vue +1 -1
  32. package/dist/runtime/components/Badge.vue +5 -3
  33. package/dist/runtime/components/Badge.vue.d.ts +2 -0
  34. package/dist/runtime/components/Breadcrumb.vue +8 -8
  35. package/dist/runtime/components/Breadcrumb.vue.d.ts +2 -0
  36. package/dist/runtime/components/Button.vue +2 -3
  37. package/dist/runtime/components/Button.vue.d.ts +1 -1
  38. package/dist/runtime/components/Calendar.vue +2 -1
  39. package/dist/runtime/components/Card.vue +1 -1
  40. package/dist/runtime/components/Carousel.vue +5 -2
  41. package/dist/runtime/components/Carousel.vue.d.ts +6 -1
  42. package/dist/runtime/components/Checkbox.vue +2 -2
  43. package/dist/runtime/components/CheckboxGroup.vue +8 -5
  44. package/dist/runtime/components/CheckboxGroup.vue.d.ts +7 -1
  45. package/dist/runtime/components/Chip.vue +1 -1
  46. package/dist/runtime/components/Collapsible.vue +1 -1
  47. package/dist/runtime/components/ColorPicker.vue +1 -1
  48. package/dist/runtime/components/CommandPalette.vue +18 -18
  49. package/dist/runtime/components/CommandPalette.vue.d.ts +2 -0
  50. package/dist/runtime/components/ContextMenu.vue.d.ts +2 -0
  51. package/dist/runtime/components/ContextMenuContent.vue +69 -67
  52. package/dist/runtime/components/Drawer.vue +15 -1
  53. package/dist/runtime/components/DropdownMenu.vue.d.ts +2 -0
  54. package/dist/runtime/components/DropdownMenuContent.vue +71 -69
  55. package/dist/runtime/components/FormField.vue +5 -5
  56. package/dist/runtime/components/Input.vue +3 -2
  57. package/dist/runtime/components/Input.vue.d.ts +30 -29
  58. package/dist/runtime/components/InputMenu.vue +20 -20
  59. package/dist/runtime/components/InputMenu.vue.d.ts +210 -0
  60. package/dist/runtime/components/InputNumber.vue +13 -7
  61. package/dist/runtime/components/InputNumber.vue.d.ts +78 -0
  62. package/dist/runtime/components/Link.vue +5 -14
  63. package/dist/runtime/components/Modal.vue +2 -2
  64. package/dist/runtime/components/Modal.vue.d.ts +3 -0
  65. package/dist/runtime/components/NavigationMenu.vue +106 -41
  66. package/dist/runtime/components/NavigationMenu.vue.d.ts +38 -7
  67. package/dist/runtime/components/Pagination.vue +1 -1
  68. package/dist/runtime/components/PinInput.vue +1 -1
  69. package/dist/runtime/components/Popover.vue +4 -0
  70. package/dist/runtime/components/Popover.vue.d.ts +1 -0
  71. package/dist/runtime/components/Progress.vue +1 -1
  72. package/dist/runtime/components/RadioGroup.vue +8 -8
  73. package/dist/runtime/components/RadioGroup.vue.d.ts +2 -0
  74. package/dist/runtime/components/Select.vue +15 -15
  75. package/dist/runtime/components/Select.vue.d.ts +3 -1
  76. package/dist/runtime/components/SelectMenu.vue +16 -16
  77. package/dist/runtime/components/SelectMenu.vue.d.ts +2 -0
  78. package/dist/runtime/components/Separator.vue +1 -1
  79. package/dist/runtime/components/Slideover.vue +9 -2
  80. package/dist/runtime/components/Slideover.vue.d.ts +3 -0
  81. package/dist/runtime/components/Slider.vue +16 -4
  82. package/dist/runtime/components/Slider.vue.d.ts +26 -20
  83. package/dist/runtime/components/Stepper.vue +10 -10
  84. package/dist/runtime/components/Stepper.vue.d.ts +2 -0
  85. package/dist/runtime/components/Switch.vue +1 -1
  86. package/dist/runtime/components/Table.vue +2 -2
  87. package/dist/runtime/components/Tabs.vue +6 -6
  88. package/dist/runtime/components/Tabs.vue.d.ts +2 -0
  89. package/dist/runtime/components/Textarea.vue +7 -4
  90. package/dist/runtime/components/Textarea.vue.d.ts +30 -31
  91. package/dist/runtime/components/Toast.vue +3 -2
  92. package/dist/runtime/components/Toast.vue.d.ts +6 -0
  93. package/dist/runtime/components/Toaster.vue +4 -4
  94. package/dist/runtime/components/Toaster.vue.d.ts +6 -0
  95. package/dist/runtime/components/Tree.vue +10 -10
  96. package/dist/runtime/components/Tree.vue.d.ts +2 -0
  97. package/dist/runtime/composables/useFormField.d.ts +1 -1
  98. package/dist/runtime/composables/useFormField.js +2 -1
  99. package/dist/runtime/inertia/components/Link.vue +46 -60
  100. package/dist/runtime/inertia/components/Link.vue.d.ts +1 -1
  101. package/dist/runtime/inertia/components/LinkBase.vue +68 -0
  102. package/dist/runtime/inertia/components/LinkBase.vue.d.ts +25 -0
  103. package/dist/runtime/inertia/stubs.d.ts +1 -1
  104. package/dist/runtime/inertia/stubs.js +1 -1
  105. package/dist/runtime/locale/index.d.ts +7 -2
  106. package/dist/runtime/locale/index.js +7 -2
  107. package/dist/runtime/locale/ky.d.ts +3 -0
  108. package/dist/runtime/locale/ky.js +54 -0
  109. package/dist/runtime/locale/lt.d.ts +3 -0
  110. package/dist/runtime/locale/lt.js +54 -0
  111. package/dist/runtime/locale/mn.d.ts +3 -0
  112. package/dist/runtime/locale/mn.js +54 -0
  113. package/dist/runtime/locale/ms.d.ts +3 -0
  114. package/dist/runtime/locale/ms.js +54 -0
  115. package/dist/runtime/locale/sl.d.ts +3 -0
  116. package/dist/runtime/locale/sl.js +54 -0
  117. package/dist/runtime/utils/link.d.ts +1 -0
  118. package/dist/runtime/utils/link.js +12 -0
  119. package/dist/runtime/vue/components/Link.vue +27 -40
  120. package/dist/runtime/vue/composables/useAppConfig.js +3 -1
  121. package/dist/runtime/vue/stubs.d.ts +1 -1
  122. package/dist/runtime/vue/stubs.js +1 -1
  123. package/dist/shared/{ui.CbtTMMzt.mjs → ui.Bix4DSU4.mjs} +153 -52
  124. package/dist/unplugin.mjs +1 -1
  125. package/dist/vite.mjs +1 -1
  126. package/package.json +28 -28
@@ -1,8 +1,3 @@
1
- const buttonGroup = [
2
- "horizontal",
3
- "vertical"
4
- ] as const
5
-
6
1
  const size = [
7
2
  "xs",
8
3
  "sm",
@@ -29,10 +24,6 @@ const color = [
29
24
  "neutral"
30
25
  ] as const
31
26
 
32
- const type = [
33
- "file"
34
- ] as const
35
-
36
27
  export default {
37
28
  "slots": {
38
29
  "base": [
@@ -49,10 +40,10 @@ export default {
49
40
  "placeholder": "truncate text-dimmed",
50
41
  "arrow": "fill-default",
51
42
  "content": [
52
- "max-h-60 w-(--reka-select-trigger-width) bg-default shadow-lg rounded-md ring ring-default overflow-hidden data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-select-content-transform-origin) pointer-events-auto",
43
+ "max-h-60 w-(--reka-select-trigger-width) bg-default shadow-lg rounded-md ring ring-default overflow-hidden data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-select-content-transform-origin) pointer-events-auto flex flex-col",
53
44
  "origin-(--reka-combobox-content-transform-origin) w-(--reka-combobox-trigger-width)"
54
45
  ],
55
- "viewport": "divide-y divide-default scroll-py-1",
46
+ "viewport": "relative divide-y divide-default scroll-py-1 overflow-y-auto flex-1",
56
47
  "group": "p-1 isolate",
57
48
  "empty": "py-2 text-center text-sm text-muted",
58
49
  "label": "font-semibold text-highlighted",
@@ -77,8 +68,8 @@ export default {
77
68
  },
78
69
  "variants": {
79
70
  "buttonGroup": {
80
- "horizontal": "not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none",
81
- "vertical": "not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none"
71
+ "horizontal": "not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none focus-visible:z-[1]",
72
+ "vertical": "not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none focus-visible:z-[1]"
82
73
  },
83
74
  "size": {
84
75
  "xs": {
@@ -1,8 +1,3 @@
1
- const buttonGroup = [
2
- "horizontal",
3
- "vertical"
4
- ] as const
5
-
6
1
  const size = [
7
2
  "xs",
8
3
  "sm",
@@ -29,10 +24,6 @@ const color = [
29
24
  "neutral"
30
25
  ] as const
31
26
 
32
- const type = [
33
- "file"
34
- ] as const
35
-
36
27
  export default {
37
28
  "slots": {
38
29
  "base": [
@@ -48,8 +39,8 @@ export default {
48
39
  "value": "truncate pointer-events-none",
49
40
  "placeholder": "truncate text-dimmed",
50
41
  "arrow": "fill-default",
51
- "content": "max-h-60 w-(--reka-select-trigger-width) bg-default shadow-lg rounded-md ring ring-default overflow-hidden data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-select-content-transform-origin) pointer-events-auto",
52
- "viewport": "divide-y divide-default scroll-py-1",
42
+ "content": "max-h-60 w-(--reka-select-trigger-width) bg-default shadow-lg rounded-md ring ring-default overflow-hidden data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-select-content-transform-origin) pointer-events-auto flex flex-col",
43
+ "viewport": "relative divide-y divide-default scroll-py-1 overflow-y-auto flex-1",
53
44
  "group": "p-1 isolate",
54
45
  "empty": "py-2 text-center text-sm text-muted",
55
46
  "label": "font-semibold text-highlighted",
@@ -72,8 +63,8 @@ export default {
72
63
  },
73
64
  "variants": {
74
65
  "buttonGroup": {
75
- "horizontal": "not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none",
76
- "vertical": "not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none"
66
+ "horizontal": "not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none focus-visible:z-[1]",
67
+ "vertical": "not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none focus-visible:z-[1]"
77
68
  },
78
69
  "size": {
79
70
  "xs": {
package/.nuxt/ui/tabs.ts CHANGED
@@ -32,7 +32,7 @@ export default {
32
32
  "list": "relative flex p-1 group",
33
33
  "indicator": "absolute transition-[translate,width] duration-200",
34
34
  "trigger": [
35
- "group relative inline-flex items-center shrink-0 min-w-0 data-[state=inactive]:text-muted hover:data-[state=inactive]:not-disabled:text-default font-medium rounded-md disabled:cursor-not-allowed disabled:opacity-75",
35
+ "group relative inline-flex items-center min-w-0 data-[state=inactive]:text-muted hover:data-[state=inactive]:not-disabled:text-default font-medium rounded-md disabled:cursor-not-allowed disabled:opacity-75",
36
36
  "transition-colors"
37
37
  ],
38
38
  "content": "focus:outline-none w-full",
@@ -54,12 +54,13 @@ export default {
54
54
  "variant": {
55
55
  "pill": {
56
56
  "list": "bg-elevated rounded-lg",
57
- "trigger": "flex-1 w-full",
57
+ "trigger": "grow",
58
58
  "indicator": "rounded-md shadow-xs"
59
59
  },
60
60
  "link": {
61
61
  "list": "border-default",
62
- "indicator": "rounded-full"
62
+ "indicator": "rounded-full",
63
+ "trigger": "focus:outline-none"
63
64
  }
64
65
  },
65
66
  "orientation": {
@@ -1,8 +1,3 @@
1
- const buttonGroup = [
2
- "horizontal",
3
- "vertical"
4
- ] as const
5
-
6
1
  const size = [
7
2
  "xs",
8
3
  "sm",
@@ -29,10 +24,6 @@ const color = [
29
24
  "neutral"
30
25
  ] as const
31
26
 
32
- const type = [
33
- "file"
34
- ] as const
35
-
36
27
  export default {
37
28
  "slots": {
38
29
  "root": "relative inline-flex items-center",
@@ -50,11 +41,11 @@ export default {
50
41
  "variants": {
51
42
  "buttonGroup": {
52
43
  "horizontal": {
53
- "root": "group",
44
+ "root": "group has-focus-visible:z-[1]",
54
45
  "base": "group-not-only:group-first:rounded-e-none group-not-only:group-last:rounded-s-none group-not-last:group-not-first:rounded-none"
55
46
  },
56
47
  "vertical": {
57
- "root": "group",
48
+ "root": "group has-focus-visible:z-[1]",
58
49
  "base": "group-not-only:group-first:rounded-b-none group-not-only:group-last:rounded-t-none group-not-last:group-not-first:rounded-none"
59
50
  }
60
51
  },
package/.nuxt/ui/toast.ts CHANGED
@@ -8,11 +8,6 @@ const color = [
8
8
  "neutral"
9
9
  ] as const
10
10
 
11
- const orientation = [
12
- "horizontal",
13
- "vertical"
14
- ] as const
15
-
16
11
  export default {
17
12
  "slots": {
18
13
  "root": "relative group overflow-hidden bg-default shadow-lg rounded-lg ring ring-default p-4 flex gap-2.5 focus:outline-none",
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "slots": {
3
- "content": "flex items-center gap-1 bg-default text-highlighted shadow-sm rounded-sm ring ring-default h-6 px-2 py-1 text-xs select-none data-[state=delayed-open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-tooltip-content-transform-origin) pointer-events-auto",
3
+ "content": "flex items-center gap-1 bg-default text-highlighted shadow-sm rounded-sm ring ring-default h-6 px-2.5 py-1 text-xs select-none data-[state=delayed-open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-tooltip-content-transform-origin) pointer-events-auto",
4
4
  "arrow": "fill-default",
5
5
  "text": "truncate",
6
6
  "kbds": "hidden lg:inline-flex items-center shrink-0 gap-0.5 before:content-['·'] before:me-0.5",
package/.nuxt/ui.css CHANGED
@@ -1,6 +1,6 @@
1
1
  @source "./ui";
2
2
 
3
- @theme default inline {
3
+ @theme static {
4
4
  --color-old-neutral-50: oklch(98.5% 0 0);
5
5
  --color-old-neutral-100: oklch(97% 0 0);
6
6
  --color-old-neutral-200: oklch(92.2% 0 0);
@@ -12,6 +12,9 @@
12
12
  --color-old-neutral-800: oklch(26.9% 0 0);
13
13
  --color-old-neutral-900: oklch(20.5% 0 0);
14
14
  --color-old-neutral-950: oklch(14.5% 0 0);
15
+ }
16
+
17
+ @theme default inline {
15
18
  --color-primary-50: var(--ui-color-primary-50);
16
19
  --color-primary-100: var(--ui-color-primary-100);
17
20
  --color-primary-200: var(--ui-color-primary-200);
package/cli/templates.mjs CHANGED
@@ -66,7 +66,7 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.${camelName}
66
66
  </script>
67
67
 
68
68
  <template>
69
- <Primitive :as="as" :class="ui.root({ class: [props.class, props.ui?.root] })">
69
+ <Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })">
70
70
  <slot />
71
71
  </Primitive>
72
72
  </template>
@@ -109,7 +109,7 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.${camelName}
109
109
  </script>
110
110
 
111
111
  <template>
112
- <${upperName}Root v-bind="rootProps" :class="ui.root({ class: [props.class, props.ui?.root] })" />
112
+ <${upperName}Root v-bind="rootProps" :class="ui.root({ class: [props.ui?.root, props.class] })" />
113
113
  </template>
114
114
  `
115
115
  }
package/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt/ui",
3
- "version": "3.1.1",
3
+ "version": "3.1.3",
4
4
  "docs": "https://ui.nuxt.com/getting-started/installation/nuxt",
5
5
  "configKey": "ui",
6
6
  "compatibility": {
package/dist/module.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { defu } from 'defu';
2
2
  import { defineNuxtModule, createResolver, addVitePlugin, addPlugin, addComponentsDir, addImportsDir, hasNuxtModule, installModule } from '@nuxt/kit';
3
- import { d as defaultOptions, r as resolveColors, a as getDefaultUiConfig, b as addTemplates } from './shared/ui.CbtTMMzt.mjs';
3
+ import { d as defaultOptions, r as resolveColors, a as getDefaultUiConfig, b as addTemplates } from './shared/ui.Bix4DSU4.mjs';
4
4
  import '../dist/runtime/utils/index.js';
5
5
  import 'node:url';
6
6
  import 'scule';
@@ -8,7 +8,7 @@ import 'tailwindcss/colors';
8
8
  import 'knitwork';
9
9
 
10
10
  const name = "@nuxt/ui";
11
- const version = "3.1.1";
11
+ const version = "3.1.3";
12
12
 
13
13
  const module = defineNuxtModule({
14
14
  meta: {
@@ -43,12 +43,21 @@ const module = defineNuxtModule({
43
43
  nuxt.options[key] = defu(nuxt.options[key], options2);
44
44
  }
45
45
  }
46
- await registerModule("@nuxt/icon", "icon", { cssLayer: "components" });
46
+ await registerModule("@nuxt/icon", "icon", {
47
+ cssLayer: "components"
48
+ });
47
49
  if (options.fonts) {
48
- await registerModule("@nuxt/fonts", "fonts", { experimental: { processCSSVariables: true } });
50
+ await registerModule("@nuxt/fonts", "fonts", {
51
+ defaults: {
52
+ weights: [400, 500, 600, 700]
53
+ }
54
+ });
49
55
  }
50
56
  if (options.colorMode) {
51
- await registerModule("@nuxtjs/color-mode", "colorMode", { classSuffix: "", disableTransition: true });
57
+ await registerModule("@nuxtjs/color-mode", "colorMode", {
58
+ classSuffix: "",
59
+ disableTransition: true
60
+ });
52
61
  }
53
62
  addPlugin({ src: resolve("./runtime/plugins/colors") });
54
63
  addComponentsDir({
@@ -34,34 +34,34 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.accordion ||
34
34
  </script>
35
35
 
36
36
  <template>
37
- <AccordionRoot v-bind="rootProps" :class="ui.root({ class: [props.class, props.ui?.root] })">
37
+ <AccordionRoot v-bind="rootProps" :class="ui.root({ class: [props.ui?.root, props.class] })">
38
38
  <AccordionItem
39
39
  v-for="(item, index) in props.items"
40
40
  v-slot="{ open }"
41
41
  :key="index"
42
42
  :value="item.value || String(index)"
43
43
  :disabled="item.disabled"
44
- :class="ui.item({ class: props.ui?.item })"
44
+ :class="ui.item({ class: [props.ui?.item, item.ui?.item, item.class] })"
45
45
  >
46
- <AccordionHeader as="div" :class="ui.header({ class: props.ui?.header })">
47
- <AccordionTrigger :class="ui.trigger({ class: props.ui?.trigger, disabled: item.disabled })">
46
+ <AccordionHeader as="div" :class="ui.header({ class: [props.ui?.header, item.ui?.header] })">
47
+ <AccordionTrigger :class="ui.trigger({ class: [props.ui?.trigger, item.ui?.trigger], disabled: item.disabled })">
48
48
  <slot name="leading" :item="item" :index="index" :open="open">
49
- <UIcon v-if="item.icon" :name="item.icon" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
49
+ <UIcon v-if="item.icon" :name="item.icon" :class="ui.leadingIcon({ class: [props.ui?.leadingIcon, item?.ui?.leadingIcon] })" />
50
50
  </slot>
51
51
 
52
- <span v-if="get(item, props.labelKey) || !!slots.default" :class="ui.label({ class: props.ui?.label })">
52
+ <span v-if="get(item, props.labelKey) || !!slots.default" :class="ui.label({ class: [props.ui?.label, item.ui?.label] })">
53
53
  <slot :item="item" :index="index" :open="open">{{ get(item, props.labelKey) }}</slot>
54
54
  </span>
55
55
 
56
56
  <slot name="trailing" :item="item" :index="index" :open="open">
57
- <UIcon :name="item.trailingIcon || trailingIcon || appConfig.ui.icons.chevronDown" :class="ui.trailingIcon({ class: props.ui?.trailingIcon })" />
57
+ <UIcon :name="item.trailingIcon || trailingIcon || appConfig.ui.icons.chevronDown" :class="ui.trailingIcon({ class: [props.ui?.trailingIcon, item.ui?.trailingIcon] })" />
58
58
  </slot>
59
59
  </AccordionTrigger>
60
60
  </AccordionHeader>
61
61
 
62
- <AccordionContent v-if="item.content || !!slots.content || item.slot && !!slots[item.slot] || !!slots.body || item.slot && !!slots[`${item.slot}-body`]" :class="ui.content({ class: props.ui?.content })">
62
+ <AccordionContent v-if="item.content || !!slots.content || item.slot && !!slots[item.slot] || !!slots.body || item.slot && !!slots[`${item.slot}-body`]" :class="ui.content({ class: [props.ui?.content, item.ui?.content] })">
63
63
  <slot :name="item.slot || 'content'" :item="item" :index="index" :open="open">
64
- <div :class="ui.body({ class: props.ui?.body })">
64
+ <div :class="ui.body({ class: [props.ui?.body, item.ui?.body] })">
65
65
  <slot :name="item.slot ? `${item.slot}-body` : 'body'" :item="item" :index="index" :open="open">
66
66
  {{ item.content }}
67
67
  </slot>
@@ -18,6 +18,8 @@ export interface AccordionItem {
18
18
  /** A unique value for the accordion item. Defaults to the index. */
19
19
  value?: string;
20
20
  disabled?: boolean;
21
+ class?: any;
22
+ ui?: Pick<Accordion['slots'], 'item' | 'header' | 'trigger' | 'leadingIcon' | 'label' | 'trailingIcon' | 'content' | 'body'>;
21
23
  [key: string]: any;
22
24
  }
23
25
  export interface AccordionProps<T extends AccordionItem = AccordionItem> extends Pick<AccordionRootProps, 'collapsible' | 'defaultValue' | 'modelValue' | 'type' | 'disabled' | 'unmountOnHide'> {
@@ -39,7 +39,7 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.alert || {} }
39
39
  </script>
40
40
 
41
41
  <template>
42
- <Primitive :as="as" :data-orientation="orientation" :class="ui.root({ class: [props.class, props.ui?.root] })">
42
+ <Primitive :as="as" :data-orientation="orientation" :class="ui.root({ class: [props.ui?.root, props.class] })">
43
43
  <slot name="leading">
44
44
  <UAvatar v-if="avatar" :size="props.ui?.avatarSize || ui.avatarSize()" v-bind="avatar" :class="ui.avatar({ class: props.ui?.avatar })" />
45
45
  <UIcon v-else-if="icon" :name="icon" :class="ui.icon({ class: props.ui?.icon })" />
@@ -51,7 +51,7 @@ function onError() {
51
51
  </script>
52
52
 
53
53
  <template>
54
- <Primitive :as="as" :class="ui.root({ class: [props.class, props.ui?.root] })" :style="props.style">
54
+ <Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })" :style="props.style">
55
55
  <component
56
56
  :is="ImageComponent"
57
57
  v-if="src && !error"
@@ -68,7 +68,7 @@ function onError() {
68
68
  <Slot v-else v-bind="$attrs">
69
69
  <slot>
70
70
  <UIcon v-if="icon" :name="icon" :class="ui.icon({ class: props.ui?.icon })" />
71
- <span v-else :class="ui.fallback({ class: props.ui?.fallback })">{{ fallback || '\xA0' }}</span>
71
+ <span v-else :class="ui.fallback({ class: props.ui?.fallback })">{{ fallback || "\xA0" }}</span>
72
72
  </slot>
73
73
  </Slot>
74
74
  </Primitive>
@@ -58,7 +58,7 @@ provide(avatarGroupInjectionKey, computed(() => ({
58
58
  </script>
59
59
 
60
60
  <template>
61
- <Primitive :as="as" :class="ui.root({ class: [props.class, props.ui?.root] })">
61
+ <Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })">
62
62
  <UAvatar v-if="hiddenCount > 0" :text="`+${hiddenCount}`" :class="ui.base({ class: props.ui?.base })" />
63
63
  <component :is="avatar" v-for="(avatar, count) in visibleAvatars" :key="count" :class="ui.base({ class: props.ui?.base })" />
64
64
  </Primitive>
@@ -17,6 +17,7 @@ const props = defineProps({
17
17
  color: { type: null, required: false },
18
18
  variant: { type: null, required: false },
19
19
  size: { type: null, required: false },
20
+ square: { type: Boolean, required: false },
20
21
  class: { type: null, required: false },
21
22
  ui: { type: null, required: false },
22
23
  icon: { type: String, required: false },
@@ -26,7 +27,7 @@ const props = defineProps({
26
27
  trailing: { type: Boolean, required: false },
27
28
  trailingIcon: { type: String, required: false }
28
29
  });
29
- defineSlots();
30
+ const slots = defineSlots();
30
31
  const appConfig = useAppConfig();
31
32
  const { orientation, size: buttonGroupSize } = useButtonGroup(props);
32
33
  const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponentIcons(props);
@@ -34,19 +35,20 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.badge || {} }
34
35
  color: props.color,
35
36
  variant: props.variant,
36
37
  size: buttonGroupSize.value || props.size,
38
+ square: props.square || !slots.default && !props.label,
37
39
  buttonGroup: orientation.value
38
40
  }));
39
41
  </script>
40
42
 
41
43
  <template>
42
- <Primitive :as="as" :class="ui.base({ class: [props.class, props.ui?.base] })">
44
+ <Primitive :as="as" :class="ui.base({ class: [props.ui?.base, props.class] })">
43
45
  <slot name="leading">
44
46
  <UIcon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
45
47
  <UAvatar v-else-if="!!avatar" :size="props.ui?.leadingAvatarSize || ui.leadingAvatarSize()" v-bind="avatar" :class="ui.leadingAvatar({ class: props.ui?.leadingAvatar })" />
46
48
  </slot>
47
49
 
48
50
  <slot>
49
- <span v-if="label" :class="ui.label({ class: props.ui?.label })">
51
+ <span v-if="label !== void 0 && label !== null" :class="ui.label({ class: props.ui?.label })">
50
52
  {{ label }}
51
53
  </span>
52
54
  </slot>
@@ -22,6 +22,8 @@ export interface BadgeProps extends Omit<UseComponentIconsProps, 'loading' | 'lo
22
22
  * @defaultValue 'md'
23
23
  */
24
24
  size?: Badge['variants']['size'];
25
+ /** Render the badge with equal padding on all sides. */
26
+ square?: boolean;
25
27
  class?: any;
26
28
  ui?: Badge['slots'];
27
29
  }
@@ -30,19 +30,19 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.breadcrumb ||
30
30
  </script>
31
31
 
32
32
  <template>
33
- <Primitive :as="as" aria-label="breadcrumb" :class="ui.root({ class: [props.class, props.ui?.root] })">
33
+ <Primitive :as="as" aria-label="breadcrumb" :class="ui.root({ class: [props.ui?.root, props.class] })">
34
34
  <ol :class="ui.list({ class: props.ui?.list })">
35
35
  <template v-for="(item, index) in items" :key="index">
36
- <li :class="ui.item({ class: props.ui?.item })">
36
+ <li :class="ui.item({ class: [props.ui?.item, item.ui?.item] })">
37
37
  <ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
38
- <ULinkBase v-bind="slotProps" as="span" :aria-current="active && index === items.length - 1 ? 'page' : void 0" :class="ui.link({ class: [props.ui?.link, item.class], active: index === items.length - 1, disabled: !!item.disabled, to: !!item.to })">
38
+ <ULinkBase v-bind="slotProps" as="span" :aria-current="active && index === items.length - 1 ? 'page' : void 0" :class="ui.link({ class: [props.ui?.link, item.ui?.link, item.class], active: index === items.length - 1, disabled: !!item.disabled, to: !!item.to })">
39
39
  <slot :name="item.slot || 'item'" :item="item" :index="index">
40
40
  <slot :name="item.slot ? `${item.slot}-leading` : 'item-leading'" :item="item" :active="index === items.length - 1" :index="index">
41
- <UIcon v-if="item.icon" :name="item.icon" :class="ui.linkLeadingIcon({ class: props.ui?.linkLeadingIcon, active: index === items.length - 1 })" />
42
- <UAvatar v-else-if="item.avatar" :size="props.ui?.linkLeadingAvatarSize || ui.linkLeadingAvatarSize()" v-bind="item.avatar" :class="ui.linkLeadingAvatar({ class: props.ui?.linkLeadingAvatar, active: index === items.length - 1 })" />
41
+ <UIcon v-if="item.icon" :name="item.icon" :class="ui.linkLeadingIcon({ class: [props.ui?.linkLeadingIcon, item.ui?.linkLeadingIcon], active: index === items.length - 1 })" />
42
+ <UAvatar v-else-if="item.avatar" :size="props.ui?.linkLeadingAvatarSize || ui.linkLeadingAvatarSize()" v-bind="item.avatar" :class="ui.linkLeadingAvatar({ class: [props.ui?.linkLeadingAvatar, item.ui?.linkLeadingAvatar], active: index === items.length - 1 })" />
43
43
  </slot>
44
44
 
45
- <span v-if="get(item, props.labelKey) || !!slots[item.slot ? `${item.slot}-label` : 'item-label']" :class="ui.linkLabel({ class: props.ui?.linkLabel })">
45
+ <span v-if="get(item, props.labelKey) || !!slots[item.slot ? `${item.slot}-label` : 'item-label']" :class="ui.linkLabel({ class: [props.ui?.linkLabel, item.ui?.linkLabel] })">
46
46
  <slot :name="item.slot ? `${item.slot}-label` : 'item-label'" :item="item" :active="index === items.length - 1" :index="index">
47
47
  {{ get(item, props.labelKey) }}
48
48
  </slot>
@@ -54,9 +54,9 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.breadcrumb ||
54
54
  </ULink>
55
55
  </li>
56
56
 
57
- <li v-if="index < items.length - 1" role="presentation" aria-hidden="true" :class="ui.separator({ class: props.ui?.separator })">
57
+ <li v-if="index < items.length - 1" role="presentation" aria-hidden="true" :class="ui.separator({ class: [props.ui?.separator, item.ui?.separator] })">
58
58
  <slot name="separator">
59
- <UIcon :name="separatorIcon" :class="ui.separatorIcon({ class: props.ui?.separatorIcon })" />
59
+ <UIcon :name="separatorIcon" :class="ui.separatorIcon({ class: [props.ui?.separatorIcon, item.ui?.separatorIcon] })" />
60
60
  </slot>
61
61
  </li>
62
62
  </template>
@@ -11,6 +11,8 @@ export interface BreadcrumbItem extends Omit<LinkProps, 'raw' | 'custom'> {
11
11
  icon?: string;
12
12
  avatar?: AvatarProps;
13
13
  slot?: string;
14
+ class?: any;
15
+ ui?: Pick<Breadcrumb['slots'], 'item' | 'link' | 'linkLeadingIcon' | 'linkLeadingAvatar' | 'linkLabel' | 'separator' | 'separatorIcon'>;
14
16
  [key: string]: any;
15
17
  }
16
18
  export interface BreadcrumbProps<T extends BreadcrumbItem = BreadcrumbItem> {
@@ -115,14 +115,13 @@ const ui = computed(() => tv({
115
115
  v-slot="{ active, ...slotProps }"
116
116
  :type="type"
117
117
  :disabled="disabled || isLoading"
118
- :class="ui.base({ class: [props.class, props.ui?.base] })"
119
118
  v-bind="omit(linkProps, ['type', 'disabled', 'onClick'])"
120
119
  custom
121
120
  >
122
121
  <ULinkBase
123
122
  v-bind="slotProps"
124
123
  :class="ui.base({
125
- class: [props.class, props.ui?.base],
124
+ class: [props.ui?.base, props.class],
126
125
  active,
127
126
  ...active && activeVariant ? { variant: activeVariant } : {},
128
127
  ...active && activeColor ? { color: activeColor } : {}
@@ -135,7 +134,7 @@ const ui = computed(() => tv({
135
134
  </slot>
136
135
 
137
136
  <slot>
138
- <span v-if="label" :class="ui.label({ class: props.ui?.label, active })">
137
+ <span v-if="label !== void 0 && label !== null" :class="ui.label({ class: props.ui?.label, active })">
139
138
  {{ label }}
140
139
  </span>
141
140
  </slot>
@@ -1,7 +1,7 @@
1
1
  import type { AppConfig } from '@nuxt/schema';
2
2
  import theme from '#build/ui/button';
3
- import type { LinkProps } from './Link.vue';
4
3
  import type { UseComponentIconsProps } from '../composables/useComponentIcons';
4
+ import type { LinkProps } from '../types';
5
5
  import type { ComponentConfig } from '../types/utils';
6
6
  type Button = ComponentConfig<typeof theme, AppConfig, 'button'>;
7
7
  export interface ButtonProps extends UseComponentIconsProps, Omit<LinkProps, 'raw' | 'custom'> {
@@ -47,6 +47,7 @@ const props = defineProps({
47
47
  initialFocus: { type: Boolean, required: false },
48
48
  isDateDisabled: { type: Function, required: false },
49
49
  isDateUnavailable: { type: Function, required: false },
50
+ isDateHighlightable: { type: Function, required: false },
50
51
  nextPage: { type: Function, required: false },
51
52
  prevPage: { type: Function, required: false }
52
53
  });
@@ -80,7 +81,7 @@ const Calendar = computed(() => props.range ? RangeCalendar : SingleCalendar);
80
81
  :default-value="defaultValue"
81
82
  :locale="locale"
82
83
  :dir="dir"
83
- :class="ui.root({ class: [props.class, props.ui?.root] })"
84
+ :class="ui.root({ class: [props.ui?.root, props.class] })"
84
85
  >
85
86
  <Calendar.Header :class="ui.header({ class: props.ui?.header })">
86
87
  <Calendar.Prev v-if="props.yearControls" :prev-page="(date) => paginateYear(date, -1)" :aria-label="t('calendar.prevYear')" as-child>
@@ -21,7 +21,7 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.card || {} })
21
21
  </script>
22
22
 
23
23
  <template>
24
- <Primitive :as="as" :class="ui.root({ class: [props.class, props.ui?.root] })">
24
+ <Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })">
25
25
  <div v-if="!!slots.header" :class="ui.header({ class: props.ui?.header })">
26
26
  <slot name="header" />
27
27
  </div>
@@ -129,6 +129,9 @@ function onSelect(api) {
129
129
  selectedIndex.value = api?.selectedScrollSnap() || 0;
130
130
  emits("select", selectedIndex.value);
131
131
  }
132
+ function isCarouselItem(item) {
133
+ return typeof item === "object" && item !== null;
134
+ }
132
135
  onMounted(() => {
133
136
  if (!emblaApi.value) {
134
137
  return;
@@ -151,7 +154,7 @@ defineExpose({
151
154
  role="region"
152
155
  aria-roledescription="carousel"
153
156
  tabindex="0"
154
- :class="ui.root({ class: [props.class, props.ui?.root] })"
157
+ :class="ui.root({ class: [props.ui?.root, props.class] })"
155
158
  @keydown="onKeyDown"
156
159
  >
157
160
  <div ref="emblaRef" :class="ui.viewport({ class: props.ui?.viewport })">
@@ -161,7 +164,7 @@ defineExpose({
161
164
  :key="index"
162
165
  role="group"
163
166
  aria-roledescription="slide"
164
- :class="ui.item({ class: props.ui?.item })"
167
+ :class="ui.item({ class: [props.ui?.item, isCarouselItem(item) && item.ui?.item, isCarouselItem(item) && item.class] })"
165
168
  >
166
169
  <slot :item="item" :index="index" />
167
170
  </div>
@@ -11,7 +11,12 @@ import theme from '#build/ui/carousel';
11
11
  import type { ButtonProps } from '../types';
12
12
  import type { ComponentConfig } from '../types/utils';
13
13
  type Carousel = ComponentConfig<typeof theme, AppConfig, 'carousel'>;
14
- export type CarouselItem = AcceptableValue;
14
+ interface _CarouselItem {
15
+ class?: any;
16
+ ui?: Pick<Carousel['slots'], 'item'>;
17
+ [key: string]: any;
18
+ }
19
+ export type CarouselItem = _CarouselItem | AcceptableValue;
15
20
  export interface CarouselProps<T extends CarouselItem = CarouselItem> extends Omit<EmblaOptionsType, 'axis' | 'container' | 'slides' | 'direction'> {
16
21
  /**
17
22
  * The element or component this component should render as.
@@ -54,7 +54,7 @@ function onUpdate(value) {
54
54
  </script>
55
55
 
56
56
  <template>
57
- <Primitive :as="variant === 'list' ? as : Label" :class="ui.root({ class: [props.class, props.ui?.root] })">
57
+ <Primitive :as="!variant || variant === 'list' ? as : Label" :class="ui.root({ class: [props.ui?.root, props.class] })">
58
58
  <div :class="ui.container({ class: props.ui?.container })">
59
59
  <CheckboxRoot
60
60
  :id="id"
@@ -75,7 +75,7 @@ function onUpdate(value) {
75
75
  </div>
76
76
 
77
77
  <div v-if="label || !!slots.label || (description || !!slots.description)" :class="ui.wrapper({ class: props.ui?.wrapper })">
78
- <component :is="variant === 'list' ? Label : 'p'" v-if="label || !!slots.label" :for="id" :class="ui.label({ class: props.ui?.label })">
78
+ <component :is="!variant || variant === 'list' ? Label : 'p'" v-if="label || !!slots.label" :for="id" :class="ui.label({ class: props.ui?.label })">
79
79
  <slot name="label" :label="label">
80
80
  {{ label }}
81
81
  </slot>
@@ -10,6 +10,7 @@ import { useAppConfig } from "#imports";
10
10
  import { useFormField } from "../composables/useFormField";
11
11
  import { get, omit } from "../utils";
12
12
  import { tv } from "../utils/tv";
13
+ import UCheckbox from "./Checkbox.vue";
13
14
  const props = defineProps({
14
15
  as: { type: null, required: false },
15
16
  legend: { type: String, required: false },
@@ -18,6 +19,7 @@ const props = defineProps({
18
19
  descriptionKey: { type: String, required: false, default: "description" },
19
20
  items: { type: Array, required: false },
20
21
  size: { type: null, required: false },
22
+ variant: { type: null, required: false },
21
23
  orientation: { type: null, required: false, default: "vertical" },
22
24
  class: { type: null, required: false },
23
25
  ui: { type: void 0, required: false },
@@ -28,7 +30,6 @@ const props = defineProps({
28
30
  name: { type: String, required: false },
29
31
  required: { type: Boolean, required: false },
30
32
  color: { type: null, required: false },
31
- variant: { type: null, required: false },
32
33
  indicator: { type: null, required: false },
33
34
  icon: { type: String, required: false }
34
35
  });
@@ -43,7 +44,9 @@ const id = _id.value ?? useId();
43
44
  const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.checkboxGroup || {} })({
44
45
  size: size.value,
45
46
  required: props.required,
46
- orientation: props.orientation
47
+ orientation: props.orientation,
48
+ color: props.color,
49
+ variant: props.variant
47
50
  }));
48
51
  function normalizeItem(item) {
49
52
  if (item === null) {
@@ -91,7 +94,7 @@ function onUpdate(value) {
91
94
  v-bind="rootProps"
92
95
  :name="name"
93
96
  :disabled="disabled"
94
- :class="ui.root({ class: [props.class, props.ui?.root] })"
97
+ :class="ui.root({ class: [props.ui?.root, props.class] })"
95
98
  @update:model-value="onUpdate"
96
99
  >
97
100
  <fieldset :class="ui.fieldset({ class: props.ui?.fieldset })" v-bind="ariaAttrs">
@@ -109,8 +112,8 @@ function onUpdate(value) {
109
112
  :size="size"
110
113
  :name="name"
111
114
  :disabled="item.disabled || disabled"
112
- :ui="props.ui ? omit(props.ui, ['root']) : void 0"
113
- :class="ui.item({ class: props.ui?.item })"
115
+ :ui="{ ...props.ui ? omit(props.ui, ['root']) : void 0, ...item.ui || {} }"
116
+ :class="ui.item({ class: [props.ui?.item, item.ui?.item, item.class] })"
114
117
  >
115
118
  <template v-for="(_, name) in proxySlots" #[name]>
116
119
  <slot :name="name" :item="item" />