@databiosphere/findable-ui 50.1.1 → 50.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/CHANGELOG.md +27 -0
  3. package/lib/components/Layout/components/Footer/components/PoweredByCleverCanary/poweredByCleverCanary.d.ts +12 -0
  4. package/lib/components/Layout/components/Footer/components/PoweredByCleverCanary/poweredByCleverCanary.js +17 -0
  5. package/lib/components/Layout/components/Footer/components/PoweredByCleverCanary/types.d.ts +6 -0
  6. package/lib/components/Layout/components/Footer/components/PoweredByCleverCanary/types.js +1 -0
  7. package/lib/components/Layout/components/Footer/footer.d.ts +5 -1
  8. package/lib/components/Layout/components/Footer/footer.js +4 -3
  9. package/lib/components/Layout/components/Footer/stories/footer.stories.d.ts +6 -0
  10. package/lib/components/Layout/components/Footer/{footer.stories.js → stories/footer.stories.js} +11 -19
  11. package/lib/views/ResearchView/assistant/assistant.js +1 -1
  12. package/lib/views/ResearchView/assistant/components/Form/form.js +1 -9
  13. package/lib/views/ResearchView/assistant/components/Input/hooks/UseControlledInput/hook.d.ts +6 -0
  14. package/lib/views/ResearchView/assistant/components/Input/hooks/UseControlledInput/hook.js +26 -0
  15. package/lib/views/ResearchView/assistant/components/Input/hooks/UseControlledInput/types.d.ts +9 -0
  16. package/lib/views/ResearchView/assistant/components/Input/hooks/UseControlledInput/types.js +1 -0
  17. package/lib/views/ResearchView/assistant/components/Input/hooks/UseKeyShortCuts/hook.d.ts +3 -1
  18. package/lib/views/ResearchView/assistant/components/Input/hooks/UseKeyShortCuts/hook.js +6 -5
  19. package/lib/views/ResearchView/assistant/components/Input/hooks/UseKeyShortCuts/types.d.ts +3 -1
  20. package/lib/views/ResearchView/assistant/components/Input/hooks/UseKeyShortCuts/utils.d.ts +13 -7
  21. package/lib/views/ResearchView/assistant/components/Input/hooks/UseKeyShortCuts/utils.js +15 -11
  22. package/lib/views/ResearchView/assistant/components/Input/input.js +7 -5
  23. package/lib/views/ResearchView/assistant/components/Input/types.d.ts +1 -1
  24. package/package.json +4 -4
  25. package/src/components/Layout/components/Footer/components/PoweredByCleverCanary/poweredByCleverCanary.tsx +31 -0
  26. package/src/components/Layout/components/Footer/components/PoweredByCleverCanary/types.ts +8 -0
  27. package/src/components/Layout/components/Footer/footer.tsx +6 -1
  28. package/src/components/Layout/components/Footer/stories/footer.stories.tsx +63 -0
  29. package/src/images/cc.svg +18 -0
  30. package/src/views/ResearchView/assistant/assistant.tsx +1 -1
  31. package/src/views/ResearchView/assistant/components/Form/form.tsx +1 -8
  32. package/src/views/ResearchView/assistant/components/Input/hooks/UseControlledInput/hook.ts +33 -0
  33. package/src/views/ResearchView/assistant/components/Input/hooks/UseControlledInput/types.ts +12 -0
  34. package/src/views/ResearchView/assistant/components/Input/hooks/UseKeyShortCuts/hook.ts +10 -8
  35. package/src/views/ResearchView/assistant/components/Input/hooks/UseKeyShortCuts/types.ts +4 -1
  36. package/src/views/ResearchView/assistant/components/Input/hooks/UseKeyShortCuts/utils.ts +19 -17
  37. package/src/views/ResearchView/assistant/components/Input/input.tsx +15 -6
  38. package/src/views/ResearchView/assistant/components/Input/types.ts +2 -1
  39. package/tests/research.useKeyShortCuts.test.ts +26 -24
  40. package/lib/components/Layout/components/Footer/footer.stories.d.ts +0 -27
  41. package/src/components/Layout/components/Footer/footer.stories.tsx +0 -69
