aidos-ui 3.0.0 → 3.0.2

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 (81) hide show
  1. package/README.md +2 -2
  2. package/dist/Badge.d.ts +1 -2
  3. package/dist/BaseLink.d.ts +1 -1
  4. package/dist/BaseList.d.ts +1 -1
  5. package/dist/BaseListAddOn.d.ts +1 -1
  6. package/dist/BaseListItem.d.ts +1 -2
  7. package/dist/BaseListItem.js +3 -1
  8. package/dist/BaseListItem.js.map +1 -1
  9. package/dist/BaseView.d.ts +1 -1
  10. package/dist/Box.d.ts +1 -2
  11. package/dist/Card.d.ts +1 -1
  12. package/dist/Checkbox.d.ts +1 -2
  13. package/dist/Circle.d.ts +1 -2
  14. package/dist/Column.d.ts +1 -1
  15. package/dist/DarkMode.d.ts +2 -2
  16. package/dist/DatePicker.d.ts +1 -2
  17. package/dist/DesignBook.d.ts +1 -2
  18. package/dist/Dialog.d.ts +2 -2
  19. package/dist/Dropdown.d.ts +1 -2
  20. package/dist/FlexLayout.d.ts +1 -1
  21. package/dist/Icon.d.ts +1 -1
  22. package/dist/List.d.ts +5 -2
  23. package/dist/List.js +22 -10
  24. package/dist/List.js.map +1 -1
  25. package/dist/ListButtonItem.d.ts +1 -2
  26. package/dist/ListButtonItem.js +4 -2
  27. package/dist/ListButtonItem.js.map +1 -1
  28. package/dist/ListDivider.d.ts +1 -2
  29. package/dist/ListHeaderItem.d.ts +2 -3
  30. package/dist/ListHeaderItem.js +4 -2
  31. package/dist/ListHeaderItem.js.map +1 -1
  32. package/dist/ListItem.d.ts +1 -2
  33. package/dist/ListItem.js +3 -1
  34. package/dist/ListItem.js.map +1 -1
  35. package/dist/ListLinkItem.d.ts +1 -2
  36. package/dist/ListLinkItem.js +4 -2
  37. package/dist/ListLinkItem.js.map +1 -1
  38. package/dist/ListSpacer.d.ts +1 -2
  39. package/dist/Popover.d.ts +2 -2
  40. package/dist/ProgressBar.d.ts +1 -2
  41. package/dist/ProgressCircle.d.ts +1 -2
  42. package/dist/Providers.d.ts +1 -1
  43. package/dist/RootView.d.ts +1 -1
  44. package/dist/Router.d.ts +1 -2
  45. package/dist/RouterState.d.ts +1 -1
  46. package/dist/Row.d.ts +1 -1
  47. package/dist/StackContext.d.ts +1 -1
  48. package/dist/StaticCheckbox.d.ts +1 -2
  49. package/dist/Sublist.d.ts +3 -3
  50. package/dist/Sublist.js +2 -2
  51. package/dist/Sublist.js.map +1 -1
  52. package/dist/SubmitIconInput.d.ts +1 -2
  53. package/dist/Tabs.d.ts +1 -1
  54. package/dist/Text.d.ts +8 -8
  55. package/dist/TextInputWithState.d.ts +1 -1
  56. package/dist/TextPairing.d.ts +1 -1
  57. package/dist/Tooltip.d.ts +1 -1
  58. package/dist/jss.d.ts +2 -2
  59. package/dist/stateMachineContextFactory.d.ts +1 -1
  60. package/package.json +10 -3
  61. package/scripts/embeddings.js +93 -0
  62. package/scripts/openai_embeddings.js +100 -0
  63. package/scripts/publish.js +1 -0
  64. package/scripts/test_embeddings.js +47 -0
  65. package/src/BaseListItem.tsx +3 -2
  66. package/src/List.tsx +33 -16
  67. package/src/ListButtonItem.tsx +3 -3
  68. package/src/ListHeaderItem.tsx +3 -3
  69. package/src/ListItem.tsx +4 -2
  70. package/src/ListLinkItem.tsx +3 -3
  71. package/src/Sublist.tsx +4 -4
  72. package/src/docs/mdx.tsx +99 -0
  73. package/src/docs/pages.ts +112 -0
  74. package/src/docs/searchIndex.ts +1 -0
  75. package/src/pages/Badge.mdx +1 -1
  76. package/src/pages/Button.mdx +4 -4
  77. package/src/pages/Link.mdx +3 -3
  78. package/src/pages/List.mdx +107 -21
  79. package/src/pages/ListHeader.mdx +12 -16
  80. package/src/pages/_app.tsx +117 -240
  81. package/src/pages/index.mdx +1 -1
