@assistant-ui/react-native 0.1.36 → 0.1.38
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/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/primitives/actionBar/ActionBarCopy.js +1 -0
- package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarEdit.d.ts +2 -3
- package/dist/primitives/actionBar/ActionBarEdit.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarEdit.js +1 -0
- package/dist/primitives/actionBar/ActionBarEdit.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.js +1 -0
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.js +1 -0
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarReload.d.ts +2 -3
- package/dist/primitives/actionBar/ActionBarReload.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarReload.js +1 -0
- package/dist/primitives/actionBar/ActionBarReload.js.map +1 -1
- package/dist/primitives/attachment/AttachmentRemove.d.ts +2 -3
- package/dist/primitives/attachment/AttachmentRemove.d.ts.map +1 -1
- package/dist/primitives/attachment/AttachmentRemove.js +1 -0
- package/dist/primitives/attachment/AttachmentRemove.js.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerNext.d.ts +2 -3
- package/dist/primitives/branchPicker/BranchPickerNext.d.ts.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerNext.js +1 -0
- package/dist/primitives/branchPicker/BranchPickerNext.js.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerPrevious.d.ts +2 -3
- package/dist/primitives/branchPicker/BranchPickerPrevious.d.ts.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerPrevious.js +1 -0
- package/dist/primitives/branchPicker/BranchPickerPrevious.js.map +1 -1
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts +2 -3
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts.map +1 -1
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js +1 -0
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js.map +1 -1
- package/dist/primitives/composer/ComposerAddAttachment.d.ts +2 -3
- package/dist/primitives/composer/ComposerAddAttachment.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerAddAttachment.js +1 -0
- package/dist/primitives/composer/ComposerAddAttachment.js.map +1 -1
- package/dist/primitives/composer/ComposerCancel.d.ts +2 -3
- package/dist/primitives/composer/ComposerCancel.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerCancel.js +1 -0
- package/dist/primitives/composer/ComposerCancel.js.map +1 -1
- package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerInput.js.map +1 -1
- package/dist/primitives/composer/ComposerQueue.d.ts +2 -0
- package/dist/primitives/composer/ComposerQueue.js +2 -0
- package/dist/primitives/composer/ComposerQuote.d.ts +10 -0
- package/dist/primitives/composer/ComposerQuote.d.ts.map +1 -0
- package/dist/primitives/composer/ComposerQuote.js +38 -0
- package/dist/primitives/composer/ComposerQuote.js.map +1 -0
- package/dist/primitives/composer/ComposerQuoteDismiss.d.ts +9 -0
- package/dist/primitives/composer/ComposerQuoteDismiss.d.ts.map +1 -0
- package/dist/primitives/composer/ComposerQuoteDismiss.js +48 -0
- package/dist/primitives/composer/ComposerQuoteDismiss.js.map +1 -0
- package/dist/primitives/composer/ComposerQuoteText.d.ts +10 -0
- package/dist/primitives/composer/ComposerQuoteText.d.ts.map +1 -0
- package/dist/primitives/composer/ComposerQuoteText.js +40 -0
- package/dist/primitives/composer/ComposerQuoteText.js.map +1 -0
- package/dist/primitives/composer/ComposerSend.d.ts +2 -3
- package/dist/primitives/composer/ComposerSend.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerSend.js +1 -0
- package/dist/primitives/composer/ComposerSend.js.map +1 -1
- package/dist/primitives/composer.d.ts +6 -2
- package/dist/primitives/composer.js +9 -1
- package/dist/primitives/composer.js.map +1 -1
- package/dist/primitives/message/MessageIf.d.ts +3 -0
- package/dist/primitives/message/MessageIf.d.ts.map +1 -1
- package/dist/primitives/message/MessageIf.js +3 -0
- package/dist/primitives/message/MessageIf.js.map +1 -1
- package/dist/primitives/queueItem/QueueItemRemove.d.ts +9 -0
- package/dist/primitives/queueItem/QueueItemRemove.d.ts.map +1 -0
- package/dist/primitives/queueItem/QueueItemRemove.js +48 -0
- package/dist/primitives/queueItem/QueueItemRemove.js.map +1 -0
- package/dist/primitives/queueItem/QueueItemSteer.d.ts +9 -0
- package/dist/primitives/queueItem/QueueItemSteer.d.ts.map +1 -0
- package/dist/primitives/queueItem/QueueItemSteer.js +48 -0
- package/dist/primitives/queueItem/QueueItemSteer.js.map +1 -0
- package/dist/primitives/queueItem/QueueItemText.d.ts +10 -0
- package/dist/primitives/queueItem/QueueItemText.d.ts.map +1 -0
- package/dist/primitives/queueItem/QueueItemText.js +45 -0
- package/dist/primitives/queueItem/QueueItemText.js.map +1 -0
- package/dist/primitives/queueItem.d.ts +9 -0
- package/dist/primitives/queueItem.d.ts.map +1 -0
- package/dist/primitives/queueItem.js +14 -0
- package/dist/primitives/queueItem.js.map +1 -0
- package/dist/primitives/suggestion/SuggestionTrigger.d.ts +2 -3
- package/dist/primitives/suggestion/SuggestionTrigger.d.ts.map +1 -1
- package/dist/primitives/suggestion/SuggestionTrigger.js +1 -0
- package/dist/primitives/suggestion/SuggestionTrigger.js.map +1 -1
- package/dist/primitives/thread/ThreadEmpty.d.ts +4 -1
- package/dist/primitives/thread/ThreadEmpty.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadEmpty.js +12 -4
- package/dist/primitives/thread/ThreadEmpty.js.map +1 -1
- package/dist/primitives/thread/ThreadIf.d.ts +3 -0
- package/dist/primitives/thread/ThreadIf.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadIf.js +5 -6
- package/dist/primitives/thread/ThreadIf.js.map +1 -1
- package/dist/primitives/thread/ThreadMessages.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadMessages.js +2 -2
- package/dist/primitives/thread/ThreadMessages.js.map +1 -1
- package/dist/primitives/thread/ThreadSuggestion.d.ts +2 -3
- package/dist/primitives/thread/ThreadSuggestion.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadSuggestion.js +1 -0
- package/dist/primitives/thread/ThreadSuggestion.js.map +1 -1
- package/dist/primitives/threadList/ThreadListItems.d.ts.map +1 -1
- package/dist/primitives/threadList/ThreadListItems.js +8 -3
- package/dist/primitives/threadList/ThreadListItems.js.map +1 -1
- package/dist/primitives/threadList/ThreadListNew.d.ts +6 -4
- package/dist/primitives/threadList/ThreadListNew.d.ts.map +1 -1
- package/dist/primitives/threadList/ThreadListNew.js +46 -15
- package/dist/primitives/threadList/ThreadListNew.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemArchive.d.ts +2 -3
- package/dist/primitives/threadListItem/ThreadListItemArchive.d.ts.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemArchive.js +1 -0
- package/dist/primitives/threadListItem/ThreadListItemArchive.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemDelete.d.ts +2 -3
- package/dist/primitives/threadListItem/ThreadListItemDelete.d.ts.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemDelete.js +1 -0
- package/dist/primitives/threadListItem/ThreadListItemDelete.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemTrigger.d.ts +6 -4
- package/dist/primitives/threadListItem/ThreadListItemTrigger.d.ts.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemTrigger.js +46 -15
- package/dist/primitives/threadListItem/ThreadListItemTrigger.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemUnarchive.d.ts +2 -3
- package/dist/primitives/threadListItem/ThreadListItemUnarchive.d.ts.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemUnarchive.js +1 -0
- package/dist/primitives/threadListItem/ThreadListItemUnarchive.js.map +1 -1
- package/package.json +9 -8
- package/src/index.ts +2 -0
- package/src/primitives/accessibilityRole.test.tsx +335 -0
- package/src/primitives/actionBar/ActionBarCopy.tsx +1 -0
- package/src/primitives/actionBar/ActionBarEdit.tsx +6 -3
- package/src/primitives/actionBar/ActionBarFeedbackNegative.tsx +1 -1
- package/src/primitives/actionBar/ActionBarFeedbackPositive.tsx +1 -1
- package/src/primitives/actionBar/ActionBarReload.tsx +6 -3
- package/src/primitives/attachment/AttachmentRemove.tsx +11 -4
- package/src/primitives/branchPicker/BranchPickerNext.tsx +6 -3
- package/src/primitives/branchPicker/BranchPickerPrevious.tsx +6 -3
- package/src/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.tsx +4 -4
- package/src/primitives/composer/ComposerAddAttachment.tsx +10 -4
- package/src/primitives/composer/ComposerCancel.tsx +6 -3
- package/src/primitives/composer/ComposerInput.tsx +17 -15
- package/src/primitives/composer/ComposerQueue.test.tsx +9 -0
- package/src/primitives/composer/ComposerQueue.tsx +1 -0
- package/src/primitives/composer/ComposerQuote.test.tsx +163 -0
- package/src/primitives/composer/ComposerQuote.tsx +17 -0
- package/src/primitives/composer/ComposerQuoteDismiss.tsx +31 -0
- package/src/primitives/composer/ComposerQuoteText.tsx +17 -0
- package/src/primitives/composer/ComposerSend.test.tsx +26 -0
- package/src/primitives/composer/ComposerSend.tsx +3 -3
- package/src/primitives/composer.ts +13 -0
- package/src/primitives/message/MessageIf.tsx +3 -0
- package/src/primitives/queueItem/QueueItem.test.tsx +132 -0
- package/src/primitives/queueItem/QueueItemRemove.tsx +31 -0
- package/src/primitives/queueItem/QueueItemSteer.tsx +31 -0
- package/src/primitives/queueItem/QueueItemText.tsx +22 -0
- package/src/primitives/queueItem.ts +12 -0
- package/src/primitives/suggestion/SuggestionTrigger.tsx +6 -3
- package/src/primitives/thread/ThreadEmpty.test.tsx +17 -3
- package/src/primitives/thread/ThreadEmpty.tsx +7 -6
- package/src/primitives/thread/ThreadIf.test.tsx +20 -20
- package/src/primitives/thread/ThreadIf.tsx +5 -8
- package/src/primitives/thread/ThreadMessages.test.tsx +18 -4
- package/src/primitives/thread/ThreadMessages.tsx +3 -2
- package/src/primitives/thread/ThreadSuggestion.tsx +6 -3
- package/src/primitives/threadList/ThreadListItems.test.tsx +166 -0
- package/src/primitives/threadList/ThreadListItems.tsx +6 -1
- package/src/primitives/threadList/ThreadListNew.test.tsx +118 -3
- package/src/primitives/threadList/ThreadListNew.tsx +28 -5
- package/src/primitives/threadListItem/ThreadListItemArchive.tsx +6 -4
- package/src/primitives/threadListItem/ThreadListItemDelete.tsx +10 -4
- package/src/primitives/threadListItem/ThreadListItemTrigger.test.tsx +74 -0
- package/src/primitives/threadListItem/ThreadListItemTrigger.tsx +28 -5
- package/src/primitives/threadListItem/ThreadListItemUnarchive.tsx +10 -4
- package/dist/runtimes/RemoteThreadListHookInstanceManager.d.ts +0 -2
- package/dist/runtimes/RemoteThreadListHookInstanceManager.js +0 -2
- package/dist/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +0 -2
- package/dist/runtimes/RemoteThreadListThreadListRuntimeCore.js +0 -2
- package/src/runtimes/RemoteThreadListHookInstanceManager.tsx +0 -1
- package/src/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +0 -1
|
@@ -5,11 +5,44 @@ import { ThreadListNew } from "./ThreadListNew";
|
|
|
5
5
|
|
|
6
6
|
const h = vi.hoisted(() => ({
|
|
7
7
|
switchToNewThread: vi.fn<() => void>(),
|
|
8
|
+
state: { threads: { newThreadId: "new", mainThreadId: "other" } },
|
|
9
|
+
pressableProps: null as Record<string, unknown> | null,
|
|
8
10
|
}));
|
|
9
11
|
|
|
10
|
-
vi.mock("@assistant-ui/core/react", () =>
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
vi.mock("@assistant-ui/core/react", async (importOriginal) => {
|
|
13
|
+
const actual =
|
|
14
|
+
await importOriginal<typeof import("@assistant-ui/core/react")>();
|
|
15
|
+
return {
|
|
16
|
+
...actual,
|
|
17
|
+
useThreadListNew: () => ({ switchToNewThread: h.switchToNewThread }),
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
vi.mock("@assistant-ui/store", async (importOriginal) => {
|
|
22
|
+
const actual = await importOriginal<typeof import("@assistant-ui/store")>();
|
|
23
|
+
return {
|
|
24
|
+
...actual,
|
|
25
|
+
useAuiState: <T,>(selector: (s: typeof h.state) => T) => selector(h.state),
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
vi.mock("react-native", async (importOriginal) => {
|
|
30
|
+
const actual = await importOriginal<typeof import("react-native")>();
|
|
31
|
+
const React = await import("react");
|
|
32
|
+
|
|
33
|
+
const PressableMock = React.forwardRef(function PressableMock(
|
|
34
|
+
props: Record<string, unknown>,
|
|
35
|
+
ref: React.Ref<unknown>,
|
|
36
|
+
) {
|
|
37
|
+
h.pressableProps = props;
|
|
38
|
+
return React.createElement(
|
|
39
|
+
actual.Pressable as unknown as React.ElementType,
|
|
40
|
+
{ ...props, ref },
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return { ...actual, Pressable: PressableMock };
|
|
45
|
+
});
|
|
13
46
|
|
|
14
47
|
(globalThis as Record<string, unknown>).IS_REACT_ACT_ENVIRONMENT = true;
|
|
15
48
|
|
|
@@ -24,6 +57,8 @@ describe("ThreadListNew", () => {
|
|
|
24
57
|
|
|
25
58
|
beforeEach(() => {
|
|
26
59
|
h.switchToNewThread.mockReset();
|
|
60
|
+
h.state.threads = { newThreadId: "new", mainThreadId: "other" };
|
|
61
|
+
h.pressableProps = null;
|
|
27
62
|
|
|
28
63
|
container = document.createElement("div");
|
|
29
64
|
document.body.appendChild(container);
|
|
@@ -50,6 +85,11 @@ describe("ThreadListNew", () => {
|
|
|
50
85
|
return container.querySelector('[data-testid="t"]') as HTMLElement;
|
|
51
86
|
};
|
|
52
87
|
|
|
88
|
+
const accessibilityState = () =>
|
|
89
|
+
h.pressableProps?.["accessibilityState"] as
|
|
90
|
+
| Record<string, unknown>
|
|
91
|
+
| undefined;
|
|
92
|
+
|
|
53
93
|
it("fires switchToNewThread when pressed", async () => {
|
|
54
94
|
const el = await mount();
|
|
55
95
|
|
|
@@ -69,4 +109,79 @@ describe("ThreadListNew", () => {
|
|
|
69
109
|
|
|
70
110
|
expect(h.switchToNewThread).not.toHaveBeenCalled();
|
|
71
111
|
});
|
|
112
|
+
|
|
113
|
+
it("marks itself selected while the new thread is the current one", async () => {
|
|
114
|
+
h.state.threads = { newThreadId: "new", mainThreadId: "new" };
|
|
115
|
+
|
|
116
|
+
await mount();
|
|
117
|
+
|
|
118
|
+
expect(accessibilityState()).toMatchObject({ selected: true });
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("is not selected while another thread is current", async () => {
|
|
122
|
+
await mount();
|
|
123
|
+
|
|
124
|
+
expect(accessibilityState()).toMatchObject({ selected: false });
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("keeps other accessibility state the caller passes", async () => {
|
|
128
|
+
h.state.threads = { newThreadId: "new", mainThreadId: "new" };
|
|
129
|
+
|
|
130
|
+
await mount({ accessibilityState: { busy: true } });
|
|
131
|
+
|
|
132
|
+
expect(accessibilityState()).toMatchObject({ selected: true, busy: true });
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("lets the caller override the selected state", async () => {
|
|
136
|
+
h.state.threads = { newThreadId: "new", mainThreadId: "new" };
|
|
137
|
+
|
|
138
|
+
await mount({ accessibilityState: { selected: false } });
|
|
139
|
+
|
|
140
|
+
expect(accessibilityState()).toMatchObject({ selected: false });
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("lets the caller select a control the state reports inactive", async () => {
|
|
144
|
+
await mount({ accessibilityState: { selected: true } });
|
|
145
|
+
|
|
146
|
+
expect(accessibilityState()).toMatchObject({ selected: true });
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("passes isActive alongside press state to render children", async () => {
|
|
150
|
+
h.state.threads = { newThreadId: "new", mainThreadId: "new" };
|
|
151
|
+
let renderState: unknown = null;
|
|
152
|
+
|
|
153
|
+
await act(async () => {
|
|
154
|
+
root.render(
|
|
155
|
+
<ThreadListNew testID="t">
|
|
156
|
+
{(state) => {
|
|
157
|
+
renderState = state;
|
|
158
|
+
return state.isActive ? "current" : "not current";
|
|
159
|
+
}}
|
|
160
|
+
</ThreadListNew>,
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
const el = container.querySelector('[data-testid="t"]') as HTMLElement;
|
|
165
|
+
expect(el.textContent).toBe("current");
|
|
166
|
+
expect(renderState).toMatchObject({ pressed: false, isActive: true });
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it("reports an inactive render state while another thread is current", async () => {
|
|
170
|
+
let renderState: unknown = null;
|
|
171
|
+
|
|
172
|
+
await act(async () => {
|
|
173
|
+
root.render(
|
|
174
|
+
<ThreadListNew testID="t">
|
|
175
|
+
{(state) => {
|
|
176
|
+
renderState = state;
|
|
177
|
+
return state.isActive ? "current" : "not current";
|
|
178
|
+
}}
|
|
179
|
+
</ThreadListNew>,
|
|
180
|
+
);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const el = container.querySelector('[data-testid="t"]') as HTMLElement;
|
|
184
|
+
expect(el.textContent).toBe("not current");
|
|
185
|
+
expect(renderState).toMatchObject({ pressed: false, isActive: false });
|
|
186
|
+
});
|
|
72
187
|
});
|
|
@@ -1,20 +1,43 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Pressable,
|
|
4
|
+
type PressableProps,
|
|
5
|
+
type PressableStateCallbackType,
|
|
6
|
+
} from "react-native";
|
|
7
|
+
import { useAuiState } from "@assistant-ui/store";
|
|
3
8
|
import { useThreadListNew } from "@assistant-ui/core/react";
|
|
4
9
|
|
|
5
|
-
export type ThreadListNewProps = Omit<
|
|
6
|
-
|
|
10
|
+
export type ThreadListNewProps = Omit<
|
|
11
|
+
PressableProps,
|
|
12
|
+
"onPress" | "children"
|
|
13
|
+
> & {
|
|
14
|
+
children:
|
|
15
|
+
| ReactNode
|
|
16
|
+
| ((
|
|
17
|
+
state: PressableStateCallbackType & { isActive: boolean },
|
|
18
|
+
) => ReactNode);
|
|
7
19
|
};
|
|
8
20
|
|
|
9
21
|
export const ThreadListNew = ({
|
|
10
22
|
children,
|
|
23
|
+
accessibilityState,
|
|
11
24
|
...pressableProps
|
|
12
25
|
}: ThreadListNewProps) => {
|
|
26
|
+
const isActive = useAuiState(
|
|
27
|
+
(s) => s.threads.newThreadId === s.threads.mainThreadId,
|
|
28
|
+
);
|
|
13
29
|
const { switchToNewThread } = useThreadListNew();
|
|
14
30
|
|
|
15
31
|
return (
|
|
16
|
-
<Pressable
|
|
17
|
-
{
|
|
32
|
+
<Pressable
|
|
33
|
+
onPress={switchToNewThread}
|
|
34
|
+
accessibilityRole="button"
|
|
35
|
+
accessibilityState={{ selected: isActive, ...accessibilityState }}
|
|
36
|
+
{...pressableProps}
|
|
37
|
+
>
|
|
38
|
+
{typeof children === "function"
|
|
39
|
+
? (state) => children({ ...state, isActive })
|
|
40
|
+
: children}
|
|
18
41
|
</Pressable>
|
|
19
42
|
);
|
|
20
43
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
2
1
|
import { Pressable, type PressableProps } from "react-native";
|
|
3
2
|
import { useThreadListItemArchive } from "@assistant-ui/core/react";
|
|
4
3
|
|
|
5
|
-
export type ThreadListItemArchiveProps = Omit<
|
|
6
|
-
|
|
4
|
+
export type ThreadListItemArchiveProps = Omit<
|
|
5
|
+
PressableProps,
|
|
6
|
+
"onPress" | "children"
|
|
7
|
+
> & {
|
|
8
|
+
children: PressableProps["children"];
|
|
7
9
|
};
|
|
8
10
|
|
|
9
11
|
export const ThreadListItemArchive = ({
|
|
@@ -13,7 +15,7 @@ export const ThreadListItemArchive = ({
|
|
|
13
15
|
const { archive } = useThreadListItemArchive();
|
|
14
16
|
|
|
15
17
|
return (
|
|
16
|
-
<Pressable onPress={archive} {...pressableProps}>
|
|
18
|
+
<Pressable onPress={archive} accessibilityRole="button" {...pressableProps}>
|
|
17
19
|
{children}
|
|
18
20
|
</Pressable>
|
|
19
21
|
);
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
2
1
|
import { Pressable, type PressableProps } from "react-native";
|
|
3
2
|
import { useThreadListItemDelete } from "@assistant-ui/core/react";
|
|
4
3
|
|
|
5
|
-
export type ThreadListItemDeleteProps = Omit<
|
|
6
|
-
|
|
4
|
+
export type ThreadListItemDeleteProps = Omit<
|
|
5
|
+
PressableProps,
|
|
6
|
+
"onPress" | "children"
|
|
7
|
+
> & {
|
|
8
|
+
children: PressableProps["children"];
|
|
7
9
|
};
|
|
8
10
|
|
|
9
11
|
export const ThreadListItemDelete = ({
|
|
@@ -13,7 +15,11 @@ export const ThreadListItemDelete = ({
|
|
|
13
15
|
const { delete: deleteThread } = useThreadListItemDelete();
|
|
14
16
|
|
|
15
17
|
return (
|
|
16
|
-
<Pressable
|
|
18
|
+
<Pressable
|
|
19
|
+
onPress={deleteThread}
|
|
20
|
+
accessibilityRole="button"
|
|
21
|
+
{...pressableProps}
|
|
22
|
+
>
|
|
17
23
|
{children}
|
|
18
24
|
</Pressable>
|
|
19
25
|
);
|
|
@@ -5,12 +5,41 @@ import { ThreadListItemTrigger } from "./ThreadListItemTrigger";
|
|
|
5
5
|
|
|
6
6
|
const h = vi.hoisted(() => ({
|
|
7
7
|
switchTo: vi.fn<() => void>(),
|
|
8
|
+
state: {
|
|
9
|
+
threads: { mainThreadId: "thread-1" },
|
|
10
|
+
threadListItem: { id: "thread-1" },
|
|
11
|
+
},
|
|
12
|
+
pressableProps: null as Record<string, unknown> | null,
|
|
8
13
|
}));
|
|
9
14
|
|
|
10
15
|
vi.mock("@assistant-ui/core/react", () => ({
|
|
11
16
|
useThreadListItemTrigger: () => ({ switchTo: h.switchTo }),
|
|
12
17
|
}));
|
|
13
18
|
|
|
19
|
+
vi.mock("@assistant-ui/store", async (importOriginal) => {
|
|
20
|
+
const actual = await importOriginal<typeof import("@assistant-ui/store")>();
|
|
21
|
+
return {
|
|
22
|
+
...actual,
|
|
23
|
+
useAuiState: <T,>(selector: (s: typeof h.state) => T) => selector(h.state),
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
vi.mock("react-native", async (importOriginal) => {
|
|
28
|
+
const actual = await importOriginal<typeof import("react-native")>();
|
|
29
|
+
const React = await import("react");
|
|
30
|
+
const PressableMock = React.forwardRef(function PressableMock(
|
|
31
|
+
props: Record<string, unknown>,
|
|
32
|
+
ref: React.Ref<unknown>,
|
|
33
|
+
) {
|
|
34
|
+
h.pressableProps = props;
|
|
35
|
+
return React.createElement(
|
|
36
|
+
actual.Pressable as unknown as React.ElementType,
|
|
37
|
+
{ ...props, ref },
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
return { ...actual, Pressable: PressableMock };
|
|
41
|
+
});
|
|
42
|
+
|
|
14
43
|
(globalThis as Record<string, unknown>).IS_REACT_ACT_ENVIRONMENT = true;
|
|
15
44
|
|
|
16
45
|
const click = (el: Element) =>
|
|
@@ -24,6 +53,9 @@ describe("ThreadListItemTrigger", () => {
|
|
|
24
53
|
|
|
25
54
|
beforeEach(() => {
|
|
26
55
|
h.switchTo.mockReset();
|
|
56
|
+
h.state.threads.mainThreadId = "thread-1";
|
|
57
|
+
h.state.threadListItem.id = "thread-1";
|
|
58
|
+
h.pressableProps = null;
|
|
27
59
|
|
|
28
60
|
container = document.createElement("div");
|
|
29
61
|
document.body.appendChild(container);
|
|
@@ -50,6 +82,11 @@ describe("ThreadListItemTrigger", () => {
|
|
|
50
82
|
return container.querySelector('[data-testid="t"]') as HTMLElement;
|
|
51
83
|
};
|
|
52
84
|
|
|
85
|
+
const accessibilityState = () =>
|
|
86
|
+
h.pressableProps?.["accessibilityState"] as
|
|
87
|
+
| Record<string, unknown>
|
|
88
|
+
| undefined;
|
|
89
|
+
|
|
53
90
|
it("fires switchTo when pressed", async () => {
|
|
54
91
|
const el = await mount();
|
|
55
92
|
|
|
@@ -69,4 +106,41 @@ describe("ThreadListItemTrigger", () => {
|
|
|
69
106
|
|
|
70
107
|
expect(h.switchTo).not.toHaveBeenCalled();
|
|
71
108
|
});
|
|
109
|
+
|
|
110
|
+
it("marks the current thread selected", async () => {
|
|
111
|
+
await mount();
|
|
112
|
+
|
|
113
|
+
expect(accessibilityState()).toMatchObject({ selected: true });
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("does not mark another thread selected", async () => {
|
|
117
|
+
h.state.threads.mainThreadId = "thread-2";
|
|
118
|
+
|
|
119
|
+
await mount();
|
|
120
|
+
|
|
121
|
+
expect(accessibilityState()).toMatchObject({ selected: false });
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("keeps caller accessibility state overrides", async () => {
|
|
125
|
+
await mount({ accessibilityState: { busy: true, selected: false } });
|
|
126
|
+
|
|
127
|
+
expect(accessibilityState()).toMatchObject({ busy: true, selected: false });
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("passes active state alongside the Pressable state", async () => {
|
|
131
|
+
let renderState: unknown = null;
|
|
132
|
+
|
|
133
|
+
await act(async () => {
|
|
134
|
+
root.render(
|
|
135
|
+
<ThreadListItemTrigger testID="t">
|
|
136
|
+
{(state) => {
|
|
137
|
+
renderState = state;
|
|
138
|
+
return "item";
|
|
139
|
+
}}
|
|
140
|
+
</ThreadListItemTrigger>,
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
expect(renderState).toMatchObject({ pressed: false, isActive: true });
|
|
145
|
+
});
|
|
72
146
|
});
|
|
@@ -1,20 +1,43 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Pressable,
|
|
4
|
+
type PressableProps,
|
|
5
|
+
type PressableStateCallbackType,
|
|
6
|
+
} from "react-native";
|
|
7
|
+
import { useAuiState } from "@assistant-ui/store";
|
|
3
8
|
import { useThreadListItemTrigger } from "@assistant-ui/core/react";
|
|
4
9
|
|
|
5
|
-
export type ThreadListItemTriggerProps = Omit<
|
|
6
|
-
|
|
10
|
+
export type ThreadListItemTriggerProps = Omit<
|
|
11
|
+
PressableProps,
|
|
12
|
+
"onPress" | "children"
|
|
13
|
+
> & {
|
|
14
|
+
children:
|
|
15
|
+
| ReactNode
|
|
16
|
+
| ((
|
|
17
|
+
state: PressableStateCallbackType & { isActive: boolean },
|
|
18
|
+
) => ReactNode);
|
|
7
19
|
};
|
|
8
20
|
|
|
9
21
|
export const ThreadListItemTrigger = ({
|
|
10
22
|
children,
|
|
23
|
+
accessibilityState,
|
|
11
24
|
...pressableProps
|
|
12
25
|
}: ThreadListItemTriggerProps) => {
|
|
26
|
+
const isActive = useAuiState(
|
|
27
|
+
(s) => s.threads.mainThreadId === s.threadListItem.id,
|
|
28
|
+
);
|
|
13
29
|
const { switchTo } = useThreadListItemTrigger();
|
|
14
30
|
|
|
15
31
|
return (
|
|
16
|
-
<Pressable
|
|
17
|
-
{
|
|
32
|
+
<Pressable
|
|
33
|
+
onPress={switchTo}
|
|
34
|
+
accessibilityRole="button"
|
|
35
|
+
accessibilityState={{ selected: isActive, ...accessibilityState }}
|
|
36
|
+
{...pressableProps}
|
|
37
|
+
>
|
|
38
|
+
{typeof children === "function"
|
|
39
|
+
? (state) => children({ ...state, isActive })
|
|
40
|
+
: children}
|
|
18
41
|
</Pressable>
|
|
19
42
|
);
|
|
20
43
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
2
1
|
import { Pressable, type PressableProps } from "react-native";
|
|
3
2
|
import { useThreadListItemUnarchive } from "@assistant-ui/core/react";
|
|
4
3
|
|
|
5
|
-
export type ThreadListItemUnarchiveProps = Omit<
|
|
6
|
-
|
|
4
|
+
export type ThreadListItemUnarchiveProps = Omit<
|
|
5
|
+
PressableProps,
|
|
6
|
+
"onPress" | "children"
|
|
7
|
+
> & {
|
|
8
|
+
children: PressableProps["children"];
|
|
7
9
|
};
|
|
8
10
|
|
|
9
11
|
export const ThreadListItemUnarchive = ({
|
|
@@ -13,7 +15,11 @@ export const ThreadListItemUnarchive = ({
|
|
|
13
15
|
const { unarchive } = useThreadListItemUnarchive();
|
|
14
16
|
|
|
15
17
|
return (
|
|
16
|
-
<Pressable
|
|
18
|
+
<Pressable
|
|
19
|
+
onPress={unarchive}
|
|
20
|
+
accessibilityRole="button"
|
|
21
|
+
{...pressableProps}
|
|
22
|
+
>
|
|
17
23
|
{children}
|
|
18
24
|
</Pressable>
|
|
19
25
|
);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { RemoteThreadListHookInstanceManager } from "@assistant-ui/core/react";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { RemoteThreadListThreadListRuntimeCore } from "@assistant-ui/core/react";
|