@@ -14,6 +14,7 @@ interface MockInputElement {
14
14
 
15
15
  // Mock useChatState
16
16
  const mockUseChatState = jest.fn();
17
+ const mockSetValue = jest.fn();
17
18
 
18
19
  jest.unstable_mockModule(
19
20
  "../src/views/ResearchView/state/hooks/UseChatState/hook",
@@ -96,12 +97,13 @@ function setupMockState(messages: Message[]): void {
96
97
  describe("useKeyShortCuts", () => {
97
98
  beforeEach(() => {
98
99
  mockUseChatState.mockReset();
100
+ mockSetValue.mockReset();
99
101
  setupMockState([]);
100
102
  });
101
103
 
102
104
  describe("enter key", () => {
103
105
  it("should prevent default and submit form on Enter", () => {
104
- const { result } = renderHook(() => useKeyShortCuts());
106
+ const { result } = renderHook(() => useKeyShortCuts(mockSetValue));
105
107
  const inputEl = createMockInputEl("some query");
106
108
  const event = createMockKeyEvent("Enter", inputEl);
107
109
 
@@ -112,7 +114,7 @@ describe("useKeyShortCuts", () => {
112
114
  });
113
115
 
114
116
  it("should not prevent default on Shift+Enter", () => {
115
- const { result } = renderHook(() => useKeyShortCuts());
117
+ const { result } = renderHook(() => useKeyShortCuts(mockSetValue));
116
118
  const inputEl = createMockInputEl("some query");
117
119
  const event = createMockKeyEvent("Enter", inputEl, true);
118
120
 
@@ -125,13 +127,13 @@ describe("useKeyShortCuts", () => {
125
127
 
126
128
  describe("escape key", () => {
127
129
  it("should clear input value on Escape", () => {
128
- const { result } = renderHook(() => useKeyShortCuts());
130
+ const { result } = renderHook(() => useKeyShortCuts(mockSetValue));
129
131
  const inputEl = createMockInputEl("some text");
130
132
  const event = createMockKeyEvent("Escape", inputEl);
131
133
 
132
134
  result.current.onKeyDown(event);
133
135
 
134
- expect(inputEl.value).toBe("");
136
+ expect(mockSetValue).toHaveBeenCalledWith("");
135
137
  });
136
138
  });
137
139
 
@@ -142,13 +144,13 @@ describe("useKeyShortCuts", () => {
142
144
  createPromptMessage("response"),
143
145
  createUserMessage("second query"),
144
146
  ]);
145
- const { result } = renderHook(() => useKeyShortCuts());
147
+ const { result } = renderHook(() => useKeyShortCuts(mockSetValue));
146
148
  const inputEl = createMockInputEl();
147
149
  const event = createMockKeyEvent("ArrowUp", inputEl);
148
150
 
149
151
  result.current.onKeyDown(event);
150
152
 
151
- expect(inputEl.value).toBe("second query");
153
+ expect(mockSetValue).toHaveBeenCalledWith("second query");
152
154
  });
153
155
 
154
156
  it("should navigate through multiple history entries on ArrowUp", () => {
@@ -156,25 +158,25 @@ describe("useKeyShortCuts", () => {
156
158
  createUserMessage("first query"),
157
159
  createUserMessage("second query"),
158
160
  ]);
159
- const { result } = renderHook(() => useKeyShortCuts());
161
+ const { result } = renderHook(() => useKeyShortCuts(mockSetValue));
160
162
  const inputEl = createMockInputEl();
161
163
 
162
164
  result.current.onKeyDown(createMockKeyEvent("ArrowUp", inputEl));
163
- expect(inputEl.value).toBe("second query");
165
+ expect(mockSetValue).toHaveBeenLastCalledWith("second query");
164
166
 
165
167
  result.current.onKeyDown(createMockKeyEvent("ArrowUp", inputEl));
166
- expect(inputEl.value).toBe("first query");
168
+ expect(mockSetValue).toHaveBeenLastCalledWith("first query");
167
169
  });
168
170
 
169
171
  it("should clamp at oldest history entry on ArrowUp", () => {
170
172
  setupMockState([createUserMessage("only query")]);
171
- const { result } = renderHook(() => useKeyShortCuts());
173
+ const { result } = renderHook(() => useKeyShortCuts(mockSetValue));
172
174
  const inputEl = createMockInputEl();
173
175
 
174
176
  result.current.onKeyDown(createMockKeyEvent("ArrowUp", inputEl));
175
177
  result.current.onKeyDown(createMockKeyEvent("ArrowUp", inputEl));
176
178
 
177
- expect(inputEl.value).toBe("only query");
179
+ expect(mockSetValue).toHaveBeenLastCalledWith("only query");
178
180
  });
179
181
 
180
182
  it("should navigate forward on ArrowDown and restore draft at index -1", () => {
@@ -182,63 +184,63 @@ describe("useKeyShortCuts", () => {
182
184
  createUserMessage("first query"),
183
185
  createUserMessage("second query"),
184
186
  ]);
185
- const { result } = renderHook(() => useKeyShortCuts());
187
+ const { result } = renderHook(() => useKeyShortCuts(mockSetValue));
186
188
  const inputEl = createMockInputEl("my draft");
187
189
 
188
190
  // Navigate up twice.
189
191
  result.current.onKeyDown(createMockKeyEvent("ArrowUp", inputEl));
190
192
  result.current.onKeyDown(createMockKeyEvent("ArrowUp", inputEl));
191
- expect(inputEl.value).toBe("first query");
193
+ expect(mockSetValue).toHaveBeenLastCalledWith("first query");
192
194
 
193
195
  // Navigate down once.
194
196
  result.current.onKeyDown(createMockKeyEvent("ArrowDown", inputEl));
195
- expect(inputEl.value).toBe("second query");
197
+ expect(mockSetValue).toHaveBeenLastCalledWith("second query");
196
198
 
197
199
  // Navigate down to restore draft.
198
200
  result.current.onKeyDown(createMockKeyEvent("ArrowDown", inputEl));
199
- expect(inputEl.value).toBe("my draft");
201
+ expect(mockSetValue).toHaveBeenLastCalledWith("my draft");
200
202
  });
201
203
 
202
204
  it("should not navigate on ArrowDown when not browsing history", () => {
203
205
  setupMockState([createUserMessage("some query")]);
204
- const { result } = renderHook(() => useKeyShortCuts());
206
+ const { result } = renderHook(() => useKeyShortCuts(mockSetValue));
205
207
  const inputEl = createMockInputEl("current text");
206
208
  const event = createMockKeyEvent("ArrowDown", inputEl);
207
209
 
208
210
  result.current.onKeyDown(event);
209
211
 
210
- expect(inputEl.value).toBe("current text");
212
+ expect(mockSetValue).not.toHaveBeenCalled();
211
213
  });
212
214
 
213
215
  it("should save draft before entering history", () => {
214
216
  setupMockState([createUserMessage("history entry")]);
215
- const { result } = renderHook(() => useKeyShortCuts());
217
+ const { result } = renderHook(() => useKeyShortCuts(mockSetValue));
216
218
  const inputEl = createMockInputEl("my draft text");
217
219
 
218
220
  // Navigate up to save draft and enter history.
219
221
  result.current.onKeyDown(createMockKeyEvent("ArrowUp", inputEl));
220
- expect(inputEl.value).toBe("history entry");
222
+ expect(mockSetValue).toHaveBeenLastCalledWith("history entry");
221
223
 
222
224
  // Navigate down to restore draft.
223
225
  result.current.onKeyDown(createMockKeyEvent("ArrowDown", inputEl));
224
- expect(inputEl.value).toBe("my draft text");
226
+ expect(mockSetValue).toHaveBeenLastCalledWith("my draft text");
225
227
  });
226
228
  });
227
229
 
228
230
  describe("tab key", () => {
229
231
  it("should fill input with placeholder when input is empty", () => {
230
- const { result } = renderHook(() => useKeyShortCuts());
232
+ const { result } = renderHook(() => useKeyShortCuts(mockSetValue));
231
233
  const inputEl = createMockInputEl("", "Search for studies...");
232
234
  const event = createMockKeyEvent("Tab", inputEl);
233
235
 
234
236
  result.current.onKeyDown(event);
235
237
 
236
238
  expect(event.preventDefault).toHaveBeenCalled();
237
- expect(inputEl.value).toBe("Search for studies...");
239
+ expect(mockSetValue).toHaveBeenCalledWith("Search for studies...");
238
240
  });
239
241
 
240
242
  it("should not prevent default when input has value", () => {
241
- const { result } = renderHook(() => useKeyShortCuts());
243
+ const { result } = renderHook(() => useKeyShortCuts(mockSetValue));
242
244
  const inputEl = createMockInputEl(
243
245
  "existing text",
244
246
  "Search for studies...",
@@ -248,7 +250,7 @@ describe("useKeyShortCuts", () => {
248
250
  result.current.onKeyDown(event);
249
251
 
250
252
  expect(event.preventDefault).not.toHaveBeenCalled();
251
- expect(inputEl.value).toBe("existing text");
253
+ expect(mockSetValue).not.toHaveBeenCalled();
252
254
  });
253
255
  });
254
256
  });
@@ -1,27 +0,0 @@
1
- import type { StoryObj } from "@storybook/nextjs-vite";
2
- import { Footer } from "./footer";
3
- declare const meta: {
4
- argTypes: {
5
- Branding: {
6
- control: {
7
- disabled: boolean;
8
- };
9
- };
10
- navLinks: {
11
- control: "object";
12
- };
13
- socials: {
14
- control: {
15
- disabled: boolean;
16
- };
17
- };
18
- };
19
- component: ({ Branding, className, navLinks, socials, versionInfo, }: import("./footer").FooterProps) => import("react").JSX.Element;
20
- parameters: {
21
- layout: string;
22
- };
23
- title: string;
24
- };
25
- export default meta;
26
- type Story = StoryObj<typeof Footer>;
27
- export declare const FooterStory: Story;
@@ -1,69 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/nextjs-vite";
2
- import logo from "../../../../images/logo.svg";
3
- import { DiscourseIcon } from "../../../common/CustomIcon/components/DiscourseIcon/discourseIcon";
4
- import { FacebookIcon } from "../../../common/CustomIcon/components/FacebookIcon/facebookIcon";
5
- import { GitHubIcon } from "../../../common/CustomIcon/components/GitHubIcon/gitHubIcon";
6
- import { XIcon } from "../../../common/CustomIcon/components/XIcon/xIcon";
7
- import { YouTubeIcon } from "../../../common/CustomIcon/components/YouTubeIcon/youTubeIcon";
8
- import { Logo } from "../Header/components/Content/components/Logo/logo";
9
- import { Footer } from "./footer";
10
-
11
- const meta = {
12
- argTypes: {
13
- Branding: { control: { disabled: true } },
14
- navLinks: { control: "object" },
15
- socials: { control: { disabled: true } },
16
- },
17
- component: Footer,
18
- parameters: {
19
- layout: "fullscreen",
20
- },
21
- title: "Components/Layout/Footer",
22
- } satisfies Meta<typeof Footer>;
23
-
24
- export default meta;
25
-
26
- type Story = StoryObj<typeof Footer>;
27
-
28
- export const FooterStory: Story = {
29
- args: {
30
- Branding: <Logo alt="logo" height={24} link={"/"} src={logo.src} />,
31
- navLinks: [
32
- {
33
- label: "Help",
34
- url: "https://support.google.com/",
35
- },
36
- {
37
- label: "Privacy",
38
- url: "https://policies.google.com/privacy?hl=en-US",
39
- },
40
- ],
41
- socials: [
42
- {
43
- Icon: DiscourseIcon,
44
- label: null,
45
- url: "https://www.discourse.org/",
46
- },
47
- {
48
- Icon: XIcon,
49
- label: null,
50
- url: "https://twitter.com",
51
- },
52
- {
53
- Icon: FacebookIcon,
54
- label: null,
55
- url: "https://facebook.com",
56
- },
57
- {
58
- Icon: YouTubeIcon,
59
- label: null,
60
- url: "https://www.youtube.com",
61
- },
62
- {
63
- Icon: GitHubIcon,
64
- label: null,
65
- url: "https://github.com",
66
- },
67
- ],
68
- },
69
- };