@assistant-ui/react 0.12.22 → 0.12.24
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/client/ExternalThread.d.ts.map +1 -1
- package/dist/client/ExternalThread.js +1 -0
- package/dist/client/ExternalThread.js.map +1 -1
- package/dist/client/InMemoryThreadList.d.ts.map +1 -1
- package/dist/client/InMemoryThreadList.js +2 -0
- package/dist/client/InMemoryThreadList.js.map +1 -1
- package/dist/client/SingleThreadList.d.ts.map +1 -1
- package/dist/client/SingleThreadList.js +2 -0
- package/dist/client/SingleThreadList.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -0
- package/dist/internal.js.map +1 -1
- package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerInput.js +27 -12
- package/dist/primitives/composer/ComposerInput.js.map +1 -1
- package/dist/primitives/composer/ComposerInputPluginContext.d.ts +31 -0
- package/dist/primitives/composer/ComposerInputPluginContext.d.ts.map +1 -0
- package/dist/primitives/composer/ComposerInputPluginContext.js +32 -0
- package/dist/primitives/composer/ComposerInputPluginContext.js.map +1 -0
- package/dist/primitives/composer/mention/ComposerMentionContext.d.ts +4 -2
- package/dist/primitives/composer/mention/ComposerMentionContext.d.ts.map +1 -1
- package/dist/primitives/composer/mention/ComposerMentionContext.js +21 -13
- package/dist/primitives/composer/mention/ComposerMentionContext.js.map +1 -1
- package/dist/primitives/composer/mention/index.d.ts +4 -4
- package/dist/primitives/composer/mention/index.d.ts.map +1 -1
- package/dist/primitives/composer/mention/index.js +6 -4
- package/dist/primitives/composer/mention/index.js.map +1 -1
- package/dist/primitives/composer/slash-command/ComposerSlashCommandRoot.d.ts +36 -0
- package/dist/primitives/composer/slash-command/ComposerSlashCommandRoot.d.ts.map +1 -0
- package/dist/primitives/composer/slash-command/ComposerSlashCommandRoot.js +36 -0
- package/dist/primitives/composer/slash-command/ComposerSlashCommandRoot.js.map +1 -0
- package/dist/primitives/composer/slash-command/index.d.ts +2 -0
- package/dist/primitives/composer/slash-command/index.d.ts.map +1 -0
- package/dist/primitives/composer/slash-command/index.js +2 -0
- package/dist/primitives/composer/slash-command/index.js.map +1 -0
- package/dist/primitives/composer/{mention/ComposerMentionBack.d.ts → trigger/TriggerPopoverBack.d.ts} +3 -10
- package/dist/primitives/composer/trigger/TriggerPopoverBack.d.ts.map +1 -0
- package/dist/primitives/composer/trigger/TriggerPopoverBack.js +19 -0
- package/dist/primitives/composer/trigger/TriggerPopoverBack.js.map +1 -0
- package/dist/primitives/composer/trigger/TriggerPopoverCategories.d.ts +38 -0
- package/dist/primitives/composer/trigger/TriggerPopoverCategories.d.ts.map +1 -0
- package/dist/primitives/composer/trigger/TriggerPopoverCategories.js +35 -0
- package/dist/primitives/composer/trigger/TriggerPopoverCategories.js.map +1 -0
- package/dist/primitives/composer/trigger/TriggerPopoverContext.d.ts +37 -0
- package/dist/primitives/composer/trigger/TriggerPopoverContext.d.ts.map +1 -0
- package/dist/primitives/composer/trigger/TriggerPopoverContext.js +70 -0
- package/dist/primitives/composer/trigger/TriggerPopoverContext.js.map +1 -0
- package/dist/primitives/composer/trigger/TriggerPopoverItems.d.ts +40 -0
- package/dist/primitives/composer/trigger/TriggerPopoverItems.d.ts.map +1 -0
- package/dist/primitives/composer/trigger/TriggerPopoverItems.js +35 -0
- package/dist/primitives/composer/trigger/TriggerPopoverItems.js.map +1 -0
- package/dist/primitives/composer/trigger/TriggerPopoverPopover.d.ts +26 -0
- package/dist/primitives/composer/trigger/TriggerPopoverPopover.d.ts.map +1 -0
- package/dist/primitives/composer/trigger/TriggerPopoverPopover.js +28 -0
- package/dist/primitives/composer/trigger/TriggerPopoverPopover.js.map +1 -0
- package/dist/primitives/composer/trigger/TriggerPopoverResource.d.ts +53 -0
- package/dist/primitives/composer/trigger/TriggerPopoverResource.d.ts.map +1 -0
- package/dist/primitives/composer/{mention/MentionResource.js → trigger/TriggerPopoverResource.js} +50 -25
- package/dist/primitives/composer/trigger/TriggerPopoverResource.js.map +1 -0
- package/dist/primitives/composer/trigger/detectTrigger.d.ts +2 -0
- package/dist/primitives/composer/trigger/detectTrigger.d.ts.map +1 -0
- package/dist/primitives/composer/{mention/detectMentionTrigger.js → trigger/detectTrigger.js} +4 -4
- package/dist/primitives/composer/trigger/detectTrigger.js.map +1 -0
- package/dist/primitives/composer/trigger/index.d.ts +7 -0
- package/dist/primitives/composer/trigger/index.d.ts.map +1 -0
- package/dist/primitives/composer/trigger/index.js +6 -0
- package/dist/primitives/composer/trigger/index.js.map +1 -0
- package/dist/primitives/composer.d.ts +10 -0
- package/dist/primitives/composer.d.ts.map +1 -1
- package/dist/primitives/composer.js +14 -0
- package/dist/primitives/composer.js.map +1 -1
- package/dist/primitives/message/MessageRoot.d.ts +25 -3
- package/dist/primitives/message/MessageRoot.d.ts.map +1 -1
- package/dist/primitives/message/MessageRoot.js +2 -2
- package/dist/primitives/message/MessageRoot.js.map +1 -1
- package/dist/primitives/thread/ThreadViewportSlack.d.ts +2 -2
- package/dist/primitives/thread/ThreadViewportSlack.d.ts.map +1 -1
- package/dist/unstable/useSlashCommandAdapter.d.ts +34 -0
- package/dist/unstable/useSlashCommandAdapter.d.ts.map +1 -0
- package/dist/unstable/useSlashCommandAdapter.js +50 -0
- package/dist/unstable/useSlashCommandAdapter.js.map +1 -0
- package/package.json +7 -7
- package/src/client/ExternalThread.ts +1 -0
- package/src/client/InMemoryThreadList.ts +3 -0
- package/src/client/SingleThreadList.ts +2 -0
- package/src/index.ts +14 -0
- package/src/internal.ts +3 -0
- package/src/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.test.ts +186 -3
- package/src/primitives/composer/ComposerInput.tsx +25 -18
- package/src/primitives/composer/ComposerInputPluginContext.tsx +100 -0
- package/src/primitives/composer/mention/ComposerMentionContext.tsx +56 -22
- package/src/primitives/composer/mention/index.ts +11 -8
- package/src/primitives/composer/slash-command/ComposerSlashCommandRoot.tsx +76 -0
- package/src/primitives/composer/slash-command/index.ts +1 -0
- package/src/primitives/composer/trigger/TriggerPopoverBack.tsx +40 -0
- package/src/primitives/composer/{mention/ComposerMentionCategories.tsx → trigger/TriggerPopoverCategories.tsx} +33 -28
- package/src/primitives/composer/trigger/TriggerPopoverContext.tsx +129 -0
- package/src/primitives/composer/{mention/ComposerMentionItems.tsx → trigger/TriggerPopoverItems.tsx} +34 -29
- package/src/primitives/composer/trigger/TriggerPopoverPopover.tsx +51 -0
- package/src/primitives/composer/{mention/MentionResource.ts → trigger/TriggerPopoverResource.ts} +146 -98
- package/src/primitives/composer/{mention/detectMentionTrigger.test.ts → trigger/detectTrigger.test.ts} +15 -15
- package/src/primitives/composer/{mention/detectMentionTrigger.ts → trigger/detectTrigger.ts} +3 -3
- package/src/primitives/composer/trigger/index.ts +16 -0
- package/src/primitives/composer.ts +16 -0
- package/src/primitives/message/MessageRoot.tsx +18 -4
- package/src/primitives/thread/ThreadViewportSlack.tsx +2 -2
- package/src/tests/BaseComposerRuntimeCore.test.ts +33 -1
- package/src/unstable/useSlashCommandAdapter.ts +83 -0
- package/dist/primitives/composer/mention/ComposerMentionBack.d.ts.map +0 -1
- package/dist/primitives/composer/mention/ComposerMentionBack.js +0 -28
- package/dist/primitives/composer/mention/ComposerMentionBack.js.map +0 -1
- package/dist/primitives/composer/mention/ComposerMentionCategories.d.ts +0 -46
- package/dist/primitives/composer/mention/ComposerMentionCategories.d.ts.map +0 -1
- package/dist/primitives/composer/mention/ComposerMentionCategories.js +0 -32
- package/dist/primitives/composer/mention/ComposerMentionCategories.js.map +0 -1
- package/dist/primitives/composer/mention/ComposerMentionItems.d.ts +0 -50
- package/dist/primitives/composer/mention/ComposerMentionItems.d.ts.map +0 -1
- package/dist/primitives/composer/mention/ComposerMentionItems.js +0 -30
- package/dist/primitives/composer/mention/ComposerMentionItems.js.map +0 -1
- package/dist/primitives/composer/mention/ComposerMentionPopover.d.ts +0 -26
- package/dist/primitives/composer/mention/ComposerMentionPopover.d.ts.map +0 -1
- package/dist/primitives/composer/mention/ComposerMentionPopover.js +0 -28
- package/dist/primitives/composer/mention/ComposerMentionPopover.js.map +0 -1
- package/dist/primitives/composer/mention/MentionResource.d.ts +0 -39
- package/dist/primitives/composer/mention/MentionResource.d.ts.map +0 -1
- package/dist/primitives/composer/mention/MentionResource.js.map +0 -1
- package/dist/primitives/composer/mention/detectMentionTrigger.d.ts +0 -2
- package/dist/primitives/composer/mention/detectMentionTrigger.d.ts.map +0 -1
- package/dist/primitives/composer/mention/detectMentionTrigger.js.map +0 -1
- package/src/primitives/composer/mention/ComposerMentionBack.tsx +0 -55
- package/src/primitives/composer/mention/ComposerMentionPopover.tsx +0 -52
|
@@ -9,52 +9,56 @@ import {
|
|
|
9
9
|
useCallback,
|
|
10
10
|
} from "react";
|
|
11
11
|
import { composeEventHandlers } from "@radix-ui/primitive";
|
|
12
|
-
import {
|
|
13
|
-
import type {
|
|
12
|
+
import { useTriggerPopoverContext } from "./TriggerPopoverContext";
|
|
13
|
+
import type { Unstable_TriggerCategory } from "@assistant-ui/core";
|
|
14
14
|
|
|
15
15
|
// =============================================================================
|
|
16
|
-
//
|
|
16
|
+
// TriggerPopoverCategories — Renders the list of categories
|
|
17
17
|
// =============================================================================
|
|
18
18
|
|
|
19
|
-
export namespace
|
|
19
|
+
export namespace ComposerPrimitiveTriggerPopoverCategories {
|
|
20
20
|
export type Element = ComponentRef<typeof Primitive.div>;
|
|
21
21
|
export type Props = Omit<
|
|
22
22
|
ComponentPropsWithoutRef<typeof Primitive.div>,
|
|
23
23
|
"children"
|
|
24
24
|
> & {
|
|
25
|
-
|
|
26
|
-
* Render function that receives the filtered categories and returns
|
|
27
|
-
* the UI. A render-function pattern is used here (instead of a
|
|
28
|
-
* `components` prop) to give consumers full control over list layout,
|
|
29
|
-
* ordering, grouping, and empty states.
|
|
30
|
-
*/
|
|
31
|
-
children: (categories: readonly Unstable_MentionCategory[]) => ReactNode;
|
|
25
|
+
children: (categories: readonly Unstable_TriggerCategory[]) => ReactNode;
|
|
32
26
|
};
|
|
33
27
|
}
|
|
34
28
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Renders the top-level category list via a render function.
|
|
31
|
+
* Only renders when no category is active and search mode is off.
|
|
32
|
+
*/
|
|
33
|
+
export const ComposerPrimitiveTriggerPopoverCategories = forwardRef<
|
|
34
|
+
ComposerPrimitiveTriggerPopoverCategories.Element,
|
|
35
|
+
ComposerPrimitiveTriggerPopoverCategories.Props
|
|
36
|
+
>(({ children, "aria-label": ariaLabel, ...props }, forwardedRef) => {
|
|
37
|
+
const { categories, activeCategoryId, isSearchMode } =
|
|
38
|
+
useTriggerPopoverContext();
|
|
40
39
|
|
|
41
40
|
if (activeCategoryId || isSearchMode) return null;
|
|
42
41
|
|
|
43
42
|
return (
|
|
44
|
-
<Primitive.div
|
|
43
|
+
<Primitive.div
|
|
44
|
+
role="group"
|
|
45
|
+
aria-label={ariaLabel ?? "Categories"}
|
|
46
|
+
{...props}
|
|
47
|
+
ref={forwardedRef}
|
|
48
|
+
>
|
|
45
49
|
{children(categories)}
|
|
46
50
|
</Primitive.div>
|
|
47
51
|
);
|
|
48
52
|
});
|
|
49
53
|
|
|
50
|
-
|
|
51
|
-
"ComposerPrimitive.
|
|
54
|
+
ComposerPrimitiveTriggerPopoverCategories.displayName =
|
|
55
|
+
"ComposerPrimitive.TriggerPopoverCategories";
|
|
52
56
|
|
|
53
57
|
// =============================================================================
|
|
54
|
-
//
|
|
58
|
+
// TriggerPopoverCategoryItem — A single category row
|
|
55
59
|
// =============================================================================
|
|
56
60
|
|
|
57
|
-
export namespace
|
|
61
|
+
export namespace ComposerPrimitiveTriggerPopoverCategoryItem {
|
|
58
62
|
export type Element = ComponentRef<typeof Primitive.button>;
|
|
59
63
|
export type Props = ComponentPropsWithoutRef<typeof Primitive.button> & {
|
|
60
64
|
categoryId: string;
|
|
@@ -65,9 +69,9 @@ export namespace ComposerPrimitiveMentionCategoryItem {
|
|
|
65
69
|
* A button that selects a category and triggers drill-down navigation.
|
|
66
70
|
* Automatically receives `data-highlighted` when keyboard-navigated.
|
|
67
71
|
*/
|
|
68
|
-
export const
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
export const ComposerPrimitiveTriggerPopoverCategoryItem = forwardRef<
|
|
73
|
+
ComposerPrimitiveTriggerPopoverCategoryItem.Element,
|
|
74
|
+
ComposerPrimitiveTriggerPopoverCategoryItem.Props
|
|
71
75
|
>(({ categoryId, onClick, ...props }, forwardedRef) => {
|
|
72
76
|
const {
|
|
73
77
|
selectCategory,
|
|
@@ -75,13 +79,13 @@ export const ComposerPrimitiveMentionCategoryItem = forwardRef<
|
|
|
75
79
|
highlightedIndex,
|
|
76
80
|
activeCategoryId,
|
|
77
81
|
isSearchMode,
|
|
78
|
-
|
|
82
|
+
popoverId,
|
|
83
|
+
} = useTriggerPopoverContext();
|
|
79
84
|
|
|
80
85
|
const handleClick = useCallback(() => {
|
|
81
86
|
selectCategory(categoryId);
|
|
82
87
|
}, [selectCategory, categoryId]);
|
|
83
88
|
|
|
84
|
-
// Derive highlighted state from context — no manual wiring needed
|
|
85
89
|
const isHighlighted =
|
|
86
90
|
!activeCategoryId &&
|
|
87
91
|
!isSearchMode &&
|
|
@@ -91,6 +95,7 @@ export const ComposerPrimitiveMentionCategoryItem = forwardRef<
|
|
|
91
95
|
<Primitive.button
|
|
92
96
|
type="button"
|
|
93
97
|
role="option"
|
|
98
|
+
id={`${popoverId}-option-${categoryId}`}
|
|
94
99
|
aria-selected={isHighlighted}
|
|
95
100
|
data-highlighted={isHighlighted ? "" : undefined}
|
|
96
101
|
{...props}
|
|
@@ -100,5 +105,5 @@ export const ComposerPrimitiveMentionCategoryItem = forwardRef<
|
|
|
100
105
|
);
|
|
101
106
|
});
|
|
102
107
|
|
|
103
|
-
|
|
104
|
-
"ComposerPrimitive.
|
|
108
|
+
ComposerPrimitiveTriggerPopoverCategoryItem.displayName =
|
|
109
|
+
"ComposerPrimitive.TriggerPopoverCategoryItem";
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createContext,
|
|
5
|
+
useContext,
|
|
6
|
+
useEffect,
|
|
7
|
+
useId,
|
|
8
|
+
type ReactNode,
|
|
9
|
+
type FC,
|
|
10
|
+
} from "react";
|
|
11
|
+
import { useResource } from "@assistant-ui/tap/react";
|
|
12
|
+
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
13
|
+
import type { Unstable_TriggerAdapter } from "@assistant-ui/core";
|
|
14
|
+
import {
|
|
15
|
+
TriggerPopoverResource,
|
|
16
|
+
type TriggerPopoverResourceOutput,
|
|
17
|
+
type OnSelectBehavior,
|
|
18
|
+
} from "./TriggerPopoverResource";
|
|
19
|
+
import {
|
|
20
|
+
useComposerInputPluginRegistryOptional,
|
|
21
|
+
ComposerInputPluginProvider,
|
|
22
|
+
} from "../ComposerInputPluginContext";
|
|
23
|
+
|
|
24
|
+
// =============================================================================
|
|
25
|
+
// Context
|
|
26
|
+
// =============================================================================
|
|
27
|
+
|
|
28
|
+
const TriggerPopoverContext =
|
|
29
|
+
createContext<TriggerPopoverResourceOutput | null>(null);
|
|
30
|
+
|
|
31
|
+
export const useTriggerPopoverContext = () => {
|
|
32
|
+
const ctx = useContext(TriggerPopoverContext);
|
|
33
|
+
if (!ctx)
|
|
34
|
+
throw new Error(
|
|
35
|
+
"useTriggerPopoverContext must be used within ComposerPrimitive.TriggerPopoverRoot",
|
|
36
|
+
);
|
|
37
|
+
return ctx;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const useTriggerPopoverContextOptional = () => {
|
|
41
|
+
return useContext(TriggerPopoverContext);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// =============================================================================
|
|
45
|
+
// Root Component
|
|
46
|
+
// =============================================================================
|
|
47
|
+
|
|
48
|
+
export namespace ComposerPrimitiveTriggerPopoverRoot {
|
|
49
|
+
export type Props = {
|
|
50
|
+
children: ReactNode;
|
|
51
|
+
/** The adapter providing categories and items. */
|
|
52
|
+
adapter: Unstable_TriggerAdapter;
|
|
53
|
+
/** Character(s) that trigger the popover. @default "@" */
|
|
54
|
+
trigger?: string | undefined;
|
|
55
|
+
/** What happens when an item is selected. */
|
|
56
|
+
onSelect: OnSelectBehavior;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const TriggerPopoverRootInner: FC<
|
|
61
|
+
ComposerPrimitiveTriggerPopoverRoot.Props
|
|
62
|
+
> = ({ children, adapter, trigger: triggerChar = "@", onSelect }) => {
|
|
63
|
+
const aui = useAui();
|
|
64
|
+
const text = useAuiState((s) => s.composer.text);
|
|
65
|
+
const popoverId = useId();
|
|
66
|
+
|
|
67
|
+
const triggerPopover = useResource(
|
|
68
|
+
TriggerPopoverResource({
|
|
69
|
+
adapter,
|
|
70
|
+
text,
|
|
71
|
+
triggerChar,
|
|
72
|
+
onSelect,
|
|
73
|
+
aui,
|
|
74
|
+
popoverId,
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// Register as ComposerInput plugin
|
|
79
|
+
const pluginRegistry = useComposerInputPluginRegistryOptional();
|
|
80
|
+
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (!pluginRegistry) return undefined;
|
|
83
|
+
return pluginRegistry.register(triggerPopover);
|
|
84
|
+
}, [pluginRegistry, triggerPopover]);
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<TriggerPopoverContext.Provider value={triggerPopover}>
|
|
88
|
+
{children}
|
|
89
|
+
</TriggerPopoverContext.Provider>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Provider that wraps the composer with trigger detection, keyboard navigation,
|
|
95
|
+
* and popover state. Supports any trigger character (`@`, `/`, `:`, etc.).
|
|
96
|
+
* Multiple trigger roots can coexist around the same input.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```tsx
|
|
100
|
+
* <ComposerPrimitive.Unstable_TriggerPopoverRoot
|
|
101
|
+
* trigger="/"
|
|
102
|
+
* adapter={slashAdapter}
|
|
103
|
+
* onSelect={{ type: "action", handler: (item) => console.log(item) }}
|
|
104
|
+
* >
|
|
105
|
+
* <ComposerPrimitive.Input />
|
|
106
|
+
* <ComposerPrimitive.Unstable_TriggerPopoverPopover>
|
|
107
|
+
* ...
|
|
108
|
+
* </ComposerPrimitive.Unstable_TriggerPopoverPopover>
|
|
109
|
+
* </ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export const ComposerPrimitiveTriggerPopoverRoot: FC<
|
|
113
|
+
ComposerPrimitiveTriggerPopoverRoot.Props
|
|
114
|
+
> = (props) => {
|
|
115
|
+
const existingRegistry = useComposerInputPluginRegistryOptional();
|
|
116
|
+
|
|
117
|
+
if (existingRegistry) {
|
|
118
|
+
return <TriggerPopoverRootInner {...props} />;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<ComposerInputPluginProvider>
|
|
123
|
+
<TriggerPopoverRootInner {...props} />
|
|
124
|
+
</ComposerInputPluginProvider>
|
|
125
|
+
);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
ComposerPrimitiveTriggerPopoverRoot.displayName =
|
|
129
|
+
"ComposerPrimitive.TriggerPopoverRoot";
|
package/src/primitives/composer/{mention/ComposerMentionItems.tsx → trigger/TriggerPopoverItems.tsx}
RENAMED
|
@@ -9,66 +9,69 @@ import {
|
|
|
9
9
|
useCallback,
|
|
10
10
|
} from "react";
|
|
11
11
|
import { composeEventHandlers } from "@radix-ui/primitive";
|
|
12
|
-
import {
|
|
13
|
-
import type {
|
|
12
|
+
import { useTriggerPopoverContext } from "./TriggerPopoverContext";
|
|
13
|
+
import type { Unstable_TriggerItem } from "@assistant-ui/core";
|
|
14
14
|
|
|
15
15
|
// =============================================================================
|
|
16
|
-
//
|
|
16
|
+
// TriggerPopoverItems — Renders the list of items within a category
|
|
17
17
|
// =============================================================================
|
|
18
18
|
|
|
19
|
-
export namespace
|
|
19
|
+
export namespace ComposerPrimitiveTriggerPopoverItems {
|
|
20
20
|
export type Element = ComponentRef<typeof Primitive.div>;
|
|
21
21
|
export type Props = Omit<
|
|
22
22
|
ComponentPropsWithoutRef<typeof Primitive.div>,
|
|
23
23
|
"children"
|
|
24
24
|
> & {
|
|
25
|
-
|
|
26
|
-
* Render function that receives the filtered items and returns
|
|
27
|
-
* the UI. A render-function pattern is used here (instead of a
|
|
28
|
-
* `components` prop) to give consumers full control over list layout,
|
|
29
|
-
* ordering, grouping, and empty states.
|
|
30
|
-
*/
|
|
31
|
-
children: (items: readonly Unstable_MentionItem[]) => ReactNode;
|
|
25
|
+
children: (items: readonly Unstable_TriggerItem[]) => ReactNode;
|
|
32
26
|
};
|
|
33
27
|
}
|
|
34
28
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Renders the list of items within a category or search results via a render function.
|
|
31
|
+
* Only renders when a category is active or search mode is on.
|
|
32
|
+
*/
|
|
33
|
+
export const ComposerPrimitiveTriggerPopoverItems = forwardRef<
|
|
34
|
+
ComposerPrimitiveTriggerPopoverItems.Element,
|
|
35
|
+
ComposerPrimitiveTriggerPopoverItems.Props
|
|
36
|
+
>(({ children, "aria-label": ariaLabel, ...props }, forwardedRef) => {
|
|
37
|
+
const { items, activeCategoryId, isSearchMode } = useTriggerPopoverContext();
|
|
40
38
|
|
|
41
39
|
if (!activeCategoryId && !isSearchMode) return null;
|
|
42
40
|
|
|
43
41
|
return (
|
|
44
|
-
<Primitive.div
|
|
42
|
+
<Primitive.div
|
|
43
|
+
role="group"
|
|
44
|
+
aria-label={ariaLabel ?? "Items"}
|
|
45
|
+
{...props}
|
|
46
|
+
ref={forwardedRef}
|
|
47
|
+
>
|
|
45
48
|
{children(items)}
|
|
46
49
|
</Primitive.div>
|
|
47
50
|
);
|
|
48
51
|
});
|
|
49
52
|
|
|
50
|
-
|
|
53
|
+
ComposerPrimitiveTriggerPopoverItems.displayName =
|
|
54
|
+
"ComposerPrimitive.TriggerPopoverItems";
|
|
51
55
|
|
|
52
56
|
// =============================================================================
|
|
53
|
-
//
|
|
57
|
+
// TriggerPopoverItem — A single selectable item
|
|
54
58
|
// =============================================================================
|
|
55
59
|
|
|
56
|
-
export namespace
|
|
60
|
+
export namespace ComposerPrimitiveTriggerPopoverItem {
|
|
57
61
|
export type Element = ComponentRef<typeof Primitive.button>;
|
|
58
62
|
export type Props = ComponentPropsWithoutRef<typeof Primitive.button> & {
|
|
59
|
-
item:
|
|
60
|
-
/** Position in the items list. Used for keyboard highlight matching. Falls back to findIndex by id. */
|
|
63
|
+
item: Unstable_TriggerItem;
|
|
61
64
|
index?: number | undefined;
|
|
62
65
|
};
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
/**
|
|
66
|
-
* A button that
|
|
69
|
+
* A button that selects a trigger item.
|
|
67
70
|
* Automatically receives `data-highlighted` when keyboard-navigated.
|
|
68
71
|
*/
|
|
69
|
-
export const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
export const ComposerPrimitiveTriggerPopoverItem = forwardRef<
|
|
73
|
+
ComposerPrimitiveTriggerPopoverItem.Element,
|
|
74
|
+
ComposerPrimitiveTriggerPopoverItem.Props
|
|
72
75
|
>(({ item, index: indexProp, onClick, ...props }, forwardedRef) => {
|
|
73
76
|
const {
|
|
74
77
|
selectItem,
|
|
@@ -76,13 +79,13 @@ export const ComposerPrimitiveMentionItem = forwardRef<
|
|
|
76
79
|
highlightedIndex,
|
|
77
80
|
activeCategoryId,
|
|
78
81
|
isSearchMode,
|
|
79
|
-
|
|
82
|
+
popoverId,
|
|
83
|
+
} = useTriggerPopoverContext();
|
|
80
84
|
|
|
81
85
|
const handleClick = useCallback(() => {
|
|
82
86
|
selectItem(item);
|
|
83
87
|
}, [selectItem, item]);
|
|
84
88
|
|
|
85
|
-
// Use explicit index prop if provided, fall back to findIndex
|
|
86
89
|
const itemIndex = indexProp ?? items.findIndex((i) => i.id === item.id);
|
|
87
90
|
const isHighlighted =
|
|
88
91
|
(isSearchMode || activeCategoryId !== null) &&
|
|
@@ -92,6 +95,7 @@ export const ComposerPrimitiveMentionItem = forwardRef<
|
|
|
92
95
|
<Primitive.button
|
|
93
96
|
type="button"
|
|
94
97
|
role="option"
|
|
98
|
+
id={`${popoverId}-option-${item.id}`}
|
|
95
99
|
aria-selected={isHighlighted}
|
|
96
100
|
data-highlighted={isHighlighted ? "" : undefined}
|
|
97
101
|
{...props}
|
|
@@ -101,4 +105,5 @@ export const ComposerPrimitiveMentionItem = forwardRef<
|
|
|
101
105
|
);
|
|
102
106
|
});
|
|
103
107
|
|
|
104
|
-
|
|
108
|
+
ComposerPrimitiveTriggerPopoverItem.displayName =
|
|
109
|
+
"ComposerPrimitive.TriggerPopoverItem";
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Primitive } from "../../../utils/Primitive";
|
|
4
|
+
import {
|
|
5
|
+
type ComponentRef,
|
|
6
|
+
type ComponentPropsWithoutRef,
|
|
7
|
+
forwardRef,
|
|
8
|
+
} from "react";
|
|
9
|
+
import { useTriggerPopoverContext } from "./TriggerPopoverContext";
|
|
10
|
+
|
|
11
|
+
export namespace ComposerPrimitiveTriggerPopoverPopover {
|
|
12
|
+
export type Element = ComponentRef<typeof Primitive.div>;
|
|
13
|
+
export type Props = ComponentPropsWithoutRef<typeof Primitive.div>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Renders a container for the trigger popover.
|
|
18
|
+
* Only renders when a trigger character is detected in the composer text.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <ComposerPrimitive.Unstable_TriggerPopoverRoot trigger="/" adapter={adapter} onSelect={onSelect}>
|
|
23
|
+
* <ComposerPrimitive.Input />
|
|
24
|
+
* <ComposerPrimitive.Unstable_TriggerPopoverPopover>
|
|
25
|
+
* <ComposerPrimitive.Unstable_TriggerPopoverCategories />
|
|
26
|
+
* </ComposerPrimitive.Unstable_TriggerPopoverPopover>
|
|
27
|
+
* </ComposerPrimitive.Unstable_TriggerPopoverRoot>
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export const ComposerPrimitiveTriggerPopoverPopover = forwardRef<
|
|
31
|
+
ComposerPrimitiveTriggerPopoverPopover.Element,
|
|
32
|
+
ComposerPrimitiveTriggerPopoverPopover.Props
|
|
33
|
+
>(({ "aria-label": ariaLabel, ...props }, forwardedRef) => {
|
|
34
|
+
const { open, popoverId, highlightedItemId } = useTriggerPopoverContext();
|
|
35
|
+
if (!open) return null;
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<Primitive.div
|
|
39
|
+
role="listbox"
|
|
40
|
+
id={popoverId}
|
|
41
|
+
aria-label={ariaLabel ?? "Suggestions"}
|
|
42
|
+
aria-activedescendant={highlightedItemId}
|
|
43
|
+
data-state="open"
|
|
44
|
+
{...props}
|
|
45
|
+
ref={forwardedRef}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
ComposerPrimitiveTriggerPopoverPopover.displayName =
|
|
51
|
+
"ComposerPrimitive.TriggerPopoverPopover";
|