@nuxt/ui 4.6.1 → 4.7.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 (175) hide show
  1. package/README.md +7 -4
  2. package/cli/package.json +1 -1
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +3 -2
  5. package/dist/runtime/components/Accordion.d.vue.ts +6 -1
  6. package/dist/runtime/components/Accordion.vue +1 -1
  7. package/dist/runtime/components/Accordion.vue.d.ts +6 -1
  8. package/dist/runtime/components/AuthForm.d.vue.ts +22 -29
  9. package/dist/runtime/components/AuthForm.vue +8 -6
  10. package/dist/runtime/components/AuthForm.vue.d.ts +22 -29
  11. package/dist/runtime/components/Button.vue +1 -0
  12. package/dist/runtime/components/Calendar.vue +4 -4
  13. package/dist/runtime/components/Card.d.vue.ts +4 -0
  14. package/dist/runtime/components/Card.vue +16 -2
  15. package/dist/runtime/components/Card.vue.d.ts +4 -0
  16. package/dist/runtime/components/ChatMessage.d.vue.ts +27 -17
  17. package/dist/runtime/components/ChatMessage.vue +10 -16
  18. package/dist/runtime/components/ChatMessage.vue.d.ts +27 -17
  19. package/dist/runtime/components/ChatMessages.d.vue.ts +27 -21
  20. package/dist/runtime/components/ChatMessages.vue +22 -23
  21. package/dist/runtime/components/ChatMessages.vue.d.ts +27 -21
  22. package/dist/runtime/components/ChatPromptSubmit.vue +3 -1
  23. package/dist/runtime/components/Checkbox.vue +5 -3
  24. package/dist/runtime/components/CommandPalette.d.vue.ts +18 -3
  25. package/dist/runtime/components/CommandPalette.vue +11 -7
  26. package/dist/runtime/components/CommandPalette.vue.d.ts +18 -3
  27. package/dist/runtime/components/ContextMenuContent.vue +68 -65
  28. package/dist/runtime/components/DashboardSearch.d.vue.ts +8 -37
  29. package/dist/runtime/components/DashboardSearch.vue +11 -10
  30. package/dist/runtime/components/DashboardSearch.vue.d.ts +8 -37
  31. package/dist/runtime/components/DashboardSidebar.vue +1 -5
  32. package/dist/runtime/components/Drawer.vue +44 -41
  33. package/dist/runtime/components/DropdownMenuContent.vue +90 -87
  34. package/dist/runtime/components/EditorEmojiMenu.d.vue.ts +1 -1
  35. package/dist/runtime/components/EditorEmojiMenu.vue +2 -0
  36. package/dist/runtime/components/EditorEmojiMenu.vue.d.ts +1 -1
  37. package/dist/runtime/components/EditorMentionMenu.d.vue.ts +1 -1
  38. package/dist/runtime/components/EditorMentionMenu.vue +2 -0
  39. package/dist/runtime/components/EditorMentionMenu.vue.d.ts +1 -1
  40. package/dist/runtime/components/EditorSuggestionMenu.d.vue.ts +1 -1
  41. package/dist/runtime/components/EditorSuggestionMenu.vue +2 -0
  42. package/dist/runtime/components/EditorSuggestionMenu.vue.d.ts +1 -1
  43. package/dist/runtime/components/FileUpload.vue +7 -5
  44. package/dist/runtime/components/FormField.d.vue.ts +1 -1
  45. package/dist/runtime/components/FormField.vue.d.ts +1 -1
  46. package/dist/runtime/components/Header.vue +1 -5
  47. package/dist/runtime/components/Input.vue +2 -2
  48. package/dist/runtime/components/InputDate.vue +6 -6
  49. package/dist/runtime/components/InputMenu.d.vue.ts +3 -3
  50. package/dist/runtime/components/InputMenu.vue +40 -38
  51. package/dist/runtime/components/InputMenu.vue.d.ts +3 -3
  52. package/dist/runtime/components/InputNumber.vue +2 -2
  53. package/dist/runtime/components/InputTags.vue +2 -2
  54. package/dist/runtime/components/InputTime.vue +2 -2
  55. package/dist/runtime/components/Link.d.vue.ts +10 -1
  56. package/dist/runtime/components/Link.vue +74 -9
  57. package/dist/runtime/components/Link.vue.d.ts +10 -1
  58. package/dist/runtime/components/Listbox.d.vue.ts +228 -0
  59. package/dist/runtime/components/Listbox.vue +242 -0
  60. package/dist/runtime/components/Listbox.vue.d.ts +228 -0
  61. package/dist/runtime/components/Modal.vue +13 -10
  62. package/dist/runtime/components/Popover.vue +7 -4
  63. package/dist/runtime/components/PricingTable.vue +60 -58
  64. package/dist/runtime/components/RadioGroup.vue +5 -3
  65. package/dist/runtime/components/Select.d.vue.ts +1 -1
  66. package/dist/runtime/components/Select.vue +84 -73
  67. package/dist/runtime/components/Select.vue.d.ts +1 -1
  68. package/dist/runtime/components/SelectMenu.d.vue.ts +3 -3
  69. package/dist/runtime/components/SelectMenu.vue +54 -52
  70. package/dist/runtime/components/SelectMenu.vue.d.ts +3 -3
  71. package/dist/runtime/components/Sidebar.vue +1 -4
  72. package/dist/runtime/components/Slideover.vue +67 -64
  73. package/dist/runtime/components/Table.d.vue.ts +1 -2
  74. package/dist/runtime/components/Table.vue +17 -29
  75. package/dist/runtime/components/Table.vue.d.ts +1 -2
  76. package/dist/runtime/components/Tabs.d.vue.ts +5 -1
  77. package/dist/runtime/components/Tabs.vue +2 -2
  78. package/dist/runtime/components/Tabs.vue.d.ts +5 -1
  79. package/dist/runtime/components/Textarea.d.vue.ts +1 -0
  80. package/dist/runtime/components/Textarea.vue +2 -1
  81. package/dist/runtime/components/Textarea.vue.d.ts +1 -0
  82. package/dist/runtime/components/Tooltip.vue +12 -9
  83. package/dist/runtime/components/content/ContentSearch.d.vue.ts +19 -35
  84. package/dist/runtime/components/content/ContentSearch.vue +10 -9
  85. package/dist/runtime/components/content/ContentSearch.vue.d.ts +19 -35
  86. package/dist/runtime/components/content/ContentToc.vue +19 -9
  87. package/dist/runtime/components/prose/Img.vue +7 -1
  88. package/dist/runtime/components/prose/Pre.vue +8 -3
  89. package/dist/runtime/components/prose/Prompt.d.vue.ts +32 -0
  90. package/dist/runtime/components/prose/Prompt.vue +88 -0
  91. package/dist/runtime/components/prose/Prompt.vue.d.ts +32 -0
  92. package/dist/runtime/composables/index.d.ts +1 -0
  93. package/dist/runtime/composables/index.js +1 -0
  94. package/dist/runtime/composables/useContentSearch.js +19 -5
  95. package/dist/runtime/composables/useEditorMenu.d.ts +5 -0
  96. package/dist/runtime/composables/useEditorMenu.js +3 -1
  97. package/dist/runtime/composables/useFieldGroup.d.ts +3 -0
  98. package/dist/runtime/composables/useFieldGroup.js +11 -1
  99. package/dist/runtime/composables/useResolvedVariants.d.ts +21 -0
  100. package/dist/runtime/composables/useResolvedVariants.js +14 -0
  101. package/dist/runtime/locale/ar.js +9 -0
  102. package/dist/runtime/locale/az.js +9 -0
  103. package/dist/runtime/locale/be.js +9 -0
  104. package/dist/runtime/locale/bg.js +9 -0
  105. package/dist/runtime/locale/bn.js +9 -0
  106. package/dist/runtime/locale/ca.js +9 -0
  107. package/dist/runtime/locale/ckb.js +10 -1
  108. package/dist/runtime/locale/cs.js +9 -0
  109. package/dist/runtime/locale/da.js +9 -0
  110. package/dist/runtime/locale/de.js +9 -0
  111. package/dist/runtime/locale/de_ch.js +9 -0
  112. package/dist/runtime/locale/el.js +9 -0
  113. package/dist/runtime/locale/en.js +10 -1
  114. package/dist/runtime/locale/es.js +9 -0
  115. package/dist/runtime/locale/et.js +9 -0
  116. package/dist/runtime/locale/eu.js +11 -2
  117. package/dist/runtime/locale/fa_ir.js +9 -0
  118. package/dist/runtime/locale/fi.js +9 -0
  119. package/dist/runtime/locale/fr.js +9 -0
  120. package/dist/runtime/locale/gl.js +9 -0
  121. package/dist/runtime/locale/he.js +9 -0
  122. package/dist/runtime/locale/hi.js +9 -0
  123. package/dist/runtime/locale/hr.js +9 -0
  124. package/dist/runtime/locale/hu.js +9 -0
  125. package/dist/runtime/locale/hy.js +9 -0
  126. package/dist/runtime/locale/id.js +9 -0
  127. package/dist/runtime/locale/is.js +9 -0
  128. package/dist/runtime/locale/it.js +9 -0
  129. package/dist/runtime/locale/ja.js +9 -0
  130. package/dist/runtime/locale/ka.js +9 -0
  131. package/dist/runtime/locale/kk.js +9 -0
  132. package/dist/runtime/locale/km.js +9 -0
  133. package/dist/runtime/locale/ko.js +9 -0
  134. package/dist/runtime/locale/ky.js +9 -0
  135. package/dist/runtime/locale/lb.js +11 -2
  136. package/dist/runtime/locale/lo.js +15 -6
  137. package/dist/runtime/locale/lt.js +9 -0
  138. package/dist/runtime/locale/mn.js +9 -0
  139. package/dist/runtime/locale/ms.js +9 -0
  140. package/dist/runtime/locale/nb_no.js +9 -0
  141. package/dist/runtime/locale/nl.js +9 -0
  142. package/dist/runtime/locale/pl.js +9 -0
  143. package/dist/runtime/locale/pt.js +9 -0
  144. package/dist/runtime/locale/pt_br.js +9 -0
  145. package/dist/runtime/locale/ro.js +9 -0
  146. package/dist/runtime/locale/ru.js +9 -0
  147. package/dist/runtime/locale/sk.js +9 -0
  148. package/dist/runtime/locale/sl.js +9 -0
  149. package/dist/runtime/locale/sq.js +9 -0
  150. package/dist/runtime/locale/sv.js +9 -0
  151. package/dist/runtime/locale/th.js +9 -0
  152. package/dist/runtime/locale/tj.js +9 -0
  153. package/dist/runtime/locale/tr.js +9 -0
  154. package/dist/runtime/locale/ug_cn.js +9 -0
  155. package/dist/runtime/locale/uk.js +9 -0
  156. package/dist/runtime/locale/ur.js +9 -0
  157. package/dist/runtime/locale/uz.js +9 -0
  158. package/dist/runtime/locale/vi.js +9 -0
  159. package/dist/runtime/locale/zh_cn.js +9 -0
  160. package/dist/runtime/locale/zh_tw.js +9 -0
  161. package/dist/runtime/plugins/colors.js +1 -1
  162. package/dist/runtime/types/index.d.ts +1 -0
  163. package/dist/runtime/types/index.js +1 -0
  164. package/dist/runtime/types/locale.d.ts +9 -0
  165. package/dist/runtime/types/prose.d.ts +1 -0
  166. package/dist/runtime/types/prose.js +1 -0
  167. package/dist/runtime/utils/link.d.ts +1 -1
  168. package/dist/runtime/utils/link.js +1 -0
  169. package/dist/runtime/vue/overrides/inertia/Link.vue +3 -3
  170. package/dist/runtime/vue/overrides/none/Link.vue +3 -2
  171. package/dist/runtime/vue/overrides/vue-router/Link.vue +27 -31
  172. package/dist/shared/{ui.DJUbBpE2.mjs → ui.C6mn7iap.mjs} +189 -37
  173. package/dist/unplugin.mjs +1 -1
  174. package/dist/vite.mjs +1 -1
  175. package/package.json +49 -40
