@nuxt/ui 4.5.1 → 4.6.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 (183) hide show
  1. package/README.md +1 -1
  2. package/dist/module.d.mts +7 -0
  3. package/dist/module.json +2 -2
  4. package/dist/module.mjs +79 -67
  5. package/dist/runtime/components/Avatar.vue +10 -12
  6. package/dist/runtime/components/Banner.vue +1 -1
  7. package/dist/runtime/components/BlogPost.vue +3 -2
  8. package/dist/runtime/components/Calendar.d.vue.ts +4 -4
  9. package/dist/runtime/components/Calendar.vue.d.ts +4 -4
  10. package/dist/runtime/components/ChangelogVersion.vue +3 -2
  11. package/dist/runtime/components/ChangelogVersions.vue +1 -1
  12. package/dist/runtime/components/ChatMessage.d.vue.ts +4 -1
  13. package/dist/runtime/components/ChatMessage.vue +5 -0
  14. package/dist/runtime/components/ChatMessage.vue.d.ts +4 -1
  15. package/dist/runtime/components/ChatMessages.vue +14 -1
  16. package/dist/runtime/components/ChatPrompt.vue +6 -1
  17. package/dist/runtime/components/ChatReasoning.d.vue.ts +78 -0
  18. package/dist/runtime/components/ChatReasoning.vue +162 -0
  19. package/dist/runtime/components/ChatReasoning.vue.d.ts +78 -0
  20. package/dist/runtime/components/ChatShimmer.d.vue.ts +34 -0
  21. package/dist/runtime/components/ChatShimmer.vue +37 -0
  22. package/dist/runtime/components/ChatShimmer.vue.d.ts +34 -0
  23. package/dist/runtime/components/ChatTool.d.vue.ts +88 -0
  24. package/dist/runtime/components/ChatTool.vue +105 -0
  25. package/dist/runtime/components/ChatTool.vue.d.ts +88 -0
  26. package/dist/runtime/components/Checkbox.d.vue.ts +22 -19
  27. package/dist/runtime/components/Checkbox.vue +9 -8
  28. package/dist/runtime/components/Checkbox.vue.d.ts +22 -19
  29. package/dist/runtime/components/DashboardGroup.d.vue.ts +1 -1
  30. package/dist/runtime/components/DashboardGroup.vue.d.ts +1 -1
  31. package/dist/runtime/components/DashboardSearchButton.vue +2 -2
  32. package/dist/runtime/components/DashboardSidebar.vue +6 -3
  33. package/dist/runtime/components/Drawer.vue +6 -4
  34. package/dist/runtime/components/DropdownMenu.d.vue.ts +29 -3
  35. package/dist/runtime/components/DropdownMenu.vue +9 -0
  36. package/dist/runtime/components/DropdownMenu.vue.d.ts +29 -3
  37. package/dist/runtime/components/DropdownMenuContent.d.vue.ts +9 -3
  38. package/dist/runtime/components/DropdownMenuContent.vue +62 -9
  39. package/dist/runtime/components/DropdownMenuContent.vue.d.ts +9 -3
  40. package/dist/runtime/components/EditorDragHandle.d.vue.ts +4 -4
  41. package/dist/runtime/components/EditorDragHandle.vue.d.ts +4 -4
  42. package/dist/runtime/components/Error.vue +5 -5
  43. package/dist/runtime/components/FileUpload.d.vue.ts +6 -0
  44. package/dist/runtime/components/FileUpload.vue +11 -7
  45. package/dist/runtime/components/FileUpload.vue.d.ts +6 -0
  46. package/dist/runtime/components/Icon.d.vue.ts +2 -1
  47. package/dist/runtime/components/Icon.vue +3 -3
  48. package/dist/runtime/components/Icon.vue.d.ts +2 -1
  49. package/dist/runtime/components/InputDate.d.vue.ts +4 -4
  50. package/dist/runtime/components/InputDate.vue.d.ts +4 -4
  51. package/dist/runtime/components/InputMenu.d.vue.ts +7 -1
  52. package/dist/runtime/components/InputMenu.vue +67 -48
  53. package/dist/runtime/components/InputMenu.vue.d.ts +7 -1
  54. package/dist/runtime/components/InputTime.d.vue.ts +53 -27
  55. package/dist/runtime/components/InputTime.vue +52 -27
  56. package/dist/runtime/components/InputTime.vue.d.ts +53 -27
  57. package/dist/runtime/components/Kbd.vue +1 -1
  58. package/dist/runtime/components/Modal.vue +6 -4
  59. package/dist/runtime/components/NavigationMenu.vue +1 -0
  60. package/dist/runtime/components/Popover.vue +1 -1
  61. package/dist/runtime/components/Progress.d.vue.ts +1 -1
  62. package/dist/runtime/components/Progress.vue.d.ts +1 -1
  63. package/dist/runtime/components/SelectMenu.d.vue.ts +1 -1
  64. package/dist/runtime/components/SelectMenu.vue +1 -1
  65. package/dist/runtime/components/SelectMenu.vue.d.ts +1 -1
  66. package/dist/runtime/components/Sidebar.d.vue.ts +131 -0
  67. package/dist/runtime/components/Sidebar.vue +222 -0
  68. package/dist/runtime/components/Sidebar.vue.d.ts +131 -0
  69. package/dist/runtime/components/Slideover.vue +6 -4
  70. package/dist/runtime/components/Switch.d.vue.ts +22 -19
  71. package/dist/runtime/components/Switch.vue +7 -6
  72. package/dist/runtime/components/Switch.vue.d.ts +22 -19
  73. package/dist/runtime/components/Table.d.vue.ts +1 -1
  74. package/dist/runtime/components/Table.vue +12 -4
  75. package/dist/runtime/components/Table.vue.d.ts +1 -1
  76. package/dist/runtime/components/Tooltip.d.vue.ts +2 -0
  77. package/dist/runtime/components/Tooltip.vue +3 -2
  78. package/dist/runtime/components/Tooltip.vue.d.ts +2 -0
  79. package/dist/runtime/components/color-mode/ColorModeSelect.d.vue.ts +1 -1
  80. package/dist/runtime/components/color-mode/ColorModeSelect.vue.d.ts +1 -1
  81. package/dist/runtime/components/color-mode/ColorModeSwitch.vue +3 -1
  82. package/dist/runtime/components/content/ContentNavigation.vue +9 -2
  83. package/dist/runtime/components/content/ContentSurround.vue +6 -2
  84. package/dist/runtime/components/content/ContentToc.d.vue.ts +5 -0
  85. package/dist/runtime/components/content/ContentToc.vue +57 -11
  86. package/dist/runtime/components/content/ContentToc.vue.d.ts +5 -0
  87. package/dist/runtime/components/locale/LocaleSelect.d.vue.ts +1 -1
  88. package/dist/runtime/components/locale/LocaleSelect.vue.d.ts +1 -1
  89. package/dist/runtime/components/prose/Pre.vue +0 -4
  90. package/dist/runtime/composables/index.d.ts +12 -0
  91. package/dist/runtime/composables/index.js +12 -0
  92. package/dist/runtime/composables/useEditorMenu.js +1 -1
  93. package/dist/runtime/composables/useFileUpload.d.ts +2 -2
  94. package/dist/runtime/composables/useFileUpload.js +3 -3
  95. package/dist/runtime/composables/{internal/useFilter.js → useFilter.js} +1 -1
  96. package/dist/runtime/composables/useIMEGuard.d.ts +10 -0
  97. package/dist/runtime/composables/useIMEGuard.js +22 -0
  98. package/dist/runtime/composables/useScrollShadow.d.ts +23 -0
  99. package/dist/runtime/composables/useScrollShadow.js +36 -0
  100. package/dist/runtime/index.css +1 -1
  101. package/dist/runtime/keyframes.css +1 -1
  102. package/dist/runtime/locale/ar.js +13 -0
  103. package/dist/runtime/locale/az.js +13 -0
  104. package/dist/runtime/locale/be.js +13 -0
  105. package/dist/runtime/locale/bg.js +13 -0
  106. package/dist/runtime/locale/bn.js +13 -0
  107. package/dist/runtime/locale/ca.js +13 -0
  108. package/dist/runtime/locale/ckb.js +13 -0
  109. package/dist/runtime/locale/cs.js +13 -0
  110. package/dist/runtime/locale/da.js +13 -0
  111. package/dist/runtime/locale/de.js +13 -0
  112. package/dist/runtime/locale/de_ch.js +13 -0
  113. package/dist/runtime/locale/el.js +13 -0
  114. package/dist/runtime/locale/en.js +13 -0
  115. package/dist/runtime/locale/es.js +13 -0
  116. package/dist/runtime/locale/et.js +13 -0
  117. package/dist/runtime/locale/eu.js +13 -0
  118. package/dist/runtime/locale/fa_ir.js +13 -0
  119. package/dist/runtime/locale/fi.js +13 -0
  120. package/dist/runtime/locale/fr.js +13 -0
  121. package/dist/runtime/locale/gl.js +13 -0
  122. package/dist/runtime/locale/he.js +13 -0
  123. package/dist/runtime/locale/hi.js +13 -0
  124. package/dist/runtime/locale/hr.js +13 -0
  125. package/dist/runtime/locale/hu.js +13 -0
  126. package/dist/runtime/locale/hy.js +13 -0
  127. package/dist/runtime/locale/id.js +13 -0
  128. package/dist/runtime/locale/index.d.ts +1 -0
  129. package/dist/runtime/locale/index.js +1 -0
  130. package/dist/runtime/locale/is.d.ts +3 -0
  131. package/dist/runtime/locale/is.js +142 -0
  132. package/dist/runtime/locale/it.js +13 -0
  133. package/dist/runtime/locale/ja.js +13 -0
  134. package/dist/runtime/locale/ka.js +13 -0
  135. package/dist/runtime/locale/kk.js +13 -0
  136. package/dist/runtime/locale/km.js +13 -0
  137. package/dist/runtime/locale/ko.js +13 -0
  138. package/dist/runtime/locale/ky.js +13 -0
  139. package/dist/runtime/locale/lb.js +13 -0
  140. package/dist/runtime/locale/lo.js +13 -0
  141. package/dist/runtime/locale/lt.js +13 -0
  142. package/dist/runtime/locale/mn.js +13 -0
  143. package/dist/runtime/locale/ms.js +13 -0
  144. package/dist/runtime/locale/nb_no.js +13 -0
  145. package/dist/runtime/locale/nl.js +13 -0
  146. package/dist/runtime/locale/pl.js +13 -0
  147. package/dist/runtime/locale/pt.js +13 -0
  148. package/dist/runtime/locale/pt_br.js +13 -0
  149. package/dist/runtime/locale/ro.js +13 -0
  150. package/dist/runtime/locale/ru.js +13 -0
  151. package/dist/runtime/locale/sk.js +13 -0
  152. package/dist/runtime/locale/sl.js +13 -0
  153. package/dist/runtime/locale/sq.js +13 -0
  154. package/dist/runtime/locale/sv.js +13 -0
  155. package/dist/runtime/locale/th.js +13 -0
  156. package/dist/runtime/locale/tj.js +13 -0
  157. package/dist/runtime/locale/tr.js +13 -0
  158. package/dist/runtime/locale/ug_cn.js +13 -0
  159. package/dist/runtime/locale/uk.js +13 -0
  160. package/dist/runtime/locale/ur.js +13 -0
  161. package/dist/runtime/locale/uz.js +13 -0
  162. package/dist/runtime/locale/vi.js +13 -0
  163. package/dist/runtime/locale/zh_cn.js +13 -0
  164. package/dist/runtime/locale/zh_tw.js +13 -0
  165. package/dist/runtime/types/index.d.ts +4 -0
  166. package/dist/runtime/types/index.js +4 -0
  167. package/dist/runtime/types/locale.d.ts +13 -0
  168. package/dist/runtime/utils/ai.d.ts +23 -0
  169. package/dist/runtime/utils/ai.js +16 -0
  170. package/dist/runtime/utils/editor.js +17 -5
  171. package/dist/runtime/vue/components/Icon.d.vue.ts +1 -4
  172. package/dist/runtime/vue/components/Icon.vue +28 -3
  173. package/dist/runtime/vue/components/Icon.vue.d.ts +1 -4
  174. package/dist/runtime/vue/components/color-mode/ColorModeSelect.d.vue.ts +1 -1
  175. package/dist/runtime/vue/components/color-mode/ColorModeSelect.vue.d.ts +1 -1
  176. package/dist/runtime/vue/components/color-mode/ColorModeSwitch.vue +3 -1
  177. package/dist/shared/{ui.DI_ypO2T.mjs → ui.DJUbBpE2.mjs} +298 -39
  178. package/dist/unplugin.d.mts +15 -5
  179. package/dist/unplugin.mjs +53 -30
  180. package/dist/vite.d.mts +1 -0
  181. package/dist/vite.mjs +1 -1
  182. package/package.json +50 -47
  183. /package/dist/runtime/composables/{internal/useFilter.d.ts → useFilter.d.ts} +0 -0
