@exegia/corpora-ui 0.18.0 → 0.20.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 (78) hide show
  1. package/dist-lib/components/blocks/nav/sidebar/__tests__/use-ai-sidebar.test.d.ts +1 -0
  2. package/dist-lib/components/blocks/nav/sidebar/ai-sidebar.d.ts +11 -2
  3. package/dist-lib/components/blocks/nav/sidebar/type.d.ts +83 -1
  4. package/dist-lib/components/blocks/nav/sidebar/use-ai-sidebar.d.ts +22 -31
  5. package/dist-lib/components/blocks/nav/sidebar/utils.d.ts +5 -0
  6. package/dist-lib/components/blocks/scaffold/constants.d.ts +8 -0
  7. package/dist-lib/components/blocks/scaffold/index.d.ts +3 -1
  8. package/dist-lib/components/blocks/scaffold/panel-menu-button.d.ts +4 -3
  9. package/dist-lib/components/blocks/scaffold/scaffold-actions.d.ts +5 -4
  10. package/dist-lib/components/blocks/scaffold/scaffold-canvas.d.ts +2 -0
  11. package/dist-lib/components/blocks/scaffold/scaffold-panel.d.ts +1 -1
  12. package/dist-lib/components/blocks/scaffold/scaffold-tab.d.ts +14 -0
  13. package/dist-lib/components/blocks/scaffold/type.d.ts +58 -28
  14. package/dist-lib/components/blocks/scaffold/use-panel-visibility.d.ts +19 -0
  15. package/dist-lib/components/blocks/scaffold/utils.d.ts +12 -0
  16. package/dist-lib/components/composed/tree/__tests__/tree.test.d.ts +1 -0
  17. package/dist-lib/components/composed/tree/__tests__/use-tree.test.d.ts +1 -0
  18. package/dist-lib/components/composed/tree/constants.d.ts +35 -0
  19. package/dist-lib/components/composed/tree/index.d.ts +4 -0
  20. package/dist-lib/components/composed/tree/tree-context.d.ts +4 -0
  21. package/dist-lib/components/composed/tree/tree-node.d.ts +7 -0
  22. package/dist-lib/components/composed/tree/tree.d.ts +19 -0
  23. package/dist-lib/components/composed/tree/type.d.ts +192 -0
  24. package/dist-lib/components/composed/tree/use-tree-dnd.d.ts +7 -0
  25. package/dist-lib/components/composed/tree/use-tree.d.ts +20 -0
  26. package/dist-lib/components/composed/tree/utils.d.ts +28 -0
  27. package/dist-lib/components/user-avatar/audio-wave.d.ts +2 -0
  28. package/dist-lib/components/user-avatar/component.d.ts +10 -0
  29. package/dist-lib/components/user-avatar/fallback.d.ts +5 -0
  30. package/dist-lib/components/user-avatar/index.d.ts +13 -0
  31. package/dist-lib/components/user-avatar/type.d.ts +26 -0
  32. package/dist-lib/components/user-avatar/utils.d.ts +2 -0
  33. package/dist-lib/index.d.ts +1 -0
  34. package/dist-lib/index.js +2309 -1285
  35. package/dist-lib/index.js.map +1 -1
  36. package/package.json +2 -1
  37. package/src/components/beste/piece/browser-frame.tsx +9 -6
  38. package/src/components/blocks/nav/sidebar/__tests__/use-ai-sidebar.test.tsx +310 -0
  39. package/src/components/blocks/nav/sidebar/ai-sidebar.tsx +90 -60
  40. package/src/components/blocks/nav/sidebar/type.ts +105 -1
  41. package/src/components/blocks/nav/sidebar/use-ai-sidebar.ts +293 -116
  42. package/src/components/blocks/nav/sidebar/utils.ts +28 -0
  43. package/src/components/blocks/scaffold/__tests__/scaffold.test.tsx +268 -26
  44. package/src/components/blocks/scaffold/constants.ts +11 -0
  45. package/src/components/blocks/scaffold/index.ts +4 -1
  46. package/src/components/blocks/scaffold/panel-menu-button.tsx +96 -115
  47. package/src/components/blocks/scaffold/scaffold-actions.tsx +41 -50
  48. package/src/components/blocks/scaffold/scaffold-canvas.tsx +48 -5
  49. package/src/components/blocks/scaffold/scaffold-inspector.tsx +27 -3
  50. package/src/components/blocks/scaffold/scaffold-main.tsx +1 -1
  51. package/src/components/blocks/scaffold/scaffold-panel.tsx +56 -30
  52. package/src/components/blocks/scaffold/scaffold-root.tsx +18 -3
  53. package/src/components/blocks/scaffold/scaffold-sidebar.tsx +1 -1
  54. package/src/components/blocks/scaffold/scaffold-tab.tsx +104 -0
  55. package/src/components/blocks/scaffold/type.ts +62 -33
  56. package/src/components/blocks/scaffold/use-panel-visibility.ts +180 -0
  57. package/src/components/blocks/scaffold/utils.ts +35 -0
  58. package/src/components/composed/tree/__tests__/tree.test.tsx +400 -0
  59. package/src/components/composed/tree/__tests__/use-tree.test.tsx +332 -0
  60. package/src/components/composed/tree/constants.ts +60 -0
  61. package/src/components/composed/tree/index.ts +13 -0
  62. package/src/components/composed/tree/tree-context.ts +13 -0
  63. package/src/components/composed/tree/tree-node.tsx +451 -0
  64. package/src/components/composed/tree/tree.tsx +278 -0
  65. package/src/components/composed/tree/type.ts +212 -0
  66. package/src/components/composed/tree/use-tree-dnd.ts +148 -0
  67. package/src/components/composed/tree/use-tree.ts +306 -0
  68. package/src/components/composed/tree/utils.ts +172 -0
  69. package/src/components/composed/user-avatar.tsx +4 -1
  70. package/src/components/docs/component-preview.tsx +11 -11
  71. package/src/components/user-avatar/audio-wave.tsx +22 -0
  72. package/src/components/user-avatar/component.tsx +53 -0
  73. package/src/components/user-avatar/fallback.tsx +26 -0
  74. package/src/components/user-avatar/index.ts +15 -0
  75. package/src/components/user-avatar/type.ts +35 -0
  76. package/src/components/user-avatar/utils.ts +8 -0
  77. package/src/index.css +211 -153
  78. package/src/index.ts +1 -0