@@ -3,7 +3,7 @@ import type { ContentNavigationItem } from '@nuxt/content';
3
3
  import type { AppConfig } from '@nuxt/schema';
4
4
  import type { UseFuseOptions } from '@vueuse/integrations/useFuse';
5
5
  import theme from '#build/ui/content/content-search';
6
- import type { ButtonProps, InputProps, LinkProps, ModalProps, CommandPaletteProps, CommandPaletteSlots, CommandPaletteGroup, CommandPaletteItem, IconProps, LinkPropsKeys } from '../../types';
6
+ import type { ButtonProps, LinkProps, ModalProps, CommandPaletteProps, CommandPaletteSlots, CommandPaletteGroup, CommandPaletteItem, IconProps, LinkPropsKeys } from '../../types';
7
7
  import type { ComponentConfig } from '../../types/tv';
8
8
  type ContentSearch = ComponentConfig<typeof theme, AppConfig, 'contentSearch'>;
9
9
  export interface ContentSearchLink extends Omit<LinkProps, 'custom'> {
@@ -29,35 +29,11 @@ export interface ContentSearchItem extends Omit<LinkProps, 'custom'>, CommandPal
29
29
  */
30
30
  icon?: IconProps['name'];
31
31
  }
32
- export interface ContentSearchProps<T extends ContentSearchLink = ContentSearchLink> extends Pick<ModalProps, 'title' | 'description' | 'overlay' | 'transition' | 'content' | 'dismissible' | 'fullscreen' | 'modal' | 'portal'> {
32
+ export interface ContentSearchProps<T extends ContentSearchLink = ContentSearchLink> extends Pick<ModalProps, 'title' | 'description' | 'overlay' | 'transition' | 'content' | 'dismissible' | 'fullscreen' | 'modal' | 'portal'>, Pick<CommandPaletteProps<CommandPaletteGroup<ContentSearchItem>, ContentSearchItem>, 'icon' | 'placeholder' | 'autofocus' | 'loading' | 'loadingIcon' | 'closeIcon' | 'groups'> {
33
33
  /**
34
34
  * @defaultValue 'md'
35
35
  */
36
36
  size?: ContentSearch['variants']['size'];
37
- /**
38
- * The icon displayed in the input.
39
- * @defaultValue appConfig.ui.icons.search
40
- * @IconifyIcon
41
- */
42
- icon?: IconProps['name'];
43
- /**
44
- * The placeholder text for the input.
45
- * @defaultValue t('commandPalette.placeholder')
46
- */
47
- placeholder?: InputProps['placeholder'];
48
- /**
49
- * Automatically focus the input when component is mounted.
50
- * @defaultValue true
51
- */
52
- autofocus?: boolean;
53
- /** When `true`, the loading icon will be displayed. */
54
- loading?: boolean;
55
- /**
56
- * The icon when the `loading` prop is `true`.
57
- * @defaultValue appConfig.ui.icons.loading
58
- * @IconifyIcon
59
- */
60
- loadingIcon?: IconProps['name'];
61
37
  /**
62
38
  * Display a close button in the input (useful when inside a Modal for example).
63
39
  * `{ size: 'md', color: 'neutral', variant: 'ghost' }`{lang="ts-type"}
@@ -65,12 +41,6 @@ export interface ContentSearchProps<T extends ContentSearchLink = ContentSearchL
65
41
  * @defaultValue true
66
42
  */
67
43
  close?: boolean | Omit<ButtonProps, LinkPropsKeys>;
68
- /**
69
- * The icon displayed in the close button.
70
- * @defaultValue appConfig.ui.icons.close
71
- * @IconifyIcon
72
- */
73
- closeIcon?: IconProps['name'];
74
44
  /**
75
45
  * Keyboard shortcut to open the search (used by [`defineShortcuts`](https://ui.nuxt.com/docs/composables/define-shortcuts))
76
46
  * @defaultValue 'meta_k'
@@ -79,14 +49,28 @@ export interface ContentSearchProps<T extends ContentSearchLink = ContentSearchL
79
49
  /** Links group displayed as the first group in the command palette. */
80
50
  links?: T[];
81
51
  navigation?: ContentNavigationItem[];
82
- /** Custom groups displayed between navigation and color mode group. */
83
- groups?: CommandPaletteGroup<ContentSearchItem>[];
84
52
  files?: ContentSearchFile[];
85
53
  /**
86
54
  * Options for [useFuse](https://vueuse.org/integrations/useFuse) passed to the [CommandPalette](https://ui.nuxt.com/docs/components/command-palette).
87
- * @defaultValue { fuseOptions: { includeMatches: true } }
55
+ * @defaultValue {
56
+ fuseOptions: {
57
+ ignoreLocation: true,
58
+ includeMatches: true,
59
+ threshold: 0.1,
60
+ keys: ['label', 'suffix']
61
+ },
62
+ resultLimit: 12,
63
+ matchAllWhenSearchEmpty: true
64
+ }
88
65
  */
89
66
  fuse?: UseFuseOptions<T>;
67
+ /**
68
+ * Delay (in milliseconds) before the search term is passed to Fuse (debounced).
69
+ * Useful for large doc sets where running fuzzy search on every keystroke is the bottleneck — the input stays responsive while Fuse only re-runs after typing settles.
70
+ * Set to `0` to disable.
71
+ * @defaultValue 100
72
+ */
73
+ searchDelay?: number;
90
74
  /**
91
75
  * When `true`, the theme command will be added to the groups.
92
76
  * @defaultValue true
@@ -3,11 +3,12 @@ import theme from "#build/ui/content/content-toc";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { computed } from "vue";
6
+ import { computed, onUnmounted } from "vue";
7
7
  import { CollapsibleRoot, CollapsibleTrigger, CollapsibleContent, useForwardPropsEmits } from "reka-ui";
8
8
  import { reactivePick, createReusableTemplate } from "@vueuse/core";
9
9
  import { useRouter, useAppConfig, useNuxtApp } from "#imports";
10
10
  import { useComponentUI } from "../../composables/useComponentUI";
11
+ import { useResolvedVariants } from "../../composables/useResolvedVariants";
11
12
  import { useScrollspy } from "../../composables/useScrollspy";
12
13
  import { useLocale } from "../../composables/useLocale";
13
14
  import { tv } from "../../utils/tv";
@@ -34,6 +35,7 @@ const { t } = useLocale();
34
35
  const router = useRouter();
35
36
  const appConfig = useAppConfig();
36
37
  const uiProp = useComponentUI("contentToc", props);
38
+ const { highlightVariant } = useResolvedVariants("contentToc", props, theme, ["highlightVariant"]);
37
39
  const { activeHeadings, updateHeadings } = useScrollspy();
38
40
  const [DefineListTemplate, ReuseListTemplate] = createReusableTemplate({
39
41
  props: {
@@ -46,7 +48,7 @@ const [DefineContentTemplate, ReuseContentTemplate] = createReusableTemplate();
46
48
  const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.contentToc || {} })({
47
49
  color: props.color,
48
50
  highlight: props.highlight,
49
- highlightVariant: props.highlightVariant,
51
+ highlightVariant: highlightVariant.value,
50
52
  highlightColor: props.highlightColor || props.color
51
53
  }));
52
54
  function scrollToHeading(id) {
@@ -76,7 +78,7 @@ const indicatorStyle = computed(() => {
76
78
  };
77
79
  });
78
80
  const circuitMaskStyle = computed(() => {
79
- if (!props.highlight || props.highlightVariant !== "circuit" || !props.links?.length) {
81
+ if (!props.highlight || highlightVariant.value !== "circuit" || !props.links?.length) {
80
82
  return;
81
83
  }
82
84
  const flatLinks = flattenLinksWithLevel(props.links);
@@ -110,13 +112,21 @@ const circuitMaskStyle = computed(() => {
110
112
  };
111
113
  });
112
114
  const nuxtApp = useNuxtApp();
113
- nuxtApp.hooks.hook("page:loading:end", () => {
114
- const headings = Array.from(document.querySelectorAll("h2, h3"));
115
- updateHeadings(headings);
116
- });
117
- nuxtApp.hooks.hook("page:transition:finish", () => {
118
- const headings = Array.from(document.querySelectorAll("h2, h3"));
115
+ function refreshHeadings() {
116
+ const flatLinks = flattenLinks(props.links || []);
117
+ if (!flatLinks.length) {
118
+ updateHeadings([]);
119
+ return;
120
+ }
121
+ const selector = flatLinks.map((l) => `#${CSS.escape(l.id)}`).join(", ");
122
+ const headings = Array.from(document.querySelectorAll(selector));
119
123
  updateHeadings(headings);
124
+ }
125
+ const offLoadingEnd = nuxtApp.hooks.hook("page:loading:end", refreshHeadings);
126
+ const offTransitionFinish = nuxtApp.hooks.hook("page:transition:finish", refreshHeadings);
127
+ onUnmounted(() => {
128
+ offLoadingEnd();
129
+ offTransitionFinish();
120
130
  });
121
131
  </script>
122
132
 
@@ -29,7 +29,8 @@ const [DefineZoomedImageTemplate, ReuseZoomedImageTemplate] = createReusableTemp
29
29
  const open = ref(false);
30
30
  const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.prose?.img || {} })({
31
31
  zoom: props.zoom,
32
- open: open.value
32
+ open: open.value,
33
+ width: !!props.width
33
34
  }));
34
35
  const refinedSrc = computed(() => resolveBaseURL(props.src, useRuntimeConfig().app.baseURL));
35
36
  const layoutId = computed(() => `${refinedSrc.value}::${useId()}`);
@@ -37,6 +38,11 @@ if (props.zoom) {
37
38
  useEventListener(window, "scroll", () => {
38
39
  open.value = false;
39
40
  });
41
+ useEventListener(window, "keydown", (e) => {
42
+ if (e.key === "Escape" && open.value) {
43
+ open.value = false;
44
+ }
45
+ });
40
46
  }
41
47
  </script>
42
48
 
@@ -3,7 +3,7 @@ import theme from "#build/ui/prose/pre";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { computed } from "vue";
6
+ import { computed, useTemplateRef } from "vue";
7
7
  import { useClipboard } from "@vueuse/core";
8
8
  import { useAppConfig } from "#imports";
9
9
  import { useComponentUI } from "../../composables/useComponentUI";
@@ -27,7 +27,12 @@ const { t } = useLocale();
27
27
  const { copy, copied } = useClipboard();
28
28
  const appConfig = useAppConfig();
29
29
  const uiProp = useComponentUI("prose.pre", props);
30
+ const baseRef = useTemplateRef("baseRef");
30
31
  const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.prose?.pre || {} })());
32
+ function copyCode() {
33
+ const code = props.code ?? baseRef.value?.textContent ?? "";
34
+ copy(code);
35
+ }
31
36
  </script>
32
37
 
33
38
  <template>
@@ -46,9 +51,9 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.prose?.pre ||
46
51
  :aria-label="t('prose.pre.copy')"
47
52
  :class="ui.copy({ class: uiProp?.copy })"
48
53
  tabindex="-1"
49
- @click="copy(props.code || '')"
54
+ @click="copyCode"
50
55
  />
51
56
 
52
- <pre :class="ui.base({ class: [uiProp?.base, props.class] })" v-bind="$attrs"><slot /></pre>
57
+ <pre ref="baseRef" :class="ui.base({ class: [uiProp?.base, props.class] })" v-bind="$attrs"><slot /></pre>
53
58
  </div>
54
59
  </template>
@@ -0,0 +1,32 @@
1
+ import type { VNode } from 'vue';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import theme from '#build/ui/prose/prompt';
4
+ import type { IconProps } from '../../types';
5
+ import type { ComponentConfig } from '../../types/tv';
6
+ type ProsePrompt = ComponentConfig<typeof theme, AppConfig, 'prompt', 'ui.prose'>;
7
+ export interface ProsePromptProps {
8
+ description?: string;
9
+ /**
10
+ * @IconifyIcon
11
+ */
12
+ icon?: IconProps['name'];
13
+ /**
14
+ * @defaultValue ['copy']
15
+ */
16
+ actions?: ('copy' | 'cursor' | 'windsurf')[];
17
+ class?: any;
18
+ ui?: ProsePrompt['slots'];
19
+ }
20
+ export interface ProsePromptSlots {
21
+ default(props?: {}): VNode[];
22
+ }
23
+ declare const _default: typeof __VLS_export;
24
+ export default _default;
25
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<ProsePromptProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ProsePromptProps> & Readonly<{}>, {
26
+ actions: ("copy" | "cursor" | "windsurf")[];
27
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ProsePromptSlots>;
28
+ type __VLS_WithSlots<T, S> = T & {
29
+ new (): {
30
+ $slots: S;
31
+ };
32
+ };
@@ -0,0 +1,88 @@
1
+ <script>
2
+ import theme from "#build/ui/prose/prompt";
3
+ </script>
4
+
5
+ <script setup>
6
+ import { computed } from "vue";
7
+ import { useClipboard } from "@vueuse/core";
8
+ import { useAppConfig } from "#imports";
9
+ import { useComponentUI } from "../../composables/useComponentUI";
10
+ import { useLocale } from "../../composables/useLocale";
11
+ import { getSlotChildrenText } from "../../utils";
12
+ import { tv } from "../../utils/tv";
13
+ import UIcon from "../Icon.vue";
14
+ import UButton from "../Button.vue";
15
+ defineOptions({ inheritAttrs: false });
16
+ const props = defineProps({
17
+ description: { type: String, required: false },
18
+ icon: { type: null, required: false },
19
+ actions: { type: Array, required: false, default: () => ["copy"] },
20
+ class: { type: null, required: false },
21
+ ui: { type: Object, required: false }
22
+ });
23
+ const slots = defineSlots();
24
+ const { t } = useLocale();
25
+ const { copy, copied } = useClipboard();
26
+ const appConfig = useAppConfig();
27
+ const uiProp = useComponentUI("prose.prompt", props);
28
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.prose?.prompt || {} })());
29
+ function getPromptText() {
30
+ const children = slots.default?.();
31
+ return children ? getSlotChildrenText(children).trim() : "";
32
+ }
33
+ function copyPrompt() {
34
+ copy(getPromptText());
35
+ }
36
+ function openInCursor() {
37
+ const url = new URL("cursor://anysphere.cursor-deeplink/prompt");
38
+ url.searchParams.set("text", getPromptText());
39
+ window.open(url.toString(), "_self");
40
+ }
41
+ function openInWindsurf() {
42
+ const url = new URL("windsurf://cascade/newChat");
43
+ url.searchParams.set("prompt", getPromptText());
44
+ window.open(url.toString(), "_self");
45
+ }
46
+ </script>
47
+
48
+ <template>
49
+ <div :class="ui.root({ class: [uiProp?.root, props.class] })" v-bind="$attrs">
50
+ <UIcon v-if="icon" :name="icon" :class="ui.icon({ class: uiProp?.icon })" />
51
+
52
+ <div :class="ui.content({ class: uiProp?.content })">
53
+ <p v-if="description" :class="ui.description({ class: uiProp?.description })">
54
+ {{ description }}
55
+ </p>
56
+ </div>
57
+
58
+ <div :class="ui.actions({ class: uiProp?.actions })">
59
+ <UButton
60
+ v-if="actions.includes('copy')"
61
+ :icon="copied ? appConfig.ui.icons.copyCheck : appConfig.ui.icons.copy"
62
+ size="sm"
63
+ :label="t('prose.prompt.copy')"
64
+ @click="copyPrompt"
65
+ />
66
+
67
+ <UButton
68
+ v-if="actions.includes('cursor')"
69
+ icon="i-simple-icons-cursor"
70
+ color="neutral"
71
+ variant="outline"
72
+ size="sm"
73
+ :label="t('prose.prompt.openIn', { name: 'Cursor' })"
74
+ @click="openInCursor"
75
+ />
76
+
77
+ <UButton
78
+ v-if="actions.includes('windsurf')"
79
+ icon="i-simple-icons-windsurf"
80
+ color="neutral"
81
+ variant="outline"
82
+ size="sm"
83
+ :label="t('prose.prompt.openIn', { name: 'Windsurf' })"
84
+ @click="openInWindsurf"
85
+ />
86
+ </div>
87
+ </div>
88
+ </template>
@@ -0,0 +1,32 @@
1
+ import type { VNode } from 'vue';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import theme from '#build/ui/prose/prompt';
4
+ import type { IconProps } from '../../types';
5
+ import type { ComponentConfig } from '../../types/tv';
6
+ type ProsePrompt = ComponentConfig<typeof theme, AppConfig, 'prompt', 'ui.prose'>;
7
+ export interface ProsePromptProps {
8
+ description?: string;
9
+ /**
10
+ * @IconifyIcon
11
+ */
12
+ icon?: IconProps['name'];
13
+ /**
14
+ * @defaultValue ['copy']
15
+ */
16
+ actions?: ('copy' | 'cursor' | 'windsurf')[];
17
+ class?: any;
18
+ ui?: ProsePrompt['slots'];
19
+ }
20
+ export interface ProsePromptSlots {
21
+ default(props?: {}): VNode[];
22
+ }
23
+ declare const _default: typeof __VLS_export;
24
+ export default _default;
25
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<ProsePromptProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ProsePromptProps> & Readonly<{}>, {
26
+ actions: ("copy" | "cursor" | "windsurf")[];
27
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ProsePromptSlots>;
28
+ type __VLS_WithSlots<T, S> = T & {
29
+ new (): {
30
+ $slots: S;
31
+ };
32
+ };
@@ -15,6 +15,7 @@ export * from './useLocale';
15
15
  export * from './useOverlay';
16
16
  export * from './usePortal';
17
17
  export * from './useResizable';
18
+ export * from './useResolvedVariants';
18
19
  export * from './useScrollShadow';
19
20
  export * from './useScrollspy';
20
21
  export * from './useToast';
@@ -15,6 +15,7 @@ export * from "./useLocale.js";
15
15
  export * from "./useOverlay.js";
16
16
  export * from "./usePortal.js";
17
17
  export * from "./useResizable.js";
18
+ export * from "./useResolvedVariants.js";
18
19
  export * from "./useScrollShadow.js";
19
20
  export * from "./useScrollspy.js";
20
21
  export * from "./useToast.js";
@@ -16,12 +16,26 @@ function _useContentSearch() {
16
16
  };
17
17
  }