@@ -0,0 +1,162 @@
1
+ <script>
2
+ import theme from "#build/ui/chat-reasoning";
3
+ </script>
4
+
5
+ <script setup>
6
+ import { ref, computed, watch, onUnmounted, nextTick, useTemplateRef } from "vue";
7
+ import { CollapsibleRoot, CollapsibleTrigger, CollapsibleContent } from "reka-ui";
8
+ import { useAppConfig } from "#imports";
9
+ import { useComponentUI } from "../composables/useComponentUI";
10
+ import { useLocale } from "../composables/useLocale";
11
+ import { useScrollShadow } from "../composables/useScrollShadow";
12
+ import { tv } from "../utils/tv";
13
+ import UIcon from "./Icon.vue";
14
+ import UChatShimmer from "./ChatShimmer.vue";
15
+ const props = defineProps({
16
+ text: { type: String, required: false },
17
+ streaming: { type: Boolean, required: false, default: false },
18
+ duration: { type: Number, required: false },
19
+ icon: { type: null, required: false },
20
+ chevron: { type: String, required: false, default: "trailing" },
21
+ chevronIcon: { type: null, required: false },
22
+ autoCloseDelay: { type: Number, required: false, default: 500 },
23
+ shimmer: { type: Object, required: false },
24
+ class: { type: null, required: false },
25
+ ui: { type: Object, required: false },
26
+ defaultOpen: { type: Boolean, required: false },
27
+ open: { type: Boolean, required: false, default: void 0 },
28
+ disabled: { type: Boolean, required: false },
29
+ unmountOnHide: { type: Boolean, required: false, default: false }
30
+ });
31
+ const emits = defineEmits(["update:open"]);
32
+ defineSlots();
33
+ const { t, code } = useLocale();
34
+ const appConfig = useAppConfig();
35
+ const uiProp = useComponentUI("chatReasoning", props);
36
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.chatReasoning || {} })({
37
+ chevron: props.chevron
38
+ }));
39
+ const isControlled = computed(() => props.open !== void 0);
40
+ const internalOpen = ref(props.defaultOpen ?? props.streaming);
41
+ const startTime = ref(props.streaming ? Date.now() : null);
42
+ const internalDuration = ref(void 0);
43
+ const autoCloseTimeout = ref(null);
44
+ watch(() => props.streaming, (streaming, wasStreaming) => {
45
+ if (streaming) {
46
+ if (autoCloseTimeout.value) {
47
+ clearTimeout(autoCloseTimeout.value);
48
+ autoCloseTimeout.value = null;
49
+ }
50
+ if (!wasStreaming) {
51
+ setOpen(true);
52
+ startTime.value = Date.now();
53
+ }
54
+ } else if (wasStreaming) {
55
+ if (startTime.value !== null) {
56
+ internalDuration.value = Math.ceil((Date.now() - startTime.value) / 1e3);
57
+ startTime.value = null;
58
+ }
59
+ if (props.autoCloseDelay > 0) {
60
+ autoCloseTimeout.value = setTimeout(() => {
61
+ setOpen(false);
62
+ }, props.autoCloseDelay);
63
+ }
64
+ }
65
+ }, { immediate: true });
66
+ const actualDuration = computed(() => props.duration ?? internalDuration.value);
67
+ const thinkingText = computed(() => {
68
+ if (props.streaming || actualDuration.value === 0) {
69
+ return t("chatReasoning.thinking");
70
+ }
71
+ if (actualDuration.value === void 0) {
72
+ return t("chatReasoning.thought");
73
+ }
74
+ const d = actualDuration.value;
75
+ const unit = d < 60 ? "second" : "minute";
76
+ const value = d < 60 ? d : Math.floor(d / 60);
77
+ const duration = new Intl.NumberFormat(code.value, { style: "unit", unit, unitDisplay: "long" }).format(value);
78
+ return t("chatReasoning.thoughtFor", { duration });
79
+ });
80
+ const resolvedOpen = computed(() => isControlled.value ? props.open : internalOpen.value);
81
+ function setOpen(value) {
82
+ if (autoCloseTimeout.value) {
83
+ clearTimeout(autoCloseTimeout.value);
84
+ autoCloseTimeout.value = null;
85
+ }
86
+ internalOpen.value = value;
87
+ emits("update:open", value);
88
+ }
89
+ onUnmounted(() => {
90
+ if (autoCloseTimeout.value) {
91
+ clearTimeout(autoCloseTimeout.value);
92
+ }
93
+ });
94
+ const hasContent = computed(() => !!props.text || props.streaming);
95
+ const chevronIconName = computed(() => props.chevronIcon || appConfig.ui.icons?.chevronDown);
96
+ const bodyRef = useTemplateRef("bodyRef");
97
+ const { style: scrollShadowStyle } = useScrollShadow(bodyRef);
98
+ watch(() => props.text, () => {
99
+ if (!props.streaming || !bodyRef.value) return;
100
+ const el = bodyRef.value;
101
+ const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
102
+ if (distanceFromBottom < 50) {
103
+ nextTick(() => {
104
+ el.scrollTop = el.scrollHeight;
105
+ });
106
+ }
107
+ });
108
+ </script>
109
+
110
+ <template>
111
+ <CollapsibleRoot
112
+ v-if="hasContent"
113
+ v-slot="{ open: isOpen }"
114
+ :open="resolvedOpen"
115
+ :disabled="disabled"
116
+ :unmount-on-hide="unmountOnHide"
117
+ data-slot="root"
118
+ :class="ui.root({ class: [uiProp?.root, props.class] })"
119
+ @update:open="setOpen"
120
+ >
121
+ <CollapsibleTrigger as-child :disabled="!hasContent">
122
+ <button
123
+ type="button"
124
+ data-slot="trigger"
125
+ :class="ui.trigger({ class: uiProp?.trigger })"
126
+ >
127
+ <span v-if="icon || hasContent && chevron === 'leading'" data-slot="leading" :class="ui.leading({ class: uiProp?.leading })">
128
+ <UIcon
129
+ v-if="icon"
130
+ :name="icon"
131
+ data-slot="leadingIcon"
132
+ :class="ui.leadingIcon({ class: uiProp?.leadingIcon, alone: !(hasContent && chevron === 'leading') })"
133
+ />
134
+ <UIcon
135
+ v-if="hasContent && chevron === 'leading'"
136
+ :name="chevronIconName"
137
+ data-slot="chevronIcon"
138
+ :class="ui.chevronIcon({ class: uiProp?.chevronIcon, alone: !icon })"
139
+ />
140
+ </span>
141
+
142
+ <UChatShimmer v-if="streaming" :text="thinkingText" v-bind="props.shimmer" data-slot="label" :class="ui.label({ class: uiProp?.label })" />
143
+ <span v-else data-slot="label" :class="ui.label({ class: uiProp?.label })">{{ thinkingText }}</span>
144
+
145
+ <UIcon
146
+ v-if="hasContent && chevron === 'trailing'"
147
+ :name="chevronIconName"
148
+ data-slot="trailingIcon"
149
+ :class="ui.trailingIcon({ class: uiProp?.trailingIcon })"
150
+ />
151
+ </button>
152
+ </CollapsibleTrigger>
153
+
154
+ <CollapsibleContent data-slot="content" :class="ui.content({ class: uiProp?.content })">
155
+ <div ref="bodyRef" data-slot="body" :class="ui.body({ class: uiProp?.body })" :style="scrollShadowStyle">
156
+ <slot :open="isOpen">
157
+ {{ text }}
158
+ </slot>
159
+ </div>
160
+ </CollapsibleContent>
161
+ </CollapsibleRoot>
162
+ </template>
@@ -0,0 +1,78 @@
1
+ import type { CollapsibleRootProps } from 'reka-ui';
2
+ import type { VNode } from 'vue';
3
+ import type { AppConfig } from '@nuxt/schema';
4
+ import theme from '#build/ui/chat-reasoning';
5
+ import type { IconProps } from '../types';
6
+ import type { ChatShimmerProps } from './ChatShimmer.vue';
7
+ import type { ComponentConfig } from '../types/tv';
8
+ type ChatReasoning = ComponentConfig<typeof theme, AppConfig, 'chatReasoning'>;
9
+ export interface ChatReasoningProps extends Pick<CollapsibleRootProps, 'defaultOpen' | 'open' | 'disabled' | 'unmountOnHide'> {
10
+ /**
11
+ * The reasoning text content to display.
12
+ */
13
+ text?: string;
14
+ /**
15
+ * Whether the reasoning content is currently streaming.
16
+ * @defaultValue false
17
+ */
18
+ streaming?: boolean;
19
+ /**
20
+ * The duration in seconds that the AI spent reasoning.
21
+ * If not provided, it will be calculated automatically based on streaming time.
22
+ */
23
+ duration?: number;
24
+ /**
25
+ * The icon displayed next to the trigger.
26
+ * @IconifyIcon
27
+ */
28
+ icon?: IconProps['name'];
29
+ /**
30
+ * The position of the chevron icon.
31
+ * @defaultValue 'trailing'
32
+ */
33
+ chevron?: 'leading' | 'trailing';
34
+ /**
35
+ * The icon displayed as the chevron.
36
+ * @defaultValue appConfig.ui.icons.chevronDown
37
+ * @IconifyIcon
38
+ */
39
+ chevronIcon?: IconProps['name'];
40
+ /**
41
+ * The delay in milliseconds before auto-closing when streaming ends.
42
+ * Set to `0` to disable auto-close.
43
+ * @defaultValue 500
44
+ */
45
+ autoCloseDelay?: number;
46
+ /**
47
+ * Customize the [`ChatShimmer`](https://ui.nuxt.com/docs/components/chat-shimmer) component when streaming.
48
+ */
49
+ shimmer?: Partial<Omit<ChatShimmerProps, 'text'>>;
50
+ class?: any;
51
+ ui?: ChatReasoning['slots'];
52
+ }
53
+ export interface ChatReasoningEmits {
54
+ 'update:open': [value: boolean];
55
+ }
56
+ export interface ChatReasoningSlots {
57
+ default?(props: {
58
+ open: boolean;
59
+ }): VNode[];
60
+ }
61
+ declare const _default: typeof __VLS_export;
62
+ export default _default;
63
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<ChatReasoningProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
64
+ "update:open": (value: boolean) => any;
65
+ }, string, import("vue").PublicProps, Readonly<ChatReasoningProps> & Readonly<{
66
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
67
+ }>, {
68
+ open: boolean;
69
+ streaming: boolean;
70
+ unmountOnHide: boolean;
71
+ chevron: "leading" | "trailing";
72
+ autoCloseDelay: number;
73
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ChatReasoningSlots>;
74
+ type __VLS_WithSlots<T, S> = T & {
75
+ new (): {
76
+ $slots: S;
77
+ };
78
+ };
@@ -0,0 +1,34 @@
1
+ import type { AppConfig } from '@nuxt/schema';
2
+ import theme from '#build/ui/chat-shimmer';
3
+ import type { ComponentConfig } from '../types/tv';
4
+ type ChatShimmer = ComponentConfig<typeof theme, AppConfig, 'chatShimmer'>;
5
+ export interface ChatShimmerProps {
6
+ /**
7
+ * The element or component this component should render as.
8
+ * @defaultValue 'span'
9
+ */
10
+ as?: any;
11
+ /**
12
+ * The text to display with the shimmer effect.
13
+ */
14
+ text: string;
15
+ /**
16
+ * The duration of the shimmer animation in seconds.
17
+ * @defaultValue 2
18
+ */
19
+ duration?: number;
20
+ /**
21
+ * The spread multiplier for the shimmer highlight. The actual spread is computed as `text.length * spread` in pixels.
22
+ * @defaultValue 2
23
+ */
24
+ spread?: number;
25
+ class?: any;
26
+ ui?: ChatShimmer['slots'];
27
+ }
28
+ declare const _default: typeof __VLS_export;
29
+ export default _default;
30
+ declare const __VLS_export: import("vue").DefineComponent<ChatShimmerProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ChatShimmerProps> & Readonly<{}>, {
31
+ as: any;
32
+ duration: number;
33
+ spread: number;
34
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -0,0 +1,37 @@
1
+ <script>
2
+ import theme from "#build/ui/chat-shimmer";
3
+ </script>
4
+
5
+ <script setup>
6
+ import { computed } from "vue";
7
+ import { Primitive } from "reka-ui";
8
+ import { useAppConfig } from "#imports";
9
+ import { useComponentUI } from "../composables/useComponentUI";
10
+ import { tv } from "../utils/tv";
11
+ const props = defineProps({
12
+ as: { type: null, required: false, default: "span" },
13
+ text: { type: String, required: true },
14
+ duration: { type: Number, required: false, default: 2 },
15
+ spread: { type: Number, required: false, default: 2 },
16
+ class: { type: null, required: false },
17
+ ui: { type: Object, required: false }
18
+ });
19
+ const appConfig = useAppConfig();
20
+ const uiProp = useComponentUI("chatShimmer", props);
21
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.chatShimmer || {} }));
22
+ const spread = computed(() => props.text.length * props.spread);
23
+ </script>
24
+
25
+ <template>
26
+ <Primitive
27
+ :as="as"
28
+ :style="{
29
+ '--spread': `${spread}px`,
30
+ '--duration': `${duration}s`
31
+ }"
32
+ data-slot="base"
33
+ :class="ui({ class: [uiProp?.base, props.class] })"
34
+ >
35
+ {{ text }}
36
+ </Primitive>
37
+ </template>
@@ -0,0 +1,34 @@
1
+ import type { AppConfig } from '@nuxt/schema';
2
+ import theme from '#build/ui/chat-shimmer';
3
+ import type { ComponentConfig } from '../types/tv';
4
+ type ChatShimmer = ComponentConfig<typeof theme, AppConfig, 'chatShimmer'>;
5
+ export interface ChatShimmerProps {
6
+ /**
7
+ * The element or component this component should render as.
8
+ * @defaultValue 'span'
9
+ */
10
+ as?: any;
11
+ /**
12
+ * The text to display with the shimmer effect.
13
+ */
14
+ text: string;
15
+ /**
16
+ * The duration of the shimmer animation in seconds.
17
+ * @defaultValue 2
18
+ */
19
+ duration?: number;
20
+ /**
21
+ * The spread multiplier for the shimmer highlight. The actual spread is computed as `text.length * spread` in pixels.
22
+ * @defaultValue 2
23
+ */
24
+ spread?: number;
25
+ class?: any;
26
+ ui?: ChatShimmer['slots'];
27
+ }
28
+ declare const _default: typeof __VLS_export;
29
+ export default _default;
30
+ declare const __VLS_export: import("vue").DefineComponent<ChatShimmerProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ChatShimmerProps> & Readonly<{}>, {
31
+ as: any;
32
+ duration: number;
33
+ spread: number;
34
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -0,0 +1,88 @@
1
+ import type { CollapsibleRootProps } from 'reka-ui';
2
+ import type { VNode } from 'vue';
3
+ import type { AppConfig } from '@nuxt/schema';
4
+ import theme from '#build/ui/chat-tool';
5
+ import type { IconProps } from '../types';
6
+ import type { ChatShimmerProps } from './ChatShimmer.vue';
7
+ import type { ComponentConfig } from '../types/tv';
8
+ type ChatTool = ComponentConfig<typeof theme, AppConfig, 'chatTool'>;
9
+ export interface ChatToolProps extends Pick<CollapsibleRootProps, 'defaultOpen' | 'open' | 'disabled' | 'unmountOnHide'> {
10
+ /**
11
+ * The text content to display.
12
+ */
13
+ text?: string;
14
+ /**
15
+ * The suffix text displayed after the main text.
16
+ */
17
+ suffix?: string;
18
+ /**
19
+ * The icon displayed next to the trigger.
20
+ * @IconifyIcon
21
+ */
22
+ icon?: IconProps['name'];
23
+ /**
24
+ * Whether the tool is in a loading state.
25
+ * @defaultValue false
26
+ */
27
+ loading?: boolean;
28
+ /**
29
+ * The icon displayed when loading.
30
+ * @defaultValue appConfig.ui.icons.loading
31
+ * @IconifyIcon
32
+ */
33
+ loadingIcon?: IconProps['name'];
34
+ /**
35
+ * Whether the tool content is currently streaming.
36
+ * @defaultValue false
37
+ */
38
+ streaming?: boolean;
39
+ /**
40
+ * The visual variant of the tool display.
41
+ * @defaultValue 'inline'
42
+ */
43
+ variant?: ChatTool['variants']['variant'];
44
+ /**
45
+ * The position of the chevron icon.
46
+ * @defaultValue 'trailing'
47
+ */
48
+ chevron?: 'leading' | 'trailing';
49
+ /**
50
+ * The icon displayed as the chevron.
51
+ * @defaultValue appConfig.ui.icons.chevronDown
52
+ * @IconifyIcon
53
+ */
54
+ chevronIcon?: IconProps['name'];
55
+ /**
56
+ * Customize the [`ChatShimmer`](https://ui.nuxt.com/docs/components/chat-shimmer) component when streaming.
57
+ */
58
+ shimmer?: Partial<Omit<ChatShimmerProps, 'text'>>;
59
+ class?: any;
60
+ ui?: ChatTool['slots'];
61
+ }
62
+ export interface ChatToolEmits {
63
+ 'update:open': [value: boolean];
64
+ }
65
+ export interface ChatToolSlots {
66
+ default?(props: {
67
+ open: boolean;
68
+ }): VNode[];
69
+ }
70
+ declare const _default: typeof __VLS_export;
71
+ export default _default;
72
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<ChatToolProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
73
+ "update:open": (value: boolean) => any;
74
+ }, string, import("vue").PublicProps, Readonly<ChatToolProps> & Readonly<{
75
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
76
+ }>, {
77
+ loading: boolean;
78
+ variant: ChatTool["variants"]["variant"];
79
+ open: boolean;
80
+ streaming: boolean;
81
+ unmountOnHide: boolean;
82
+ chevron: "leading" | "trailing";
83
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ChatToolSlots>;
84
+ type __VLS_WithSlots<T, S> = T & {
85
+ new (): {
86
+ $slots: S;
87
+ };
88
+ };
@@ -0,0 +1,105 @@
1
+ <script>
2
+ import theme from "#build/ui/chat-tool";
3
+ </script>
4
+
5
+ <script setup>
6
+ import { ref, computed } from "vue";
7
+ import { CollapsibleRoot, CollapsibleTrigger, CollapsibleContent } from "reka-ui";
8
+ import { useAppConfig } from "#imports";
9
+ import { useComponentUI } from "../composables/useComponentUI";
10
+ import { tv } from "../utils/tv";
11
+ import UIcon from "./Icon.vue";
12
+ import UChatShimmer from "./ChatShimmer.vue";
13
+ const props = defineProps({
14
+ text: { type: String, required: false },
15
+ suffix: { type: String, required: false },
16
+ icon: { type: null, required: false },
17
+ loading: { type: Boolean, required: false, default: false },
18
+ loadingIcon: { type: null, required: false },
19
+ streaming: { type: Boolean, required: false, default: false },
20
+ variant: { type: null, required: false, default: "inline" },
21
+ chevron: { type: String, required: false, default: "trailing" },
22
+ chevronIcon: { type: null, required: false },
23
+ shimmer: { type: Object, required: false },
24
+ class: { type: null, required: false },
25
+ ui: { type: Object, required: false },
26
+ defaultOpen: { type: Boolean, required: false },
27
+ open: { type: Boolean, required: false, default: void 0 },
28
+ disabled: { type: Boolean, required: false },
29
+ unmountOnHide: { type: Boolean, required: false, default: false }
30
+ });
31
+ const emits = defineEmits(["update:open"]);
32
+ const slots = defineSlots();
33
+ const appConfig = useAppConfig();
34
+ const uiProp = useComponentUI("chatTool", props);
35
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.chatTool || {} })({
36
+ variant: props.variant,
37
+ chevron: props.chevron,
38
+ loading: props.loading
39
+ }));
40
+ const isControlled = computed(() => props.open !== void 0);
41
+ const internalOpen = ref(props.defaultOpen ?? false);
42
+ const resolvedOpen = computed(() => isControlled.value ? props.open : internalOpen.value);
43
+ function setOpen(value) {
44
+ internalOpen.value = value;
45
+ emits("update:open", value);
46
+ }
47
+ const hasContent = computed(() => !!slots.default);
48
+ const resolvedLoadingIcon = computed(() => props.loadingIcon || appConfig.ui.icons?.loading);
49
+ const resolvedIcon = computed(() => props.loading ? resolvedLoadingIcon.value : props.icon);
50
+ const chevronIconName = computed(() => props.chevronIcon || appConfig.ui.icons?.chevronDown);
51
+ </script>
52
+
53
+ <template>
54
+ <CollapsibleRoot
55
+ v-slot="{ open: isOpen }"
56
+ :open="resolvedOpen"
57
+ :disabled="disabled"
58
+ :unmount-on-hide="unmountOnHide"
59
+ data-slot="root"
60
+ :class="ui.root({ class: [uiProp?.root, props.class] })"
61
+ @update:open="setOpen"
62
+ >
63
+ <CollapsibleTrigger as-child :disabled="!hasContent">
64
+ <button
65
+ type="button"
66
+ data-slot="trigger"
67
+ :class="ui.trigger({ class: uiProp?.trigger })"
68
+ >
69
+ <span v-if="resolvedIcon || hasContent && chevron === 'leading'" data-slot="leading" :class="ui.leading({ class: uiProp?.leading })">
70
+ <UIcon
71
+ v-if="resolvedIcon"
72
+ :name="resolvedIcon"
73
+ data-slot="leadingIcon"
74
+ :class="ui.leadingIcon({ class: uiProp?.leadingIcon, alone: !(hasContent && chevron === 'leading') })"
75
+ />
76
+ <UIcon
77
+ v-if="hasContent && chevron === 'leading'"
78
+ :name="chevronIconName"
79
+ data-slot="chevronIcon"
80
+ :class="ui.chevronIcon({ class: uiProp?.chevronIcon, alone: !resolvedIcon })"
81
+ />
82
+ </span>
83
+
84
+ <span data-slot="label" :class="ui.label({ class: uiProp?.label })">
85
+ <UChatShimmer v-if="streaming && text" :text="text" v-bind="props.shimmer" />
86
+ <template v-else>{{ text }}</template>
87
+ <span v-if="suffix" data-slot="suffix" :class="ui.suffix({ class: uiProp?.suffix })">{{ suffix }}</span>
88
+ </span>
89
+
90
+ <UIcon
91
+ v-if="hasContent && chevron === 'trailing'"
92
+ :name="chevronIconName"
93
+ data-slot="trailingIcon"
94
+ :class="ui.trailingIcon({ class: uiProp?.trailingIcon })"
95
+ />
96
+ </button>
97
+ </CollapsibleTrigger>
98
+
99
+ <CollapsibleContent data-slot="content" :class="ui.content({ class: uiProp?.content })">
100
+ <div data-slot="body" :class="ui.body({ class: uiProp?.body })">
101
+ <slot :open="isOpen" />
102
+ </div>
103
+ </CollapsibleContent>
104
+ </CollapsibleRoot>
105
+ </template>
@@ -0,0 +1,88 @@
1
+ import type { CollapsibleRootProps } from 'reka-ui';
2
+ import type { VNode } from 'vue';
3
+ import type { AppConfig } from '@nuxt/schema';
4
+ import theme from '#build/ui/chat-tool';
5
+ import type { IconProps } from '../types';
6
+ import type { ChatShimmerProps } from './ChatShimmer.vue';
7
+ import type { ComponentConfig } from '../types/tv';
8
+ type ChatTool = ComponentConfig<typeof theme, AppConfig, 'chatTool'>;
9
+ export interface ChatToolProps extends Pick<CollapsibleRootProps, 'defaultOpen' | 'open' | 'disabled' | 'unmountOnHide'> {
10
+ /**
11
+ * The text content to display.
12
+ */
13
+ text?: string;
14
+ /**
15
+ * The suffix text displayed after the main text.
16
+ */
17
+ suffix?: string;
18
+ /**
19
+ * The icon displayed next to the trigger.
20
+ * @IconifyIcon
21
+ */
22
+ icon?: IconProps['name'];
23
+ /**
24
+ * Whether the tool is in a loading state.
25
+ * @defaultValue false
26
+ */
27
+ loading?: boolean;
28
+ /**
29
+ * The icon displayed when loading.
30
+ * @defaultValue appConfig.ui.icons.loading
31
+ * @IconifyIcon
32
+ */
33
+ loadingIcon?: IconProps['name'];
34
+ /**
35
+ * Whether the tool content is currently streaming.
36
+ * @defaultValue false
37
+ */
38
+ streaming?: boolean;
39
+ /**
40
+ * The visual variant of the tool display.
41
+ * @defaultValue 'inline'
42
+ */
43
+ variant?: ChatTool['variants']['variant'];
44
+ /**
45
+ * The position of the chevron icon.
46
+ * @defaultValue 'trailing'
47
+ */
48
+ chevron?: 'leading' | 'trailing';
49
+ /**
50
+ * The icon displayed as the chevron.
51
+ * @defaultValue appConfig.ui.icons.chevronDown
52
+ * @IconifyIcon
53
+ */
54
+ chevronIcon?: IconProps['name'];
55
+ /**
56
+ * Customize the [`ChatShimmer`](https://ui.nuxt.com/docs/components/chat-shimmer) component when streaming.
57
+ */
58
+ shimmer?: Partial<Omit<ChatShimmerProps, 'text'>>;
59
+ class?: any;
60
+ ui?: ChatTool['slots'];
61
+ }
62
+ export interface ChatToolEmits {
63
+ 'update:open': [value: boolean];
64
+ }
65
+ export interface ChatToolSlots {
66
+ default?(props: {
67
+ open: boolean;
68
+ }): VNode[];
69
+ }
70
+ declare const _default: typeof __VLS_export;
71
+ export default _default;
72
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<ChatToolProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
73
+ "update:open": (value: boolean) => any;
74
+ }, string, import("vue").PublicProps, Readonly<ChatToolProps> & Readonly<{
75
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
76
+ }>, {
77
+ loading: boolean;
78
+ variant: ChatTool["variants"]["variant"];
79
+ open: boolean;
80
+ streaming: boolean;
81
+ unmountOnHide: boolean;
82
+ chevron: "leading" | "trailing";
83
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ChatToolSlots>;
84
+ type __VLS_WithSlots<T, S> = T & {
85
+ new (): {
86
+ $slots: S;
87
+ };
88
+ };