@@ -1,9 +1,8 @@
1
1
  import type { AppProps } from "next/app";
2
2
  import Link from "next/link";
3
3
  import Head from "next/head";
4
- import React, { useEffect, useRef, useState } from "react";
4
+ import React, { useCallback, useEffect, useRef, useState } from "react";
5
5
  import {
6
- Size,
7
6
  TABLET,
8
7
  cssVar,
9
8
  darkTheme,
@@ -14,13 +13,9 @@ import {
14
13
  mobile,
15
14
  tablet,
16
15
  } from "../jss";
17
- import { MDXProvider } from "@mdx-js/react";
18
16
  import { Providers } from "../Providers";
19
17
  import { BaseView } from "../BaseView";
20
- import { H1, H2, H3, Li, P, Span } from "../Text";
21
18
  import { ListDivider } from "../ListDivider";
22
- import { ListHeaderItem } from "../ListHeaderItem";
23
- import { Roboto } from "next/font/google";
24
19
  import { List } from "../List";
25
20
  import { ListLinkItem } from "../ListLinkItem";
26
21
  import { Row } from "../Row";
@@ -36,208 +31,23 @@ import "./prism.css";
36
31
  import { IconButton } from "../IconButton";
37
32
  import { Column } from "../Column";
38
33
  import { Icon } from "../Icon";
39
- import { BaseLink, BaseLinkComponentOverrideContext } from "../BaseLink";
34
+ import { BaseLinkComponentOverrideContext } from "../BaseLink";
35
+ import { DocsMDXProvider, labelToID } from "../docs/mdx";
36
+ import { dot } from "@xenova/transformers";
37
+ import { pages } from "../docs/pages";
40
38
 
41
- const monospace = Roboto({ weight: "400", subsets: ["latin"] });
42
-
43
- type PageLink = {
44
- type: "link";
45
- page: string;
46
- name?: string;
47
- headlineSize?: Size;
48
- headlineBold?: boolean;
49
- };
50
-
51
- type Page =
52
- | PageLink
53
- | {
54
- type: "section";
55
- label: string;
56
- content: Array<PageLink>;
57
- };
58
-
59
- const pages: Array<Page> = [
60
- {
61
- type: "link",
62
- page: "",
63
- name: "Aidos UI",
64
- headlineSize: "large",
65
- headlineBold: true,
66
- },
67
- {
68
- type: "section",
69
- label: "CSS",
70
- content: [{ type: "link", page: "css-in-js", name: "jss" }],
71
- },
72
- {
73
- type: "section",
74
- label: "Primary components",
75
- content: [
76
- { type: "link", page: "FlexLayout" },
77
- { type: "link", page: "Text" },
78
- { type: "link", page: "TextPairing" },
79
- { type: "link", page: "Icon" },
80
- ],
81
- },
82
- {
83
- type: "section",
84
- label: "Buttons and links",
85
- content: [
86
- { type: "link", page: "Button" },
87
- { type: "link", page: "Link" },
88
- { type: "link", page: "IconButton" },
89
- ],
90
- },
91
- {
92
- type: "section",
93
- label: "Inputs",
94
- content: [
95
- { type: "link", page: "TextInput" },
96
- { type: "link", page: "RangeInput" },
97
- { type: "link", page: "TimeInput" },
98
- { type: "link", page: "Checkbox" },
99
- ],
100
- },
101
- {
102
- type: "section",
103
- label: "List",
104
- content: [
105
- { type: "link", page: "List" },
106
- { type: "link", page: "ListHeader" },
107
- { type: "link", page: "navigation", name: "List navigation" },
108
- ],
109
- },
110
- {
111
- type: "section",
112
- label: "Modals",
113
- content: [
114
- { type: "link", page: "Dialog" },
115
- { type: "link", page: "Popover" },
116
- { type: "link", page: "Tooltip" },
117
- ],
118
- },
119
- {
120
- type: "section",
121
- label: "Visual indicators",
122
- content: [
123
- { type: "link", page: "Badge" },
124
- { type: "link", page: "ProgressBar" },
125
- { type: "link", page: "ProgressCircle" },
126
- ],
127
- },
128
- {
129
- type: "section",
130
- label: "Complex components",
131
- content: [
132
- { type: "link", page: "Tabs" },
133
- { type: "link", page: "Calendar" },
134
- ],
135
- },
136
- {
137
- type: "section",
138
- label: "Hooks",
139
- content: [
140
- { type: "link", page: "useCookie" },
141
- { type: "link", page: "useNavigation" },
142
- { type: "link", page: "useKeyboard" },
143
- { type: "link", page: "useRefEffect" },
144
- { type: "link", page: "usePromise" },
145
- ],
146
- },
147
- {
148
- type: "section",
149
- label: "Utils",
150
- content: [{ type: "link", page: "Hashing" }],
151
- },
152
- ];
153
-
154
- const components = {
155
- h1: (props) => (
156
- <H1 jsStyle={{ marginBottom: cssVar("--spacing-xl") }} {...props} />
157
- ),
158
- h2: (props) => (
159
- <H2
160
- id={props.children
161
- .replace(/[A-Z]/g, (m) => m.toLowerCase())
162
- .replace(/\s/g, "-")
163
- .replace(/\?/g, "")}
164
- jsStyle={{ marginBottom: cssVar("--spacing-l") }}
165
- {...props}
166
- />
167
- ),
168
- h3: (props) => {
169
- return <H3 {...props} />;
170
- },
171
- p: (props) => (
172
- <P jsStyle={{ marginBottom: cssVar("--spacing-m") }} {...props} />
173
- ),
174
- span: (props) => <Span {...props} />,
175
- li: (props) => (
176
- <Li jsStyle={{ marginBottom: cssVar("--spacing-s") }} {...props} />
177
- ),
178
- a: (props) => {
179
- return (
180
- <BaseLink
181
- bare
182
- color="positive"
183
- jsStyle={{
184
- display: "inline-block",
185
- paddingBottom: cssVar("--spacing-s"),
186
- paddingTop: cssVar("--spacing-s"),
187
- }}
188
- href={props.href}
189
- >
190
- {props.children}
191
- </BaseLink>
192
- );
193
- },
194
- hr: () => (
195
- <BaseView
196
- jsStyle={{
197
- marginBottom: cssVar("--spacing-xxl"),
198
- marginTop: cssVar("--spacing-xxl"),
199
- }}
200
- >
201
- <ListDivider />
202
- </BaseView>
203
- ),
204
- pre: (props) => {
205
- return (
206
- <pre
207
- style={{ borderRadius: cssVar("--border-radius-l") }}
208
- className={props.children.props.className}
209
- tabIndex={0}
210
- >
211
- <code className={props.children.props.className}>
212
- {props.children.props.children}
213
- </code>
214
- </pre>
215
- );
216
- },
217
- code: ({ children }) => (
218
- <span
219
- className={monospace.className}
220
- style={{
221
- color: cssVar("--primary-text"),
222
- backgroundColor: cssVar("--secondary-background"),
223
- borderRadius: cssVar("--border-radius-m"),
224
- padding: cssVar("--spacing-xs"),
225
- border: `1px solid ${cssVar("--divider")}`,
226
- display: "inline-block",
227
- }}
228
- >
229
- {children}
230
- </span>
231
- ),
232
- };
39
+ const transformers = import("@xenova/transformers");
40
+ const searchIndex = import("../docs/searchIndex").then(
41
+ (module) => module.index
42
+ );
233
43
 
234
44
  export default function App({ Component, pageProps }: AppProps) {
235
45
  const router = useRouter();
236
-
237
46
  const [pathname, setPathname] = useState(router.pathname);
238
47
  const [showList, setShowList] = useState(false);
239
48
  const [query, setQuery] = useState("");
240
- const filteredPagesRef = useRef<Array<Page>>([]);
49
+ const [queriedPages, setQueriedPages] = useState<Array<PageLink>>([]);
50
+ const queriedPagesRef = useRef<Array<PageLink>>([]);
241
51
  const queryIndexRef = useRef<void | number>(undefined);
242
52
  const queryInputRef = useKeyboard<HTMLInputElement>([
243
53
  {
@@ -265,7 +75,7 @@ export default function App({ Component, pageProps }: AppProps) {
265
75
  onlyWhenFocused: true,
266
76
  action: () => {
267
77
  setQueryIndex((current) =>
268
- Math.min((current ?? 0) + 1, filteredPagesRef.current.length - 1)
78
+ Math.min((current ?? 0) + 1, queriedPagesRef.current.length - 1)
269
79
  );
270
80
  },
271
81
  },
@@ -275,7 +85,7 @@ export default function App({ Component, pageProps }: AppProps) {
275
85
  ctrlKey: true,
276
86
  action: () => {
277
87
  setQueryIndex((current) =>
278
- Math.min((current ?? 0) + 1, filteredPagesRef.current.length - 1)
88
+ Math.min((current ?? 0) + 1, queriedPagesRef.current.length - 1)
279
89
  );
280
90
  },
281
91
  },
@@ -285,10 +95,13 @@ export default function App({ Component, pageProps }: AppProps) {
285
95
  action: () => {
286
96
  if (queryIndexRef.current === undefined) {
287
97
  return;
98
+ } else if (queriedPagesRef.current.length === 0) {
99
+ return;
288
100
  } else {
289
- const element = filteredPagesRef.current[queryIndexRef.current];
101
+ const element = queriedPagesRef.current[queryIndexRef.current];
290
102
  if (element.type === "link") {
291
103
  window.open(`/${element.page}`, "_self");
104
+ setQuery("");
292
105
  }
293
106
  }
294
107
  },
@@ -308,42 +121,106 @@ export default function App({ Component, pageProps }: AppProps) {
308
121
  .trim()
309
122
  .toLowerCase();
310
123
 
124
+ const isQuerying = sanetisedQuery.length > 0;
125
+
311
126
  useEffect(() => {
312
- if (sanetisedQuery.length === 0) {
313
- setQueryIndex(undefined);
127
+ if (isQuerying) {
128
+ setQueryIndex(0);
314
129
  if (window.innerWidth <= TABLET) {
315
- setShowList(false);
130
+ setShowList(true);
316
131
  }
317
132
  } else {
318
- setQueryIndex(0);
133
+ setQueryIndex(undefined);
319
134
  if (window.innerWidth <= TABLET) {
320
- setShowList(true);
135
+ setShowList(false);
321
136
  }
322
137
  }
323
- }, [sanetisedQuery]);
138
+ }, [isQuerying]);
324
139
 
325
140
  useEffect(() => {
326
141
  queryIndexRef.current = queryIndex;
327
142
  }, [queryIndex]);
328
143
 
329
- filteredPagesRef.current =
330
- sanetisedQuery.length > 0
331
- ? pages
332
- .flatMap((element) =>
333
- element.type === "section" ? element.content : element
334
- )
335
- .filter((element) => {
336
- return (
337
- element.page.toLowerCase().includes(sanetisedQuery) ||
338
- element?.name?.toLowerCase()?.includes(sanetisedQuery)
339
- );
340
- })
341
- : pages;
144
+ useEffect(() => {
145
+ if (sanetisedQuery.length === 0) {
146
+ return;
147
+ }
148
+
149
+ let state = { cancel: false };
150
+
151
+ async function run() {
152
+ const data = await searchIndex;
153
+
154
+ if (state.cancel) {
155
+ return;
156
+ }
157
+ const { pipeline } = await transformers;
158
+ if (state.cancel) {
159
+ return;
160
+ }
161
+ const generateEmbeddings = await pipeline(
162
+ "feature-extraction",
163
+ "Xenova/all-MiniLM-L6-v2"
164
+ );
165
+ if (state.cancel) {
166
+ return;
167
+ }
168
+ const queryEmbeddings = await generateEmbeddings(query, {
169
+ normalize: true,
170
+ pooling: "mean",
171
+ }).then((embedding) => embedding.data);
172
+ if (state.cancel) {
173
+ return;
174
+ }
175
+
176
+ let seen = new Set();
177
+
178
+ queriedPagesRef.current = data.index
179
+ .map((element) => {
180
+ return {
181
+ ...element,
182
+ dot: dot(queryEmbeddings, element.embedding),
183
+ };
184
+ })
185
+ .filter((element) => element.dot > 0.2)
186
+ .sort((a, b) => b.dot - a.dot)
187
+ .slice(0, 5)
188
+ .filter((result) => {
189
+ if (seen.has(result.filename)) {
190
+ return false;
191
+ } else {
192
+ seen.add(result.filename);
193
+ return true;
194
+ }
195
+ })
196
+ .map((result) => {
197
+ const heading =
198
+ result.headingDepth > 1 && result.heading.length > 0
199
+ ? labelToID(result.heading)
200
+ : null;
201
+ const page = result.filename === "index" ? "" : result.filename;
202
+ return {
203
+ type: "link",
204
+ name: result.filename,
205
+ page: heading ? `${page}#${heading}` : page,
206
+ };
207
+ });
208
+ setQueriedPages(queriedPagesRef.current.slice());
209
+ }
210
+
211
+ run();
212
+
213
+ return () => {
214
+ state.cancel = true;
215
+ };
216
+ }, [sanetisedQuery]);
342
217
 
343
218
  useEffect(() => {
344
219
  highlightAll();
345
220
  });
346
221
 
222
+ const link = useCallback((props) => <Link {...props} />, []);
223
+
347
224
  return (
348
225
  <>
349
226
  <Head>
@@ -351,10 +228,9 @@ export default function App({ Component, pageProps }: AppProps) {
351
228
  <meta name="description" content="A humble UI toolkit" />
352
229
  <meta name="viewport" content="width=device-width, initial-scale=1" />
353
230
  </Head>
354
- <BaseLinkComponentOverrideContext.Provider value={Link}>
231
+ <BaseLinkComponentOverrideContext.Provider value={link}>
355
232
  <Providers themes={{ light: lightTheme, dark: darkTheme }}>
356
- {/* @ts-ignore */}
357
- <MDXProvider components={components}>
233
+ <DocsMDXProvider>
358
234
  <BaseView
359
235
  jsStyle={[
360
236
  {
@@ -409,6 +285,10 @@ export default function App({ Component, pageProps }: AppProps) {
409
285
  <TextInput
410
286
  rootJSStyle={{ flexGrow: 1 }}
411
287
  ref={queryInputRef}
288
+ role="combobox"
289
+ aria-haspopup="grid"
290
+ aria-expanded={isQuerying ? "true" : "false"}
291
+ aria-controls=""
412
292
  placeholder="Search (⌘K)"
413
293
  value={query}
414
294
  onValueChange={(value) => {
@@ -423,7 +303,7 @@ export default function App({ Component, pageProps }: AppProps) {
423
303
  <IconLink
424
304
  aria-label="github"
425
305
  target="_blank"
426
- href="https://github.com/germtb/simple-ui"
306
+ href="https://github.com/germtb/aidos-ui"
427
307
  icon="fa-github"
428
308
  size="medium"
429
309
  color="secondary"
@@ -478,27 +358,27 @@ export default function App({ Component, pageProps }: AppProps) {
478
358
  jsStyle={[{ overflow: "scroll" }]}
479
359
  ariaLabel={"API"}
480
360
  >
481
- {(filteredPagesRef.current.length > 0
482
- ? filteredPagesRef.current
483
- : pages
484
- ).map((element, index) => {
361
+ {(isQuerying ? queriedPages : pages).map((element, index) => {
485
362
  if (element.type === "link") {
486
363
  const page = element.page;
364
+ const name = element.name;
365
+
487
366
  return (
488
367
  <ListLinkItem
489
- key={page}
368
+ key={isQuerying ? `${index}-${page}` : page}
490
369
  bare
491
370
  onClick={() => {
492
371
  setPathname(`/${page}`);
372
+ setQuery("");
493
373
  setShowList(false);
494
374
  }}
495
375
  selected={
496
- sanetisedQuery.length > 0
376
+ isQuerying
497
377
  ? index === queryIndex
498
378
  : pathname === `/${page}`
499
379
  }
500
380
  href={`/${page}`}
501
- headline={element.name ?? page}
381
+ headline={name ?? page}
502
382
  headlineSize={element.headlineSize}
503
383
  headlineBold={element.headlineBold}
504
384
  />
@@ -508,6 +388,7 @@ export default function App({ Component, pageProps }: AppProps) {
508
388
  <Sublist
509
389
  key={`section-${element.label}`}
510
390
  label={element.label}
391
+ labelBold
511
392
  bare
512
393
  >
513
394
  {element.content.map((element) => {
@@ -520,11 +401,7 @@ export default function App({ Component, pageProps }: AppProps) {
520
401
  setPathname(`/${page}`);
521
402
  setShowList(false);
522
403
  }}
523
- selected={
524
- sanetisedQuery.length > 0
525
- ? index === queryIndex
526
- : pathname === `/${page}`
527
- }
404
+ selected={pathname === `/${page}`}
528
405
  href={`/${page}`}
529
406
  headline={element.name ?? page}
530
407
  headlineSize={element.headlineSize}
@@ -553,7 +430,7 @@ export default function App({ Component, pageProps }: AppProps) {
553
430
  <Component {...pageProps} />
554
431
  </BaseView>
555
432
  </BaseView>
556
- </MDXProvider>
433
+ </DocsMDXProvider>
557
434
  </Providers>
558
435
  </BaseLinkComponentOverrideContext.Provider>
559
436
  </>
@@ -45,7 +45,7 @@ As few dependencies as possible, to keep things light and under control. The onl
45
45
  This library can be installed through npm
46
46
 
47
47
  ```bash
48
- npm install --save simple-ui-core
48
+ npm install --save aidos-ui
49
49
  ```
50
50
 
51
51
  ---