dou-ui 0.1.0-alpha.3 → 0.1.0-alpha.4
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.
- package/dist/components/card/card.js.map +1 -1
- package/dist/components/card/card.vue_vue_type_script_setup_true_lang.js +45 -19
- package/dist/components/card/card.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-confirm/chat-confirm.js.map +1 -1
- package/dist/components/chat-confirm/chat-confirm.vue_vue_type_script_setup_true_lang.js +2 -3
- package/dist/components/chat-confirm/chat-confirm.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-input/chat-input.js.map +1 -1
- package/dist/components/chat-input/chat-input.vue_vue_type_script_setup_true_lang.js +75 -7
- package/dist/components/chat-input/chat-input.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-input/chat-input2.js.map +1 -1
- package/dist/components/chat-list/chat-list.js +9 -4
- package/dist/components/chat-list/chat-list.js.map +1 -1
- package/dist/components/chat-list/chat-list.vue_vue_type_script_setup_true_lang.js +34 -0
- package/dist/components/chat-list/chat-list.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-list/chat-list2.js +6 -0
- package/dist/components/chat-list/chat-list2.js.map +1 -0
- package/dist/components/chat-list/index.js +1 -1
- package/dist/components/chat-message/chat-message.js.map +1 -1
- package/dist/components/chat-message/chat-message.vue_vue_type_script_setup_true_lang.js +32 -7
- package/dist/components/chat-message/chat-message.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chat-message/chat-message2.js.map +1 -1
- package/dist/components/chat-message/style.js +1 -0
- package/dist/components/chat-question/chat-question.js +6 -0
- package/dist/components/chat-question/chat-question.js.map +1 -0
- package/dist/components/chat-question/chat-question.vue_vue_type_script_setup_true_lang.js +116 -0
- package/dist/components/chat-question/chat-question.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/chat-question/index.js +7 -0
- package/dist/components/chat-question/index.js.map +1 -0
- package/dist/components/chat-question/style.d.ts +1 -0
- package/dist/components/chat-question/style.js +2 -0
- package/dist/components/comment-thread/comment-thread.js.map +1 -1
- package/dist/components/comment-thread/comment-thread.vue_vue_type_script_setup_true_lang.js +5 -1
- package/dist/components/comment-thread/comment-thread.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/config-provider/use-config.js +5 -2
- package/dist/components/config-provider/use-config.js.map +1 -1
- package/dist/components/dialog/functional.js +3 -7
- package/dist/components/dialog/functional.js.map +1 -1
- package/dist/components/dialog/index.js +4 -3
- package/dist/components/dialog/index.js.map +1 -1
- package/dist/components/image/image.js.map +1 -1
- package/dist/components/image/image.vue_vue_type_script_setup_true_lang.js +10 -1
- package/dist/components/image/image.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/link/link.js.map +1 -1
- package/dist/components/link/link.vue_vue_type_script_setup_true_lang.js +116 -31
- package/dist/components/link/link.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu-actions.js +65 -0
- package/dist/components/menu/menu-actions.js.map +1 -0
- package/dist/components/menu/menu-item.js.map +1 -1
- package/dist/components/menu/menu-item.vue_vue_type_script_setup_true_lang.js +50 -12
- package/dist/components/menu/menu-item.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu-list.js.map +1 -1
- package/dist/components/menu/menu-list.vue_vue_type_script_setup_true_lang.js +32 -17
- package/dist/components/menu/menu-list.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu-popup.js.map +1 -1
- package/dist/components/menu/menu-popup.vue_vue_type_script_setup_true_lang.js +37 -8
- package/dist/components/menu/menu-popup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu.js +1 -0
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/menu/menu.vue_vue_type_script_setup_true_lang.js +5 -1
- package/dist/components/menu/menu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/menu/menu2.js.map +1 -1
- package/dist/components/node-graph/layout.js +123 -15
- package/dist/components/node-graph/layout.js.map +1 -1
- package/dist/components/toast/index.js +5 -4
- package/dist/components/toast/index.js.map +1 -1
- package/dist/components/toast/store.js +1 -9
- package/dist/components/toast/store.js.map +1 -1
- package/dist/components/virtual-list/virtual-list.js +7 -1
- package/dist/components/virtual-list/virtual-list.js.map +1 -1
- package/dist/components/virtual-list/virtual-list.vue_vue_type_script_setup_true_lang.js +2 -7
- package/dist/components/virtual-list/virtual-list.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/virtual-list/virtual-list2.js.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/locale/en.js +1 -0
- package/dist/locale/en.js.map +1 -1
- package/dist/locale/zh-cn.js +1 -0
- package/dist/locale/zh-cn.js.map +1 -1
- package/dist/locale/zh-tw.js +1 -0
- package/dist/locale/zh-tw.js.map +1 -1
- package/dist/plugin.js +4 -0
- package/dist/plugin.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/components/card/card.d.ts +6 -1
- package/dist/types/components/chat-input/chat-input.d.ts +33 -3
- package/dist/types/components/chat-input/chat-input.vue.d.ts +7 -0
- package/dist/types/components/chat-input/index.d.ts +20 -0
- package/dist/types/components/chat-list/chat-list.d.ts +19 -1
- package/dist/types/components/chat-message/chat-message.d.ts +32 -2
- package/dist/types/components/chat-message/chat-message.vue.d.ts +4 -1
- package/dist/types/components/chat-message/index.d.ts +8 -0
- package/dist/types/components/chat-question/chat-question.d.ts +43 -0
- package/dist/types/components/chat-question/chat-question.vue.d.ts +18 -0
- package/dist/types/components/chat-question/index.d.ts +43 -0
- package/dist/types/components/comment-thread/comment-thread.d.ts +6 -0
- package/dist/types/components/comment-thread/comment-thread.vue.d.ts +1 -0
- package/dist/types/components/comment-thread/index.d.ts +3 -0
- package/dist/types/components/dialog/functional.d.ts +0 -3
- package/dist/types/components/dialog/index.d.ts +1 -1
- package/dist/types/components/image/image.d.ts +9 -0
- package/dist/types/components/index.d.ts +1 -0
- package/dist/types/components/link/index.d.ts +3 -0
- package/dist/types/components/link/link.d.ts +24 -3
- package/dist/types/components/link/link.vue.d.ts +1 -0
- package/dist/types/components/menu/index.d.ts +3 -0
- package/dist/types/components/menu/menu-actions.d.ts +26 -0
- package/dist/types/components/menu/menu-item.vue.d.ts +6 -0
- package/dist/types/components/menu/menu.d.ts +32 -0
- package/dist/types/components/menu/menu.vue.d.ts +1 -0
- package/dist/types/components/node-graph/layout.d.ts +26 -0
- package/dist/types/components/select/index.d.ts +3 -3
- package/dist/types/components/select/select.vue.d.ts +1 -1
- package/dist/types/components/toast/index.d.ts +0 -2
- package/dist/types/components/toast/store.d.ts +0 -4
- package/dist/types/components/virtual-list/virtual-list.d.ts +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/locale/types.d.ts +3 -1
- package/dist/types/utils/app-context.d.ts +14 -0
- package/dist/utils/app-context.js +22 -0
- package/dist/utils/app-context.js.map +1 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.js","names":["_sfc_main"],"sources":["../../../src/components/card/card.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport type { CardProps, CardSlots } from './card'\n\ndefineOptions({ name: 'DouCard' })\n\nconst props = withDefaults(defineProps<CardProps>(), {\n padding: 'md',\n raised: false,\n interactive: false,\n as: 'div',\n})\nconst slots = defineSlots<CardSlots>()\n\nconst ns = useNamespace('card')\n\nconst hasHeader = computed(\n () => !!(slots.header || slots.extra || props.title || props.description),\n)\n\nconst classes = computed(() => [\n ns.b(),\n ns.m(`padding-${props.padding}`),\n ns.is('raised', props.raised),\n ns.is('interactive', props.interactive),\n])\n</script>\n\n<template>\n <component :is=\"as\" :class=\"classes\">\n <header v-if=\"hasHeader\" :class=\"ns.e('header')\">\n <div :class=\"ns.e('heading')\">\n <slot name=\"header\">\n <div v-if=\"title\" :class=\"ns.e('title')\">{{ title }}</
|
|
1
|
+
{"version":3,"file":"card.js","names":["_sfc_main"],"sources":["../../../src/components/card/card.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport type { CardProps, CardSlots } from './card'\n\ndefineOptions({ name: 'DouCard' })\n\nconst props = withDefaults(defineProps<CardProps>(), {\n padding: 'md',\n raised: false,\n interactive: false,\n as: 'div',\n})\nconst slots = defineSlots<CardSlots>()\n\nconst ns = useNamespace('card')\n\nconst hasHeader = computed(\n () => !!(slots.header || slots.extra || props.title || props.description),\n)\n\n// A button may only hold phrasing content: inside one the parts are spans.\nconst inButton = computed(() => props.as === 'button')\nconst part = (tag: string) => (inButton.value ? 'span' : tag)\n\nconst classes = computed(() => [\n ns.b(),\n ns.m(`padding-${props.padding}`),\n ns.is('raised', props.raised),\n ns.is('interactive', props.interactive || inButton.value),\n])\n</script>\n\n<template>\n <component :is=\"as\" :class=\"classes\" :type=\"inButton ? 'button' : undefined\">\n <component :is=\"part('header')\" v-if=\"hasHeader\" :class=\"ns.e('header')\">\n <component :is=\"part('div')\" :class=\"ns.e('heading')\">\n <slot name=\"header\">\n <component :is=\"part('div')\" v-if=\"title\" :class=\"ns.e('title')\">{{ title }}</component>\n <component :is=\"part('div')\" v-if=\"description\" :class=\"ns.e('description')\">\n {{ description }}\n </component>\n </slot>\n </component>\n <component :is=\"part('div')\" v-if=\"slots.extra\" :class=\"ns.e('extra')\">\n <slot name=\"extra\" />\n </component>\n </component>\n <component :is=\"part('div')\" v-if=\"slots.default\" :class=\"ns.e('body')\">\n <slot />\n </component>\n <component :is=\"part('footer')\" v-if=\"slots.footer\" :class=\"ns.e('footer')\">\n <slot name=\"footer\" />\n </component>\n </component>\n</template>\n"],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useNamespace } from "../../utils/namespace.js";
|
|
2
|
-
import { computed, createBlock, createCommentVNode,
|
|
2
|
+
import { computed, createBlock, createCommentVNode, createTextVNode, defineComponent, normalizeClass, openBlock, renderSlot, resolveDynamicComponent, toDisplayString, unref, useSlots, withCtx } from "vue";
|
|
3
3
|
// src/components/card/card.vue?vue&type=script&setup=true&lang.ts
|
|
4
4
|
var card_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
5
5
|
name: "DouCard",
|
|
@@ -23,39 +23,65 @@ var card_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
|
|
|
23
23
|
const slots = useSlots();
|
|
24
24
|
const ns = useNamespace("card");
|
|
25
25
|
const hasHeader = computed(() => !!(slots.header || slots.extra || props.title || props.description));
|
|
26
|
+
const inButton = computed(() => props.as === "button");
|
|
27
|
+
const part = (tag) => inButton.value ? "span" : tag;
|
|
26
28
|
const classes = computed(() => [
|
|
27
29
|
ns.b(),
|
|
28
30
|
ns.m(`padding-${props.padding}`),
|
|
29
31
|
ns.is("raised", props.raised),
|
|
30
|
-
ns.is("interactive", props.interactive)
|
|
32
|
+
ns.is("interactive", props.interactive || inButton.value)
|
|
31
33
|
]);
|
|
32
34
|
return (_ctx, _cache) => {
|
|
33
|
-
return openBlock(), createBlock(resolveDynamicComponent(__props.as), {
|
|
35
|
+
return openBlock(), createBlock(resolveDynamicComponent(__props.as), {
|
|
36
|
+
class: normalizeClass(classes.value),
|
|
37
|
+
type: inButton.value ? "button" : void 0
|
|
38
|
+
}, {
|
|
34
39
|
default: withCtx(() => [
|
|
35
|
-
hasHeader.value ? (openBlock(),
|
|
40
|
+
hasHeader.value ? (openBlock(), createBlock(resolveDynamicComponent(part("header")), {
|
|
36
41
|
key: 0,
|
|
37
42
|
class: normalizeClass(unref(ns).e("header"))
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
}, {
|
|
44
|
+
default: withCtx(() => [(openBlock(), createBlock(resolveDynamicComponent(part("div")), { class: normalizeClass(unref(ns).e("heading")) }, {
|
|
45
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "header", {}, () => [__props.title ? (openBlock(), createBlock(resolveDynamicComponent(part("div")), {
|
|
46
|
+
key: 0,
|
|
47
|
+
class: normalizeClass(unref(ns).e("title"))
|
|
48
|
+
}, {
|
|
49
|
+
default: withCtx(() => [createTextVNode(toDisplayString(__props.title), 1)]),
|
|
50
|
+
_: 1
|
|
51
|
+
}, 8, ["class"])) : createCommentVNode("", true), __props.description ? (openBlock(), createBlock(resolveDynamicComponent(part("div")), {
|
|
52
|
+
key: 1,
|
|
53
|
+
class: normalizeClass(unref(ns).e("description"))
|
|
54
|
+
}, {
|
|
55
|
+
default: withCtx(() => [createTextVNode(toDisplayString(__props.description), 1)]),
|
|
56
|
+
_: 1
|
|
57
|
+
}, 8, ["class"])) : createCommentVNode("", true)])]),
|
|
58
|
+
_: 3
|
|
59
|
+
}, 8, ["class"])), slots.extra ? (openBlock(), createBlock(resolveDynamicComponent(part("div")), {
|
|
60
|
+
key: 0,
|
|
61
|
+
class: normalizeClass(unref(ns).e("extra"))
|
|
62
|
+
}, {
|
|
63
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "extra")]),
|
|
64
|
+
_: 3
|
|
65
|
+
}, 8, ["class"])) : createCommentVNode("", true)]),
|
|
66
|
+
_: 3
|
|
67
|
+
}, 8, ["class"])) : createCommentVNode("", true),
|
|
68
|
+
slots.default ? (openBlock(), createBlock(resolveDynamicComponent(part("div")), {
|
|
49
69
|
key: 1,
|
|
50
70
|
class: normalizeClass(unref(ns).e("body"))
|
|
51
|
-
},
|
|
52
|
-
|
|
71
|
+
}, {
|
|
72
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
|
|
73
|
+
_: 3
|
|
74
|
+
}, 8, ["class"])) : createCommentVNode("", true),
|
|
75
|
+
slots.footer ? (openBlock(), createBlock(resolveDynamicComponent(part("footer")), {
|
|
53
76
|
key: 2,
|
|
54
77
|
class: normalizeClass(unref(ns).e("footer"))
|
|
55
|
-
},
|
|
78
|
+
}, {
|
|
79
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "footer")]),
|
|
80
|
+
_: 3
|
|
81
|
+
}, 8, ["class"])) : createCommentVNode("", true)
|
|
56
82
|
]),
|
|
57
83
|
_: 3
|
|
58
|
-
}, 8, ["class"]);
|
|
84
|
+
}, 8, ["class", "type"]);
|
|
59
85
|
};
|
|
60
86
|
}
|
|
61
87
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_openBlock","_createBlock","_resolveDynamicComponent","_normalizeClass","_withCtx","
|
|
1
|
+
{"version":3,"file":"card.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_openBlock","_createBlock","_resolveDynamicComponent","_normalizeClass","_withCtx","_unref","_renderSlot","_createTextVNode","_toDisplayString","_createCommentVNode"],"sources":["../../../src/components/card/card.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport type { CardProps, CardSlots } from './card'\n\ndefineOptions({ name: 'DouCard' })\n\nconst props = withDefaults(defineProps<CardProps>(), {\n padding: 'md',\n raised: false,\n interactive: false,\n as: 'div',\n})\nconst slots = defineSlots<CardSlots>()\n\nconst ns = useNamespace('card')\n\nconst hasHeader = computed(\n () => !!(slots.header || slots.extra || props.title || props.description),\n)\n\n// A button may only hold phrasing content: inside one the parts are spans.\nconst inButton = computed(() => props.as === 'button')\nconst part = (tag: string) => (inButton.value ? 'span' : tag)\n\nconst classes = computed(() => [\n ns.b(),\n ns.m(`padding-${props.padding}`),\n ns.is('raised', props.raised),\n ns.is('interactive', props.interactive || inButton.value),\n])\n</script>\n\n<template>\n <component :is=\"as\" :class=\"classes\" :type=\"inButton ? 'button' : undefined\">\n <component :is=\"part('header')\" v-if=\"hasHeader\" :class=\"ns.e('header')\">\n <component :is=\"part('div')\" :class=\"ns.e('heading')\">\n <slot name=\"header\">\n <component :is=\"part('div')\" v-if=\"title\" :class=\"ns.e('title')\">{{ title }}</component>\n <component :is=\"part('div')\" v-if=\"description\" :class=\"ns.e('description')\">\n {{ description }}\n </component>\n </slot>\n </component>\n <component :is=\"part('div')\" v-if=\"slots.extra\" :class=\"ns.e('extra')\">\n <slot name=\"extra\" />\n </component>\n </component>\n <component :is=\"part('div')\" v-if=\"slots.default\" :class=\"ns.e('body')\">\n <slot />\n </component>\n <component :is=\"part('footer')\" v-if=\"slots.footer\" :class=\"ns.e('footer')\">\n <slot name=\"footer\" />\n </component>\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAOA,MAAM,QAAQ;EAMd,MAAM,QAAQA,SAAA;EAEd,MAAM,KAAK,aAAa,MAAM;EAE9B,MAAM,YAAY,eACV,CAAC,EAAE,MAAM,UAAU,MAAM,SAAS,MAAM,SAAS,MAAM,YAC/D;EAGA,MAAM,WAAW,eAAe,MAAM,OAAO,QAAQ;EACrD,MAAM,QAAQ,QAAiB,SAAS,QAAQ,SAAS;EAEzD,MAAM,UAAU,eAAe;GAC7B,GAAG,EAAE;GACL,GAAG,EAAE,WAAW,MAAM,SAAS;GAC/B,GAAG,GAAG,UAAU,MAAM,MAAM;GAC5B,GAAG,GAAG,eAAe,MAAM,eAAe,SAAS,KAAK;EAC1D,CAAC;;GAIC,OAAAC,UAAA,GAAAC,YAoBYC,wBApBI,QAAA,EAAE,GAAA;IAAG,OAAKC,eAAE,QAAA,KAAO;IAAG,MAAM,SAAA,QAAQ,WAAc,KAAA;;IAChE,SAAAC,cAYY;KAZ0B,UAAA,SAAtCJ,UAAA,GAAAC,YAYYC,wBAZI,KAAI,QAAA,CAAA,GAAA;;MAA8B,OAAKC,eAAEE,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,CAAA;;MAC3D,SAAAD,cAOY,EAPZJ,UAAA,GAAAC,YAOYC,wBAPI,KAAI,KAAA,CAAA,GAAA,EAAU,OAAKC,eAAEE,MAAA,EAAA,CAAE,CAAC,EAAC,SAAA,CAAA,E;OACvC,SAAAD,cAKO,CALPE,WAKO,KAAA,QAAA,UAAA,CAAA,SAAA,CAJ8B,QAAA,SAAnCN,UAAA,GAAAC,YAAwFC,wBAAxE,KAAI,KAAA,CAAA,GAAA;;QAAuB,OAAKC,eAAEE,MAAA,EAAA,CAAE,CAAC,EAAC,OAAA,CAAA;;QAAW,SAAAD,cAAW,CAARG,gBAAAC,gBAAA,QAAA,KAAK,GAAA,CAAA,C;;O,kDACtC,QAAA,eAAnCR,UAAA,GAAAC,YAEYC,wBAFI,KAAI,KAAA,CAAA,GAAA;;QAA6B,OAAKC,eAAEE,MAAA,EAAA,CAAE,CAAC,EAAC,aAAA,CAAA;;QAC1D,SAAAD,cAAiB,CAAdG,gBAAAC,gBAAA,QAAA,WAAW,GAAA,CAAA,C;;;;M,mBAIe,MAAM,SAAzCR,UAAA,GAAAC,YAEYC,wBAFI,KAAI,KAAA,CAAA,GAAA;;OAA6B,OAAKC,eAAEE,MAAA,EAAA,CAAE,CAAC,EAAC,OAAA,CAAA;;OAC1D,SAAAD,cAAqB,CAArBE,WAAqB,KAAA,QAAA,OAAA,C;;;;;KAGU,MAAM,WAAzCN,UAAA,GAAAC,YAEYC,wBAFI,KAAI,KAAA,CAAA,GAAA;;MAA+B,OAAKC,eAAEE,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,CAAA;;MAC5D,SAAAD,cAAQ,CAARE,WAAQ,KAAA,QAAA,SAAA,C;;;KAE4B,MAAM,UAA5CN,UAAA,GAAAC,YAEYC,wBAFI,KAAI,QAAA,CAAA,GAAA;;MAAiC,OAAKC,eAAEE,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,CAAA;;MAC9D,SAAAD,cAAsB,CAAtBE,WAAsB,KAAA,QAAA,QAAA,C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-confirm.js","names":["_sfc_main"],"sources":["../../../src/components/chat-confirm/chat-confirm.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { CheckIcon, CloseIcon, ShieldIcon, UndoIcon } from '@dou-ui/icons'\nimport { computed, nextTick, ref, useId, watch } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { useStatusCheck } from '../../utils/status-check'\nimport { DouButton } from '../button'\nimport { useLocale } from '../config-provider/use-config'\nimport type { ChatConfirmEmits, ChatConfirmProps, ChatConfirmSlots } from './chat-confirm'\n\ndefineOptions({ name: 'DouChatConfirm' })\n\nconst props = withDefaults(defineProps<ChatConfirmProps>(), {\n status: 'waiting',\n allowAlways: false,\n tone: 'neutral',\n})\nconst emit = defineEmits<ChatConfirmEmits>()\nconst slots = defineSlots<ChatConfirmSlots>()\n\nconst ns = useNamespace('chat-confirm')\nconst { t } = useLocale()\nconst id = useId()\n\nconst
|
|
1
|
+
{"version":3,"file":"chat-confirm.js","names":["_sfc_main"],"sources":["../../../src/components/chat-confirm/chat-confirm.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { CheckIcon, CloseIcon, ShieldIcon, UndoIcon } from '@dou-ui/icons'\nimport { computed, nextTick, ref, useId, watch } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { useStatusCheck } from '../../utils/status-check'\nimport { DouButton } from '../button'\nimport { useLocale } from '../config-provider/use-config'\nimport type { ChatConfirmEmits, ChatConfirmProps, ChatConfirmSlots } from './chat-confirm'\n\ndefineOptions({ name: 'DouChatConfirm' })\n\nconst props = withDefaults(defineProps<ChatConfirmProps>(), {\n status: 'waiting',\n allowAlways: false,\n tone: 'neutral',\n})\nconst emit = defineEmits<ChatConfirmEmits>()\nconst slots = defineSlots<ChatConfirmSlots>()\n\nconst ns = useNamespace('chat-confirm')\nconst { t } = useLocale()\nconst id = useId()\n\nconst waiting = computed(() => props.status === 'waiting')\n// How each answered or withdrawn request reads once it has collapsed.\nconst outcomes = {\n approved: { icon: CheckIcon, text: 'chat.approved' },\n denied: { icon: CloseIcon, text: 'chat.denied' },\n withdrawn: { icon: UndoIcon, text: 'chat.withdrawn' },\n} as const\nconst outcome = computed(() =>\n Object.hasOwn(outcomes, props.status)\n ? outcomes[props.status as keyof typeof outcomes]\n : undefined,\n)\n\n// Answering or withdrawing removes the buttons; if focus was on one, keep it\n// on the card instead of losing it to the page. The watcher runs before the\n// DOM updates, while the focused button is still there to find.\nconst root = ref<HTMLElement>()\nwatch(\n () => props.status,\n (now, before) => {\n if (before !== 'waiting' || now === 'waiting') return\n if (!root.value?.contains(document.activeElement)) return\n void nextTick(() => root.value?.focus({ preventScroll: true }))\n },\n)\n\nconst statuses = ['waiting', 'approved', 'denied', 'withdrawn']\nuseStatusCheck('DouChatConfirm', () => [props.status], statuses, { pending: 'waiting' })\n</script>\n\n<template>\n <div\n ref=\"root\"\n :class=\"[ns.b(), ns.m(tone), ns.is(status)]\"\n role=\"group\"\n tabindex=\"-1\"\n :aria-labelledby=\"title || slots.title ? `${id}-title` : undefined\"\n >\n <div :class=\"ns.e('header')\">\n <span :class=\"ns.e('icon')\" aria-hidden=\"true\">\n <slot name=\"icon\"><ShieldIcon /></slot>\n </span>\n <div :class=\"ns.e('text')\">\n <div v-if=\"title || slots.title\" :id=\"`${id}-title`\" :class=\"ns.e('title')\">\n <slot name=\"title\">{{ title }}</slot>\n </div>\n <div v-if=\"description\" :class=\"ns.e('description')\">{{ description }}</div>\n </div>\n <!-- always there, so screen readers announce the outcome when it appears -->\n <span :class=\"ns.e('result')\" role=\"status\">\n <template v-if=\"outcome\">\n <component :is=\"outcome.icon\" aria-hidden=\"true\" />\n {{ t(outcome.text) }}\n </template>\n </span>\n </div>\n <div v-if=\"slots.default\" :class=\"ns.e('detail')\"><slot /></div>\n <div v-if=\"waiting\" :class=\"ns.e('actions')\">\n <DouButton size=\"sm\" variant=\"outline\" @click=\"emit('decide', 'deny')\">\n {{ denyText ?? t('chat.deny') }}\n </DouButton>\n <DouButton v-if=\"allowAlways\" size=\"sm\" variant=\"outline\" @click=\"emit('decide', 'always')\">\n {{ t('chat.allowAlways') }}\n </DouButton>\n <DouButton\n size=\"sm\"\n :tone=\"tone === 'danger' ? 'danger' : 'neutral'\"\n @click=\"emit('decide', 'approve')\"\n >\n {{ approveText ?? t('chat.approve') }}\n </DouButton>\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -30,7 +30,6 @@ var chat_confirm_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
30
30
|
const ns = useNamespace("chat-confirm");
|
|
31
31
|
const { t } = useLocale();
|
|
32
32
|
const id = useId();
|
|
33
|
-
const hasTitle = computed(() => !!props.title || !!slots.title);
|
|
34
33
|
const waiting = computed(() => props.status === "waiting");
|
|
35
34
|
const outcomes = {
|
|
36
35
|
approved: {
|
|
@@ -70,14 +69,14 @@ var chat_confirm_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
70
69
|
]),
|
|
71
70
|
role: "group",
|
|
72
71
|
tabindex: "-1",
|
|
73
|
-
"aria-labelledby":
|
|
72
|
+
"aria-labelledby": __props.title || slots.title ? `${unref(id)}-title` : void 0
|
|
74
73
|
}, [
|
|
75
74
|
createElementVNode("div", { class: normalizeClass(unref(ns).e("header")) }, [
|
|
76
75
|
createElementVNode("span", {
|
|
77
76
|
class: normalizeClass(unref(ns).e("icon")),
|
|
78
77
|
"aria-hidden": "true"
|
|
79
78
|
}, [renderSlot(_ctx.$slots, "icon", {}, () => [createVNode(unref(ShieldIcon))])], 2),
|
|
80
|
-
createElementVNode("div", { class: normalizeClass(unref(ns).e("text")) }, [
|
|
79
|
+
createElementVNode("div", { class: normalizeClass(unref(ns).e("text")) }, [__props.title || slots.title ? (openBlock(), createElementBlock("div", {
|
|
81
80
|
key: 0,
|
|
82
81
|
id: `${unref(id)}-title`,
|
|
83
82
|
class: normalizeClass(unref(ns).e("title"))
|
package/dist/components/chat-confirm/chat-confirm.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-confirm.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_openBlock","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_renderSlot","_createVNode","_createTextVNode","_toDisplayString","_createCommentVNode","_Fragment","_createBlock","_resolveDynamicComponent","_withCtx"],"sources":["../../../src/components/chat-confirm/chat-confirm.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { CheckIcon, CloseIcon, ShieldIcon, UndoIcon } from '@dou-ui/icons'\nimport { computed, nextTick, ref, useId, watch } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { useStatusCheck } from '../../utils/status-check'\nimport { DouButton } from '../button'\nimport { useLocale } from '../config-provider/use-config'\nimport type { ChatConfirmEmits, ChatConfirmProps, ChatConfirmSlots } from './chat-confirm'\n\ndefineOptions({ name: 'DouChatConfirm' })\n\nconst props = withDefaults(defineProps<ChatConfirmProps>(), {\n status: 'waiting',\n allowAlways: false,\n tone: 'neutral',\n})\nconst emit = defineEmits<ChatConfirmEmits>()\nconst slots = defineSlots<ChatConfirmSlots>()\n\nconst ns = useNamespace('chat-confirm')\nconst { t } = useLocale()\nconst id = useId()\n\nconst
|
|
1
|
+
{"version":3,"file":"chat-confirm.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_openBlock","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_renderSlot","_createVNode","_createTextVNode","_toDisplayString","_createCommentVNode","_Fragment","_createBlock","_resolveDynamicComponent","_withCtx"],"sources":["../../../src/components/chat-confirm/chat-confirm.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { CheckIcon, CloseIcon, ShieldIcon, UndoIcon } from '@dou-ui/icons'\nimport { computed, nextTick, ref, useId, watch } from 'vue'\nimport { useNamespace } from '../../utils/namespace'\nimport { useStatusCheck } from '../../utils/status-check'\nimport { DouButton } from '../button'\nimport { useLocale } from '../config-provider/use-config'\nimport type { ChatConfirmEmits, ChatConfirmProps, ChatConfirmSlots } from './chat-confirm'\n\ndefineOptions({ name: 'DouChatConfirm' })\n\nconst props = withDefaults(defineProps<ChatConfirmProps>(), {\n status: 'waiting',\n allowAlways: false,\n tone: 'neutral',\n})\nconst emit = defineEmits<ChatConfirmEmits>()\nconst slots = defineSlots<ChatConfirmSlots>()\n\nconst ns = useNamespace('chat-confirm')\nconst { t } = useLocale()\nconst id = useId()\n\nconst waiting = computed(() => props.status === 'waiting')\n// How each answered or withdrawn request reads once it has collapsed.\nconst outcomes = {\n approved: { icon: CheckIcon, text: 'chat.approved' },\n denied: { icon: CloseIcon, text: 'chat.denied' },\n withdrawn: { icon: UndoIcon, text: 'chat.withdrawn' },\n} as const\nconst outcome = computed(() =>\n Object.hasOwn(outcomes, props.status)\n ? outcomes[props.status as keyof typeof outcomes]\n : undefined,\n)\n\n// Answering or withdrawing removes the buttons; if focus was on one, keep it\n// on the card instead of losing it to the page. The watcher runs before the\n// DOM updates, while the focused button is still there to find.\nconst root = ref<HTMLElement>()\nwatch(\n () => props.status,\n (now, before) => {\n if (before !== 'waiting' || now === 'waiting') return\n if (!root.value?.contains(document.activeElement)) return\n void nextTick(() => root.value?.focus({ preventScroll: true }))\n },\n)\n\nconst statuses = ['waiting', 'approved', 'denied', 'withdrawn']\nuseStatusCheck('DouChatConfirm', () => [props.status], statuses, { pending: 'waiting' })\n</script>\n\n<template>\n <div\n ref=\"root\"\n :class=\"[ns.b(), ns.m(tone), ns.is(status)]\"\n role=\"group\"\n tabindex=\"-1\"\n :aria-labelledby=\"title || slots.title ? `${id}-title` : undefined\"\n >\n <div :class=\"ns.e('header')\">\n <span :class=\"ns.e('icon')\" aria-hidden=\"true\">\n <slot name=\"icon\"><ShieldIcon /></slot>\n </span>\n <div :class=\"ns.e('text')\">\n <div v-if=\"title || slots.title\" :id=\"`${id}-title`\" :class=\"ns.e('title')\">\n <slot name=\"title\">{{ title }}</slot>\n </div>\n <div v-if=\"description\" :class=\"ns.e('description')\">{{ description }}</div>\n </div>\n <!-- always there, so screen readers announce the outcome when it appears -->\n <span :class=\"ns.e('result')\" role=\"status\">\n <template v-if=\"outcome\">\n <component :is=\"outcome.icon\" aria-hidden=\"true\" />\n {{ t(outcome.text) }}\n </template>\n </span>\n </div>\n <div v-if=\"slots.default\" :class=\"ns.e('detail')\"><slot /></div>\n <div v-if=\"waiting\" :class=\"ns.e('actions')\">\n <DouButton size=\"sm\" variant=\"outline\" @click=\"emit('decide', 'deny')\">\n {{ denyText ?? t('chat.deny') }}\n </DouButton>\n <DouButton v-if=\"allowAlways\" size=\"sm\" variant=\"outline\" @click=\"emit('decide', 'always')\">\n {{ t('chat.allowAlways') }}\n </DouButton>\n <DouButton\n size=\"sm\"\n :tone=\"tone === 'danger' ? 'danger' : 'neutral'\"\n @click=\"emit('decide', 'approve')\"\n >\n {{ approveText ?? t('chat.approve') }}\n </DouButton>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-input.js","names":[],"sources":["../../../src/components/chat-input/chat-input.ts"],"sourcesContent":["import type { Component } from 'vue'\nimport type { Size } from '../../utils/types'\n\n/** An entry of the `/` command or `@` mention menu. */\nexport interface ChatInputOption {\n
|
|
1
|
+
{"version":3,"file":"chat-input.js","names":[],"sources":["../../../src/components/chat-input/chat-input.ts"],"sourcesContent":["import type { Component } from 'vue'\nimport type { Size } from '../../utils/types'\n\n/** An entry of the `/` command or `@` mention menu. */\nexport interface ChatInputOption {\n /**\n * Handed back when picked; for a mention it is also what gets inserted\n * after `@`, and so matched too. A command's value is never shown and\n * is matched only when there is no `label`: it may be an id.\n */\n value: string\n /** Shown in the menu and matched against what is typed. Defaults to `value`. */\n label?: string\n /** More words that find it, e.g. other names or pinyin. */\n keywords?: string[]\n /** A quieter line after the label; matched too. */\n description?: string\n /** An icon component before the label. */\n icon?: Component\n disabled?: boolean\n}\n\n/** Whether an option matches what is typed after the `/` or `@`. */\nexport type ChatInputFilter = (\n option: ChatInputOption,\n query: string,\n trigger: '/' | '@',\n) => boolean\n/** `true` matches as described under `filter`, `false` lists every option as given. */\nexport type ChatInputFilterMode = boolean | ChatInputFilter\n\n/** `enter` sends on Enter (Shift+Enter breaks the line); `mod-enter` sends on Ctrl / ⌘ + Enter. */\nexport type ChatInputSubmitOn = 'enter' | 'mod-enter'\n\nexport interface ChatInputProps {\n /** The text, bound with `v-model`. */\n modelValue?: string\n /** Defaults to the locale's prompt. */\n placeholder?: string\n /** Which key sends. Keys pressed while an input method is composing never send. */\n submitOn?: ChatInputSubmitOn\n /**\n * A reply is being generated: the send button turns into a stop button.\n * Typing goes on meanwhile; once there is text, the button sends again\n * so the app can queue the message.\n */\n loading?: boolean\n /** Text size and padding; the corners and buttons follow. */\n size?: Size\n disabled?: boolean\n /** Rows shown when empty. */\n minRows?: number\n /** Rows to grow to before the text scrolls. */\n maxRows?: number\n /**\n * Whether sending is allowed. By default only when the text is not\n * blank; set it when, say, attachments alone may be sent.\n */\n canSubmit?: boolean\n /**\n * Commands offered when the text starts with `/`. Picking one removes\n * the typed `/…` and emits `command`.\n */\n commands?: ChatInputOption[]\n /**\n * Things to reference offered after `@`, e.g. files or people. Picking\n * one replaces the typed `@…` with `@value` and emits `mention`.\n */\n mentions?: ChatInputOption[]\n /**\n * How options match what is typed after the trigger. By default what\n * the person sees holds it, ignoring case: the label (or the value, when\n * there is no label), a mention's value, the description and `keywords`.\n * `false` lists them all as given, e.g. results already looked up with\n * `search`. Give `{ '@': false }` to set the `/` and `@` menus apart;\n * a trigger left out matches by default.\n */\n filter?: ChatInputFilterMode | { '/'?: ChatInputFilterMode; '@'?: ChatInputFilterMode }\n /** Wait this many ms after the last keystroke before emitting `search`. */\n searchDelay?: number\n /** Where to render the `/` and `@` menu; `false` keeps it in place. */\n teleport?: string | HTMLElement | false\n}\n\nexport interface ChatInputEmits {\n 'update:modelValue': [value: string]\n /** The send key or button was pressed, with the text. Clearing it is up to you. */\n submit: [value: string]\n /** The stop button was pressed while `loading`. */\n stop: []\n /** A command was picked from the `/` menu. */\n command: [option: ChatInputOption]\n /** Something was picked from the `@` menu. */\n mention: [option: ChatInputOption]\n /**\n * The text after a `/` or `@` changed (after `searchDelay`), and when one\n * is typed: look options up somewhere else and replace `commands` or\n * `mentions` with them, usually with `filter` set to `false`.\n */\n search: [query: string, trigger: '/' | '@']\n /** Files were pasted or dropped onto the input. */\n attach: [files: File[]]\n}\n\nexport interface ChatInputSlots {\n /** Above the text, e.g. `DouChatAttachments` or a quoted message. */\n header?: () => unknown\n /** The left of the bottom bar: buttons to attach files, pick a model and the like. */\n actions?: () => unknown\n /** Replaces the inside of each menu entry. */\n option?: (props: { option: ChatInputOption; trigger: '/' | '@' }) => unknown\n /** Replaces the send / stop button. */\n submit?: (props: {\n submit: () => void\n stop: () => void\n loading: boolean\n disabled: boolean\n }) => unknown\n}\n\nexport interface ChatInputExpose {\n /** The native `<textarea>`. */\n textarea: HTMLTextAreaElement | null\n focus: () => void\n blur: () => void\n /** Send as if the send key were pressed. */\n submit: () => void\n}\n\n/** The `/` or `@` token the caret is in, if any. */\nexport interface ChatInputToken {\n trigger: '/' | '@'\n /** Typed after the trigger. */\n query: string\n /** Where the trigger character is. */\n start: number\n /** Where the token ends (the caret). */\n end: number\n}\n\n/**\n * Find the token being typed at `caret`. A `/` counts only at the very\n * start of the text; an `@` at the start or after white space. The query\n * holds no white space.\n */\nexport function findToken(text: string, caret: number): ChatInputToken | null {\n let start = caret\n while (start > 0 && !/\\s/.test(text[start - 1]!)) start--\n const word = text.slice(start, caret)\n const trigger = word[0]\n if (trigger === '/' && text.slice(0, start).trim() === '')\n return { trigger, query: word.slice(1), start, end: caret }\n if (trigger === '@') return { trigger, query: word.slice(1), start, end: caret }\n return null\n}\n"],"mappings":";;;;;;AAiJA,SAAgB,UAAU,MAAc,OAAsC;CAC5E,IAAI,QAAQ;CACZ,OAAO,QAAQ,KAAK,CAAC,KAAK,KAAK,KAAK,QAAQ,EAAG,GAAG;CAClD,MAAM,OAAO,KAAK,MAAM,OAAO,KAAK;CACpC,MAAM,UAAU,KAAK;CACrB,IAAI,YAAY,OAAO,KAAK,MAAM,GAAG,KAAK,CAAC,CAAC,KAAK,MAAM,IACrD,OAAO;EAAE;EAAS,OAAO,KAAK,MAAM,CAAC;EAAG;EAAO,KAAK;CAAM;CAC5D,IAAI,YAAY,KAAK,OAAO;EAAE;EAAS,OAAO,KAAK,MAAM,CAAC;EAAG;EAAO,KAAK;CAAM;CAC/E,OAAO;AACT"}
|
|
@@ -8,7 +8,7 @@ import { useFormDisabled } from "../form/use-form-item.js";
|
|
|
8
8
|
import { useTeleport } from "../../utils/teleport.js";
|
|
9
9
|
import { DouButton } from "../button/index.js";
|
|
10
10
|
import { findToken } from "./chat-input.js";
|
|
11
|
-
import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, mergeModels, mergeProps, nextTick, normalizeClass, normalizeStyle, onMounted, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useAttrs, useId, useModel, useSlots, useTemplateRef, vModelText, watch, withCtx, withDirectives, withModifiers } from "vue";
|
|
11
|
+
import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, getCurrentInstance, mergeModels, mergeProps, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, reactive, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useAttrs, useId, useModel, useSlots, useTemplateRef, vModelText, watch, withCtx, withDirectives, withModifiers } from "vue";
|
|
12
12
|
import { ArrowUpIcon, StopIcon } from "@dou-ui/icons";
|
|
13
13
|
// src/components/chat-input/chat-input.vue?vue&type=script&setup=true&lang.ts
|
|
14
14
|
var _hoisted_1 = [
|
|
@@ -23,6 +23,7 @@ var _hoisted_1 = [
|
|
|
23
23
|
];
|
|
24
24
|
var _hoisted_2 = [
|
|
25
25
|
"id",
|
|
26
|
+
"aria-busy",
|
|
26
27
|
"data-placement",
|
|
27
28
|
"data-dou-theme"
|
|
28
29
|
];
|
|
@@ -58,6 +59,15 @@ var chat_input_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
58
59
|
},
|
|
59
60
|
commands: { default: () => [] },
|
|
60
61
|
mentions: { default: () => [] },
|
|
62
|
+
filter: {
|
|
63
|
+
type: [
|
|
64
|
+
Boolean,
|
|
65
|
+
Function,
|
|
66
|
+
Object
|
|
67
|
+
],
|
|
68
|
+
default: true
|
|
69
|
+
},
|
|
70
|
+
searchDelay: { default: 300 },
|
|
61
71
|
teleport: {
|
|
62
72
|
type: [String, Boolean],
|
|
63
73
|
default: void 0
|
|
@@ -72,6 +82,7 @@ var chat_input_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
72
82
|
"stop",
|
|
73
83
|
"command",
|
|
74
84
|
"mention",
|
|
85
|
+
"search",
|
|
75
86
|
"attach"
|
|
76
87
|
], ["update:modelValue"]),
|
|
77
88
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
@@ -121,22 +132,71 @@ var chat_input_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
121
132
|
const token = ref(null);
|
|
122
133
|
const dismissed = ref(null);
|
|
123
134
|
const active = ref(0);
|
|
135
|
+
let composing = false;
|
|
136
|
+
function onCaret(event) {
|
|
137
|
+
if (composing || event instanceof KeyboardEvent && isComposing(event)) return;
|
|
138
|
+
if (event?.isComposing) return;
|
|
139
|
+
readToken();
|
|
140
|
+
}
|
|
141
|
+
function onCompositionStart() {
|
|
142
|
+
composing = true;
|
|
143
|
+
}
|
|
144
|
+
function onCompositionEnd() {
|
|
145
|
+
composing = false;
|
|
146
|
+
readToken();
|
|
147
|
+
}
|
|
124
148
|
function readToken() {
|
|
125
149
|
const el = textareaRef.value;
|
|
126
150
|
if (!el) return;
|
|
127
|
-
const next = findToken(
|
|
151
|
+
const next = findToken(el.value, el.selectionStart ?? el.value.length);
|
|
128
152
|
const current = token.value;
|
|
129
153
|
if (next && current && next.trigger === current.trigger && next.start === current.start && next.end === current.end && next.query === current.query) return;
|
|
130
154
|
if (next?.start !== current?.start) dismissed.value = null;
|
|
131
155
|
token.value = next;
|
|
132
156
|
}
|
|
157
|
+
const filterOf = (trigger) => typeof props.filter === "object" ? props.filter[trigger] ?? true : props.filter;
|
|
133
158
|
const options = computed(() => {
|
|
134
159
|
const current = token.value;
|
|
135
160
|
if (!current || dismissed.value === current.start) return [];
|
|
136
161
|
const source = current.trigger === "/" ? props.commands : props.mentions;
|
|
162
|
+
const filter = filterOf(current.trigger);
|
|
163
|
+
if (filter === false || filter === true && !current.query) return source;
|
|
164
|
+
if (typeof filter === "function") return source.filter((option) => filter(option, current.query, current.trigger));
|
|
137
165
|
const query = current.query.toLowerCase();
|
|
138
|
-
|
|
166
|
+
const texts = (option) => [
|
|
167
|
+
option.label ?? option.value,
|
|
168
|
+
...current.trigger === "@" && option.label ? [option.value] : [],
|
|
169
|
+
option.description ?? "",
|
|
170
|
+
...option.keywords ?? []
|
|
171
|
+
];
|
|
172
|
+
return source.filter((option) => texts(option).some((text) => text.toLowerCase().includes(query)));
|
|
173
|
+
});
|
|
174
|
+
const instance = getCurrentInstance();
|
|
175
|
+
const listening = () => !!instance?.vnode.props?.onSearch;
|
|
176
|
+
const asked = {};
|
|
177
|
+
const answered = reactive({});
|
|
178
|
+
watch(() => props.commands, () => answered["/"] = asked["/"]);
|
|
179
|
+
watch(() => props.mentions, () => answered["@"] = asked["@"]);
|
|
180
|
+
const stale = computed(() => {
|
|
181
|
+
const current = token.value;
|
|
182
|
+
if (!current || filterOf(current.trigger) !== false || !listening()) return false;
|
|
183
|
+
const last = answered[current.trigger];
|
|
184
|
+
return !!last && (last.start !== current.start || last.query !== current.query);
|
|
185
|
+
});
|
|
186
|
+
let searchTimer;
|
|
187
|
+
watch(() => token.value ? `${token.value.start}${token.value.trigger}${token.value.query}` : null, (key) => {
|
|
188
|
+
clearTimeout(searchTimer);
|
|
189
|
+
const current = token.value;
|
|
190
|
+
if (key === null || !current || dismissed.value === current.start) return;
|
|
191
|
+
searchTimer = setTimeout(() => {
|
|
192
|
+
if (listening()) asked[current.trigger] = {
|
|
193
|
+
start: current.start,
|
|
194
|
+
query: current.query
|
|
195
|
+
};
|
|
196
|
+
emit("search", current.query, current.trigger);
|
|
197
|
+
}, props.searchDelay);
|
|
139
198
|
});
|
|
199
|
+
onBeforeUnmount(() => clearTimeout(searchTimer));
|
|
140
200
|
const menuOpen = computed(() => !disabled.value && options.value.length > 0);
|
|
141
201
|
const rootRef = useTemplateRef("root");
|
|
142
202
|
const menuRef = useTemplateRef("menu");
|
|
@@ -217,6 +277,7 @@ var chat_input_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
217
277
|
}
|
|
218
278
|
if ((event.key === "Enter" || event.key === "Tab") && !isComposing(event)) {
|
|
219
279
|
event.preventDefault();
|
|
280
|
+
if (stale.value) return true;
|
|
220
281
|
pick(options.value[active.value]);
|
|
221
282
|
return true;
|
|
222
283
|
}
|
|
@@ -317,9 +378,11 @@ var chat_input_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
317
378
|
"aria-controls": menuOpen.value ? `${unref(id)}-menu` : void 0,
|
|
318
379
|
"aria-activedescendant": menuOpen.value ? optionId(active.value) : void 0,
|
|
319
380
|
onKeydown,
|
|
320
|
-
onKeyup:
|
|
321
|
-
onClick:
|
|
322
|
-
onInput:
|
|
381
|
+
onKeyup: onCaret,
|
|
382
|
+
onClick: onCaret,
|
|
383
|
+
onInput: onCaret,
|
|
384
|
+
onCompositionstart: onCompositionStart,
|
|
385
|
+
onCompositionend: onCompositionEnd,
|
|
323
386
|
onBlur: _cache[1] || (_cache[1] = ($event) => token.value = null),
|
|
324
387
|
onPaste
|
|
325
388
|
}), null, 16, _hoisted_1), [[vModelText, model.value]]),
|
|
@@ -332,7 +395,12 @@ var chat_input_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
332
395
|
key: 0,
|
|
333
396
|
id: `${unref(id)}-menu`,
|
|
334
397
|
ref: "menu",
|
|
335
|
-
class: normalizeClass([
|
|
398
|
+
class: normalizeClass([
|
|
399
|
+
unref(ns).e("menu"),
|
|
400
|
+
"dou-floating",
|
|
401
|
+
unref(ns).is("stale", stale.value)
|
|
402
|
+
]),
|
|
403
|
+
"aria-busy": stale.value || void 0,
|
|
336
404
|
style: normalizeStyle(menuStyle.value),
|
|
337
405
|
"data-placement": unref(menuPlacement),
|
|
338
406
|
"data-dou-theme": unref(theme),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-input.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_useModel","_openBlock","_createElementBlock","_normalizeClass","_unref","_normalizeStyle","_renderSlot","_createCommentVNode","_withDirectives","_createElementVNode","_mergeProps","_vModelText","_createBlock","_Teleport","_createVNode","_Transition","_withCtx","_withModifiers","_Fragment","_renderList","_resolveDynamicComponent","_toDisplayString"],"sources":["../../../src/components/chat-input/chat-input.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ArrowUpIcon, StopIcon } from '@dou-ui/icons'\nimport { computed, nextTick, onMounted, ref, useAttrs, useId, useTemplateRef, watch } from 'vue'\nimport type { StyleValue } from 'vue'\nimport { useFloating } from '../../composables/use-floating'\nimport { useLayer } from '../../composables/use-layer'\nimport { useThemeScope } from '../../composables/use-theme-scope'\nimport { isComposing } from '../../utils/keyboard'\nimport { useNamespace } from '../../utils/namespace'\nimport { useTeleport } from '../../utils/teleport'\nimport { DouButton } from '../button'\nimport { useLocale, useZIndex } from '../config-provider/use-config'\nimport { useFormDisabled } from '../form/use-form-item'\nimport { findToken } from './chat-input'\nimport type {\n ChatInputEmits,\n ChatInputExpose,\n ChatInputOption,\n ChatInputProps,\n ChatInputSlots,\n ChatInputToken,\n} from './chat-input'\n\ndefineOptions({ name: 'DouChatInput', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<ChatInputProps>(), {\n submitOn: 'enter',\n loading: false,\n size: 'md',\n disabled: false,\n minRows: 1,\n maxRows: 8,\n canSubmit: undefined,\n commands: () => [],\n mentions: () => [],\n teleport: undefined,\n})\nconst emit = defineEmits<ChatInputEmits>()\nconst slots = defineSlots<ChatInputSlots>()\nconst model = defineModel<string>({ default: '' })\n\nconst ns = useNamespace('chat-input')\nconst id = useId()\nconst { t } = useLocale()\nconst disabled = useFormDisabled(() => props.disabled)\nconst buttonSize = computed(() => (props.size === 'lg' ? 'md' : 'sm'))\n\n// `class` and `style` dress the frame, the rest goes to the textarea.\nconst attrs = useAttrs()\nconst textareaAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs\n return rest\n})\n\nconst textareaRef = useTemplateRef<HTMLTextAreaElement>('textarea')\n\nconst submittable = computed(\n () => !disabled.value && (props.canSubmit ?? model.value.trim().length > 0),\n)\n\nfunction resize() {\n const el = textareaRef.value\n if (!el) return\n const style = getComputedStyle(el)\n const lineHeight = Number.parseFloat(style.lineHeight) || 22\n const padding = Number.parseFloat(style.paddingTop) + Number.parseFloat(style.paddingBottom)\n const min = props.minRows * lineHeight + (padding || 0)\n const max = props.maxRows * lineHeight + (padding || 0)\n el.style.height = 'auto'\n const content = el.scrollHeight\n el.style.height = `${Math.min(Math.max(content, min), max)}px`\n el.style.overflowY = content > max ? 'auto' : 'hidden'\n}\nwatch([model, () => props.minRows, () => props.maxRows], () => nextTick(resize))\nonMounted(resize)\n\n// While a reply is generated the button stops it, unless something new\n// has been typed: then it sends, and the app may queue the message.\nconst stopping = computed(() => props.loading && !submittable.value)\n\nfunction submit() {\n if (!submittable.value) return\n emit('submit', model.value)\n}\n\nfunction stop() {\n if (props.loading) emit('stop')\n}\n\n// --- `/` command and `@` mention menu ---\nconst token = ref<ChatInputToken | null>(null)\nconst dismissed = ref<number | null>(null)\nconst active = ref(0)\n\nfunction readToken() {\n const el = textareaRef.value\n if (!el) return\n const next = findToken(model.value, el.selectionStart ?? model.value.length)\n const current = token.value\n // keyup and click re-read the caret after every key, arrows included: an\n // unchanged token must keep its identity or the menu resets its highlight.\n if (\n next &&\n current &&\n next.trigger === current.trigger &&\n next.start === current.start &&\n next.end === current.end &&\n next.query === current.query\n )\n return\n if (next?.start !== current?.start) dismissed.value = null\n token.value = next\n}\n\nconst options = computed<ChatInputOption[]>(() => {\n const current = token.value\n if (!current || dismissed.value === current.start) return []\n const source = current.trigger === '/' ? props.commands : props.mentions\n const query = current.query.toLowerCase()\n return source.filter(\n (option) =>\n option.value.toLowerCase().includes(query) ||\n (option.label ?? '').toLowerCase().includes(query),\n )\n})\nconst menuOpen = computed(() => !disabled.value && options.value.length > 0)\n\n// The menu is a popup like any other: rendered on top of the page, above\n// the frame (or below it when there is no room), stacked over what opened\n// before and closed by a press outside. The focus stays in the textarea.\nconst rootRef = useTemplateRef<HTMLElement>('root')\nconst menuRef = useTemplateRef<HTMLElement>('menu')\nconst teleportTarget = useTeleport(() => props.teleport)\nconst { style: floatingStyle, placement: menuPlacement } = useFloating(\n () => (menuOpen.value ? rootRef.value : null),\n menuRef,\n { open: menuOpen, placement: 'top-start', offset: 6 },\n)\nconst { next: nextZIndex } = useZIndex()\nconst menuZIndex = ref<number>()\nconst menuWidth = ref<number>()\n// rendered the first time it opens, so the server output stays the same\nconst menuRendered = ref(false)\nconst { theme, sync: syncTheme } = useThemeScope(() => rootRef.value)\nwatch(menuOpen, (value) => {\n if (!value) return\n menuRendered.value = true\n menuZIndex.value = nextZIndex()\n menuWidth.value = rootRef.value?.offsetWidth\n syncTheme()\n})\nconst menuStyle = computed(() => ({\n ...floatingStyle.value,\n zIndex: menuZIndex.value,\n '--dou-chat-input-menu-width': menuWidth.value ? `${menuWidth.value}px` : undefined,\n}))\nuseLayer({\n open: menuOpen,\n elements: () => [rootRef.value, menuRef.value],\n onOutside: () => (token.value = null),\n onEscape: () => (dismissed.value = token.value?.start ?? null),\n})\n// Only a different list moves the highlight back to the first usable option.\nconst firstEnabled = () =>\n Math.max(\n 0,\n options.value.findIndex((option) => !option.disabled),\n )\nwatch(\n () =>\n menuOpen.value\n ? `${token.value?.trigger}${options.value.map((option) => option.value).join('\\u0000')}`\n : '',\n () => (active.value = firstEnabled()),\n)\n\nfunction move(step: 1 | -1) {\n const list = options.value\n for (let offset = 1; offset <= list.length; offset++) {\n const index = (((active.value + step * offset) % list.length) + list.length) % list.length\n if (!list[index]!.disabled) {\n active.value = index\n return\n }\n }\n}\nconst optionId = (index: number) => `${id}-option-${index}`\nwatch(active, async (index) => {\n await nextTick()\n document.getElementById(optionId(index))?.scrollIntoView?.({ block: 'nearest' })\n})\n\nfunction pick(option: ChatInputOption) {\n const current = token.value\n if (!current || option.disabled) return\n const before = model.value.slice(0, current.start)\n const after = model.value.slice(current.end)\n let caret: number\n if (current.trigger === '/') {\n model.value = before + after.replace(/^\\s+/, '')\n caret = before.length\n emit('command', option)\n } else {\n const inserted = `@${option.value} `\n model.value = before + inserted + after.replace(/^\\s+/, '')\n caret = before.length + inserted.length\n emit('mention', option)\n }\n token.value = null\n void nextTick(() => {\n textareaRef.value?.focus()\n textareaRef.value?.setSelectionRange(caret, caret)\n })\n}\n\nfunction onMenuKeydown(event: KeyboardEvent): boolean {\n if (!menuOpen.value) return false\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n move(event.key === 'ArrowDown' ? 1 : -1)\n return true\n }\n if ((event.key === 'Enter' || event.key === 'Tab') && !isComposing(event)) {\n event.preventDefault()\n pick(options.value[active.value]!)\n return true\n }\n if (event.key === 'Escape') {\n event.preventDefault()\n dismissed.value = token.value?.start ?? null\n return true\n }\n return false\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (onMenuKeydown(event)) return\n if (event.key !== 'Enter' || isComposing(event)) return\n const mod = event.ctrlKey || event.metaKey\n const sends = props.submitOn === 'enter' ? !event.shiftKey && !mod : mod\n if (!sends) return\n event.preventDefault()\n submit()\n}\n\nconst filesOf = (list: DataTransferItemList | undefined) =>\n [...(list ?? [])]\n .filter((item) => item.kind === 'file')\n .map((item) => item.getAsFile())\n .filter((file): file is File => !!file)\n\nfunction onPaste(event: ClipboardEvent) {\n const files = filesOf(event.clipboardData?.items)\n if (!files.length) return\n // keep the file's name from being pasted as text\n event.preventDefault()\n emit('attach', files)\n}\n\nconst dragging = ref(false)\nlet depth = 0\nconst carriesFiles = (event: DragEvent) => !!event.dataTransfer?.types.includes('Files')\n\nfunction onDragenter(event: DragEvent) {\n if (disabled.value || !carriesFiles(event)) return\n depth++\n dragging.value = true\n}\nfunction onDragover(event: DragEvent) {\n if (disabled.value || !carriesFiles(event)) return\n event.preventDefault()\n}\nfunction onDragleave() {\n depth = Math.max(0, depth - 1)\n if (!depth) dragging.value = false\n}\nfunction onDrop(event: DragEvent) {\n depth = 0\n dragging.value = false\n if (disabled.value) return\n const files = [...(event.dataTransfer?.files ?? [])]\n if (!files.length) return\n event.preventDefault()\n emit('attach', files)\n}\n\n// A press anywhere on the frame that is not a control puts the caret in the text.\nfunction onMousedown(event: MouseEvent) {\n const target = event.target as HTMLElement\n if (target === textareaRef.value || target.closest('button, a, input, select, [tabindex]')) return\n event.preventDefault()\n textareaRef.value?.focus()\n}\n\ndefineExpose<ChatInputExpose>({\n get textarea() {\n return textareaRef.value\n },\n focus: () => textareaRef.value?.focus(),\n blur: () => textareaRef.value?.blur(),\n submit,\n})\n</script>\n\n<template>\n <div\n ref=\"root\"\n :class=\"[\n ns.b(),\n ns.m(size),\n ns.is('disabled', disabled),\n ns.is('loading', loading),\n ns.is('dragging', dragging),\n attrs.class,\n ]\"\n :style=\"attrs.style as StyleValue\"\n @mousedown=\"onMousedown\"\n @dragenter=\"onDragenter\"\n @dragover=\"onDragover\"\n @dragleave=\"onDragleave\"\n @drop=\"onDrop\"\n >\n <div v-if=\"slots.header\" :class=\"ns.e('header')\"><slot name=\"header\" /></div>\n <textarea\n ref=\"textarea\"\n v-model=\"model\"\n :aria-label=\"placeholder ?? t('chat.placeholder')\"\n v-bind=\"textareaAttrs\"\n :class=\"ns.e('native')\"\n :rows=\"minRows\"\n :placeholder=\"placeholder ?? t('chat.placeholder')\"\n :disabled=\"disabled\"\n :aria-autocomplete=\"commands.length || mentions.length ? 'list' : undefined\"\n :aria-expanded=\"commands.length || mentions.length ? menuOpen : undefined\"\n :aria-controls=\"menuOpen ? `${id}-menu` : undefined\"\n :aria-activedescendant=\"menuOpen ? optionId(active) : undefined\"\n @keydown=\"onKeydown\"\n @keyup=\"readToken\"\n @click=\"readToken\"\n @input=\"readToken\"\n @blur=\"token = null\"\n @paste=\"onPaste\"\n />\n <Teleport v-if=\"menuRendered\" :to=\"teleportTarget.to\" :disabled=\"teleportTarget.disabled\">\n <Transition name=\"dou-floating\">\n <ul\n v-if=\"menuOpen\"\n :id=\"`${id}-menu`\"\n ref=\"menu\"\n :class=\"[ns.e('menu'), 'dou-floating']\"\n :style=\"menuStyle\"\n :data-placement=\"menuPlacement\"\n :data-dou-theme=\"theme\"\n role=\"listbox\"\n @mousedown.prevent\n >\n <li\n v-for=\"(option, index) in options\"\n :id=\"optionId(index)\"\n :key=\"option.value\"\n role=\"option\"\n :class=\"[\n ns.e('option'),\n ns.is('active', index === active),\n ns.is('disabled', !!option.disabled),\n ]\"\n :aria-selected=\"index === active\"\n :aria-disabled=\"option.disabled || undefined\"\n @mouseenter=\"!option.disabled && (active = index)\"\n @click=\"pick(option)\"\n >\n <slot name=\"option\" :option=\"option\" :trigger=\"token!.trigger\">\n <component :is=\"option.icon\" v-if=\"option.icon\" :class=\"ns.e('option-icon')\" />\n <span :class=\"ns.e('option-label')\">\n {{ token?.trigger === '/' ? '/' : '@' }}{{ option.label ?? option.value }}\n </span>\n <span v-if=\"option.description\" :class=\"ns.e('option-description')\">\n {{ option.description }}\n </span>\n </slot>\n </li>\n </ul>\n </Transition>\n </Teleport>\n <div :class=\"ns.e('footer')\">\n <div :class=\"ns.e('actions')\"><slot name=\"actions\" /></div>\n <slot\n name=\"submit\"\n :submit=\"submit\"\n :stop=\"stop\"\n :loading=\"loading\"\n :disabled=\"stopping ? false : !submittable\"\n >\n <DouButton\n v-if=\"stopping\"\n :class=\"ns.e('submit')\"\n :size=\"buttonSize\"\n :aria-label=\"t('chat.stop')\"\n @click=\"stop\"\n >\n <StopIcon />\n </DouButton>\n <DouButton\n v-else\n :class=\"ns.e('submit')\"\n :size=\"buttonSize\"\n :disabled=\"!submittable\"\n :aria-label=\"t('chat.send')\"\n @click=\"submit\"\n >\n <ArrowUpIcon />\n </DouButton>\n </slot>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyBA,MAAM,QAAQ;EAYd,MAAM,OAAO;EACb,MAAM,QAAQA,SAAA;EACd,MAAM,QAAQC,SAAmB,SAAA,YAAgB;EAEjD,MAAM,KAAK,aAAa,YAAY;EACpC,MAAM,KAAK,MAAM;EACjB,MAAM,EAAE,MAAM,UAAU;EACxB,MAAM,WAAW,sBAAsB,MAAM,QAAQ;EACrD,MAAM,aAAa,eAAgB,MAAM,SAAS,OAAO,OAAO,IAAK;EAGrE,MAAM,QAAQ,SAAS;EACvB,MAAM,gBAAgB,eAAe;GACnC,MAAM,EAAE,OAAO,QAAQ,OAAO,QAAQ,GAAG,SAAS;GAClD,OAAO;EACT,CAAC;EAED,MAAM,cAAc,eAAoC,UAAU;EAElE,MAAM,cAAc,eACZ,CAAC,SAAS,UAAU,MAAM,aAAa,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,EAC3E;EAEA,SAAS,SAAS;GAChB,MAAM,KAAK,YAAY;GACvB,IAAI,CAAC,IAAI;GACT,MAAM,QAAQ,iBAAiB,EAAE;GACjC,MAAM,aAAa,OAAO,WAAW,MAAM,UAAU,KAAK;GAC1D,MAAM,UAAU,OAAO,WAAW,MAAM,UAAU,IAAI,OAAO,WAAW,MAAM,aAAa;GAC3F,MAAM,MAAM,MAAM,UAAU,cAAc,WAAW;GACrD,MAAM,MAAM,MAAM,UAAU,cAAc,WAAW;GACrD,GAAG,MAAM,SAAS;GAClB,MAAM,UAAU,GAAG;GACnB,GAAG,MAAM,SAAS,GAAG,KAAK,IAAI,KAAK,IAAI,SAAS,GAAG,GAAG,GAAG,EAAE;GAC3D,GAAG,MAAM,YAAY,UAAU,MAAM,SAAS;EAChD;EACA,MAAM;GAAC;SAAa,MAAM;SAAe,MAAM;EAAO,SAAS,SAAS,MAAM,CAAC;EAC/E,UAAU,MAAM;EAIhB,MAAM,WAAW,eAAe,MAAM,WAAW,CAAC,YAAY,KAAK;EAEnE,SAAS,SAAS;GAChB,IAAI,CAAC,YAAY,OAAO;GACxB,KAAK,UAAU,MAAM,KAAK;EAC5B;EAEA,SAAS,OAAO;GACd,IAAI,MAAM,SAAS,KAAK,MAAM;EAChC;EAGA,MAAM,QAAQ,IAA2B,IAAI;EAC7C,MAAM,YAAY,IAAmB,IAAI;EACzC,MAAM,SAAS,IAAI,CAAC;EAEpB,SAAS,YAAY;GACnB,MAAM,KAAK,YAAY;GACvB,IAAI,CAAC,IAAI;GACT,MAAM,OAAO,UAAU,MAAM,OAAO,GAAG,kBAAkB,MAAM,MAAM,MAAM;GAC3E,MAAM,UAAU,MAAM;GAGtB,IACE,QACA,WACA,KAAK,YAAY,QAAQ,WACzB,KAAK,UAAU,QAAQ,SACvB,KAAK,QAAQ,QAAQ,OACrB,KAAK,UAAU,QAAQ,OAEvB;GACF,IAAI,MAAM,UAAU,SAAS,OAAO,UAAU,QAAQ;GACtD,MAAM,QAAQ;EAChB;EAEA,MAAM,UAAU,eAAkC;GAChD,MAAM,UAAU,MAAM;GACtB,IAAI,CAAC,WAAW,UAAU,UAAU,QAAQ,OAAO,OAAO,CAAC;GAC3D,MAAM,SAAS,QAAQ,YAAY,MAAM,MAAM,WAAW,MAAM;GAChE,MAAM,QAAQ,QAAQ,MAAM,YAAY;GACxC,OAAO,OAAO,QACX,WACC,OAAO,MAAM,YAAY,CAAC,CAAC,SAAS,KAAK,MACxC,OAAO,SAAS,GAAA,CAAI,YAAY,CAAC,CAAC,SAAS,KAAK,CACrD;EACF,CAAC;EACD,MAAM,WAAW,eAAe,CAAC,SAAS,SAAS,QAAQ,MAAM,SAAS,CAAC;EAK3E,MAAM,UAAU,eAA4B,MAAM;EAClD,MAAM,UAAU,eAA4B,MAAM;EAClD,MAAM,iBAAiB,kBAAkB,MAAM,QAAQ;EACvD,MAAM,EAAE,OAAO,eAAe,WAAW,kBAAkB,kBAClD,SAAS,QAAQ,QAAQ,QAAQ,MACxC,SACA;GAAE,MAAM;GAAU,WAAW;GAAa,QAAQ;EAAE,CACtD;EACA,MAAM,EAAE,MAAM,eAAe,UAAU;EACvC,MAAM,aAAa,IAAY;EAC/B,MAAM,YAAY,IAAY;EAE9B,MAAM,eAAe,IAAI,KAAK;EAC9B,MAAM,EAAE,OAAO,MAAM,cAAc,oBAAoB,QAAQ,KAAK;EACpE,MAAM,WAAW,UAAU;GACzB,IAAI,CAAC,OAAO;GACZ,aAAa,QAAQ;GACrB,WAAW,QAAQ,WAAW;GAC9B,UAAU,QAAQ,QAAQ,OAAO;GACjC,UAAU;EACZ,CAAC;EACD,MAAM,YAAY,gBAAgB;GAChC,GAAG,cAAc;GACjB,QAAQ,WAAW;GACnB,+BAA+B,UAAU,QAAQ,GAAG,UAAU,MAAM,MAAM,KAAA;EAC5E,EAAE;EACF,SAAS;GACP,MAAM;GACN,gBAAgB,CAAC,QAAQ,OAAO,QAAQ,KAAK;GAC7C,iBAAkB,MAAM,QAAQ;GAChC,gBAAiB,UAAU,QAAQ,MAAM,OAAO,SAAS;EAC3D,CAAC;EAED,MAAM,qBACJ,KAAK,IACH,GACA,QAAQ,MAAM,WAAW,WAAW,CAAC,OAAO,QAAQ,CACtD;EACF,YAEI,SAAS,QACL,GAAG,MAAM,OAAO,UAAU,QAAQ,MAAM,KAAK,WAAW,OAAO,KAAK,CAAC,CAAC,KAAK,IAAQ,MACnF,UACC,OAAO,QAAQ,aAAa,CACrC;EAEA,SAAS,KAAK,MAAc;GAC1B,MAAM,OAAO,QAAQ;GACrB,KAAK,IAAI,SAAS,GAAG,UAAU,KAAK,QAAQ,UAAU;IACpD,MAAM,UAAW,OAAO,QAAQ,OAAO,UAAU,KAAK,SAAU,KAAK,UAAU,KAAK;IACpF,IAAI,CAAC,KAAK,MAAM,CAAE,UAAU;KAC1B,OAAO,QAAQ;KACf;IACF;GACF;EACF;EACA,MAAM,YAAY,UAAkB,GAAG,GAAG,UAAU;EACpD,MAAM,QAAQ,OAAO,UAAU;GAC7B,MAAM,SAAS;GACf,SAAS,eAAe,SAAS,KAAK,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,UAAU,CAAC;EACjF,CAAC;EAED,SAAS,KAAK,QAAyB;GACrC,MAAM,UAAU,MAAM;GACtB,IAAI,CAAC,WAAW,OAAO,UAAU;GACjC,MAAM,SAAS,MAAM,MAAM,MAAM,GAAG,QAAQ,KAAK;GACjD,MAAM,QAAQ,MAAM,MAAM,MAAM,QAAQ,GAAG;GAC3C,IAAI;GACJ,IAAI,QAAQ,YAAY,KAAK;IAC3B,MAAM,QAAQ,SAAS,MAAM,QAAQ,QAAQ,EAAE;IAC/C,QAAQ,OAAO;IACf,KAAK,WAAW,MAAM;GACxB,OAAO;IACL,MAAM,WAAW,IAAI,OAAO,MAAM;IAClC,MAAM,QAAQ,SAAS,WAAW,MAAM,QAAQ,QAAQ,EAAE;IAC1D,QAAQ,OAAO,SAAS,SAAS;IACjC,KAAK,WAAW,MAAM;GACxB;GACA,MAAM,QAAQ;GACd,eAAoB;IAClB,YAAY,OAAO,MAAM;IACzB,YAAY,OAAO,kBAAkB,OAAO,KAAK;GACnD,CAAC;EACH;EAEA,SAAS,cAAc,OAA+B;GACpD,IAAI,CAAC,SAAS,OAAO,OAAO;GAC5B,IAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,WAAW;IACxD,MAAM,eAAe;IACrB,KAAK,MAAM,QAAQ,cAAc,IAAI,EAAE;IACvC,OAAO;GACT;GACA,KAAK,MAAM,QAAQ,WAAW,MAAM,QAAQ,UAAU,CAAC,YAAY,KAAK,GAAG;IACzE,MAAM,eAAe;IACrB,KAAK,QAAQ,MAAM,OAAO,MAAO;IACjC,OAAO;GACT;GACA,IAAI,MAAM,QAAQ,UAAU;IAC1B,MAAM,eAAe;IACrB,UAAU,QAAQ,MAAM,OAAO,SAAS;IACxC,OAAO;GACT;GACA,OAAO;EACT;EAEA,SAAS,UAAU,OAAsB;GACvC,IAAI,cAAc,KAAK,GAAG;GAC1B,IAAI,MAAM,QAAQ,WAAW,YAAY,KAAK,GAAG;GACjD,MAAM,MAAM,MAAM,WAAW,MAAM;GAEnC,IAAI,EADU,MAAM,aAAa,UAAU,CAAC,MAAM,YAAY,CAAC,MAAM,MACzD;GACZ,MAAM,eAAe;GACrB,OAAO;EACT;EAEA,MAAM,WAAW,SACf,CAAC,GAAI,QAAQ,CAAC,CAAE,CAAA,CACb,QAAQ,SAAS,KAAK,SAAS,MAAM,CAAA,CACrC,KAAK,SAAS,KAAK,UAAU,CAAC,CAAA,CAC9B,QAAQ,SAAuB,CAAC,CAAC,IAAI;EAE1C,SAAS,QAAQ,OAAuB;GACtC,MAAM,QAAQ,QAAQ,MAAM,eAAe,KAAK;GAChD,IAAI,CAAC,MAAM,QAAQ;GAEnB,MAAM,eAAe;GACrB,KAAK,UAAU,KAAK;EACtB;EAEA,MAAM,WAAW,IAAI,KAAK;EAC1B,IAAI,QAAQ;EACZ,MAAM,gBAAgB,UAAqB,CAAC,CAAC,MAAM,cAAc,MAAM,SAAS,OAAO;EAEvF,SAAS,YAAY,OAAkB;GACrC,IAAI,SAAS,SAAS,CAAC,aAAa,KAAK,GAAG;GAC5C;GACA,SAAS,QAAQ;EACnB;EACA,SAAS,WAAW,OAAkB;GACpC,IAAI,SAAS,SAAS,CAAC,aAAa,KAAK,GAAG;GAC5C,MAAM,eAAe;EACvB;EACA,SAAS,cAAc;GACrB,QAAQ,KAAK,IAAI,GAAG,QAAQ,CAAC;GAC7B,IAAI,CAAC,OAAO,SAAS,QAAQ;EAC/B;EACA,SAAS,OAAO,OAAkB;GAChC,QAAQ;GACR,SAAS,QAAQ;GACjB,IAAI,SAAS,OAAO;GACpB,MAAM,QAAQ,CAAC,GAAI,MAAM,cAAc,SAAS,CAAC,CAAE;GACnD,IAAI,CAAC,MAAM,QAAQ;GACnB,MAAM,eAAe;GACrB,KAAK,UAAU,KAAK;EACtB;EAGA,SAAS,YAAY,OAAmB;GACtC,MAAM,SAAS,MAAM;GACrB,IAAI,WAAW,YAAY,SAAS,OAAO,QAAQ,sCAAsC,GAAG;GAC5F,MAAM,eAAe;GACrB,YAAY,OAAO,MAAM;EAC3B;EAEA,SAA8B;GAC5B,IAAI,WAAW;IACb,OAAO,YAAY;GACrB;GACA,aAAa,YAAY,OAAO,MAAM;GACtC,YAAY,YAAY,OAAO,KAAK;GACpC;EACF,CAAC;;GAIC,OAAAC,UAAA,GAAAC,mBA6GM,OAAA;IA5GJ,KAAI;IACH,OAAKC,eAAA;KAAUC,MAAA,EAAA,CAAE,CAAC,EAAC;KAAUA,MAAA,EAAA,CAAE,CAAC,EAAE,QAAA,IAAI;KAASA,MAAA,EAAA,CAAE,CAAC,GAAE,YAAaA,MAAA,QAAA,CAAQ;KAASA,MAAA,EAAA,CAAE,CAAC,GAAE,WAAY,QAAA,OAAO;KAASA,MAAA,EAAA,CAAE,CAAC,GAAE,YAAa,SAAA,KAAQ;KAASA,MAAA,KAAA,CAAK,CAAC;;IAQ5J,OAAKC,eAAED,MAAA,KAAA,CAAK,CAAC,KAAK;IACP;IACA;IACD;IACC;IACL;;IAEI,MAAM,UAAjBH,UAAA,GAAAC,mBAA6E,OAAA;;KAAnD,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,CAAA;I,IAAYE,WAAsB,KAAA,QAAA,QAAA,C;IACvEE,eAAAC,mBAmBE,YAnBFC,WAmBE;KAlBA,KAAI;KACK,uBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,MAAK,QAAA;KACb,cAAY,QAAA,eAAeN,MAAA,CAAA,CAAC,CAAA,kBAAA;IACrB,GAAA,cAAA,OAAa;KACpB,OAAOA,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA;KACX,MAAM,QAAA;KACN,aAAa,QAAA,eAAeA,MAAA,CAAA,CAAC,CAAA,kBAAA;KAC7B,UAAUA,MAAA,QAAA;KACV,qBAAmB,QAAA,SAAS,UAAU,QAAA,SAAS,SAAM,SAAY,KAAA;KACjE,iBAAe,QAAA,SAAS,UAAU,QAAA,SAAS,SAAS,SAAA,QAAW,KAAA;KAC/D,iBAAe,SAAA,QAAQ,GAAMA,MAAA,EAAA,EAAE,SAAU,KAAA;KACzC,yBAAuB,SAAA,QAAW,SAAS,OAAA,KAAM,IAAI,KAAA;KAC5C;KACT,SAAO;KACP,SAAO;KACP,SAAO;KACP,QAAI,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,QAAK;KACJ;I,4BAhBC,CAAAO,YAAA,MAAA,KAAK,C;IAkBA,aAAA,SAAhBV,UAAA,GAAAW,YAwCWC,UAAA;;KAxCoB,IAAIT,MAAA,cAAA,CAAc,CAAC;KAAK,UAAUA,MAAA,cAAA,CAAc,CAAC;I,IAC9EU,YAsCaC,YAAA,EAtCD,MAAK,eAAc,GAAA;KAC7B,SAAAC,cAoCK,CAnCG,SAAA,SADRf,UAAA,GAAAC,mBAoCK,MAAA;;MAlCF,IAAE,GAAKE,MAAA,EAAA,EAAE;MACV,KAAI;MACH,OAAKD,eAAA,CAAGC,MAAA,EAAA,CAAE,CAAC,EAAC,MAAA,GAAA,cAAA,CAAA;MACZ,OAAKC,eAAE,UAAA,KAAS;MAChB,kBAAgBD,MAAA,aAAA;MAChB,kBAAgBA,MAAA,KAAA;MACjB,MAAK;MACJ,aAAS,OAAA,OAAA,OAAA,KAAAa,oBAAV,CAAA,GAAkB,CAAA,SAAA,CAAA;K,KAElBhB,UAAA,IAAA,GAAAC,mBAwBKgB,UAAA,MAAAC,WAvBuB,QAAA,QAAlB,QAAQ,UAAK;MADvB,OAAAlB,UAAA,GAAAC,mBAwBK,MAAA;OAtBF,IAAI,SAAS,KAAK;OAClB,KAAK,OAAO;OACb,MAAK;OACJ,OAAKC,eAAA;QAAkBC,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA;QAA0BA,MAAA,EAAA,CAAE,CAAC,GAAE,UAAW,UAAU,OAAA,KAAM;QAAiBA,MAAA,EAAA,CAAE,CAAC,GAAE,YAAA,CAAA,CAAe,OAAO,QAAQ;;OAKzI,iBAAe,UAAU,OAAA;OACzB,iBAAe,OAAO,YAAY,KAAA;OAClC,eAAU,WAAA,CAAG,OAAO,aAAa,OAAA,QAAS;OAC1C,UAAK,WAAE,KAAK,MAAM;M,IAEnBE,WAQO,KAAA,QAAA,UAAA;OARsB;OAAS,SAAS,MAAA,MAAO;MAAtD,SAQO;OAP8B,OAAO,QAA1CL,UAAA,GAAAW,YAA+EQ,wBAA/D,OAAO,IAAI,GAAA;;QAAsB,OAAKjB,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,aAAA,CAAA;;OAC5DK,mBAEO,QAAA,EAFA,OAAKN,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,cAAA,CAAA,EACb,GAAAiB,gBAAA,MAAA,OAAO,YAAO,MAAA,MAAA,GAAA,IAAAA,gBAA0B,OAAO,SAAS,OAAO,KAAK,GAAA,CAAA;OAE7D,OAAO,eAAnBpB,UAAA,GAAAC,mBAEO,QAAA;;QAF0B,OAAKC,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,oBAAA,CAAA;OACvC,GAAAiB,gBAAA,OAAO,WAAW,GAAA,CAAA,K;;;;;IAOjCZ,mBA6BM,OAAA,EA7BA,OAAKN,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,CAAA,E,IACfK,mBAA2D,OAAA,EAArD,OAAKN,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,SAAA,CAAA,E,IAAaE,WAAuB,KAAA,QAAA,SAAA,C,OACrDA,WA0BO,KAAA,QAAA,UAAA;KAxBI;KACF;KACN,SAAS,QAAA;KACT,UAAU,SAAA,QAAQ,QAAA,CAAY,YAAA;IALjC,SA0BO,CAlBG,SAAA,SADRL,UAAA,GAAAW,YAQYR,MAAA,SAAA,GAAA;;KANT,OAAKD,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,CAAA;KACX,MAAM,WAAA;KACN,cAAYA,MAAA,CAAA,CAAC,CAAA,WAAA;KACb,SAAO;;KAER,SAAAY,cAAY,CAAZF,YAAYV,MAAA,QAAA,CAAA,C;;;;;;I,OAEdH,UAAA,GAAAW,YASYR,MAAA,SAAA,GAAA;;KAPT,OAAKD,eAAEC,MAAA,EAAA,CAAE,CAAC,EAAC,QAAA,CAAA;KACX,MAAM,WAAA;KACN,UAAQ,CAAG,YAAA;KACX,cAAYA,MAAA,CAAA,CAAC,CAAA,WAAA;KACb,SAAO;;KAER,SAAAY,cAAe,CAAfF,YAAeV,MAAA,WAAA,CAAA,C"}
|
|
1
|
+
{"version":3,"file":"chat-input.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_useModel","_openBlock","_createElementBlock","_normalizeClass","_unref","_normalizeStyle","_renderSlot","_createCommentVNode","_withDirectives","_createElementVNode","_mergeProps","_vModelText","_createBlock","_Teleport","_createVNode","_Transition","_withCtx","_withModifiers","_Fragment","_renderList","_resolveDynamicComponent","_toDisplayString"],"sources":["../../../src/components/chat-input/chat-input.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ArrowUpIcon, StopIcon } from '@dou-ui/icons'\nimport {\n computed,\n getCurrentInstance,\n nextTick,\n onBeforeUnmount,\n onMounted,\n reactive,\n ref,\n useAttrs,\n useId,\n useTemplateRef,\n watch,\n} from 'vue'\nimport type { StyleValue } from 'vue'\nimport { useFloating } from '../../composables/use-floating'\nimport { useLayer } from '../../composables/use-layer'\nimport { useThemeScope } from '../../composables/use-theme-scope'\nimport { isComposing } from '../../utils/keyboard'\nimport { useNamespace } from '../../utils/namespace'\nimport { useTeleport } from '../../utils/teleport'\nimport { DouButton } from '../button'\nimport { useLocale, useZIndex } from '../config-provider/use-config'\nimport { useFormDisabled } from '../form/use-form-item'\nimport { findToken } from './chat-input'\nimport type {\n ChatInputEmits,\n ChatInputExpose,\n ChatInputOption,\n ChatInputProps,\n ChatInputSlots,\n ChatInputToken,\n} from './chat-input'\n\ndefineOptions({ name: 'DouChatInput', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<ChatInputProps>(), {\n submitOn: 'enter',\n loading: false,\n size: 'md',\n disabled: false,\n minRows: 1,\n maxRows: 8,\n canSubmit: undefined,\n commands: () => [],\n mentions: () => [],\n filter: true,\n searchDelay: 300,\n teleport: undefined,\n})\nconst emit = defineEmits<ChatInputEmits>()\nconst slots = defineSlots<ChatInputSlots>()\nconst model = defineModel<string>({ default: '' })\n\nconst ns = useNamespace('chat-input')\nconst id = useId()\nconst { t } = useLocale()\nconst disabled = useFormDisabled(() => props.disabled)\nconst buttonSize = computed(() => (props.size === 'lg' ? 'md' : 'sm'))\n\n// `class` and `style` dress the frame, the rest goes to the textarea.\nconst attrs = useAttrs()\nconst textareaAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs\n return rest\n})\n\nconst textareaRef = useTemplateRef<HTMLTextAreaElement>('textarea')\n\nconst submittable = computed(\n () => !disabled.value && (props.canSubmit ?? model.value.trim().length > 0),\n)\n\nfunction resize() {\n const el = textareaRef.value\n if (!el) return\n const style = getComputedStyle(el)\n const lineHeight = Number.parseFloat(style.lineHeight) || 22\n const padding = Number.parseFloat(style.paddingTop) + Number.parseFloat(style.paddingBottom)\n const min = props.minRows * lineHeight + (padding || 0)\n const max = props.maxRows * lineHeight + (padding || 0)\n el.style.height = 'auto'\n const content = el.scrollHeight\n el.style.height = `${Math.min(Math.max(content, min), max)}px`\n el.style.overflowY = content > max ? 'auto' : 'hidden'\n}\nwatch([model, () => props.minRows, () => props.maxRows], () => nextTick(resize))\nonMounted(resize)\n\n// While a reply is generated the button stops it, unless something new\n// has been typed: then it sends, and the app may queue the message.\nconst stopping = computed(() => props.loading && !submittable.value)\n\nfunction submit() {\n if (!submittable.value) return\n emit('submit', model.value)\n}\n\nfunction stop() {\n if (props.loading) emit('stop')\n}\n\n// --- `/` command and `@` mention menu ---\nconst token = ref<ChatInputToken | null>(null)\nconst dismissed = ref<number | null>(null)\nconst active = ref(0)\n\n// While an input method composes, the text holds what is being spelled\n// (pinyin, say), not what will be typed: wait for it to finish.\nlet composing = false\nfunction onCaret(event?: Event) {\n if (composing || (event instanceof KeyboardEvent && isComposing(event))) return\n if ((event as InputEvent | undefined)?.isComposing) return\n readToken()\n}\nfunction onCompositionStart() {\n composing = true\n}\nfunction onCompositionEnd() {\n composing = false\n readToken()\n}\n\nfunction readToken() {\n const el = textareaRef.value\n if (!el) return\n // the textarea's own text: the model may not have caught up yet, e.g. right\n // after an input method puts its text down\n const next = findToken(el.value, el.selectionStart ?? el.value.length)\n const current = token.value\n // keyup and click re-read the caret after every key, arrows included: an\n // unchanged token must keep its identity or the menu resets its highlight.\n if (\n next &&\n current &&\n next.trigger === current.trigger &&\n next.start === current.start &&\n next.end === current.end &&\n next.query === current.query\n )\n return\n if (next?.start !== current?.start) dismissed.value = null\n token.value = next\n}\n\nconst filterOf = (trigger: '/' | '@') =>\n typeof props.filter === 'object' ? (props.filter[trigger] ?? true) : props.filter\n\nconst options = computed<ChatInputOption[]>(() => {\n const current = token.value\n if (!current || dismissed.value === current.start) return []\n const source = current.trigger === '/' ? props.commands : props.mentions\n const filter = filterOf(current.trigger)\n if (filter === false || (filter === true && !current.query)) return source\n if (typeof filter === 'function')\n return source.filter((option) => filter(option, current.query, current.trigger))\n // what the person sees: the label, a mention's value (it gets inserted), the description\n const query = current.query.toLowerCase()\n const texts = (option: ChatInputOption) => [\n option.label ?? option.value,\n ...(current.trigger === '@' && option.label ? [option.value] : []),\n option.description ?? '',\n ...(option.keywords ?? []),\n ]\n return source.filter((option) => texts(option).some((text) => text.toLowerCase().includes(query)))\n})\n\n// Without local matching, a list the parent puts in after a `search` is the\n// answer to the last query handed out. While what is typed now differs from\n// that query (its search still waits for `searchDelay`, or its answer is on\n// the way), the list shown answers an older one: it stays in view, but\n// Enter and Tab must not pick from it. A list put in before any search,\n// e.g. loaded once after mounting, is fixed and never stale. Nor is any\n// list when nobody listens to `search`: with no one to answer, a parent\n// that passes a new array each render is not answering a query.\nconst instance = getCurrentInstance()\nconst listening = () => !!instance?.vnode.props?.onSearch\ntype Query = { start: number; query: string }\nconst asked: { '/'?: Query; '@'?: Query } = {}\nconst answered = reactive<{ '/'?: Query; '@'?: Query }>({})\nwatch(\n () => props.commands,\n () => (answered['/'] = asked['/']),\n)\nwatch(\n () => props.mentions,\n () => (answered['@'] = asked['@']),\n)\nconst stale = computed(() => {\n const current = token.value\n if (!current || filterOf(current.trigger) !== false || !listening()) return false\n const last = answered[current.trigger]\n return !!last && (last.start !== current.start || last.query !== current.query)\n})\n\n// Each new query is handed out once typing pauses, to look options up\n// elsewhere; the same text at another `@` is a new query too.\nlet searchTimer: ReturnType<typeof setTimeout> | undefined\nwatch(\n () => (token.value ? `${token.value.start}${token.value.trigger}${token.value.query}` : null),\n (key) => {\n clearTimeout(searchTimer)\n const current = token.value\n // Escape closed this one: nothing to look up until another is typed\n if (key === null || !current || dismissed.value === current.start) return\n searchTimer = setTimeout(() => {\n if (listening()) asked[current.trigger] = { start: current.start, query: current.query }\n emit('search', current.query, current.trigger)\n }, props.searchDelay)\n },\n)\nonBeforeUnmount(() => clearTimeout(searchTimer))\nconst menuOpen = computed(() => !disabled.value && options.value.length > 0)\n\n// The menu is a popup like any other: rendered on top of the page, above\n// the frame (or below it when there is no room), stacked over what opened\n// before and closed by a press outside. The focus stays in the textarea.\nconst rootRef = useTemplateRef<HTMLElement>('root')\nconst menuRef = useTemplateRef<HTMLElement>('menu')\nconst teleportTarget = useTeleport(() => props.teleport)\nconst { style: floatingStyle, placement: menuPlacement } = useFloating(\n () => (menuOpen.value ? rootRef.value : null),\n menuRef,\n { open: menuOpen, placement: 'top-start', offset: 6 },\n)\nconst { next: nextZIndex } = useZIndex()\nconst menuZIndex = ref<number>()\nconst menuWidth = ref<number>()\n// rendered the first time it opens, so the server output stays the same\nconst menuRendered = ref(false)\nconst { theme, sync: syncTheme } = useThemeScope(() => rootRef.value)\nwatch(menuOpen, (value) => {\n if (!value) return\n menuRendered.value = true\n menuZIndex.value = nextZIndex()\n menuWidth.value = rootRef.value?.offsetWidth\n syncTheme()\n})\nconst menuStyle = computed(() => ({\n ...floatingStyle.value,\n zIndex: menuZIndex.value,\n '--dou-chat-input-menu-width': menuWidth.value ? `${menuWidth.value}px` : undefined,\n}))\nuseLayer({\n open: menuOpen,\n elements: () => [rootRef.value, menuRef.value],\n onOutside: () => (token.value = null),\n onEscape: () => (dismissed.value = token.value?.start ?? null),\n})\n// Only a different list moves the highlight back to the first usable option.\nconst firstEnabled = () =>\n Math.max(\n 0,\n options.value.findIndex((option) => !option.disabled),\n )\nwatch(\n () =>\n menuOpen.value\n ? `${token.value?.trigger}${options.value.map((option) => option.value).join('\\u0000')}`\n : '',\n () => (active.value = firstEnabled()),\n)\n\nfunction move(step: 1 | -1) {\n const list = options.value\n for (let offset = 1; offset <= list.length; offset++) {\n const index = (((active.value + step * offset) % list.length) + list.length) % list.length\n if (!list[index]!.disabled) {\n active.value = index\n return\n }\n }\n}\nconst optionId = (index: number) => `${id}-option-${index}`\nwatch(active, async (index) => {\n await nextTick()\n document.getElementById(optionId(index))?.scrollIntoView?.({ block: 'nearest' })\n})\n\nfunction pick(option: ChatInputOption) {\n const current = token.value\n if (!current || option.disabled) return\n const before = model.value.slice(0, current.start)\n const after = model.value.slice(current.end)\n let caret: number\n if (current.trigger === '/') {\n model.value = before + after.replace(/^\\s+/, '')\n caret = before.length\n emit('command', option)\n } else {\n const inserted = `@${option.value} `\n model.value = before + inserted + after.replace(/^\\s+/, '')\n caret = before.length + inserted.length\n emit('mention', option)\n }\n token.value = null\n void nextTick(() => {\n textareaRef.value?.focus()\n textareaRef.value?.setSelectionRange(caret, caret)\n })\n}\n\nfunction onMenuKeydown(event: KeyboardEvent): boolean {\n if (!menuOpen.value) return false\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n move(event.key === 'ArrowDown' ? 1 : -1)\n return true\n }\n if ((event.key === 'Enter' || event.key === 'Tab') && !isComposing(event)) {\n event.preventDefault()\n // the results for what is typed now are on their way: wait for them\n if (stale.value) return true\n pick(options.value[active.value]!)\n return true\n }\n if (event.key === 'Escape') {\n event.preventDefault()\n dismissed.value = token.value?.start ?? null\n return true\n }\n return false\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (onMenuKeydown(event)) return\n if (event.key !== 'Enter' || isComposing(event)) return\n const mod = event.ctrlKey || event.metaKey\n const sends = props.submitOn === 'enter' ? !event.shiftKey && !mod : mod\n if (!sends) return\n event.preventDefault()\n submit()\n}\n\nconst filesOf = (list: DataTransferItemList | undefined) =>\n [...(list ?? [])]\n .filter((item) => item.kind === 'file')\n .map((item) => item.getAsFile())\n .filter((file): file is File => !!file)\n\nfunction onPaste(event: ClipboardEvent) {\n const files = filesOf(event.clipboardData?.items)\n if (!files.length) return\n // keep the file's name from being pasted as text\n event.preventDefault()\n emit('attach', files)\n}\n\nconst dragging = ref(false)\nlet depth = 0\nconst carriesFiles = (event: DragEvent) => !!event.dataTransfer?.types.includes('Files')\n\nfunction onDragenter(event: DragEvent) {\n if (disabled.value || !carriesFiles(event)) return\n depth++\n dragging.value = true\n}\nfunction onDragover(event: DragEvent) {\n if (disabled.value || !carriesFiles(event)) return\n event.preventDefault()\n}\nfunction onDragleave() {\n depth = Math.max(0, depth - 1)\n if (!depth) dragging.value = false\n}\nfunction onDrop(event: DragEvent) {\n depth = 0\n dragging.value = false\n if (disabled.value) return\n const files = [...(event.dataTransfer?.files ?? [])]\n if (!files.length) return\n event.preventDefault()\n emit('attach', files)\n}\n\n// A press anywhere on the frame that is not a control puts the caret in the text.\nfunction onMousedown(event: MouseEvent) {\n const target = event.target as HTMLElement\n if (target === textareaRef.value || target.closest('button, a, input, select, [tabindex]')) return\n event.preventDefault()\n textareaRef.value?.focus()\n}\n\ndefineExpose<ChatInputExpose>({\n get textarea() {\n return textareaRef.value\n },\n focus: () => textareaRef.value?.focus(),\n blur: () => textareaRef.value?.blur(),\n submit,\n})\n</script>\n\n<template>\n <div\n ref=\"root\"\n :class=\"[\n ns.b(),\n ns.m(size),\n ns.is('disabled', disabled),\n ns.is('loading', loading),\n ns.is('dragging', dragging),\n attrs.class,\n ]\"\n :style=\"attrs.style as StyleValue\"\n @mousedown=\"onMousedown\"\n @dragenter=\"onDragenter\"\n @dragover=\"onDragover\"\n @dragleave=\"onDragleave\"\n @drop=\"onDrop\"\n >\n <div v-if=\"slots.header\" :class=\"ns.e('header')\"><slot name=\"header\" /></div>\n <textarea\n ref=\"textarea\"\n v-model=\"model\"\n :aria-label=\"placeholder ?? t('chat.placeholder')\"\n v-bind=\"textareaAttrs\"\n :class=\"ns.e('native')\"\n :rows=\"minRows\"\n :placeholder=\"placeholder ?? t('chat.placeholder')\"\n :disabled=\"disabled\"\n :aria-autocomplete=\"commands.length || mentions.length ? 'list' : undefined\"\n :aria-expanded=\"commands.length || mentions.length ? menuOpen : undefined\"\n :aria-controls=\"menuOpen ? `${id}-menu` : undefined\"\n :aria-activedescendant=\"menuOpen ? optionId(active) : undefined\"\n @keydown=\"onKeydown\"\n @keyup=\"onCaret\"\n @click=\"onCaret\"\n @input=\"onCaret\"\n @compositionstart=\"onCompositionStart\"\n @compositionend=\"onCompositionEnd\"\n @blur=\"token = null\"\n @paste=\"onPaste\"\n />\n <Teleport v-if=\"menuRendered\" :to=\"teleportTarget.to\" :disabled=\"teleportTarget.disabled\">\n <Transition name=\"dou-floating\">\n <ul\n v-if=\"menuOpen\"\n :id=\"`${id}-menu`\"\n ref=\"menu\"\n :class=\"[ns.e('menu'), 'dou-floating', ns.is('stale', stale)]\"\n :aria-busy=\"stale || undefined\"\n :style=\"menuStyle\"\n :data-placement=\"menuPlacement\"\n :data-dou-theme=\"theme\"\n role=\"listbox\"\n @mousedown.prevent\n >\n <li\n v-for=\"(option, index) in options\"\n :id=\"optionId(index)\"\n :key=\"option.value\"\n role=\"option\"\n :class=\"[\n ns.e('option'),\n ns.is('active', index === active),\n ns.is('disabled', !!option.disabled),\n ]\"\n :aria-selected=\"index === active\"\n :aria-disabled=\"option.disabled || undefined\"\n @mouseenter=\"!option.disabled && (active = index)\"\n @click=\"pick(option)\"\n >\n <slot name=\"option\" :option=\"option\" :trigger=\"token!.trigger\">\n <component :is=\"option.icon\" v-if=\"option.icon\" :class=\"ns.e('option-icon')\" />\n <span :class=\"ns.e('option-label')\">\n {{ token?.trigger === '/' ? '/' : '@' }}{{ option.label ?? option.value }}\n </span>\n <span v-if=\"option.description\" :class=\"ns.e('option-description')\">\n {{ option.description }}\n </span>\n </slot>\n </li>\n </ul>\n </Transition>\n </Teleport>\n <div :class=\"ns.e('footer')\">\n <div :class=\"ns.e('actions')\"><slot name=\"actions\" /></div>\n <slot\n name=\"submit\"\n :submit=\"submit\"\n :stop=\"stop\"\n :loading=\"loading\"\n :disabled=\"stopping ? false : !submittable\"\n >\n <DouButton\n v-if=\"stopping\"\n :class=\"ns.e('submit')\"\n :size=\"buttonSize\"\n :aria-label=\"t('chat.stop')\"\n @click=\"stop\"\n >\n <StopIcon />\n </DouButton>\n <DouButton\n v-else\n :class=\"ns.e('submit')\"\n :size=\"buttonSize\"\n :disabled=\"!submittable\"\n :aria-label=\"t('chat.send')\"\n @click=\"submit\"\n >\n <ArrowUpIcon />\n </DouButton>\n </slot>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|