@@ -0,0 +1,192 @@
1
+ import type * as React from "react";
2
+ /** One node in the tree. Nesting depth carries meaning per variant — see
3
+ * `TreeProps["variant"]`. */
4
+ export interface TreeNode {
5
+ id: string;
6
+ label: string;
7
+ /** Leading icon. Required in practice for `sidebar` — it is all that
8
+ * remains of a row while the rail is collapsed. */
9
+ icon?: React.ReactNode;
10
+ /** Renders an anchor. Without one the row is a button; `toc` leaves
11
+ * default to `#{id}` so they scroll to the matching heading. */
12
+ href?: string;
13
+ target?: "_blank" | "_self" | "_parent" | "_top";
14
+ disabled?: boolean;
15
+ /** Start expanded. Ancestors of `activeId` expand regardless. */
16
+ defaultOpen?: boolean;
17
+ /** Trailing hint — a count, a "New" pill. */
18
+ badge?: React.ReactNode;
19
+ /** Fires on selection, before the tree-level `onNavigate`. */
20
+ onSelect?: () => void;
21
+ children?: TreeNode[];
22
+ }
23
+ export type TreeVariant = "navigation" | "toc" | "sidebar" | "files";
24
+ /** Where a dragged row lands relative to its drop target. */
25
+ export type TreeDropPosition = "before" | "after" | "inside";
26
+ interface TreeBaseProps {
27
+ items: TreeNode[];
28
+ /** Never set on the data form — `tree` selects the controller form. */
29
+ tree?: never;
30
+ /** `id` of the current entry — matches any depth. Its ancestors expand. */
31
+ activeId?: string;
32
+ /** Fires for every selection (rows and leaves alike), after the row's
33
+ * anchor default — wire your router's navigate here. */
34
+ onNavigate?: (node: TreeNode) => void;
35
+ /** Expand/collapse cues. Silent until `bindSounds()`. */
36
+ sound?: boolean;
37
+ ariaLabel?: string;
38
+ className?: string;
39
+ }
40
+ interface TreeReadonlyProps {
41
+ collapsed?: never;
42
+ onMove?: never;
43
+ onRename?: never;
44
+ renderTrailing?: never;
45
+ }
46
+ /** Drive the tree from a `useTree` controller instead of raw props. The
47
+ * controller carries the variant, the data and every handler; only the
48
+ * presentational props stay here. */
49
+ export interface TreeControllerProps {
50
+ tree: TreeController;
51
+ items?: never;
52
+ ariaLabel?: string;
53
+ className?: string;
54
+ /** Row actions revealed on hover/focus (`files` only — ignored by the
55
+ * other variants, which the controller form cannot type-gate). */
56
+ renderTrailing?: (node: TreeNode) => React.ReactNode;
57
+ }
58
+ /** Either form: raw props, or a `useTree` controller via `tree`. */
59
+ export type TreeProps = TreeDataProps | TreeControllerProps;
60
+ /** The four shapes a Tree takes. Editing props only exist on `files`;
61
+ * `collapsed` only on `sidebar` — the union is the contract. */
62
+ export type TreeDataProps = TreeBaseProps & (({
63
+ /** Nested app navigation. With 3 levels of nodes the top level
64
+ * becomes collapsible section names (styled as headings, not
65
+ * links); with 2 it renders plain link rows. */
66
+ variant: "navigation";
67
+ } & TreeReadonlyProps) | ({
68
+ /** Table of contents: top-level nodes are routes, leaf nodes are
69
+ * in-page anchors (`#{id}` unless the node carries an `href`). */
70
+ variant: "toc";
71
+ } & TreeReadonlyProps) | ({
72
+ /** Single-level icon rail. `collapsed` shrinks rows to their
73
+ * leading icon; nested children are ignored. */
74
+ variant: "sidebar";
75
+ collapsed?: boolean;
76
+ } & Omit<TreeReadonlyProps, "collapsed">) | {
77
+ /** File explorer: only leaves navigate, folders toggle. Compact
78
+ * spacing; rename, drag-and-drop and trailing actions enabled. */
79
+ variant: "files";
80
+ /** Enables drag-and-drop. Reorder `items` yourself: `parentId`
81
+ * `null` means the root list, `index` is the slot among the new
82
+ * siblings (computed on the list without the dragged node). */
83
+ onMove?: (id: string, parentId: string | null, index: number) => void;
84
+ /** Enables inline rename (double-click or F2). */
85
+ onRename?: (id: string, label: string) => void;
86
+ /** Row actions revealed on hover/focus — a menu, a delete icon. */
87
+ renderTrailing?: (node: TreeNode) => React.ReactNode;
88
+ collapsed?: never;
89
+ });
90
+ /** Options for `useTree`. Each of `items`, `activeId` and `collapsed` is
91
+ * controlled when passed and hook-owned when its `default*` twin is used
92
+ * instead. */
93
+ export interface UseTreeOptions {
94
+ /** Which shape the tree takes — gates rename/reorder (`files`) and the
95
+ * collapsible rail (`sidebar`). */
96
+ variant: TreeVariant;
97
+ /** Controlled data. With it, `rename`/`move` only report the edit unless
98
+ * you also pass `onItemsChange`. */
99
+ items?: TreeNode[];
100
+ /** Hook-owned data — `rename` and `move` apply the edit themselves. */
101
+ defaultItems?: TreeNode[];
102
+ /** Next tree after a `rename`/`move`. Also enables self-applying edits
103
+ * on top of controlled `items`. */
104
+ onItemsChange?: (items: TreeNode[]) => void;
105
+ /** Controlled selection. Ancestors of the active node expand. */
106
+ activeId?: string;
107
+ defaultActiveId?: string;
108
+ /** Fires for every selection (rows and leaves alike), after the node's
109
+ * own `onSelect` — wire your router's navigate here. */
110
+ onNavigate?: (node: TreeNode) => void;
111
+ /** Start with these ids expanded instead of the `defaultOpen` set. */
112
+ defaultExpandedIds?: Iterable<string>;
113
+ onExpandedChange?: (ids: string[]) => void;
114
+ /** Controlled rail fold (`sidebar` only). */
115
+ collapsed?: boolean;
116
+ defaultCollapsed?: boolean;
117
+ onCollapsedChange?: (collapsed: boolean) => void;
118
+ /** Enables rename (`files`). Not needed when the hook owns the data. */
119
+ onRename?: (id: string, label: string) => void;
120
+ /** Enables drag-and-drop (`files`). `parentId` `null` means the root
121
+ * list, `index` is the slot among the new siblings (computed on the list
122
+ * without the moved node). Not needed when the hook owns the data. */
123
+ onMove?: (id: string, parentId: string | null, index: number) => void;
124
+ /** Expand/collapse cues. Silent until `bindSounds()`. */
125
+ sound?: boolean;
126
+ }
127
+ /** Everything the tree can do, callable from outside the component.
128
+ * Returned by `useTree` and accepted by `<Tree tree={…} />`. */
129
+ export interface TreeController {
130
+ variant: TreeVariant;
131
+ items: TreeNode[];
132
+ /** `navigation` with 3 levels of nodes — depth 0 renders as sections. */
133
+ sectioned: boolean;
134
+ /** Ids of the section headings, empty unless `sectioned`. Pass one to
135
+ * `expand`/`collapse`/`toggleExpanded` to work a whole section. */
136
+ sectionIds: string[];
137
+ sound: boolean;
138
+ getNode: (id: string) => TreeNode | null;
139
+ expandedIds: ReadonlySet<string>;
140
+ isExpanded: (id: string) => boolean;
141
+ expand: (id: string) => void;
142
+ collapse: (id: string) => void;
143
+ toggleExpanded: (id: string) => void;
144
+ expandAll: () => void;
145
+ collapseAll: () => void;
146
+ /** Open every ancestor of `id`, leaving the rest of the tree alone. */
147
+ reveal: (id: string) => void;
148
+ /** Rail folded to icons — always `false` outside `sidebar`. */
149
+ collapsed: boolean;
150
+ setCollapsed: (collapsed: boolean) => void;
151
+ toggleCollapsed: () => void;
152
+ activeId?: string;
153
+ /** Select a node: runs its `onSelect`, then `onNavigate`. Inert on
154
+ * disabled and unknown nodes. */
155
+ select: (id: string) => void;
156
+ /** Whether rename is wired up at all (`files` + a handler or owned data). */
157
+ canRename: boolean;
158
+ /** Rename target id, `null` while idle. */
159
+ renamingId: string | null;
160
+ startRename: (id: string) => void;
161
+ cancelRename: () => void;
162
+ /** Commit a rename and leave rename mode. Blank or unchanged labels are
163
+ * dropped. */
164
+ rename: (id: string, label: string) => void;
165
+ /** Whether reorder is wired up at all. */
166
+ canMove: boolean;
167
+ move: (id: string, parentId: string | null, index: number) => void;
168
+ dnd: TreeDndContextValue;
169
+ }
170
+ /** @internal What a row needs from the root, threaded through context so
171
+ * the recursive rows stay prop-light. */
172
+ export interface TreeContextValue {
173
+ tree: TreeController;
174
+ renderTrailing?: (node: TreeNode) => React.ReactNode;
175
+ }
176
+ /** @internal Drag state shared by every row (all `null`/no-op outside
177
+ * `files`). */
178
+ export interface TreeDndContextValue {
179
+ enabled: boolean;
180
+ draggedId: string | null;
181
+ /** Row the pointer is over and where the drop would land. */
182
+ dropTarget: {
183
+ id: string;
184
+ position: TreeDropPosition;
185
+ } | null;
186
+ onRowDragStart: (event: React.DragEvent, id: string) => void;
187
+ onRowDragOver: (event: React.DragEvent, node: TreeNode) => void;
188
+ onRowDragLeave: (event: React.DragEvent) => void;
189
+ onRowDrop: (event: React.DragEvent, node: TreeNode) => void;
190
+ onRowDragEnd: () => void;
191
+ }
192
+ export {};
@@ -0,0 +1,7 @@
1
+ import { TreeDndContextValue, TreeNode, UseTreeOptions } from './type';
2
+ /** Owns drag state for the `files` variant: which row is in flight, which
3
+ * row the pointer rests on and where the drop would land. Everything is
4
+ * component state — `dataTransfer` is set for interop but never read, so
5
+ * the flow also works where the store is unavailable (tests, some
6
+ * webviews). Without `onMove` every handler is inert. */
7
+ export declare function useTreeDnd(items: readonly TreeNode[], onMove: UseTreeOptions["onMove"]): TreeDndContextValue;
@@ -0,0 +1,20 @@
1
+ import { TreeController, UseTreeOptions } from './type';
2
+ /**
3
+ * The tree's headless controller — every behaviour the component exposes,
4
+ * callable from outside it: expand/collapse (a node, a section, the whole
5
+ * tree), fold the `sidebar` rail, select a node, rename, reorder.
6
+ *
7
+ * Each piece of state is controlled-or-uncontrolled in the usual React
8
+ * shape: pass `items`/`activeId`/`collapsed` to own it yourself, or
9
+ * `defaultItems`/`defaultActiveId`/`defaultCollapsed` to let the hook. When
10
+ * the hook owns `items` (or you pass `onItemsChange`), `rename` and `move`
11
+ * apply the edit to the data themselves — otherwise they only report it
12
+ * through `onRename`/`onMove` and you reduce the tree yourself.
13
+ *
14
+ * ```tsx
15
+ * const tree = useTree({ variant: "files", defaultItems: files })
16
+ * <Tree tree={tree} />
17
+ * <Button onClick={tree.collapseAll}>Collapse all</Button>
18
+ * ```
19
+ */
20
+ export declare function useTree(options: UseTreeOptions): TreeController;
@@ -0,0 +1,28 @@
1
+ import { TreeNode } from './type';
2
+ /** Depth-0 nodes read as sections only when the data actually nests three
3
+ * levels — a two-level tree keeps its top level as plain link rows. */
4
+ export declare function hasThreeLevels(items: readonly TreeNode[]): boolean;
5
+ /** Ids of every ancestor of `id` (nearest last); empty when absent. */
6
+ export declare function ancestorIdsOf(items: readonly TreeNode[], id: string): string[];
7
+ /** Ids that start expanded: `defaultOpen` nodes plus every ancestor of the
8
+ * active entry, so the current location is never folded away. */
9
+ export declare function initialExpandedIds(items: readonly TreeNode[], activeId?: string): Set<string>;
10
+ /** Ids of every node that can hold children — the set `expandAll` opens.
11
+ * In `files` an empty `children: []` still counts (it is a folder). */
12
+ export declare function expandableIdsOf(items: readonly TreeNode[], filesVariant?: boolean): string[];
13
+ /** Immutably relabel `id`. Returns the same array reference when absent. */
14
+ export declare function renameNode(items: readonly TreeNode[], id: string, label: string): TreeNode[];
15
+ /** Whether `candidateId` is `id` itself or nests anywhere under it — the
16
+ * guard that keeps a folder from being dropped into its own subtree. */
17
+ export declare function containsNode(items: readonly TreeNode[], id: string, candidateId: string): boolean;
18
+ export declare function findNode(items: readonly TreeNode[], id: string): TreeNode | null;
19
+ /** Parent id (`null` at root) and index of `id` among its siblings. */
20
+ export declare function locateNode(items: readonly TreeNode[], id: string): {
21
+ parentId: string | null;
22
+ index: number;
23
+ } | null;
24
+ /** Immutably lift `id` out of the tree and reinsert it under `parentId`
25
+ * (`null` = root) at `index` — the standard `onMove` reducer, exported so
26
+ * consumers don't each rebuild it. `index` addresses the sibling list
27
+ * *after* the node has been lifted out. */
28
+ export declare function moveNode(items: readonly TreeNode[], id: string, parentId: string | null, index: number): TreeNode[];
@@ -0,0 +1,2 @@
1
+ import { IAudioWaveProps } from './type';
2
+ export declare function AudioWave({ className, volume: _volume, children }: IAudioWaveProps): import("react").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import { UserAvatarProps } from './type';
2
+ import * as React from "react";
3
+ /**
4
+ * Identity avatar: an image when one is given, initials otherwise.
5
+ *
6
+ * A passed `src` is assumed to be remote, so the slot holds a skeleton until
7
+ * the image resolves rather than flashing initials that are about to be
8
+ * replaced. A failed load settles on the initials.
9
+ */
10
+ export declare function UserAvatar({ src, name, initials, alt, loading: loadingProp, className, ...props }: UserAvatarProps): React.ReactElement;
@@ -0,0 +1,5 @@
1
+ export declare function Fallback({ name, initials, loading, }: {
2
+ name?: string;
3
+ initials?: string;
4
+ loading?: boolean;
5
+ }): import("react").JSX.Element;
@@ -0,0 +1,13 @@
1
+ import { AudioWave } from './audio-wave';
2
+ import { UserAvatar } from './component';
3
+ import { Fallback } from './fallback';
4
+ export { AudioWave } from './audio-wave';
5
+ export { UserAvatar } from './component';
6
+ export { Fallback } from './fallback';
7
+ export { initialsFrom } from './utils';
8
+ export type * from './type';
9
+ export declare const Avatar: {
10
+ AudioWave: typeof AudioWave;
11
+ Component: typeof UserAvatar;
12
+ Fallback: typeof Fallback;
13
+ };
@@ -0,0 +1,26 @@
1
+ import { AvatarPrimitive } from '../ui/avatar';
2
+ import type * as React from "react";
3
+ export type ImageStatus = Parameters<NonNullable<AvatarPrimitive.Image.Props["onLoadingStatusChange"]>>[0];
4
+ export interface UserAvatarProps extends Omit<AvatarPrimitive.Root.Props, "children"> {
5
+ /** Image URL. Without one the initials show immediately — no skeleton. */
6
+ src?: string;
7
+ /** Drives the initials, and the alt text unless `alt` overrides it. */
8
+ name?: string;
9
+ /** Overrides the initials derived from `name`. */
10
+ initials?: string;
11
+ /**
12
+ * Alt text for the image. Pass "" when adjacent text already names the
13
+ * person — the image is then decorative.
14
+ */
15
+ alt?: string;
16
+ /**
17
+ * Force the skeleton, for when the identity itself is still being fetched.
18
+ * Omitted, it follows the image: a passed `src` skeletons until it resolves.
19
+ */
20
+ loading?: boolean;
21
+ }
22
+ export interface IAudioWaveProps {
23
+ className?: string;
24
+ children?: React.ReactNode;
25
+ volume?: number;
26
+ }
@@ -0,0 +1,2 @@
1
+ /** "Jenny Hamilton" → "JH", "luna" → "L". */
2
+ export declare function initialsFrom(name: string): string;
@@ -22,6 +22,7 @@ export * from './components/ui/spinner';
22
22
  export * from './components/ui/textarea';
23
23
  export * from './components/composed/password-input';
24
24
  export * from './components/composed/social-providers';
25
+ export * from './components/composed/tree';
25
26
  export * from './components/composed/user-avatar';
26
27
  export * from './components/blocks/auth/auth-shell';
27
28
  export * from './components/blocks/auth/code-auth-block';