@anchrd/intel-ui 0.4.0 → 0.5.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 (36) hide show
  1. package/package.json +1 -1
  2. package/src/app/action-slot/action-slot.tsx +23 -0
  3. package/src/app/app-sidebar/app-sidebar.tsx +39 -24
  4. package/src/app/app-tree/app-tree.tsx +431 -60
  5. package/src/app/app.tsx +17 -2
  6. package/src/app/sidebar-resize-handle/sidebar-resize-handle.tsx +2 -1
  7. package/src/app/tree-move/tree-move.tsx +197 -0
  8. package/src/app/user-footer/user-footer.tsx +73 -46
  9. package/src/app/view-toggle/view-toggle.tsx +77 -0
  10. package/src/blocknote-view/blocknote-view.tsx +19 -2
  11. package/src/branding/favicon.default.svg +2 -2
  12. package/src/branding/favicon.svg +2 -2
  13. package/src/components/ui/dropdown-menu.tsx +78 -0
  14. package/src/data/intel-data-provider/intel-data-provider.ts +120 -54
  15. package/src/data/intel-data-provider/intel-data-provider.types.ts +47 -12
  16. package/src/document-link/document-link.tsx +132 -0
  17. package/src/flow-runs/flow-runs.tsx +225 -0
  18. package/src/flows/flows.tsx +670 -271
  19. package/src/flows/node-icon/node-icon.ts +28 -0
  20. package/src/flows/node-palette/node-palette.tsx +174 -0
  21. package/src/flows/node-palette/node-palette.types.ts +15 -0
  22. package/src/graph-pane/graph-pane.tsx +44 -0
  23. package/src/i18n/en.json +141 -24
  24. package/src/knowledge/knowledge.tsx +69 -355
  25. package/src/knowledge-editor/knowledge-editor.tsx +169 -21
  26. package/src/knowledge-graph/knowledge-graph.ts +26 -24
  27. package/src/knowledge-graph/knowledge-graph.tsx +33 -24
  28. package/src/knowledge-table/knowledge-table.tsx +129 -0
  29. package/src/main.tsx +2 -2
  30. package/src/resource-menu/resource-menu.tsx +580 -0
  31. package/src/router/selection-search.ts +27 -3
  32. package/src/save-button/save-button.tsx +103 -0
  33. package/src/styles.css +37 -0
  34. package/src/theme/theme.ts +24 -0
  35. package/src/tools/tools.tsx +3 -3
  36. package/src/app/header-actions/header-actions.tsx +0 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anchrd/intel-ui",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -0,0 +1,23 @@
1
+ import type * as React from "react";
2
+ import { useEffect, useState } from "react";
3
+ import { createPortal } from "react-dom";
4
+
5
+ // A bar owns a place for actions, and whoever owns the action renders into it from wherever its
6
+ // state happens to live. Two such places exist: `header-actions` in the shell, beside the
7
+ // breadcrumb, for what belongs to the area; and `title-actions` in the title line of an open
8
+ // document, for what belongs to that one document (#24).
9
+ //
10
+ // ⚠️ The slot lives above the component that fills it, so it is not in the document while that
11
+ // component first renders. Looking it up in an effect costs one extra render and is the only order
12
+ // that works; reading it during render finds nothing on the first paint.
13
+ export function ActionSlot({
14
+ name = "header-actions",
15
+ children,
16
+ }: {
17
+ name?: string;
18
+ children: React.ReactNode;
19
+ }) {
20
+ const [slot, setSlot] = useState<Element | null>(null);
21
+ useEffect(() => setSlot(document.querySelector(`[data-slot="${name}"]`)), [name]);
22
+ return slot ? createPortal(children, slot) : null;
23
+ }
@@ -11,6 +11,7 @@ import {
11
11
  SidebarMenu,
12
12
  SidebarMenuButton,
13
13
  SidebarMenuItem,
14
+ useSidebar,
14
15
  } from "@/components/ui/sidebar";
15
16
  import { useIntelRouterContext } from "@/router/router-context.ts";
16
17
 
@@ -25,32 +26,46 @@ export function AppSidebar({
25
26
  onWidthChange(width: number): void;
26
27
  }) {
27
28
  const { i18n } = useIntelRouterContext();
29
+ // `offcanvas` rather than `icon`: the icon rail is the mode for a list of equal entries with one
30
+ // icon each, and a tree says what it says through indentation, disclosure arrows and nesting —
31
+ // none of which survives 48px. Collapsing exists to free the canvas, so the sidebar goes.
32
+ //
33
+ // ⚠️ Offcanvas only moves the panel out of sight; it stays in the document and keeps its focus
34
+ // order, so a keyboard would still walk through an invisible tree. The shell therefore unmounts
35
+ // the panel's content itself — the registry file is off limits. On a narrow screen the sidebar is
36
+ // an overlay driven by `openMobile`, and `state` says nothing about it, hence the `isMobile` arm.
37
+ const { state, isMobile } = useSidebar();
38
+ const showPanel = isMobile || state === "expanded";
28
39
 
29
40
  return (
30
- <Sidebar collapsible="icon" variant="inset">
31
- <SidebarHeader>
32
- <SidebarMenu>
33
- <SidebarMenuItem>
34
- <SidebarMenuButton size="lg" asChild>
35
- <Link to="/knowledge">
36
- <AppLogo className="size-8" />
37
- <span className="font-semibold">{i18n.t("app.name")}</span>
38
- </Link>
39
- </SidebarMenuButton>
40
- </SidebarMenuItem>
41
- </SidebarMenu>
42
- </SidebarHeader>
43
- <SidebarContent aria-label={i18n.t("nav.primary")}>
44
- <AppTree />
45
- </SidebarContent>
46
- <SidebarFooter>
47
- <UserFooter />
48
- </SidebarFooter>
49
- <SidebarResizeHandle
50
- width={width}
51
- label={i18n.t("shell.resizeSidebar")}
52
- onWidthChange={onWidthChange}
53
- />
41
+ <Sidebar collapsible="offcanvas" variant="inset">
42
+ {!showPanel ? null : (
43
+ <>
44
+ <SidebarHeader>
45
+ <SidebarMenu>
46
+ <SidebarMenuItem>
47
+ <SidebarMenuButton size="lg" asChild>
48
+ <Link to="/knowledge">
49
+ <AppLogo className="size-8" />
50
+ <span className="font-semibold">{i18n.t("app.name")}</span>
51
+ </Link>
52
+ </SidebarMenuButton>
53
+ </SidebarMenuItem>
54
+ </SidebarMenu>
55
+ </SidebarHeader>
56
+ <SidebarContent aria-label={i18n.t("nav.primary")}>
57
+ <AppTree />
58
+ </SidebarContent>
59
+ <SidebarFooter>
60
+ <UserFooter />
61
+ </SidebarFooter>
62
+ <SidebarResizeHandle
63
+ width={width}
64
+ label={i18n.t("shell.resizeSidebar")}
65
+ onWidthChange={onWidthChange}
66
+ />
67
+ </>
68
+ )}
54
69
  </Sidebar>
55
70
  );
56
71
  }