18
18
  function mapNavigationItems(children, files, parent) {
19
- return children.flatMap((link) => {
20
- if (link.children?.length) {
21
- return mapNavigationItems(link.children, files, link);
19
+ const filesByPath = /* @__PURE__ */ new Map();
20
+ for (const file of files || []) {
21
+ const basePath = file.id.split("#")[0] || file.id;
22
+ let bucket = filesByPath.get(basePath);
23
+ if (!bucket) {
24
+ bucket = [];
25
+ filesByPath.set(basePath, bucket);
22
26
  }
23
- return files?.filter((file) => file.id === link.path || file.id.startsWith(`${link.path}#`))?.map((file) => mapFile(file, link, parent)) || [];
24
- });
27
+ bucket.push(file);
28
+ }
29
+ function visit(nodes, nodeParent) {
30
+ return nodes.flatMap((link) => {
31
+ if (link.children?.length) {
32
+ return visit(link.children, link);
33
+ }
34
+ const matched = link.path ? filesByPath.get(link.path) : void 0;
35
+ return matched?.map((file) => mapFile(file, link, nodeParent)) || [];
36
+ });
37
+ }
38
+ return visit(children, parent);
25
39
  }
26
40
  function postFilter(query, items) {
27
41
  if (!query) {
@@ -1,5 +1,6 @@
1
1
  import type { Ref, ComputedRef, MaybeRef } from 'vue';
2
2
  import type { Editor } from '@tiptap/vue-3';
3
+ import type { SuggestionOptions } from '@tiptap/suggestion';
3
4
  import type { FloatingUIOptions } from '../types/editor';
4
5
  export interface EditorMenuOptions<T = any> {
5
6
  editor: Editor;
@@ -53,6 +54,10 @@ export interface EditorMenuOptions<T = any> {
53
54
  * @see https://floating-ui.com/docs/computePosition#options
54
55
  */
55
56
  options?: FloatingUIOptions;
57
+ /**
58
+ * Optional TipTap Suggestion matching options.
59
+ */
60
+ suggestion?: Omit<Partial<SuggestionOptions>, 'pluginKey' | 'editor' | 'char' | 'items' | 'command' | 'render'>;
56
61
  /**
57
62
  * The DOM element to append the menu to. Default is the editor's parent element.
58
63
  *
@@ -195,7 +195,8 @@ export function useEditorMenu(options) {
195
195
  };
196
196
  element.addEventListener("mousedown", handleMouseDown);
197
197
  const appendToElement = typeof options.appendTo === "function" ? options.appendTo() : options.appendTo;
198
- (appendToElement ?? options.editor.view.dom.parentElement)?.appendChild(element);
198
+ const container = appendToElement ?? options.editor.view.dom.parentElement;
199
+ container?.appendChild(element);
199
200
  if (renderer.element) {
200
201
  element.appendChild(renderer.element);
201
202
  }
@@ -311,6 +312,7 @@ export function useEditorMenu(options) {
311
312
  }
312
313
  };
313
314
  const plugin = Suggestion({
315
+ ...options.suggestion || {},
314
316
  pluginKey: pluginKeyInstance,
315
317
  editor: options.editor,
316
318
  char: options.char,
@@ -12,4 +12,7 @@ export declare function useFieldGroup<T>(props: Props<T>): {
12
12
  orientation: ComputedRef<"horizontal" | "vertical" | undefined>;
13
13
  size: ComputedRef<"xs" | "sm" | "md" | "lg" | "xl" | NonNullable<GetObjectField<T, "size">> | undefined>;
14
14
  };
15
+ export declare const FieldGroupReset: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
16
+ [key: string]: any;
17
+ }>[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
15
18
  export {};
@@ -1,4 +1,4 @@
1
- import { inject, computed } from "vue";
1
+ import { computed, defineComponent, inject, provide } from "vue";
2
2
  export const fieldGroupInjectionKey = Symbol("nuxt-ui.field-group");
3
3
  export function useFieldGroup(props) {
4
4
  const fieldGroup = inject(fieldGroupInjectionKey, void 0);
@@ -7,3 +7,13 @@ export function useFieldGroup(props) {
7
7
  size: computed(() => props?.size ?? fieldGroup?.value.size)
8
8
  };
9
9
  }
10
+ export const FieldGroupReset = defineComponent({
11
+ name: "FieldGroupReset",
12
+ setup(_, { slots }) {
13
+ provide(fieldGroupInjectionKey, computed(() => ({
14
+ size: void 0,
15
+ orientation: void 0
16
+ })));
17
+ return () => slots.default?.();
18
+ }
19
+ });
@@ -0,0 +1,21 @@
1
+ import type { ComputedRef, MaybeRefOrGetter } from 'vue';
2
+ /**
3
+ * Resolve variant values that are consumed in template logic (e.g. `<component :is="...">`).
4
+ *
5
+ * `tv()`'s `defaultVariants` only apply when computing classes — they don't affect
6
+ * template conditionals that read the prop directly. This mirrors tv's priority:
7
+ * `props[key]` > `app.config.ts` `defaultVariants[key]` > `theme.defaultVariants[key]`.
8
+ *
9
+ * @example
10
+ * const { variant } = useResolvedVariants('radioGroup', props, theme, ['variant'])
11
+ *
12
+ * // For nested prop paths, override with a getter:
13
+ * const { position } = useResolvedVariants('select', props, theme, ['position'], {
14
+ * position: () => props.content?.position
15
+ * })
16
+ *
17
+ * Related: #6360
18
+ */
19
+ export declare function useResolvedVariants<K extends string>(name: string, props: Record<string, any>, theme: Record<string, any>, keys: K[], overrides?: Partial<Record<K, MaybeRefOrGetter<any>>>): {
20
+ [P in K]: ComputedRef<any>;
21
+ };
@@ -0,0 +1,14 @@
1
+ import { computed, toValue } from "vue";
2
+ import { useAppConfig } from "#imports";
3
+ import { get } from "../utils/index.js";
4
+ export function useResolvedVariants(name, props, theme, keys, overrides) {
5
+ const appConfig = useAppConfig();
6
+ const result = {};
7
+ for (const key of keys) {
8
+ result[key] = computed(() => {
9
+ const value = overrides?.[key] !== void 0 ? toValue(overrides[key]) : get(props, key);
10
+ return value ?? appConfig.ui?.[name]?.defaultVariants?.[key] ?? theme.defaultVariants?.[key];
11
+ });
12
+ }
13
+ return result;
14
+ }
@@ -99,6 +99,11 @@ export default defineLocale({
99
99
  decrement: "\u062A\u0642\u0644\u064A\u0644",
100
100
  increment: "\u0632\u064A\u0627\u062F\u0629"
101
101
  },
102
+ listbox: {
103
+ noData: "\u0644\u0627 \u062A\u0648\u062C\u062F \u0628\u064A\u0627\u0646\u0627\u062A",
104
+ noMatch: "\u0644\u0627 \u062A\u0648\u062C\u062F \u0646\u062A\u0627\u0626\u062C \u0645\u0637\u0627\u0628\u0642\u0629",
105
+ search: "\u0628\u062D\u062B\u2026"
106
+ },
102
107
  modal: {
103
108
  close: "\u0625\u063A\u0644\u0627\u0642"
104
109
  },
@@ -118,6 +123,10 @@ export default defineLocale({
118
123
  },
119
124
  pre: {
120
125
  copy: "\u0646\u0633\u062E \u0627\u0644\u0643\u0648\u062F \u0625\u0644\u0649 \u0627\u0644\u062D\u0627\u0641\u0638\u0629"
126
+ },
127
+ prompt: {
128
+ copy: "\u0646\u0633\u062E \u0627\u0644\u062A\u0639\u0644\u064A\u0645\u0627\u062A",
129
+ openIn: "\u0641\u062A\u062D \u0641\u064A {name}"
121
130
  }
122
131
  },
123
132
  sidebar: {
@@ -98,6 +98,11 @@ export default defineLocale({
98
98
  decrement: "Azalt",
99
99
  increment: "Art\u0131r"
100
100
  },
101
+ listbox: {
102
+ noData: "M\u0259lumat yoxdur",
103
+ noMatch: "Uy\u011Fun m\u0259lumat tap\u0131lmad\u0131",
104
+ search: "Axtar\u2026"
105
+ },
101
106
  modal: {
102
107
  close: "Ba\u011Fla"
103
108
  },
@@ -117,6 +122,10 @@ export default defineLocale({
117
122
  },
118
123
  pre: {
119
124
  copy: "Kodu bufer\u0259 kopyala"
125
+ },
126
+ prompt: {
127
+ copy: "T\u0259limat\u0131 kopyala",
128
+ openIn: "{name} il\u0259 a\xE7"
120
129
  }
121
130
  },
122
131
  sidebar: {
@@ -98,6 +98,11 @@ export default defineLocale({
98
98
  decrement: "\u041F\u0430\u043C\u0435\u043D\u0448\u044B\u0446\u044C",
99
99
  increment: "\u041F\u0430\u0432\u044F\u043B\u0456\u0447\u044B\u0446\u044C"
100
100
  },
101
+ listbox: {
102
+ noData: "\u041D\u044F\u043C\u0430 \u0434\u0430\u043D\u044B\u0445",
103
+ noMatch: "\u0421\u0443\u043F\u0430\u0434\u0437\u0435\u043D\u043D\u044F\u045E \u043D\u0435 \u0437\u043D\u043E\u0439\u0434\u0437\u0435\u043D\u0430",
104
+ search: "\u041F\u043E\u0448\u0443\u043A\u2026"
105
+ },
101
106
  modal: {
102
107
  close: "\u0417\u0430\u043A\u0440\u044B\u0446\u044C"
103
108
  },
@@ -117,6 +122,10 @@ export default defineLocale({
117
122
  },
118
123
  pre: {
119
124
  copy: "\u0421\u043A\u0430\u043F\u0456\u044F\u0432\u0430\u0446\u044C \u043A\u043E\u0434 \u0443 \u0431\u0443\u0444\u0435\u0440 \u0430\u0431\u043C\u0435\u043D\u0443"
125
+ },
126
+ prompt: {
127
+ copy: "\u0421\u043A\u0430\u043F\u0456\u044F\u0432\u0430\u0446\u044C \u0437\u0430\u043F\u044B\u0442",
128
+ openIn: "\u0410\u0434\u043A\u0440\u044B\u0446\u044C \u0443 {name}"
120
129
  }
121
130
  },
122
131
  sidebar: {
@@ -98,6 +98,11 @@ export default defineLocale({
98
98
  decrement: "\u041D\u0430\u043C\u0430\u043B\u044F\u0432\u0430\u043D\u0435",
99
99
  increment: "\u0423\u0432\u0435\u043B\u0438\u0447\u0430\u0432\u0430\u043D\u0435"
100
100
  },
101
+ listbox: {
102
+ noData: "\u041D\u044F\u043C\u0430 \u0434\u0430\u043D\u043D\u0438",
103
+ noMatch: "\u041D\u044F\u043C\u0430 \u0441\u044A\u0432\u043F\u0430\u0434\u0435\u043D\u0438\u0435 \u043D\u0430 \u0434\u0430\u043D\u043D\u0438",
104
+ search: "\u041F\u043E\u0442\u044A\u0440\u0441\u0435\u0442\u0435\u2026"
105
+ },
101
106
  modal: {
102
107
  close: "\u0417\u0430\u0442\u0432\u043E\u0440\u0435\u0442\u0435"
103
108
  },
@@ -117,6 +122,10 @@ export default defineLocale({
117
122
  },
118
123
  pre: {
119
124
  copy: "\u041A\u043E\u043F\u0438\u0440\u0430\u0439 \u043A\u043E\u0434\u0430 \u0432 \u043A\u043B\u0438\u043F\u0431\u043E\u0440\u0434\u0430"
125
+ },
126
+ prompt: {
127
+ copy: "\u041A\u043E\u043F\u0438\u0440\u0430\u0439 \u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0430\u0442\u0430",
128
+ openIn: "\u041E\u0442\u0432\u043E\u0440\u0438 \u0432 {name}"
120
129
  }
121
130
  },
122
131
  sidebar: {
@@ -98,6 +98,11 @@ export default defineLocale({
98
98
  decrement: "\u09B9\u09CD\u09B0\u09BE\u09B8 \u0995\u09B0\u09C1\u09A8",
99
99
  increment: "\u09AC\u09C3\u09A6\u09CD\u09A7\u09BF \u0995\u09B0\u09C1\u09A8"
100
100
  },
101
+ listbox: {
102
+ noData: "\u0995\u09CB\u09A8 \u09A4\u09A5\u09CD\u09AF \u09A8\u09C7\u0987",
103
+ noMatch: "\u0995\u09CB\u09A8 \u09AE\u09BF\u09B2 \u09AA\u09BE\u0993\u09AF\u09BC\u09BE \u09AF\u09BE\u09AF\u09BC\u09A8\u09BF",
104
+ search: "\u0985\u09A8\u09C1\u09B8\u09A8\u09CD\u09A7\u09BE\u09A8 \u0995\u09B0\u09C1\u09A8\u2026"
105
+ },
101
106
  modal: {
102
107
  close: "\u09AC\u09A8\u09CD\u09A7 \u0995\u09B0\u09C1\u09A8"
103
108
  },
@@ -117,6 +122,10 @@ export default defineLocale({
117
122
  },
118
123
  pre: {
119
124
  copy: "\u0995\u09CB\u09A1 \u0995\u09CD\u09B2\u09BF\u09AA\u09AC\u09CB\u09B0\u09CD\u09A1\u09C7 \u0995\u09AA\u09BF \u0995\u09B0\u09C1\u09A8"
125
+ },
126
+ prompt: {
127
+ copy: "\u09AA\u09CD\u09B0\u09AE\u09CD\u09AA\u099F \u0995\u09AA\u09BF \u0995\u09B0\u09C1\u09A8",
128
+ openIn: "{name}-\u098F \u0996\u09C1\u09B2\u09C1\u09A8"
120
129
  }
121
130
  },
122
131
  sidebar: {