@assistant-ui/vue 0.0.0-stage → 0.0.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.
- package/LICENSE +21 -0
- package/README.md +90 -2
- package/dist/AuiIf.d.ts +27 -0
- package/dist/AuiIf.d.ts.map +1 -0
- package/dist/AuiIf.js +30 -0
- package/dist/AuiIf.js.map +1 -0
- package/dist/AuiProvider.d.ts +41 -0
- package/dist/AuiProvider.d.ts.map +1 -0
- package/dist/AuiProvider.js +61 -0
- package/dist/AuiProvider.js.map +1 -0
- package/dist/context.d.ts +10 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +17 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/primitives/AttachmentByIndexProvider.d.ts +30 -0
- package/dist/primitives/AttachmentByIndexProvider.d.ts.map +1 -0
- package/dist/primitives/AttachmentByIndexProvider.js +63 -0
- package/dist/primitives/AttachmentByIndexProvider.js.map +1 -0
- package/dist/primitives/ChainOfThoughtPrimitiveAccordionTrigger.d.ts +11 -0
- package/dist/primitives/ChainOfThoughtPrimitiveAccordionTrigger.d.ts.map +1 -0
- package/dist/primitives/ChainOfThoughtPrimitiveAccordionTrigger.js +31 -0
- package/dist/primitives/ChainOfThoughtPrimitiveAccordionTrigger.js.map +1 -0
- package/dist/primitives/ChainOfThoughtPrimitiveParts.d.ts +19 -0
- package/dist/primitives/ChainOfThoughtPrimitiveParts.d.ts.map +1 -0
- package/dist/primitives/ChainOfThoughtPrimitiveParts.js +85 -0
- package/dist/primitives/ChainOfThoughtPrimitiveParts.js.map +1 -0
- package/dist/primitives/ComposerPrimitiveCancel.d.ts +12 -0
- package/dist/primitives/ComposerPrimitiveCancel.d.ts.map +1 -0
- package/dist/primitives/ComposerPrimitiveCancel.js +33 -0
- package/dist/primitives/ComposerPrimitiveCancel.js.map +1 -0
- package/dist/primitives/ComposerPrimitiveInput.d.ts +26 -0
- package/dist/primitives/ComposerPrimitiveInput.d.ts.map +1 -0
- package/dist/primitives/ComposerPrimitiveInput.js +57 -0
- package/dist/primitives/ComposerPrimitiveInput.js.map +1 -0
- package/dist/primitives/ComposerPrimitiveSend.d.ts +13 -0
- package/dist/primitives/ComposerPrimitiveSend.d.ts.map +1 -0
- package/dist/primitives/ComposerPrimitiveSend.js +31 -0
- package/dist/primitives/ComposerPrimitiveSend.js.map +1 -0
- package/dist/primitives/MessageByIdProvider.d.ts +23 -0
- package/dist/primitives/MessageByIdProvider.d.ts.map +1 -0
- package/dist/primitives/MessageByIdProvider.js +70 -0
- package/dist/primitives/MessageByIdProvider.js.map +1 -0
- package/dist/primitives/MessagePrimitiveParts.d.ts +50 -0
- package/dist/primitives/MessagePrimitiveParts.d.ts.map +1 -0
- package/dist/primitives/MessagePrimitiveParts.js +93 -0
- package/dist/primitives/MessagePrimitiveParts.js.map +1 -0
- package/dist/primitives/PartByIndexProvider.d.ts +21 -0
- package/dist/primitives/PartByIndexProvider.d.ts.map +1 -0
- package/dist/primitives/PartByIndexProvider.js +50 -0
- package/dist/primitives/PartByIndexProvider.js.map +1 -0
- package/dist/primitives/ThreadListItemPrimitiveRoot.d.ts +7 -0
- package/dist/primitives/ThreadListItemPrimitiveRoot.d.ts.map +1 -0
- package/dist/primitives/ThreadListItemPrimitiveRoot.js +36 -0
- package/dist/primitives/ThreadListItemPrimitiveRoot.js.map +1 -0
- package/dist/primitives/ThreadListItemPrimitiveTrigger.d.ts +14 -0
- package/dist/primitives/ThreadListItemPrimitiveTrigger.d.ts.map +1 -0
- package/dist/primitives/ThreadListItemPrimitiveTrigger.js +58 -0
- package/dist/primitives/ThreadListItemPrimitiveTrigger.js.map +1 -0
- package/dist/primitives/ThreadListPrimitiveRoot.d.ts +7 -0
- package/dist/primitives/ThreadListPrimitiveRoot.d.ts.map +1 -0
- package/dist/primitives/ThreadListPrimitiveRoot.js +16 -0
- package/dist/primitives/ThreadListPrimitiveRoot.js.map +1 -0
- package/dist/primitives/ThreadPrimitiveMessages.d.ts +23 -0
- package/dist/primitives/ThreadPrimitiveMessages.d.ts.map +1 -0
- package/dist/primitives/ThreadPrimitiveMessages.js +37 -0
- package/dist/primitives/ThreadPrimitiveMessages.js.map +1 -0
- package/dist/primitives/ThreadPrimitiveScrollToBottom.d.ts +25 -0
- package/dist/primitives/ThreadPrimitiveScrollToBottom.d.ts.map +1 -0
- package/dist/primitives/ThreadPrimitiveScrollToBottom.js +43 -0
- package/dist/primitives/ThreadPrimitiveScrollToBottom.js.map +1 -0
- package/dist/primitives/ThreadPrimitiveViewport.d.ts +57 -0
- package/dist/primitives/ThreadPrimitiveViewport.d.ts.map +1 -0
- package/dist/primitives/ThreadPrimitiveViewport.js +174 -0
- package/dist/primitives/ThreadPrimitiveViewport.js.map +1 -0
- package/dist/primitives/ThreadPrimitiveViewportFooter.d.ts +13 -0
- package/dist/primitives/ThreadPrimitiveViewportFooter.d.ts.map +1 -0
- package/dist/primitives/ThreadPrimitiveViewportFooter.js +46 -0
- package/dist/primitives/ThreadPrimitiveViewportFooter.js.map +1 -0
- package/dist/primitives/actionBar.d.ts +41 -0
- package/dist/primitives/actionBar.d.ts.map +1 -0
- package/dist/primitives/actionBar.js +110 -0
- package/dist/primitives/actionBar.js.map +1 -0
- package/dist/primitives/attachment.d.ts +27 -0
- package/dist/primitives/attachment.d.ts.map +1 -0
- package/dist/primitives/attachment.js +63 -0
- package/dist/primitives/attachment.js.map +1 -0
- package/dist/primitives/attrDisabled.d.ts +2 -0
- package/dist/primitives/attrDisabled.d.ts.map +1 -0
- package/dist/primitives/attrDisabled.js +6 -0
- package/dist/primitives/attrDisabled.js.map +1 -0
- package/dist/primitives/branchPicker.d.ts +18 -0
- package/dist/primitives/branchPicker.d.ts.map +1 -0
- package/dist/primitives/branchPicker.js +48 -0
- package/dist/primitives/branchPicker.js.map +1 -0
- package/dist/primitives/composerAttachments.d.ts +57 -0
- package/dist/primitives/composerAttachments.d.ts.map +1 -0
- package/dist/primitives/composerAttachments.js +132 -0
- package/dist/primitives/composerAttachments.js.map +1 -0
- package/dist/primitives/error.d.ts +15 -0
- package/dist/primitives/error.d.ts.map +1 -0
- package/dist/primitives/error.js +29 -0
- package/dist/primitives/error.js.map +1 -0
- package/dist/primitives/lastValidCache.d.ts +6 -0
- package/dist/primitives/lastValidCache.d.ts.map +1 -0
- package/dist/primitives/lastValidCache.js +9 -0
- package/dist/primitives/lastValidCache.js.map +1 -0
- package/dist/primitives/message.d.ts +12 -0
- package/dist/primitives/message.d.ts.map +1 -0
- package/dist/primitives/message.js +44 -0
- package/dist/primitives/message.js.map +1 -0
- package/dist/primitives/messageAttachments.d.ts +12 -0
- package/dist/primitives/messageAttachments.d.ts.map +1 -0
- package/dist/primitives/messageAttachments.js +27 -0
- package/dist/primitives/messageAttachments.js.map +1 -0
- package/dist/primitives/stableKeys.d.ts +5 -0
- package/dist/primitives/stableKeys.d.ts.map +1 -0
- package/dist/primitives/stableKeys.js +14 -0
- package/dist/primitives/stableKeys.js.map +1 -0
- package/dist/primitives/suggestions.d.ts +66 -0
- package/dist/primitives/suggestions.d.ts.map +1 -0
- package/dist/primitives/suggestions.js +137 -0
- package/dist/primitives/suggestions.js.map +1 -0
- package/dist/primitives/thread.d.ts +11 -0
- package/dist/primitives/thread.d.ts.map +1 -0
- package/dist/primitives/thread.js +37 -0
- package/dist/primitives/thread.js.map +1 -0
- package/dist/primitives/threadList.d.ts +82 -0
- package/dist/primitives/threadList.d.ts.map +1 -0
- package/dist/primitives/threadList.js +128 -0
- package/dist/primitives/threadList.js.map +1 -0
- package/dist/primitives/threadListFocusGroup.d.ts +14 -0
- package/dist/primitives/threadListFocusGroup.d.ts.map +1 -0
- package/dist/primitives/threadListFocusGroup.js +32 -0
- package/dist/primitives/threadListFocusGroup.js.map +1 -0
- package/dist/primitives/threadListStructural.d.ts +29 -0
- package/dist/primitives/threadListStructural.d.ts.map +1 -0
- package/dist/primitives/threadListStructural.js +55 -0
- package/dist/primitives/threadListStructural.js.map +1 -0
- package/dist/primitives/useComposerSendState.d.ts +6 -0
- package/dist/primitives/useComposerSendState.d.ts.map +1 -0
- package/dist/primitives/useComposerSendState.js +15 -0
- package/dist/primitives/useComposerSendState.js.map +1 -0
- package/dist/primitives/viewportContext.d.ts +12 -0
- package/dist/primitives/viewportContext.d.ts.map +1 -0
- package/dist/primitives/viewportContext.js +6 -0
- package/dist/primitives/viewportContext.js.map +1 -0
- package/dist/useAui.d.ts +15 -0
- package/dist/useAui.d.ts.map +1 -0
- package/dist/useAui.js +21 -0
- package/dist/useAui.js.map +1 -0
- package/dist/useAuiEvent.d.ts +17 -0
- package/dist/useAuiEvent.d.ts.map +1 -0
- package/dist/useAuiEvent.js +52 -0
- package/dist/useAuiEvent.js.map +1 -0
- package/dist/useAuiState.d.ts +23 -0
- package/dist/useAuiState.d.ts.map +1 -0
- package/dist/useAuiState.js +42 -0
- package/dist/useAuiState.js.map +1 -0
- package/dist/useScrollLock.d.ts +3 -0
- package/dist/useScrollLock.d.ts.map +1 -0
- package/dist/useScrollLock.js +53 -0
- package/dist/useScrollLock.js.map +1 -0
- package/package.json +64 -3
- package/src/AuiIf.ts +34 -0
- package/src/AuiProvider.ts +90 -0
- package/src/__tests__/AuiIf.test.ts +54 -0
- package/src/__tests__/AuiProvider.test.ts +266 -0
- package/src/__tests__/byindex-shrink-race.test.ts +411 -0
- package/src/__tests__/dist-graph.test.ts +49 -0
- package/src/__tests__/fixtures.ts +51 -0
- package/src/__tests__/primitives-actionbar.test.ts +469 -0
- package/src/__tests__/primitives-attachment.test.ts +493 -0
- package/src/__tests__/primitives-content.test.ts +749 -0
- package/src/__tests__/primitives-keyed-items.test.ts +270 -0
- package/src/__tests__/primitives-keyed-messages.test.ts +264 -0
- package/src/__tests__/primitives-structural.test.ts +573 -0
- package/src/__tests__/primitives-suggestions.test.ts +374 -0
- package/src/__tests__/primitives-threadlist.test.ts +443 -0
- package/src/__tests__/primitives-tool-ui.test.ts +579 -0
- package/src/__tests__/primitives.test.ts +361 -0
- package/src/__tests__/useAuiEvent.test.ts +159 -0
- package/src/__tests__/useAuiState.test.ts +124 -0
- package/src/context.ts +31 -0
- package/src/index.ts +87 -0
- package/src/primitives/AttachmentByIndexProvider.ts +88 -0
- package/src/primitives/ChainOfThoughtPrimitiveAccordionTrigger.test.ts +105 -0
- package/src/primitives/ChainOfThoughtPrimitiveAccordionTrigger.ts +38 -0
- package/src/primitives/ChainOfThoughtPrimitiveParts.test.ts +254 -0
- package/src/primitives/ChainOfThoughtPrimitiveParts.ts +112 -0
- package/src/primitives/ComposerPrimitiveCancel.ts +41 -0
- package/src/primitives/ComposerPrimitiveInput.ts +64 -0
- package/src/primitives/ComposerPrimitiveSend.ts +39 -0
- package/src/primitives/MessageByIdProvider.ts +89 -0
- package/src/primitives/MessagePrimitiveParts.tool-interaction.test.ts +88 -0
- package/src/primitives/MessagePrimitiveParts.ts +166 -0
- package/src/primitives/PartByIndexProvider.ts +62 -0
- package/src/primitives/ThreadListItemPrimitiveRoot.ts +57 -0
- package/src/primitives/ThreadListItemPrimitiveTrigger.ts +74 -0
- package/src/primitives/ThreadListKeyboardNav.test.ts +298 -0
- package/src/primitives/ThreadListPrimitiveRoot.ts +18 -0
- package/src/primitives/ThreadPrimitiveMessages.ts +40 -0
- package/src/primitives/ThreadPrimitiveScrollToBottom.ts +65 -0
- package/src/primitives/ThreadPrimitiveViewport.ts +233 -0
- package/src/primitives/ThreadPrimitiveViewportFooter.test.ts +305 -0
- package/src/primitives/ThreadPrimitiveViewportFooter.ts +60 -0
- package/src/primitives/actionBar.ts +159 -0
- package/src/primitives/attachment.ts +76 -0
- package/src/primitives/attrDisabled.ts +6 -0
- package/src/primitives/branchPicker.ts +77 -0
- package/src/primitives/composerAttachments.ts +181 -0
- package/src/primitives/error.ts +36 -0
- package/src/primitives/lastValidCache.ts +12 -0
- package/src/primitives/message.ts +54 -0
- package/src/primitives/messageAttachments.ts +32 -0
- package/src/primitives/stableKeys.test.ts +19 -0
- package/src/primitives/stableKeys.ts +21 -0
- package/src/primitives/suggestions.ts +179 -0
- package/src/primitives/thread.ts +46 -0
- package/src/primitives/threadList.ts +163 -0
- package/src/primitives/threadListFocusGroup.ts +56 -0
- package/src/primitives/threadListStructural.ts +86 -0
- package/src/primitives/useComposerSendState.ts +13 -0
- package/src/primitives/viewportContext.ts +16 -0
- package/src/useAui.ts +18 -0
- package/src/useAuiEvent.ts +64 -0
- package/src/useAuiState.ts +55 -0
- package/src/useScrollLock.test.ts +207 -0
- package/src/useScrollLock.ts +79 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { AuiProvider } from "../AuiProvider.js";
|
|
2
|
+
import { useAui } from "../useAui.js";
|
|
3
|
+
import { createLastValidCache as createLastValidCache$1, createStaleReporter } from "./lastValidCache.js";
|
|
4
|
+
import { computed, defineComponent, h, onScopeDispose } from "vue";
|
|
5
|
+
import { AuiConfig, Derived } from "@assistant-ui/store/client";
|
|
6
|
+
//#region src/primitives/PartByIndexProvider.ts
|
|
7
|
+
/**
|
|
8
|
+
* Scopes the subtree to the message part at `index`: descendants read the
|
|
9
|
+
* part through `s.part`.
|
|
10
|
+
*/
|
|
11
|
+
const PartByIndexProvider = defineComponent({
|
|
12
|
+
name: "PartByIndexProvider",
|
|
13
|
+
props: { index: {
|
|
14
|
+
type: Number,
|
|
15
|
+
required: true
|
|
16
|
+
} },
|
|
17
|
+
slots: Object,
|
|
18
|
+
setup(props, { slots }) {
|
|
19
|
+
const aui = useAui();
|
|
20
|
+
let disposed = false;
|
|
21
|
+
onScopeDispose(() => {
|
|
22
|
+
disposed = true;
|
|
23
|
+
});
|
|
24
|
+
const config = computed(() => {
|
|
25
|
+
const index = props.index;
|
|
26
|
+
const cache = createLastValidCache$1(createStaleReporter({
|
|
27
|
+
name: "PartByIndexProvider",
|
|
28
|
+
index,
|
|
29
|
+
isCurrent: () => !disposed && index === props.index,
|
|
30
|
+
isValid: () => index < aui.message.getState().parts.length
|
|
31
|
+
}));
|
|
32
|
+
return AuiConfig({ part: Derived({
|
|
33
|
+
source: "message",
|
|
34
|
+
query: {
|
|
35
|
+
type: "index",
|
|
36
|
+
index
|
|
37
|
+
},
|
|
38
|
+
get: (aui) => cache.resolve(index < aui.message.getState().parts.length, () => aui.message.part({ index }))
|
|
39
|
+
}) });
|
|
40
|
+
});
|
|
41
|
+
return () => h(AuiProvider, {
|
|
42
|
+
config: config.value,
|
|
43
|
+
extends: aui
|
|
44
|
+
}, { default: () => slots.default?.() });
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
//#endregion
|
|
48
|
+
export { PartByIndexProvider };
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=PartByIndexProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PartByIndexProvider.js","names":["createLastValidCache"],"sources":["../../src/primitives/PartByIndexProvider.ts"],"sourcesContent":["import {\n computed,\n defineComponent,\n h,\n onScopeDispose,\n type SlotsType,\n type VNodeChild,\n} from \"vue\";\nimport { AuiConfig, Derived } from \"@assistant-ui/store/client\";\nimport type { PartMethods } from \"@assistant-ui/core/store\";\nimport { AuiProvider } from \"../AuiProvider\";\nimport { useAui } from \"../useAui\";\nimport { createLastValidCache, createStaleReporter } from \"./lastValidCache\";\n\n/**\n * Scopes the subtree to the message part at `index`: descendants read the\n * part through `s.part`.\n */\nexport const PartByIndexProvider = defineComponent({\n name: \"PartByIndexProvider\",\n props: {\n index: {\n type: Number,\n required: true,\n },\n },\n slots: Object as SlotsType<{ default?: () => VNodeChild[] }>,\n setup(props, { slots }) {\n const aui = useAui();\n let disposed = false;\n onScopeDispose(() => {\n disposed = true;\n });\n const config = computed(() => {\n const index = props.index;\n const cache = createLastValidCache<PartMethods>(\n createStaleReporter({\n name: \"PartByIndexProvider\",\n index,\n isCurrent: () => !disposed && index === props.index,\n isValid: () => index < aui.message.getState().parts.length,\n }),\n );\n return AuiConfig({\n part: Derived({\n source: \"message\",\n query: { type: \"index\", index },\n get: (aui) =>\n cache.resolve(index < aui.message.getState().parts.length, () =>\n aui.message.part({ index }),\n ),\n }),\n });\n });\n return () =>\n h(\n AuiProvider,\n { config: config.value, extends: aui },\n { default: () => slots.default?.() },\n );\n },\n});\n"],"mappings":";;;;;;;;;;AAkBA,MAAa,sBAAsB,gBAAgB;CACjD,MAAM;CACN,OAAO,EACL,OAAO;EACL,MAAM;EACN,UAAU;CACZ,EACF;CACA,OAAO;CACP,MAAM,OAAO,EAAE,SAAS;EACtB,MAAM,MAAM,OAAO;EACnB,IAAI,WAAW;EACf,qBAAqB;GACnB,WAAW;EACb,CAAC;EACD,MAAM,SAAS,eAAe;GAC5B,MAAM,QAAQ,MAAM;GACpB,MAAM,QAAQA,uBACZ,oBAAoB;IAClB,MAAM;IACN;IACA,iBAAiB,CAAC,YAAY,UAAU,MAAM;IAC9C,eAAe,QAAQ,IAAI,QAAQ,SAAS,CAAC,CAAC,MAAM;GACtD,CAAC,CACH;GACA,OAAO,UAAU,EACf,MAAM,QAAQ;IACZ,QAAQ;IACR,OAAO;KAAE,MAAM;KAAS;IAAM;IAC9B,MAAM,QACJ,MAAM,QAAQ,QAAQ,IAAI,QAAQ,SAAS,CAAC,CAAC,MAAM,cACjD,IAAI,QAAQ,KAAK,EAAE,MAAM,CAAC,CAC5B;GACJ,CAAC,EACH,CAAC;EACH,CAAC;EACD,aACE,EACE,aACA;GAAE,QAAQ,OAAO;GAAO,SAAS;EAAI,GACrC,EAAE,eAAe,MAAM,UAAU,EAAE,CACrC;CACJ;AACF,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type SlotsType, type VNodeChild } from "vue";
|
|
2
|
+
export declare const ThreadListItemPrimitiveRoot: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
3
|
+
[key: string]: any;
|
|
4
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, SlotsType<{
|
|
5
|
+
default?: () => VNodeChild[];
|
|
6
|
+
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
7
|
+
//# sourceMappingURL=ThreadListItemPrimitiveRoot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadListItemPrimitiveRoot.d.ts","sourceRoot":"","sources":["../../src/primitives/ThreadListItemPrimitiveRoot.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,KAAK,CAAC;AAOb,eAAO,MAAM,2BAA2B;;;cAGC,MAAM,UAAU,EAAE;yEAwCzD,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useAuiState } from "../useAuiState.js";
|
|
2
|
+
import { provideThreadListItemFocus, useThreadListCollection } from "./threadListFocusGroup.js";
|
|
3
|
+
import { defineComponent, h, mergeProps } from "vue";
|
|
4
|
+
//#region src/primitives/ThreadListItemPrimitiveRoot.ts
|
|
5
|
+
const ThreadListItemPrimitiveRoot = defineComponent({
|
|
6
|
+
name: "ThreadListItemPrimitiveRoot",
|
|
7
|
+
inheritAttrs: false,
|
|
8
|
+
slots: Object,
|
|
9
|
+
setup(_, { attrs, slots }) {
|
|
10
|
+
const active = useAuiState((s) => s.threads.mainThreadId === s.threadListItem.id);
|
|
11
|
+
const focus = provideThreadListItemFocus();
|
|
12
|
+
const collection = useThreadListCollection();
|
|
13
|
+
const onKeydown = (event) => {
|
|
14
|
+
if (event.defaultPrevented) return;
|
|
15
|
+
const trigger = focus.trigger.value;
|
|
16
|
+
if (!trigger || event.target !== trigger || event.key !== "ArrowDown" && event.key !== "ArrowUp") return;
|
|
17
|
+
const triggers = collection?.getTriggers();
|
|
18
|
+
if (!triggers) return;
|
|
19
|
+
const next = triggers[triggers.indexOf(trigger) + (event.key === "ArrowDown" ? 1 : -1)];
|
|
20
|
+
if (!next) return;
|
|
21
|
+
next.focus();
|
|
22
|
+
event.preventDefault();
|
|
23
|
+
};
|
|
24
|
+
return () => h("div", mergeProps(attrs, {
|
|
25
|
+
...active.value && {
|
|
26
|
+
"data-active": "true",
|
|
27
|
+
"aria-current": "true"
|
|
28
|
+
},
|
|
29
|
+
onKeydown
|
|
30
|
+
}), slots.default?.());
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
//#endregion
|
|
34
|
+
export { ThreadListItemPrimitiveRoot };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=ThreadListItemPrimitiveRoot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadListItemPrimitiveRoot.js","names":[],"sources":["../../src/primitives/ThreadListItemPrimitiveRoot.ts"],"sourcesContent":["import {\n defineComponent,\n h,\n mergeProps,\n type SlotsType,\n type VNodeChild,\n} from \"vue\";\nimport { useAuiState } from \"../useAuiState\";\nimport {\n provideThreadListItemFocus,\n useThreadListCollection,\n} from \"./threadListFocusGroup\";\n\nexport const ThreadListItemPrimitiveRoot = defineComponent({\n name: \"ThreadListItemPrimitiveRoot\",\n inheritAttrs: false,\n slots: Object as SlotsType<{ default?: () => VNodeChild[] }>,\n setup(_, { attrs, slots }) {\n const active = useAuiState(\n (s) => s.threads.mainThreadId === s.threadListItem.id,\n );\n const focus = provideThreadListItemFocus();\n const collection = useThreadListCollection();\n const onKeydown = (event: KeyboardEvent) => {\n if (event.defaultPrevented) return;\n const trigger = focus.trigger.value;\n if (\n !trigger ||\n event.target !== trigger ||\n (event.key !== \"ArrowDown\" && event.key !== \"ArrowUp\")\n ) {\n return;\n }\n const triggers = collection?.getTriggers();\n if (!triggers) return;\n const next =\n triggers[\n triggers.indexOf(trigger) + (event.key === \"ArrowDown\" ? 1 : -1)\n ];\n if (!next) return;\n next.focus();\n event.preventDefault();\n };\n return () =>\n h(\n \"div\",\n mergeProps(attrs, {\n ...(active.value && {\n \"data-active\": \"true\",\n \"aria-current\": \"true\",\n }),\n onKeydown,\n }),\n slots.default?.(),\n );\n },\n});\n"],"mappings":";;;;AAaA,MAAa,8BAA8B,gBAAgB;CACzD,MAAM;CACN,cAAc;CACd,OAAO;CACP,MAAM,GAAG,EAAE,OAAO,SAAS;EACzB,MAAM,SAAS,aACZ,MAAM,EAAE,QAAQ,iBAAiB,EAAE,eAAe,EACrD;EACA,MAAM,QAAQ,2BAA2B;EACzC,MAAM,aAAa,wBAAwB;EAC3C,MAAM,aAAa,UAAyB;GAC1C,IAAI,MAAM,kBAAkB;GAC5B,MAAM,UAAU,MAAM,QAAQ;GAC9B,IACE,CAAC,WACD,MAAM,WAAW,WAChB,MAAM,QAAQ,eAAe,MAAM,QAAQ,WAE5C;GAEF,MAAM,WAAW,YAAY,YAAY;GACzC,IAAI,CAAC,UAAU;GACf,MAAM,OACJ,SACE,SAAS,QAAQ,OAAO,KAAK,MAAM,QAAQ,cAAc,IAAI;GAEjE,IAAI,CAAC,MAAM;GACX,KAAK,MAAM;GACX,MAAM,eAAe;EACvB;EACA,aACE,EACE,OACA,WAAW,OAAO;GAChB,GAAI,OAAO,SAAS;IAClB,eAAe;IACf,gBAAgB;GAClB;GACA;EACF,CAAC,GACD,MAAM,UAAU,CAClB;CACJ;AACF,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type SlotsType, type VNodeChild } from "vue";
|
|
2
|
+
/**
|
|
3
|
+
* A button that switches to the current thread-list item's thread. Carries
|
|
4
|
+
* `data-active` and `aria-current` while that thread is the main one, for
|
|
5
|
+
* standalone use; when nested under `ThreadListItemPrimitiveRoot` the root
|
|
6
|
+
* stamps them too, diverging from React's root-only pattern to keep existing
|
|
7
|
+
* standalone consumers styled.
|
|
8
|
+
*/
|
|
9
|
+
export declare const ThreadListItemPrimitiveTrigger: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, SlotsType<{
|
|
12
|
+
default?: () => VNodeChild[];
|
|
13
|
+
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
14
|
+
//# sourceMappingURL=ThreadListItemPrimitiveTrigger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadListItemPrimitiveTrigger.d.ts","sourceRoot":"","sources":["../../src/primitives/ThreadListItemPrimitiveTrigger.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,KAAK,CAAC;AASb;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B;;;cAGF,MAAM,UAAU,EAAE;yEA8CzD,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useAuiState } from "../useAuiState.js";
|
|
2
|
+
import { useAui } from "../useAui.js";
|
|
3
|
+
import { isAttrDisabled } from "./attrDisabled.js";
|
|
4
|
+
import { useThreadListCollection, useThreadListItemFocus } from "./threadListFocusGroup.js";
|
|
5
|
+
import { defineComponent, h, mergeProps, onScopeDispose } from "vue";
|
|
6
|
+
//#region src/primitives/ThreadListItemPrimitiveTrigger.ts
|
|
7
|
+
/**
|
|
8
|
+
* A button that switches to the current thread-list item's thread. Carries
|
|
9
|
+
* `data-active` and `aria-current` while that thread is the main one, for
|
|
10
|
+
* standalone use; when nested under `ThreadListItemPrimitiveRoot` the root
|
|
11
|
+
* stamps them too, diverging from React's root-only pattern to keep existing
|
|
12
|
+
* standalone consumers styled.
|
|
13
|
+
*/
|
|
14
|
+
const ThreadListItemPrimitiveTrigger = defineComponent({
|
|
15
|
+
name: "ThreadListItemPrimitiveTrigger",
|
|
16
|
+
inheritAttrs: false,
|
|
17
|
+
slots: Object,
|
|
18
|
+
setup(_, { attrs, slots }) {
|
|
19
|
+
const aui = useAui();
|
|
20
|
+
const active = useAuiState((s) => s.threads.mainThreadId === s.threadListItem.id);
|
|
21
|
+
const collection = useThreadListCollection();
|
|
22
|
+
const focus = useThreadListItemFocus();
|
|
23
|
+
const key = Symbol();
|
|
24
|
+
let trigger = null;
|
|
25
|
+
let unregister;
|
|
26
|
+
const setTrigger = (element) => {
|
|
27
|
+
const next = element instanceof HTMLButtonElement ? element : null;
|
|
28
|
+
const previous = trigger;
|
|
29
|
+
if (previous === next) return;
|
|
30
|
+
unregister?.();
|
|
31
|
+
if (focus && (next || focus.trigger.value === previous)) focus.trigger.value = next;
|
|
32
|
+
trigger = next;
|
|
33
|
+
unregister = next ? collection?.registerTrigger(key, next) : void 0;
|
|
34
|
+
};
|
|
35
|
+
onScopeDispose(() => {
|
|
36
|
+
unregister?.();
|
|
37
|
+
if (focus?.trigger.value === trigger) focus.trigger.value = null;
|
|
38
|
+
});
|
|
39
|
+
const onClick = (event) => {
|
|
40
|
+
if (event.defaultPrevented || isAttrDisabled(attrs)) return;
|
|
41
|
+
aui.threadListItem.switchTo();
|
|
42
|
+
};
|
|
43
|
+
return () => h("button", mergeProps(attrs, {
|
|
44
|
+
ref: setTrigger,
|
|
45
|
+
type: "button",
|
|
46
|
+
disabled: isAttrDisabled(attrs),
|
|
47
|
+
...active.value && {
|
|
48
|
+
"data-active": "true",
|
|
49
|
+
"aria-current": "true"
|
|
50
|
+
},
|
|
51
|
+
onClick
|
|
52
|
+
}), slots.default?.());
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
//#endregion
|
|
56
|
+
export { ThreadListItemPrimitiveTrigger };
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=ThreadListItemPrimitiveTrigger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadListItemPrimitiveTrigger.js","names":[],"sources":["../../src/primitives/ThreadListItemPrimitiveTrigger.ts"],"sourcesContent":["import {\n defineComponent,\n h,\n mergeProps,\n onScopeDispose,\n type ComponentPublicInstance,\n type SlotsType,\n type VNodeChild,\n} from \"vue\";\nimport { isAttrDisabled } from \"./attrDisabled\";\nimport { useAui } from \"../useAui\";\nimport { useAuiState } from \"../useAuiState\";\nimport {\n useThreadListCollection,\n useThreadListItemFocus,\n} from \"./threadListFocusGroup\";\n\n/**\n * A button that switches to the current thread-list item's thread. Carries\n * `data-active` and `aria-current` while that thread is the main one, for\n * standalone use; when nested under `ThreadListItemPrimitiveRoot` the root\n * stamps them too, diverging from React's root-only pattern to keep existing\n * standalone consumers styled.\n */\nexport const ThreadListItemPrimitiveTrigger = defineComponent({\n name: \"ThreadListItemPrimitiveTrigger\",\n inheritAttrs: false,\n slots: Object as SlotsType<{ default?: () => VNodeChild[] }>,\n setup(_, { attrs, slots }) {\n const aui = useAui();\n const active = useAuiState(\n (s) => s.threads.mainThreadId === s.threadListItem.id,\n );\n const collection = useThreadListCollection();\n const focus = useThreadListItemFocus();\n const key = Symbol();\n let trigger: HTMLButtonElement | null = null;\n let unregister: (() => void) | undefined;\n const setTrigger = (element: Element | ComponentPublicInstance | null) => {\n const next = element instanceof HTMLButtonElement ? element : null;\n const previous = trigger;\n if (previous === next) return;\n unregister?.();\n if (focus && (next || focus.trigger.value === previous)) {\n focus.trigger.value = next;\n }\n trigger = next;\n unregister = next ? collection?.registerTrigger(key, next) : undefined;\n };\n onScopeDispose(() => {\n unregister?.();\n if (focus?.trigger.value === trigger) focus.trigger.value = null;\n });\n const onClick = (event: MouseEvent) => {\n if (event.defaultPrevented || isAttrDisabled(attrs)) return;\n aui.threadListItem.switchTo();\n };\n return () =>\n h(\n \"button\",\n mergeProps(attrs, {\n ref: setTrigger,\n type: \"button\",\n disabled: isAttrDisabled(attrs),\n ...(active.value && {\n \"data-active\": \"true\",\n \"aria-current\": \"true\",\n }),\n onClick,\n }),\n slots.default?.(),\n );\n },\n});\n"],"mappings":";;;;;;;;;;;;;AAwBA,MAAa,iCAAiC,gBAAgB;CAC5D,MAAM;CACN,cAAc;CACd,OAAO;CACP,MAAM,GAAG,EAAE,OAAO,SAAS;EACzB,MAAM,MAAM,OAAO;EACnB,MAAM,SAAS,aACZ,MAAM,EAAE,QAAQ,iBAAiB,EAAE,eAAe,EACrD;EACA,MAAM,aAAa,wBAAwB;EAC3C,MAAM,QAAQ,uBAAuB;EACrC,MAAM,MAAM,OAAO;EACnB,IAAI,UAAoC;EACxC,IAAI;EACJ,MAAM,cAAc,YAAsD;GACxE,MAAM,OAAO,mBAAmB,oBAAoB,UAAU;GAC9D,MAAM,WAAW;GACjB,IAAI,aAAa,MAAM;GACvB,aAAa;GACb,IAAI,UAAU,QAAQ,MAAM,QAAQ,UAAU,WAC5C,MAAM,QAAQ,QAAQ;GAExB,UAAU;GACV,aAAa,OAAO,YAAY,gBAAgB,KAAK,IAAI,IAAI,KAAA;EAC/D;EACA,qBAAqB;GACnB,aAAa;GACb,IAAI,OAAO,QAAQ,UAAU,SAAS,MAAM,QAAQ,QAAQ;EAC9D,CAAC;EACD,MAAM,WAAW,UAAsB;GACrC,IAAI,MAAM,oBAAoB,eAAe,KAAK,GAAG;GACrD,IAAI,eAAe,SAAS;EAC9B;EACA,aACE,EACE,UACA,WAAW,OAAO;GAChB,KAAK;GACL,MAAM;GACN,UAAU,eAAe,KAAK;GAC9B,GAAI,OAAO,SAAS;IAClB,eAAe;IACf,gBAAgB;GAClB;GACA;EACF,CAAC,GACD,MAAM,UAAU,CAClB;CACJ;AACF,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type SlotsType, type VNodeChild } from "vue";
|
|
2
|
+
export declare const ThreadListPrimitiveRoot: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
3
|
+
[key: string]: any;
|
|
4
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, SlotsType<{
|
|
5
|
+
default?: () => VNodeChild[];
|
|
6
|
+
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
7
|
+
//# sourceMappingURL=ThreadListPrimitiveRoot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadListPrimitiveRoot.d.ts","sourceRoot":"","sources":["../../src/primitives/ThreadListPrimitiveRoot.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,KAAK,CAAC;AAGb,eAAO,MAAM,uBAAuB;;;cAGK,MAAM,UAAU,EAAE;yEAKzD,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { provideThreadListCollection } from "./threadListFocusGroup.js";
|
|
2
|
+
import { defineComponent, h, mergeProps } from "vue";
|
|
3
|
+
//#region src/primitives/ThreadListPrimitiveRoot.ts
|
|
4
|
+
const ThreadListPrimitiveRoot = defineComponent({
|
|
5
|
+
name: "ThreadListPrimitiveRoot",
|
|
6
|
+
inheritAttrs: false,
|
|
7
|
+
slots: Object,
|
|
8
|
+
setup(_, { attrs, slots }) {
|
|
9
|
+
provideThreadListCollection();
|
|
10
|
+
return () => h("div", mergeProps(attrs), slots.default?.());
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
//#endregion
|
|
14
|
+
export { ThreadListPrimitiveRoot };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=ThreadListPrimitiveRoot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadListPrimitiveRoot.js","names":[],"sources":["../../src/primitives/ThreadListPrimitiveRoot.ts"],"sourcesContent":["import {\n defineComponent,\n h,\n mergeProps,\n type SlotsType,\n type VNodeChild,\n} from \"vue\";\nimport { provideThreadListCollection } from \"./threadListFocusGroup\";\n\nexport const ThreadListPrimitiveRoot = defineComponent({\n name: \"ThreadListPrimitiveRoot\",\n inheritAttrs: false,\n slots: Object as SlotsType<{ default?: () => VNodeChild[] }>,\n setup(_, { attrs, slots }) {\n provideThreadListCollection();\n return () => h(\"div\", mergeProps(attrs), slots.default?.());\n },\n});\n"],"mappings":";;;AASA,MAAa,0BAA0B,gBAAgB;CACrD,MAAM;CACN,cAAc;CACd,OAAO;CACP,MAAM,GAAG,EAAE,OAAO,SAAS;EACzB,4BAA4B;EAC5B,aAAa,EAAE,OAAO,WAAW,KAAK,GAAG,MAAM,UAAU,CAAC;CAC5D;AACF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type SlotsType, type VNodeChild } from "vue";
|
|
2
|
+
/**
|
|
3
|
+
* Renders the default slot once per message in the current thread, each
|
|
4
|
+
* instance scoped to its message through {@link MessageByIdProvider} and
|
|
5
|
+
* keyed by the message id: an edit or reload that replaces the occupant of a
|
|
6
|
+
* slot remounts that row, so `<TransitionGroup>` and per-row component state
|
|
7
|
+
* follow message identity. The empty optimistic placeholder that precedes a
|
|
8
|
+
* response is its own identity, so the arrival of the real assistant message
|
|
9
|
+
* remounts that one row (a leave/enter pair under `<TransitionGroup>`).
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```html
|
|
13
|
+
* <ThreadPrimitiveMessages>
|
|
14
|
+
* <ChatMessage />
|
|
15
|
+
* </ThreadPrimitiveMessages>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare const ThreadPrimitiveMessages: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
19
|
+
[key: string]: any;
|
|
20
|
+
}>[], {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, SlotsType<{
|
|
21
|
+
default?: () => VNodeChild[];
|
|
22
|
+
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
23
|
+
//# sourceMappingURL=ThreadPrimitiveMessages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadPrimitiveMessages.d.ts","sourceRoot":"","sources":["../../src/primitives/ThreadPrimitiveMessages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,KAAK,CAAC;AAM1E;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,uBAAuB;;;cAEK,MAAM,UAAU,EAAE;yEAezD,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useAuiState } from "../useAuiState.js";
|
|
2
|
+
import { MessageByIdProvider } from "./MessageByIdProvider.js";
|
|
3
|
+
import { useStableKeys } from "./stableKeys.js";
|
|
4
|
+
import { defineComponent, h } from "vue";
|
|
5
|
+
//#region src/primitives/ThreadPrimitiveMessages.ts
|
|
6
|
+
/**
|
|
7
|
+
* Renders the default slot once per message in the current thread, each
|
|
8
|
+
* instance scoped to its message through {@link MessageByIdProvider} and
|
|
9
|
+
* keyed by the message id: an edit or reload that replaces the occupant of a
|
|
10
|
+
* slot remounts that row, so `<TransitionGroup>` and per-row component state
|
|
11
|
+
* follow message identity. The empty optimistic placeholder that precedes a
|
|
12
|
+
* response is its own identity, so the arrival of the real assistant message
|
|
13
|
+
* remounts that one row (a leave/enter pair under `<TransitionGroup>`).
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```html
|
|
17
|
+
* <ThreadPrimitiveMessages>
|
|
18
|
+
* <ChatMessage />
|
|
19
|
+
* </ThreadPrimitiveMessages>
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
const ThreadPrimitiveMessages = defineComponent({
|
|
23
|
+
name: "ThreadPrimitiveMessages",
|
|
24
|
+
slots: Object,
|
|
25
|
+
setup(_, { slots }) {
|
|
26
|
+
const messages = useAuiState((s) => s.thread.messages);
|
|
27
|
+
const ids = useStableKeys(() => messages.value.map((message) => message.id));
|
|
28
|
+
return () => ids.value.map((id) => h(MessageByIdProvider, {
|
|
29
|
+
id,
|
|
30
|
+
key: id
|
|
31
|
+
}, { default: () => slots.default?.() }));
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
//#endregion
|
|
35
|
+
export { ThreadPrimitiveMessages };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=ThreadPrimitiveMessages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadPrimitiveMessages.js","names":[],"sources":["../../src/primitives/ThreadPrimitiveMessages.ts"],"sourcesContent":["import { defineComponent, h, type SlotsType, type VNodeChild } from \"vue\";\nimport type {} from \"@assistant-ui/core/store\";\nimport { useAuiState } from \"../useAuiState\";\nimport { MessageByIdProvider } from \"./MessageByIdProvider\";\nimport { useStableKeys } from \"./stableKeys\";\n\n/**\n * Renders the default slot once per message in the current thread, each\n * instance scoped to its message through {@link MessageByIdProvider} and\n * keyed by the message id: an edit or reload that replaces the occupant of a\n * slot remounts that row, so `<TransitionGroup>` and per-row component state\n * follow message identity. The empty optimistic placeholder that precedes a\n * response is its own identity, so the arrival of the real assistant message\n * remounts that one row (a leave/enter pair under `<TransitionGroup>`).\n *\n * @example\n * ```html\n * <ThreadPrimitiveMessages>\n * <ChatMessage />\n * </ThreadPrimitiveMessages>\n * ```\n */\nexport const ThreadPrimitiveMessages = defineComponent({\n name: \"ThreadPrimitiveMessages\",\n slots: Object as SlotsType<{ default?: () => VNodeChild[] }>,\n setup(_, { slots }) {\n const messages = useAuiState((s) => s.thread.messages);\n const ids = useStableKeys(() =>\n messages.value.map((message) => message.id),\n );\n return () =>\n ids.value.map((id) =>\n h(\n MessageByIdProvider,\n { id, key: id },\n { default: () => slots.default?.() },\n ),\n );\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,0BAA0B,gBAAgB;CACrD,MAAM;CACN,OAAO;CACP,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,WAAW,aAAa,MAAM,EAAE,OAAO,QAAQ;EACrD,MAAM,MAAM,oBACV,SAAS,MAAM,KAAK,YAAY,QAAQ,EAAE,CAC5C;EACA,aACE,IAAI,MAAM,KAAK,OACb,EACE,qBACA;GAAE;GAAI,KAAK;EAAG,GACd,EAAE,eAAe,MAAM,UAAU,EAAE,CACrC,CACF;CACJ;AACF,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type PropType, type SlotsType, type VNodeChild } from "vue";
|
|
2
|
+
export declare const clearScrollToBottomWarningForTesting: () => void;
|
|
3
|
+
/**
|
|
4
|
+
* A button that scrolls the surrounding {@link ThreadPrimitiveViewport} to
|
|
5
|
+
* the bottom. Disabled while the viewport is already at the bottom, or when
|
|
6
|
+
* no viewport provides the channel.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ThreadPrimitiveScrollToBottom: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
9
|
+
behavior: {
|
|
10
|
+
type: PropType<ScrollBehavior>;
|
|
11
|
+
default: string;
|
|
12
|
+
};
|
|
13
|
+
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
16
|
+
behavior: {
|
|
17
|
+
type: PropType<ScrollBehavior>;
|
|
18
|
+
default: string;
|
|
19
|
+
};
|
|
20
|
+
}>> & Readonly<{}>, {
|
|
21
|
+
behavior: ScrollBehavior;
|
|
22
|
+
}, SlotsType<{
|
|
23
|
+
default?: () => VNodeChild[];
|
|
24
|
+
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
25
|
+
//# sourceMappingURL=ThreadPrimitiveScrollToBottom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadPrimitiveScrollToBottom.d.ts","sourceRoot":"","sources":["../../src/primitives/ThreadPrimitiveScrollToBottom.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,KAAK,CAAC;AAOb,eAAO,MAAM,oCAAoC,YAEhD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,6BAA6B;;cAKpB,QAAQ,CAAC,cAAc,CAAC;;;;;;;cAAxB,QAAQ,CAAC,cAAc,CAAC;;;;;;cAIL,MAAM,UAAU,EAAE;yEA+BzD,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { viewportInjectionKey } from "./viewportContext.js";
|
|
2
|
+
import { isAttrDisabled } from "./attrDisabled.js";
|
|
3
|
+
import { defineComponent, h, inject, mergeProps } from "vue";
|
|
4
|
+
import { isDevelopment } from "@assistant-ui/core/store/internal";
|
|
5
|
+
//#region src/primitives/ThreadPrimitiveScrollToBottom.ts
|
|
6
|
+
let warnedOutsideViewport = false;
|
|
7
|
+
const clearScrollToBottomWarningForTesting = () => {
|
|
8
|
+
warnedOutsideViewport = false;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A button that scrolls the surrounding {@link ThreadPrimitiveViewport} to
|
|
12
|
+
* the bottom. Disabled while the viewport is already at the bottom, or when
|
|
13
|
+
* no viewport provides the channel.
|
|
14
|
+
*/
|
|
15
|
+
const ThreadPrimitiveScrollToBottom = defineComponent({
|
|
16
|
+
name: "ThreadPrimitiveScrollToBottom",
|
|
17
|
+
inheritAttrs: false,
|
|
18
|
+
props: { behavior: {
|
|
19
|
+
type: String,
|
|
20
|
+
default: "auto"
|
|
21
|
+
} },
|
|
22
|
+
slots: Object,
|
|
23
|
+
setup(props, { attrs, slots }) {
|
|
24
|
+
const viewport = inject(viewportInjectionKey, null);
|
|
25
|
+
if (isDevelopment && !viewport && !warnedOutsideViewport) {
|
|
26
|
+
warnedOutsideViewport = true;
|
|
27
|
+
console.warn("ThreadPrimitiveScrollToBottom: no surrounding ThreadPrimitiveViewport provides the scroll channel; the button stays disabled. Place it inside the viewport.");
|
|
28
|
+
}
|
|
29
|
+
const onClick = (event) => {
|
|
30
|
+
if (event.defaultPrevented || !viewport || viewport.isAtBottom.value || isAttrDisabled(attrs)) return;
|
|
31
|
+
viewport.scrollToBottom(props.behavior);
|
|
32
|
+
};
|
|
33
|
+
return () => h("button", mergeProps(attrs, {
|
|
34
|
+
type: "button",
|
|
35
|
+
disabled: !viewport || viewport.isAtBottom.value || isAttrDisabled(attrs),
|
|
36
|
+
onClick
|
|
37
|
+
}), slots.default?.());
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
//#endregion
|
|
41
|
+
export { ThreadPrimitiveScrollToBottom, clearScrollToBottomWarningForTesting };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=ThreadPrimitiveScrollToBottom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadPrimitiveScrollToBottom.js","names":[],"sources":["../../src/primitives/ThreadPrimitiveScrollToBottom.ts"],"sourcesContent":["import {\n defineComponent,\n h,\n inject,\n mergeProps,\n type PropType,\n type SlotsType,\n type VNodeChild,\n} from \"vue\";\nimport { isDevelopment } from \"@assistant-ui/core/store/internal\";\nimport { isAttrDisabled } from \"./attrDisabled\";\nimport { viewportInjectionKey } from \"./viewportContext\";\n\nlet warnedOutsideViewport = false;\n\nexport const clearScrollToBottomWarningForTesting = () => {\n warnedOutsideViewport = false;\n};\n\n/**\n * A button that scrolls the surrounding {@link ThreadPrimitiveViewport} to\n * the bottom. Disabled while the viewport is already at the bottom, or when\n * no viewport provides the channel.\n */\nexport const ThreadPrimitiveScrollToBottom = defineComponent({\n name: \"ThreadPrimitiveScrollToBottom\",\n inheritAttrs: false,\n props: {\n behavior: {\n type: String as PropType<ScrollBehavior>,\n default: \"auto\",\n },\n },\n slots: Object as SlotsType<{ default?: () => VNodeChild[] }>,\n setup(props, { attrs, slots }) {\n const viewport = inject(viewportInjectionKey, null);\n if (isDevelopment && !viewport && !warnedOutsideViewport) {\n warnedOutsideViewport = true;\n console.warn(\n \"ThreadPrimitiveScrollToBottom: no surrounding ThreadPrimitiveViewport provides the scroll channel; the button stays disabled. Place it inside the viewport.\",\n );\n }\n const onClick = (event: MouseEvent) => {\n if (\n event.defaultPrevented ||\n !viewport ||\n viewport.isAtBottom.value ||\n isAttrDisabled(attrs)\n )\n return;\n viewport.scrollToBottom(props.behavior);\n };\n return () =>\n h(\n \"button\",\n mergeProps(attrs, {\n type: \"button\",\n disabled:\n !viewport || viewport.isAtBottom.value || isAttrDisabled(attrs),\n onClick,\n }),\n slots.default?.(),\n );\n },\n});\n"],"mappings":";;;;;AAaA,IAAI,wBAAwB;AAE5B,MAAa,6CAA6C;CACxD,wBAAwB;AAC1B;;;;;;AAOA,MAAa,gCAAgC,gBAAgB;CAC3D,MAAM;CACN,cAAc;CACd,OAAO,EACL,UAAU;EACR,MAAM;EACN,SAAS;CACX,EACF;CACA,OAAO;CACP,MAAM,OAAO,EAAE,OAAO,SAAS;EAC7B,MAAM,WAAW,OAAO,sBAAsB,IAAI;EAClD,IAAI,iBAAiB,CAAC,YAAY,CAAC,uBAAuB;GACxD,wBAAwB;GACxB,QAAQ,KACN,6JACF;EACF;EACA,MAAM,WAAW,UAAsB;GACrC,IACE,MAAM,oBACN,CAAC,YACD,SAAS,WAAW,SACpB,eAAe,KAAK,GAEpB;GACF,SAAS,eAAe,MAAM,QAAQ;EACxC;EACA,aACE,EACE,UACA,WAAW,OAAO;GAChB,MAAM;GACN,UACE,CAAC,YAAY,SAAS,WAAW,SAAS,eAAe,KAAK;GAChE;EACF,CAAC,GACD,MAAM,UAAU,CAClB;CACJ;AACF,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type SlotsType, type VNodeChild } from "vue";
|
|
2
|
+
/**
|
|
3
|
+
* A scrollable container that keeps the thread pinned to the bottom: content
|
|
4
|
+
* growth scrolls back down while the user sits at the bottom, a run start
|
|
5
|
+
* scrolls down, and scrolling up unpins until the user returns to the bottom.
|
|
6
|
+
* The four options mirror the React hook and are independent: `autoScroll`
|
|
7
|
+
* covers follow-on-content-growth, and the other three gate the
|
|
8
|
+
* first-messages, run-start, and thread-switch scrolls. Provides the
|
|
9
|
+
* scroll-to-bottom channel that {@link ThreadPrimitiveScrollToBottom} drives;
|
|
10
|
+
* the React viewport's top-anchor system stays in the React viewport store
|
|
11
|
+
* and is not ported.
|
|
12
|
+
*/
|
|
13
|
+
export declare const ThreadPrimitiveViewport: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
14
|
+
autoScroll: {
|
|
15
|
+
type: BooleanConstructor;
|
|
16
|
+
default: boolean;
|
|
17
|
+
};
|
|
18
|
+
scrollToBottomOnInitialize: {
|
|
19
|
+
type: BooleanConstructor;
|
|
20
|
+
default: boolean;
|
|
21
|
+
};
|
|
22
|
+
scrollToBottomOnRunStart: {
|
|
23
|
+
type: BooleanConstructor;
|
|
24
|
+
default: boolean;
|
|
25
|
+
};
|
|
26
|
+
scrollToBottomOnThreadSwitch: {
|
|
27
|
+
type: BooleanConstructor;
|
|
28
|
+
default: boolean;
|
|
29
|
+
};
|
|
30
|
+
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
31
|
+
[key: string]: any;
|
|
32
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
33
|
+
autoScroll: {
|
|
34
|
+
type: BooleanConstructor;
|
|
35
|
+
default: boolean;
|
|
36
|
+
};
|
|
37
|
+
scrollToBottomOnInitialize: {
|
|
38
|
+
type: BooleanConstructor;
|
|
39
|
+
default: boolean;
|
|
40
|
+
};
|
|
41
|
+
scrollToBottomOnRunStart: {
|
|
42
|
+
type: BooleanConstructor;
|
|
43
|
+
default: boolean;
|
|
44
|
+
};
|
|
45
|
+
scrollToBottomOnThreadSwitch: {
|
|
46
|
+
type: BooleanConstructor;
|
|
47
|
+
default: boolean;
|
|
48
|
+
};
|
|
49
|
+
}>> & Readonly<{}>, {
|
|
50
|
+
autoScroll: boolean;
|
|
51
|
+
scrollToBottomOnInitialize: boolean;
|
|
52
|
+
scrollToBottomOnRunStart: boolean;
|
|
53
|
+
scrollToBottomOnThreadSwitch: boolean;
|
|
54
|
+
}, SlotsType<{
|
|
55
|
+
default?: () => VNodeChild[];
|
|
56
|
+
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
57
|
+
//# sourceMappingURL=ThreadPrimitiveViewport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadPrimitiveViewport.d.ts","sourceRoot":"","sources":["../../src/primitives/ThreadPrimitiveViewport.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,KAAK,CAAC;AAYb;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoBK,MAAM,UAAU,EAAE;yEAmLzD,CAAC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { useAuiState } from "../useAuiState.js";
|
|
2
|
+
import { useAuiEvent } from "../useAuiEvent.js";
|
|
3
|
+
import { viewportInjectionKey } from "./viewportContext.js";
|
|
4
|
+
import { defineComponent, h, onMounted, onScopeDispose, provide, shallowRef, watch } from "vue";
|
|
5
|
+
import { isUserScrollUp, isViewportAtBottom, observeContentResize, viewportOverflows } from "@assistant-ui/store/client";
|
|
6
|
+
//#region src/primitives/ThreadPrimitiveViewport.ts
|
|
7
|
+
/**
|
|
8
|
+
* A scrollable container that keeps the thread pinned to the bottom: content
|
|
9
|
+
* growth scrolls back down while the user sits at the bottom, a run start
|
|
10
|
+
* scrolls down, and scrolling up unpins until the user returns to the bottom.
|
|
11
|
+
* The four options mirror the React hook and are independent: `autoScroll`
|
|
12
|
+
* covers follow-on-content-growth, and the other three gate the
|
|
13
|
+
* first-messages, run-start, and thread-switch scrolls. Provides the
|
|
14
|
+
* scroll-to-bottom channel that {@link ThreadPrimitiveScrollToBottom} drives;
|
|
15
|
+
* the React viewport's top-anchor system stays in the React viewport store
|
|
16
|
+
* and is not ported.
|
|
17
|
+
*/
|
|
18
|
+
const ThreadPrimitiveViewport = defineComponent({
|
|
19
|
+
name: "ThreadPrimitiveViewport",
|
|
20
|
+
props: {
|
|
21
|
+
autoScroll: {
|
|
22
|
+
type: Boolean,
|
|
23
|
+
default: true
|
|
24
|
+
},
|
|
25
|
+
scrollToBottomOnInitialize: {
|
|
26
|
+
type: Boolean,
|
|
27
|
+
default: true
|
|
28
|
+
},
|
|
29
|
+
scrollToBottomOnRunStart: {
|
|
30
|
+
type: Boolean,
|
|
31
|
+
default: true
|
|
32
|
+
},
|
|
33
|
+
scrollToBottomOnThreadSwitch: {
|
|
34
|
+
type: Boolean,
|
|
35
|
+
default: true
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
slots: Object,
|
|
39
|
+
setup(props, { slots }) {
|
|
40
|
+
const divRef = shallowRef(null);
|
|
41
|
+
const contentInset = shallowRef(0);
|
|
42
|
+
const contentInsetEntries = /* @__PURE__ */ new Map();
|
|
43
|
+
let intent = null;
|
|
44
|
+
const isAtBottom = shallowRef(true);
|
|
45
|
+
let lastScrollTop = 0;
|
|
46
|
+
let lastScrollHeight = 0;
|
|
47
|
+
let lastObservedScrollHeight = 0;
|
|
48
|
+
let lastObservedClientHeight = 0;
|
|
49
|
+
let frame = null;
|
|
50
|
+
const scrollToBottom = (behavior) => {
|
|
51
|
+
const div = divRef.value;
|
|
52
|
+
if (!div) return;
|
|
53
|
+
intent = behavior;
|
|
54
|
+
div.scrollTo?.({
|
|
55
|
+
top: div.scrollHeight,
|
|
56
|
+
behavior
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
const scheduleScrollToBottom = (behavior) => {
|
|
60
|
+
intent = behavior;
|
|
61
|
+
if (typeof requestAnimationFrame === "undefined") return;
|
|
62
|
+
if (frame !== null) cancelAnimationFrame(frame);
|
|
63
|
+
frame = requestAnimationFrame(() => {
|
|
64
|
+
frame = null;
|
|
65
|
+
scrollToBottom(behavior);
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
const handleScroll = () => {
|
|
69
|
+
const div = divRef.value;
|
|
70
|
+
if (!div) return;
|
|
71
|
+
const newIsAtBottom = isViewportAtBottom(div, contentInset.value);
|
|
72
|
+
if (!(!newIsAtBottom && lastScrollTop < div.scrollTop)) {
|
|
73
|
+
if (newIsAtBottom) {
|
|
74
|
+
if (viewportOverflows(div, contentInset.value)) intent = null;
|
|
75
|
+
} else if (isUserScrollUp({
|
|
76
|
+
scrollTop: lastScrollTop,
|
|
77
|
+
scrollHeight: lastScrollHeight
|
|
78
|
+
}, div)) intent = null;
|
|
79
|
+
if (newIsAtBottom || intent === null) isAtBottom.value = newIsAtBottom;
|
|
80
|
+
}
|
|
81
|
+
lastScrollTop = div.scrollTop;
|
|
82
|
+
lastScrollHeight = div.scrollHeight;
|
|
83
|
+
};
|
|
84
|
+
const updateContentInset = () => {
|
|
85
|
+
let total = 0;
|
|
86
|
+
for (const height of contentInsetEntries.values()) total += height;
|
|
87
|
+
if (contentInset.value === total) return;
|
|
88
|
+
const grew = total > contentInset.value;
|
|
89
|
+
contentInset.value = total;
|
|
90
|
+
if (grew) {
|
|
91
|
+
if (intent) scrollToBottom(intent);
|
|
92
|
+
else if (props.autoScroll && isAtBottom.value) scrollToBottom("instant");
|
|
93
|
+
}
|
|
94
|
+
handleScroll();
|
|
95
|
+
};
|
|
96
|
+
const registerContentInset = () => {
|
|
97
|
+
const id = Symbol();
|
|
98
|
+
contentInsetEntries.set(id, 0);
|
|
99
|
+
return {
|
|
100
|
+
setHeight: (height) => {
|
|
101
|
+
if (contentInsetEntries.get(id) === height) return;
|
|
102
|
+
contentInsetEntries.set(id, height);
|
|
103
|
+
updateContentInset();
|
|
104
|
+
},
|
|
105
|
+
unregister: () => {
|
|
106
|
+
if (!contentInsetEntries.delete(id)) return;
|
|
107
|
+
updateContentInset();
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
const onContentResize = () => {
|
|
112
|
+
const div = divRef.value;
|
|
113
|
+
if (!div) return;
|
|
114
|
+
const { scrollHeight, clientHeight } = div;
|
|
115
|
+
if (scrollHeight === lastObservedScrollHeight && clientHeight === lastObservedClientHeight) return;
|
|
116
|
+
lastObservedScrollHeight = scrollHeight;
|
|
117
|
+
lastObservedClientHeight = clientHeight;
|
|
118
|
+
if (intent) scrollToBottom(intent);
|
|
119
|
+
else if (props.autoScroll && isAtBottom.value) scrollToBottom("instant");
|
|
120
|
+
handleScroll();
|
|
121
|
+
};
|
|
122
|
+
const onPointerdown = () => {
|
|
123
|
+
intent = null;
|
|
124
|
+
if (frame !== null) {
|
|
125
|
+
cancelAnimationFrame(frame);
|
|
126
|
+
frame = null;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
let disconnect;
|
|
130
|
+
onMounted(() => {
|
|
131
|
+
const div = divRef.value;
|
|
132
|
+
if (!div) return;
|
|
133
|
+
disconnect = observeContentResize(div, onContentResize);
|
|
134
|
+
});
|
|
135
|
+
onScopeDispose(() => {
|
|
136
|
+
disconnect?.();
|
|
137
|
+
if (frame !== null) cancelAnimationFrame(frame);
|
|
138
|
+
});
|
|
139
|
+
const hasMessages = useAuiState((s) => s.thread.messages.length > 0);
|
|
140
|
+
let initialized = false;
|
|
141
|
+
watch([hasMessages, () => props.scrollToBottomOnInitialize], ([has, enabled]) => {
|
|
142
|
+
if (!has) {
|
|
143
|
+
initialized = false;
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (!enabled || initialized) return;
|
|
147
|
+
initialized = true;
|
|
148
|
+
if (intent !== null) return;
|
|
149
|
+
scheduleScrollToBottom("instant");
|
|
150
|
+
}, { immediate: true });
|
|
151
|
+
useAuiEvent("thread.runStart", () => {
|
|
152
|
+
if (!props.scrollToBottomOnRunStart) return;
|
|
153
|
+
scheduleScrollToBottom("auto");
|
|
154
|
+
});
|
|
155
|
+
useAuiEvent("threads.selectionChanged", () => {
|
|
156
|
+
if (!props.scrollToBottomOnThreadSwitch) return;
|
|
157
|
+
scheduleScrollToBottom("instant");
|
|
158
|
+
});
|
|
159
|
+
provide(viewportInjectionKey, {
|
|
160
|
+
isAtBottom,
|
|
161
|
+
scrollToBottom: (behavior = "auto") => scrollToBottom(behavior),
|
|
162
|
+
registerContentInset
|
|
163
|
+
});
|
|
164
|
+
return () => h("div", {
|
|
165
|
+
ref: divRef,
|
|
166
|
+
onScroll: handleScroll,
|
|
167
|
+
onPointerdown
|
|
168
|
+
}, slots.default?.());
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
//#endregion
|
|
172
|
+
export { ThreadPrimitiveViewport };
|
|
173
|
+
|
|
174
|
+
//# sourceMappingURL=ThreadPrimitiveViewport.js.map
|