@exegia/corpora-ui 0.20.0 → 0.22.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.
- package/dist-lib/components/blocks/auth/auth-flow-atom.d.ts +77 -0
- package/dist-lib/components/blocks/auth/auth-session-atom.d.ts +28 -0
- package/dist-lib/components/blocks/auth/auth-state-type.d.ts +71 -0
- package/dist-lib/components/blocks/auth/auth-state.d.ts +9 -0
- package/dist-lib/components/blocks/auth/use-auth-state.d.ts +52 -0
- package/dist-lib/components/blocks/layout.d.ts +4 -1
- package/dist-lib/components/blocks/nav/sidebar/__tests__/ai-sidebar-atom.test.d.ts +1 -0
- package/dist-lib/components/blocks/nav/sidebar/ai-sidebar-atom.d.ts +217 -0
- package/dist-lib/components/blocks/nav/sidebar/index.d.ts +3 -1
- package/dist-lib/components/blocks/nav/sidebar/sidebar-context.d.ts +3 -0
- package/dist-lib/components/blocks/nav/sidebar/sidebar-row.d.ts +3 -1
- package/dist-lib/components/blocks/nav/sidebar/type.d.ts +109 -29
- package/dist-lib/components/blocks/nav/sidebar/use-ai-sidebar-state.d.ts +29 -0
- package/dist-lib/components/blocks/nav/sidebar/use-ai-sidebar.d.ts +6 -1
- package/dist-lib/components/blocks/nav/sidebar/utils.d.ts +1 -1
- package/dist-lib/components/blocks/profile/index.d.ts +7 -0
- package/dist-lib/components/blocks/profile/profile-card-atom.d.ts +68 -0
- package/dist-lib/components/blocks/profile/profile-card-block.d.ts +28 -39
- package/dist-lib/components/blocks/profile/type.d.ts +80 -0
- package/dist-lib/components/blocks/profile/use-profile-card-state.d.ts +24 -0
- package/dist-lib/components/blocks/profile/use-profile-card.d.ts +34 -0
- package/dist-lib/components/blocks/shell/__tests__/shell-fit-atom.test.d.ts +1 -0
- package/dist-lib/components/blocks/shell/__tests__/shell-metrics.test.d.ts +1 -0
- package/dist-lib/components/blocks/shell/animated-panel-provider.d.ts +1 -1
- package/dist-lib/components/blocks/shell/animated-panel.d.ts +1 -1
- package/dist-lib/components/blocks/shell/index.d.ts +4 -12
- package/dist-lib/components/blocks/shell/shell-fit-atom.d.ts +68 -0
- package/dist-lib/components/blocks/shell/shell-metrics.d.ts +54 -0
- package/dist-lib/components/blocks/shell/type.d.ts +115 -3
- package/dist-lib/components/blocks/shell/use-shell-fit-state.d.ts +25 -0
- package/dist-lib/components/blocks/shell/use-shell-fit.d.ts +14 -0
- package/dist-lib/components/blocks/shell/use-shell-panels.d.ts +12 -1
- package/dist-lib/components/blocks/shell/utils.d.ts +32 -0
- package/dist-lib/components/composed/__tests__/logo.test.d.ts +1 -0
- package/dist-lib/components/composed/logo.d.ts +34 -0
- package/dist-lib/components/composed/tree/__tests__/tree-atom.test.d.ts +1 -0
- package/dist-lib/components/composed/tree/constants.d.ts +4 -4
- package/dist-lib/components/composed/tree/index.d.ts +3 -1
- package/dist-lib/components/composed/tree/tree-atom.d.ts +160 -0
- package/dist-lib/components/composed/tree/tree-node.d.ts +6 -1
- package/dist-lib/components/composed/tree/type.d.ts +116 -18
- package/dist-lib/components/composed/tree/use-tree-dnd.d.ts +18 -7
- package/dist-lib/components/composed/tree/use-tree-state.d.ts +25 -0
- package/dist-lib/components/composed/tree/use-tree.d.ts +4 -0
- package/dist-lib/components/composed/user-avatar.d.ts +5 -28
- package/dist-lib/components/user-avatar/__tests__/user-avatar.test.d.ts +1 -0
- package/dist-lib/components/user-avatar/component.d.ts +1 -8
- package/dist-lib/components/user-avatar/index.d.ts +5 -0
- package/dist-lib/components/user-avatar/presence-badge.d.ts +16 -0
- package/dist-lib/components/user-avatar/type.d.ts +53 -0
- package/dist-lib/components/user-avatar/use-user-avatar-state.d.ts +26 -0
- package/dist-lib/components/user-avatar/use-user-avatar.d.ts +37 -0
- package/dist-lib/components/user-avatar/user-avatar-atom.d.ts +64 -0
- package/dist-lib/components/user-avatar/utils.d.ts +22 -0
- package/dist-lib/index.d.ts +6 -3
- package/dist-lib/index.js +3732 -2670
- package/dist-lib/index.js.map +1 -1
- package/dist-lib/state/exegia-provider.d.ts +51 -0
- package/dist-lib/state/index.d.ts +4 -0
- package/dist-lib/state/store.d.ts +17 -0
- package/package.json +15 -12
- package/src/components/blocks/auth/__tests__/auth-state-atom.test.tsx +247 -0
- package/src/components/blocks/auth/auth-flow-atom.ts +238 -0
- package/src/components/blocks/auth/auth-session-atom.ts +82 -0
- package/src/components/blocks/auth/auth-state-type.ts +97 -0
- package/src/components/blocks/auth/auth-state.ts +52 -0
- package/src/components/blocks/auth/use-auth-state.ts +127 -0
- package/src/components/blocks/layout.ts +30 -2
- package/src/components/blocks/nav/sidebar/__tests__/ai-sidebar-atom.test.tsx +325 -0
- package/src/components/blocks/nav/sidebar/ai-sidebar-atom.ts +698 -0
- package/src/components/blocks/nav/sidebar/ai-sidebar.tsx +48 -42
- package/src/components/blocks/nav/sidebar/index.ts +53 -1
- package/src/components/blocks/nav/sidebar/sidebar-context.ts +15 -0
- package/src/components/blocks/nav/sidebar/sidebar-row.tsx +119 -50
- package/src/components/blocks/nav/sidebar/type.ts +125 -30
- package/src/components/blocks/nav/sidebar/use-ai-sidebar-state.ts +123 -0
- package/src/components/blocks/nav/sidebar/use-ai-sidebar.ts +301 -248
- package/src/components/blocks/nav/sidebar/utils.ts +1 -1
- package/src/components/blocks/profile/__tests__/profile-card-block.test.tsx +194 -0
- package/src/components/blocks/profile/index.ts +28 -0
- package/src/components/blocks/profile/profile-card-atom.ts +247 -0
- package/src/components/blocks/profile/profile-card-block.tsx +153 -74
- package/src/components/blocks/profile/type.ts +95 -0
- package/src/components/blocks/profile/use-profile-card-state.ts +67 -0
- package/src/components/blocks/profile/use-profile-card.ts +126 -0
- package/src/components/blocks/shell/__tests__/shell-fit-atom.test.tsx +360 -0
- package/src/components/blocks/shell/__tests__/shell-layout.test.tsx +192 -3
- package/src/components/blocks/shell/__tests__/shell-metrics.test.ts +108 -0
- package/src/components/blocks/shell/animated-panel-inset.tsx +5 -1
- package/src/components/blocks/shell/animated-panel-provider.tsx +77 -11
- package/src/components/blocks/shell/animated-panel-trigger.tsx +4 -0
- package/src/components/blocks/shell/animated-panel.tsx +126 -29
- package/src/components/blocks/shell/index.ts +18 -13
- package/src/components/blocks/shell/shell-fit-atom.ts +243 -0
- package/src/components/blocks/shell/shell-layout.tsx +55 -53
- package/src/components/blocks/shell/shell-metrics.ts +79 -0
- package/src/components/blocks/shell/type.ts +130 -3
- package/src/components/blocks/shell/use-shell-fit-state.ts +49 -0
- package/src/components/blocks/shell/use-shell-fit.ts +135 -0
- package/src/components/blocks/shell/use-shell-panels.ts +57 -4
- package/src/components/blocks/shell/utils.ts +44 -4
- package/src/components/composed/__tests__/logo.test.tsx +60 -0
- package/src/components/composed/logo.tsx +159 -0
- package/src/components/composed/tree/CLAUDE.md +132 -0
- package/src/components/composed/tree/__tests__/tree-atom.test.tsx +217 -0
- package/src/components/composed/tree/__tests__/tree.test.tsx +162 -37
- package/src/components/composed/tree/__tests__/use-tree.test.tsx +2 -1
- package/src/components/composed/tree/constants.ts +4 -4
- package/src/components/composed/tree/index.ts +38 -0
- package/src/components/composed/tree/tree-atom.ts +590 -0
- package/src/components/composed/tree/tree-node.tsx +117 -78
- package/src/components/composed/tree/tree.tsx +24 -16
- package/src/components/composed/tree/type.ts +125 -15
- package/src/components/composed/tree/use-tree-dnd.ts +82 -51
- package/src/components/composed/tree/use-tree-state.ts +105 -0
- package/src/components/composed/tree/use-tree.ts +185 -184
- package/src/components/composed/user-avatar.tsx +11 -99
- package/src/components/user-avatar/__tests__/user-avatar.test.tsx +286 -0
- package/src/components/user-avatar/component.tsx +151 -22
- package/src/components/user-avatar/fallback.tsx +3 -1
- package/src/components/user-avatar/index.ts +19 -0
- package/src/components/user-avatar/presence-badge.tsx +56 -0
- package/src/components/user-avatar/type.ts +58 -0
- package/src/components/user-avatar/use-user-avatar-state.ts +60 -0
- package/src/components/user-avatar/use-user-avatar.ts +180 -0
- package/src/components/user-avatar/user-avatar-atom.ts +218 -0
- package/src/components/user-avatar/utils.ts +94 -0
- package/src/index.ts +35 -3
- package/src/state/exegia-provider.tsx +79 -0
- package/src/state/index.ts +4 -0
- package/src/state/store.ts +19 -0
- package/dist-lib/components/blocks/nav/sidebar-block.d.ts +0 -14
- package/dist-lib/components/blocks/nav/sidebar-nav-row.d.ts +0 -3
- package/dist-lib/components/blocks/nav/types.d.ts +0 -60
- package/dist-lib/components/blocks/nav/utils.d.ts +0 -1
- package/dist-lib/components/blocks/shell/animated-sidebar-content.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-footer.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-group-content.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-group-label.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-group.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-header.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-button.d.ts +0 -3
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-item.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-sub-button.d.ts +0 -3
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-sub-item.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-sub.d.ts +0 -2
- package/dist-lib/components/blocks/shell/animated-sidebar-menu.d.ts +0 -2
- package/src/components/blocks/nav/__tests__/sidebar-block.test.tsx +0 -125
- package/src/components/blocks/nav/sidebar-block.tsx +0 -142
- package/src/components/blocks/nav/sidebar-nav-row.tsx +0 -78
- package/src/components/blocks/nav/types.ts +0 -65
- package/src/components/blocks/nav/utils.ts +0 -4
- package/src/components/blocks/shell/animated-sidebar-content.tsx +0 -19
- package/src/components/blocks/shell/animated-sidebar-footer.tsx +0 -19
- package/src/components/blocks/shell/animated-sidebar-group-content.tsx +0 -16
- package/src/components/blocks/shell/animated-sidebar-group-label.tsx +0 -29
- package/src/components/blocks/shell/animated-sidebar-group.tsx +0 -16
- package/src/components/blocks/shell/animated-sidebar-header.tsx +0 -16
- package/src/components/blocks/shell/animated-sidebar-menu-button.tsx +0 -151
- package/src/components/blocks/shell/animated-sidebar-menu-item.tsx +0 -20
- package/src/components/blocks/shell/animated-sidebar-menu-sub-button.tsx +0 -85
- package/src/components/blocks/shell/animated-sidebar-menu-sub-item.tsx +0 -19
- package/src/components/blocks/shell/animated-sidebar-menu-sub.tsx +0 -44
- package/src/components/blocks/shell/animated-sidebar-menu.tsx +0 -26
- /package/dist-lib/components/blocks/{nav/__tests__/sidebar-block.test.d.ts → auth/__tests__/auth-state-atom.test.d.ts} +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shell's layout arithmetic, as plain functions over px.
|
|
3
|
+
*
|
|
4
|
+
* Nothing here touches React or the DOM. This module IS the contract of who
|
|
5
|
+
* gets which column, which keeps the rule unit-testable on its own and lets
|
|
6
|
+
* the shell-fit atoms (`shellFitFitsAtom`, `shellFitPanelWidthAtom`) call it
|
|
7
|
+
* without restating it: `useShellFit` only supplies the measurements.
|
|
8
|
+
*/
|
|
9
|
+
/** The px the shell lays itself out with. Every field is measured from a CSS
|
|
10
|
+
* variable (see `SHELL_WIDTHS`), never hard-coded, so a consumer's override
|
|
11
|
+
* flows straight through the rule. */
|
|
12
|
+
export interface ShellMetrics {
|
|
13
|
+
/** What the left rail occupies right now — its expanded width, its icon
|
|
14
|
+
* width, or 0 when there is no rail at all (or it is off canvas). */
|
|
15
|
+
rail: number;
|
|
16
|
+
/** The floor the body refuses to go below. */
|
|
17
|
+
insetMin: number;
|
|
18
|
+
/** The secondary panel's floor, which is also the width it opens at. */
|
|
19
|
+
panelMin: number;
|
|
20
|
+
/** The viewport all three columns share. */
|
|
21
|
+
viewport: number;
|
|
22
|
+
/** px the shell's own frame eats before any column gets a share: its
|
|
23
|
+
* padding, plus the gap between columns.
|
|
24
|
+
*
|
|
25
|
+
* Deliberately absent from `fitsPanel` — that rule is stated against the raw
|
|
26
|
+
* viewport — but subtracted from the resize ceiling, where ignoring it lets
|
|
27
|
+
* a full-width drag push the row past the shell by exactly this much. */
|
|
28
|
+
chrome: number;
|
|
29
|
+
}
|
|
30
|
+
/** px the shell needs before a secondary panel can exist: the rail as it
|
|
31
|
+
* stands, plus the body and the panel at their own floors. */
|
|
32
|
+
export declare function requiredWidth({ rail, insetMin, panelMin }: ShellMetrics): number;
|
|
33
|
+
/**
|
|
34
|
+
* Whether the shell can hold a secondary panel at all. Strictly `<`: a shell
|
|
35
|
+
* that fits its columns exactly has no room left to give one.
|
|
36
|
+
*
|
|
37
|
+
* An unmeasurable shell fails open. A server render, a `display: none` host
|
|
38
|
+
* or a test environment with no layout engine all report 0, and a panel must
|
|
39
|
+
* never disappear over a reading the layout could not produce.
|
|
40
|
+
*/
|
|
41
|
+
export declare function fitsPanel(metrics: ShellMetrics): boolean;
|
|
42
|
+
/** How wide the secondary panel may be: never under its own floor, never past
|
|
43
|
+
* the slack the body holds above its floor. `max` never drops below `min`, so
|
|
44
|
+
* a shell that does not fit reports a degenerate range instead of an inverted
|
|
45
|
+
* one — `fitsPanel` is what hides the panel, not a negative bound. */
|
|
46
|
+
export declare function panelBounds(metrics: ShellMetrics): {
|
|
47
|
+
min: number;
|
|
48
|
+
max: number;
|
|
49
|
+
};
|
|
50
|
+
export declare function clampPanelWidth(width: number, metrics: ShellMetrics): number;
|
|
51
|
+
/** Resizes fire per pointer move and per resize event, most of them landing
|
|
52
|
+
* on the same numbers — comparing fields keeps those from re-rendering the
|
|
53
|
+
* whole shell. */
|
|
54
|
+
export declare function metricsEqual(a: ShellMetrics, b: ShellMetrics): boolean;
|
|
@@ -1,5 +1,68 @@
|
|
|
1
|
-
import { ReactNode, ButtonHTMLAttributes, CSSProperties, HTMLAttributes } from 'react';
|
|
1
|
+
import { ReactNode, RefObject, ButtonHTMLAttributes, CSSProperties, HTMLAttributes } from 'react';
|
|
2
2
|
import { HTMLMotionProps } from 'motion/react';
|
|
3
|
+
import { ShellMetrics } from './shell-metrics';
|
|
4
|
+
/** The key a shell's fit state is filed under. Pass your own to reach it from
|
|
5
|
+
* anywhere (`useShellFitState("app-shell")`); leave it out and the provider
|
|
6
|
+
* generates one that dies with it. */
|
|
7
|
+
export type ShellFitInstanceId = string;
|
|
8
|
+
/** The range a secondary-panel resize may land in, in px. */
|
|
9
|
+
export interface ShellFitPanelBounds {
|
|
10
|
+
min: number;
|
|
11
|
+
max: number;
|
|
12
|
+
}
|
|
13
|
+
/** What the shell measured of itself — readable by id through
|
|
14
|
+
* `useShellFitState`. */
|
|
15
|
+
export interface ShellFitState {
|
|
16
|
+
/** The px the shell last measured, or null before its first measurement
|
|
17
|
+
* (a server render, a host with no layout). */
|
|
18
|
+
metrics: ShellMetrics | null;
|
|
19
|
+
/** Whether the shell can hold a secondary panel. True while unmeasured, so
|
|
20
|
+
* a panel never flickers out over a reading that has not happened yet. */
|
|
21
|
+
fits: boolean;
|
|
22
|
+
/** The secondary panel's width in px, already clamped to `bounds` — null
|
|
23
|
+
* before the first measurement, where the panel falls back to
|
|
24
|
+
* `--panel-width`. */
|
|
25
|
+
panelWidth: number | null;
|
|
26
|
+
/** The range a resize may land in. */
|
|
27
|
+
bounds: ShellFitPanelBounds;
|
|
28
|
+
}
|
|
29
|
+
/** Writes only — drive a shell's secondary panel by id through
|
|
30
|
+
* `useShellFitActions` without re-rendering when it moves. */
|
|
31
|
+
export interface ShellFitActions {
|
|
32
|
+
/** Resize the secondary panel. Clamped on the way in, so a drag past the
|
|
33
|
+
* gutter parks at the bound instead of banking travel it has to give back. */
|
|
34
|
+
resizePanel: (width: number) => void;
|
|
35
|
+
/** Back to the width the shell mounted with — `defaultPanelWidth`, or
|
|
36
|
+
* `--panel-width` when there was none. */
|
|
37
|
+
resetPanelWidth: () => void;
|
|
38
|
+
}
|
|
39
|
+
/** What `useShellFit` hands the provider: the state, the actions and the id
|
|
40
|
+
* they are filed under. */
|
|
41
|
+
export interface ShellFitController extends ShellFitState, ShellFitActions {
|
|
42
|
+
shellId: ShellFitInstanceId;
|
|
43
|
+
}
|
|
44
|
+
export interface UseShellFitOptions {
|
|
45
|
+
/** File the fit under this id so it can be read elsewhere and outlive the
|
|
46
|
+
* shell. Generated (and dropped on unmount) when omitted. */
|
|
47
|
+
shellId?: ShellFitInstanceId;
|
|
48
|
+
/** The element the shell's CSS variables live on (the provider wrapper). */
|
|
49
|
+
hostRef: RefObject<HTMLElement | null>;
|
|
50
|
+
/** Whether the left rail is expanded right now — a render input, so a fold
|
|
51
|
+
* counts the moment React commits it rather than a frame later when the
|
|
52
|
+
* width animation has moved. */
|
|
53
|
+
railOpen: boolean;
|
|
54
|
+
/** The width the secondary panel opens at, in px, instead of
|
|
55
|
+
* `--panel-width`. Read once, on mount. */
|
|
56
|
+
defaultPanelWidth?: number;
|
|
57
|
+
/** Fired whenever a measurement lands on "no room": the shell uses it to
|
|
58
|
+
* retire the panel's open state instead of parking it. */
|
|
59
|
+
onUnfit?: () => void;
|
|
60
|
+
}
|
|
61
|
+
/** @internal What an instance starts from, restored by `resetShellPanelWidthAtom`. */
|
|
62
|
+
export interface ShellFitSeed {
|
|
63
|
+
/** The requested panel width at mount — null for `--panel-width`. */
|
|
64
|
+
panelWidth: number | null;
|
|
65
|
+
}
|
|
3
66
|
export interface ShellAction {
|
|
4
67
|
id: string;
|
|
5
68
|
label: string;
|
|
@@ -38,27 +101,53 @@ export type TPanelMap<Side extends TPanelSide = TPanelSide> = Partial<Record<Sid
|
|
|
38
101
|
* AnimatedPanelProvider — every prop is keyed by side, there are no
|
|
39
102
|
* explicit per-side props. `useShellPanels` produces the controlled subset
|
|
40
103
|
* of these as `providerProps`. */
|
|
41
|
-
export type ShellPanelControlProps = Pick<AnimatedSidebarProviderProps, "open" | "defaultOpen" | "onOpenChange" | "openMobile" | "defaultOpenMobile" | "onOpenMobileChange">;
|
|
104
|
+
export type ShellPanelControlProps = Pick<AnimatedSidebarProviderProps, "open" | "defaultOpen" | "onOpenChange" | "openMobile" | "defaultOpenMobile" | "onOpenMobileChange" | "shellId" | "defaultPanelWidth">;
|
|
42
105
|
export interface UseShellPanelsOptions {
|
|
106
|
+
/** The id the shell's fit state is filed under. Name it to read the same
|
|
107
|
+
* shell from elsewhere (`useShellFitState("app-shell")`) and to keep a
|
|
108
|
+
* dragged panel width across a route change; otherwise the hook generates
|
|
109
|
+
* one that dies with it. */
|
|
110
|
+
shellId?: ShellFitInstanceId;
|
|
43
111
|
/** Initial desktop open state per side, merged over
|
|
44
112
|
* `{ left: true, right: false }`. */
|
|
45
113
|
defaultOpen?: AnimatedSidebarProviderProps["defaultOpen"];
|
|
46
114
|
/** Initial mobile overlay state per side — every side starts closed. */
|
|
47
115
|
defaultOpenMobile?: AnimatedSidebarProviderProps["defaultOpenMobile"];
|
|
116
|
+
/** The width the secondary panel opens at, in px, instead of
|
|
117
|
+
* `--panel-width`. */
|
|
118
|
+
defaultPanelWidth?: number;
|
|
48
119
|
/** Panel change event returning both the next open state and the side of
|
|
49
120
|
* the panel the change comes from. Mobile overlay changes report the same
|
|
50
121
|
* side as their desktop counterpart. */
|
|
51
122
|
onPanelChange?: (open: boolean, side: TPanelSide) => void;
|
|
52
123
|
}
|
|
53
124
|
export interface ShellPanelControls {
|
|
125
|
+
/** The id the shell's fit state is filed under — hand it to
|
|
126
|
+
* `useShellFitState` / `useShellFitActions` anywhere below `ExegiaProvider`. */
|
|
127
|
+
shellId: ShellFitInstanceId;
|
|
128
|
+
/** The viewport cannot hold the secondary panel beside the rail and the
|
|
129
|
+
* body at their floors, so the shell has dropped the right panel and its
|
|
130
|
+
* trigger — UI outside the shell should stand down with them. Read straight
|
|
131
|
+
* out of the shell's fit atoms; it is only ever `true` once the shell is
|
|
132
|
+
* mounted and measured. */
|
|
133
|
+
isNarrow: boolean;
|
|
134
|
+
/** The secondary panel's current width in px, or null until the shell has
|
|
135
|
+
* measured itself (the panel then sits at `--panel-width`). */
|
|
136
|
+
panelWidth: number | null;
|
|
137
|
+
/** Resize the secondary panel from outside the shell — clamped to the room
|
|
138
|
+
* the shell has. */
|
|
139
|
+
resizePanel: (width: number) => void;
|
|
54
140
|
/** Live desktop open state, keyed by side. */
|
|
55
141
|
open: Record<SidebarSide, boolean>;
|
|
56
142
|
/** Live mobile overlay state, keyed by side. */
|
|
57
143
|
openMobile: Record<SidebarSide, boolean>;
|
|
144
|
+
/** Refuses to OPEN the right panel while `isNarrow` — there is nothing on
|
|
145
|
+
* screen to open. Closing it always goes through. */
|
|
58
146
|
setOpen: (open: boolean, side: SidebarSide) => void;
|
|
59
147
|
setOpenMobile: (open: boolean, side: SidebarSide) => void;
|
|
60
148
|
/** Desktop-only convenience — the in-shell triggers already pick the
|
|
61
|
-
* mobile state themselves when the viewport is narrow.
|
|
149
|
+
* mobile state themselves when the viewport is narrow. Carries the same
|
|
150
|
+
* `isNarrow` refusal as `setOpen`. */
|
|
62
151
|
toggle: (side: SidebarSide) => void;
|
|
63
152
|
/** Spread onto ShellLayout (or AnimatedPanelProvider directly). */
|
|
64
153
|
providerProps: ShellPanelControlProps;
|
|
@@ -80,6 +169,10 @@ export type SidebarVariant = "sidebar" | "floating" | "inset";
|
|
|
80
169
|
export type SidebarCollapsible = "offcanvas" | "icon" | "none";
|
|
81
170
|
export interface AnimatedSidebarContextValue {
|
|
82
171
|
isMobile: boolean;
|
|
172
|
+
/** What the shell measured of itself: whether it can hold a secondary panel
|
|
173
|
+
* at all, how wide that panel is, and the range a resize may land in. The
|
|
174
|
+
* right panel and its trigger stand down when `fit.fits` is false. */
|
|
175
|
+
fit: ShellFitController;
|
|
83
176
|
layoutId: string;
|
|
84
177
|
/** Desktop open state, keyed by side. */
|
|
85
178
|
open: Record<SidebarSide, boolean>;
|
|
@@ -93,6 +186,14 @@ export interface AnimatedSidebarContextValue {
|
|
|
93
186
|
triggerRefs: Record<SidebarSide, React.RefObject<HTMLButtonElement | null>>;
|
|
94
187
|
}
|
|
95
188
|
export interface AnimatedSidebarProviderProps extends HTMLAttributes<HTMLDivElement> {
|
|
189
|
+
/** The id this shell's fit state (whether a secondary panel fits, how wide
|
|
190
|
+
* it is) is filed under in the store. Name it to read or drive the shell
|
|
191
|
+
* from elsewhere and to keep a dragged width across a route change; omit it
|
|
192
|
+
* and the provider generates one that is dropped on unmount. */
|
|
193
|
+
shellId?: ShellFitInstanceId;
|
|
194
|
+
/** The width the secondary panel opens at, in px, instead of
|
|
195
|
+
* `--panel-width`. Read once, on mount. */
|
|
196
|
+
defaultPanelWidth?: number;
|
|
96
197
|
/** Controlled desktop open state, keyed by the side. A side left undefined
|
|
97
198
|
* stays uncontrolled. */
|
|
98
199
|
open?: SidebarOpenState;
|
|
@@ -104,12 +205,23 @@ export interface AnimatedSidebarProviderProps extends HTMLAttributes<HTMLDivElem
|
|
|
104
205
|
/** Initial mobile overlay state — every side starts closed. */
|
|
105
206
|
defaultOpenMobile?: SidebarOpenState;
|
|
106
207
|
onOpenMobileChange?: (open: boolean, side: SidebarSide) => void;
|
|
208
|
+
/** Fires when the shell crosses the width a secondary panel needs (rail +
|
|
209
|
+
* body + panel at their floors). An imperative escape hatch for a consumer
|
|
210
|
+
* that mounts the provider on its own; anything under `ExegiaProvider` can
|
|
211
|
+
* subscribe by id instead with `useShellFitState(shellId).fits`. */
|
|
212
|
+
onNarrowChange?: (isNarrow: boolean) => void;
|
|
107
213
|
style?: SidebarProviderStyle;
|
|
108
214
|
}
|
|
109
215
|
export type SidebarProviderStyle = CSSProperties & {
|
|
216
|
+
/** Left rail, expanded. */
|
|
110
217
|
"--sidebar-width"?: string;
|
|
218
|
+
/** Left rail, folded to icons. */
|
|
111
219
|
"--sidebar-width-icon"?: string;
|
|
112
220
|
"--sidebar-width-mobile"?: string;
|
|
221
|
+
/** The secondary panel's floor, and the width it opens at. */
|
|
222
|
+
"--panel-width"?: string;
|
|
223
|
+
/** The body's floor — the secondary panel may never squeeze it past this. */
|
|
224
|
+
"--inset-min-width"?: string;
|
|
113
225
|
};
|
|
114
226
|
export type AnimatedSidebarInsetProps = HTMLMotionProps<"main">;
|
|
115
227
|
export interface AnimatedSidebarTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ShellFitActions, ShellFitInstanceId, ShellFitState } from './type';
|
|
2
|
+
/**
|
|
3
|
+
* Read the fit of the shell registered under `shellId` from anywhere below
|
|
4
|
+
* `ExegiaProvider` — no controller, no props, no provider of its own.
|
|
5
|
+
*
|
|
6
|
+
* ```tsx
|
|
7
|
+
* const { fits, panelWidth } = useShellFitState("app-shell")
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* This returns the whole state object, so the caller re-renders on every
|
|
11
|
+
* measurement. A component that reads one field should subscribe to that
|
|
12
|
+
* field's atom instead: `useAtomValue(shellFitFitsAtom("app-shell"))`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useShellFitState(shellId: ShellFitInstanceId): ShellFitState;
|
|
15
|
+
/**
|
|
16
|
+
* Drive the secondary panel of the shell registered under `shellId` from
|
|
17
|
+
* anywhere. Writes only — the caller never re-renders when the shell moves,
|
|
18
|
+
* so this is what a command palette or a keyboard shortcut should reach for.
|
|
19
|
+
*
|
|
20
|
+
* ```tsx
|
|
21
|
+
* const shell = useShellFitActions("app-shell")
|
|
22
|
+
* <Button onClick={() => shell.resizePanel(480)}>Wide inspector</Button>
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function useShellFitActions(shellId: ShellFitInstanceId): ShellFitActions;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ShellFitController, UseShellFitOptions } from './type';
|
|
2
|
+
/**
|
|
3
|
+
* Measures the shell and decides what the secondary panel may do: whether it
|
|
4
|
+
* exists at all, and how wide it may be dragged.
|
|
5
|
+
*
|
|
6
|
+
* The three things that move the answer are all observed here — the viewport
|
|
7
|
+
* (`resize`), the rail's fold (`railOpen`, a render input) and the user's own
|
|
8
|
+
* drag (`resizePanel`) — so no caller has to re-derive it. The measurement is
|
|
9
|
+
* the only thing this hook keeps to itself: the numbers land in the shell-fit
|
|
10
|
+
* atoms keyed by `shellId`, so anything under `ExegiaProvider` can read the
|
|
11
|
+
* verdict (`useShellFitState`) or move the panel (`useShellFitActions`)
|
|
12
|
+
* without holding this controller.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useShellFit({ shellId: explicitId, hostRef, railOpen, defaultPanelWidth, onUnfit, }: UseShellFitOptions): ShellFitController;
|
|
@@ -5,5 +5,16 @@ import { ShellPanelControls, UseShellPanelsOptions } from './type';
|
|
|
5
5
|
* callback. Spread the returned `providerProps` onto ShellLayout; the
|
|
6
6
|
* setters and `toggle` are for UI that lives outside the shell (title-bar
|
|
7
7
|
* buttons, command palette, shortcuts).
|
|
8
|
+
*
|
|
9
|
+
* The way back down is the store: `providerProps` carries a `shellId`, the
|
|
10
|
+
* shell files its measurement under it, and this hook reads `isNarrow` and
|
|
11
|
+
* `panelWidth` straight out of those atoms — so outside UI stands down with
|
|
12
|
+
* the panel instead of measuring `--sidebar-width` a second time. Name the
|
|
13
|
+
* `shellId` and any component below `ExegiaProvider` can do the same with
|
|
14
|
+
* `useShellFitState(shellId)`.
|
|
15
|
+
*
|
|
16
|
+
* Call it under the same `ExegiaProvider` as the shell it drives (or under
|
|
17
|
+
* none at all, on both sides): mounted above the provider it would read
|
|
18
|
+
* Jotai's default store while the shell writes to the provider's.
|
|
8
19
|
*/
|
|
9
|
-
export declare function useShellPanels({ defaultOpen, defaultOpenMobile, onPanelChange, }?: UseShellPanelsOptions): ShellPanelControls;
|
|
20
|
+
export declare function useShellPanels({ shellId: explicitId, defaultOpen, defaultOpenMobile, defaultPanelWidth, onPanelChange, }?: UseShellPanelsOptions): ShellPanelControls;
|
|
@@ -29,6 +29,38 @@ export declare const SUBMENU_ITEM_VARIANTS: Variants;
|
|
|
29
29
|
export declare const FOCUSABLE_SELECTOR: string;
|
|
30
30
|
export declare const MOBILE_QUERY = "(max-width: 767px)";
|
|
31
31
|
export declare const SIDEBAR_KEYBOARD_SHORTCUT = "b";
|
|
32
|
+
/**
|
|
33
|
+
* The shell's layout contract, in px. Every entry lands on the provider's
|
|
34
|
+
* wrapper as a CSS variable, so a consumer overrides a column by restyling it
|
|
35
|
+
* rather than by passing a prop:
|
|
36
|
+
*
|
|
37
|
+
* | variable | column |
|
|
38
|
+
* | ---------------------- | ----------------------------------------- |
|
|
39
|
+
* | `--sidebar-width` | left rail, expanded |
|
|
40
|
+
* | `--sidebar-width-icon` | left rail, folded to icons |
|
|
41
|
+
* | `--panel-width` | secondary panel: its floor AND its default |
|
|
42
|
+
* | `--inset-min-width` | the body's floor |
|
|
43
|
+
*
|
|
44
|
+
* These are only the defaults. Every measurement resolves the live variable,
|
|
45
|
+
* so an override wins over the value written here.
|
|
46
|
+
*/
|
|
47
|
+
export declare const SHELL_WIDTHS: {
|
|
48
|
+
readonly "--sidebar-width": "256px";
|
|
49
|
+
readonly "--sidebar-width-icon": "56px";
|
|
50
|
+
readonly "--sidebar-width-mobile": "18rem";
|
|
51
|
+
readonly "--panel-width": "320px";
|
|
52
|
+
readonly "--inset-min-width": "360px";
|
|
53
|
+
};
|
|
54
|
+
/** The expanded width of a panel docked to `side`: the secondary panel opens
|
|
55
|
+
* at `--panel-width`, the primary rail at `--sidebar-width`. */
|
|
56
|
+
export declare function expandedWidthVar(side: "left" | "right"): "var(--panel-width)" | "var(--sidebar-width)";
|
|
57
|
+
/** Resolve a CSS length — `var()` included — to px inside `host`'s cascade.
|
|
58
|
+
* Custom properties inherit, so a throwaway probe mounted in `host` reads the
|
|
59
|
+
* very `--sidebar-width` the shell lays out with, including a value a
|
|
60
|
+
* consumer overrode on the provider. Returns 0 when `host` has no layout
|
|
61
|
+
* (server render, `display: none`), so callers must fail open on 0 rather
|
|
62
|
+
* than treat it as a real measurement. */
|
|
63
|
+
export declare function resolveLength(host: HTMLElement, value: string): number;
|
|
32
64
|
export declare const AnimatedSidebarContext: import('react').Context<AnimatedSidebarContextValue | null>;
|
|
33
65
|
export declare const AnimatedSidebarPanelContext: import('react').Context<AnimatedSidebarPanelContextValue | null>;
|
|
34
66
|
export declare function useAnimatedSidebar(): AnimatedSidebarContextValue;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/** `full` shows mark + wordmark; `mark` folds the wordmark away — an icon
|
|
3
|
+
* rail, a favicon-sized corner. */
|
|
4
|
+
export type LogoVariant = "full" | "mark";
|
|
5
|
+
export interface LogoProps extends Omit<React.HTMLAttributes<HTMLElement>, "children"> {
|
|
6
|
+
/**
|
|
7
|
+
* Brand name. Labels the logo for AT (and the link, when `href` renders
|
|
8
|
+
* one), drives the default wordmark, and the monogram tile when no mark
|
|
9
|
+
* is given.
|
|
10
|
+
*/
|
|
11
|
+
name: string;
|
|
12
|
+
/** Custom mark — an inline SVG sized to fill its box. Wins over `src`. */
|
|
13
|
+
mark?: React.ReactNode;
|
|
14
|
+
/** Image URL for the mark. Decorative — `name` labels the logo. */
|
|
15
|
+
src?: string;
|
|
16
|
+
/** Wordmark content. Defaults to `name`. */
|
|
17
|
+
wordmark?: React.ReactNode;
|
|
18
|
+
/** `full` (default) or `mark` — the wordmark folds away, animated. */
|
|
19
|
+
variant?: LogoVariant;
|
|
20
|
+
/** Renders the logo as a link — the usual "mark goes home" affordance. */
|
|
21
|
+
href?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Brand lockup: a mark beside a wordmark. The mark is whatever the brand
|
|
25
|
+
* has — an SVG (`mark`), an image (`src`), or, given neither, a monogram
|
|
26
|
+
* tile derived from `name`. `variant="mark"` folds the wordmark away with
|
|
27
|
+
* the same motion a collapsing rail uses, so the lockup can sit in one and
|
|
28
|
+
* follow its fold. With `href` the whole lockup is a link named by `name`.
|
|
29
|
+
*
|
|
30
|
+
* Sizing rides on the mark: it defaults to `size-8`; restyle via
|
|
31
|
+
* `[&_[data-slot=logo-mark]]:size-*` or wrap in a text-size context for the
|
|
32
|
+
* wordmark, which inherits.
|
|
33
|
+
*/
|
|
34
|
+
export declare function Logo({ name, mark, src, wordmark, variant, href, className, ...props }: LogoProps): React.ReactElement;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -9,10 +9,10 @@ export declare const TREE_CLOSE_DURATION = 0.15;
|
|
|
9
9
|
export declare const TREE_MICRO_DURATION = 0.15;
|
|
10
10
|
/** Sidebar rail label reveal/hide when `collapsed` flips. */
|
|
11
11
|
export declare const TREE_COLLAPSE_DURATION = 0.2;
|
|
12
|
-
/** The collapsed rail's width in px —
|
|
13
|
-
* sync with the `w-
|
|
14
|
-
* expanded width has been measured. */
|
|
15
|
-
export declare const RAIL_COLLAPSED_WIDTH =
|
|
12
|
+
/** The collapsed rail's width in px — one `h-10 rounded-xl` icon row, edge
|
|
13
|
+
* to edge. Kept in sync with the `w-10` resting class the rail falls back to
|
|
14
|
+
* before its expanded width has been measured. */
|
|
15
|
+
export declare const RAIL_COLLAPSED_WIDTH = 40;
|
|
16
16
|
/** Rail label text fade — starts as the width growth is finishing, so the
|
|
17
17
|
* label never reads as clipped mid-grow. */
|
|
18
18
|
export declare const TREE_LABEL_REVEAL_DELAY = 0.01;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { Tree } from './tree';
|
|
2
2
|
export { useTree } from './use-tree';
|
|
3
|
+
export { useTreeActions, useTreeState } from './use-tree-state';
|
|
3
4
|
export { moveNode, renameNode } from './utils';
|
|
4
|
-
export
|
|
5
|
+
export { cancelTreeRenameAtom, collapseAllTreeNodesAtom, collapseTreeNodeAtom, expandAllTreeNodesAtom, expandTreeNodeAtom, moveTreeNodeAtom, removeTreeInstance, renameTreeNodeAtom, resetTreeAtom, revealTreeNodeAtom, selectTreeNodeAtom, setTreeCollapsedAtom, setTreeItemsAtom, startTreeRenameAtom, toggleTreeCollapsedAtom, toggleTreeNodeAtom, treeActiveIdAtom, treeCanMoveAtom, treeCanRenameAtom, treeCollapsedAtom, treeDraggedIdAtom, treeDropTargetAtom, treeExpandedIdsAtom, treeItemsAtom, treeRenamingIdAtom, treeSectionedAtom, treeSectionIdsAtom, treeStateAtom, } from './tree-atom';
|
|
6
|
+
export type { TreeActions, TreeController, TreeControllerProps, TreeDataProps, TreeDropPosition, TreeDropTarget, TreeInstanceId, TreeNode, TreeProps, TreeState, TreeVariant, UseTreeOptions, } from './type';
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Atom } from 'jotai';
|
|
2
|
+
import { TreeConfig, TreeDropPosition, TreeDropTarget, TreeHandlers, TreeInstanceId, TreeNode, TreeSeed, TreeState, TreeVariant } from './type';
|
|
3
|
+
/** What a tree reads as before `useTree` publishes its options. */
|
|
4
|
+
export declare const DEFAULT_TREE_CONFIG: TreeConfig;
|
|
5
|
+
/**
|
|
6
|
+
* A string-keyed atom family.
|
|
7
|
+
*
|
|
8
|
+
* `jotai/utils`' `atomFamily` is deprecated for Jotai v3, and we need only
|
|
9
|
+
* the string-keyed case with a `remove` — so this stays in-house rather than
|
|
10
|
+
* adding `jotai-family` as a second Jotai package to keep version-aligned.
|
|
11
|
+
* Dropping a key lets the store's WeakMap release that instance's state.
|
|
12
|
+
*/
|
|
13
|
+
type Family<AtomType> = ((id: TreeInstanceId) => AtomType) & {
|
|
14
|
+
remove: (id: TreeInstanceId) => void;
|
|
15
|
+
};
|
|
16
|
+
/** @internal */
|
|
17
|
+
export declare const treeConfigAtom: Family<import('jotai').PrimitiveAtom<TreeConfig> & {
|
|
18
|
+
init: TreeConfig;
|
|
19
|
+
}>;
|
|
20
|
+
/** @internal Refreshed every commit; nothing subscribes, so it is free. */
|
|
21
|
+
export declare const treeHandlersAtom: Family<import('jotai').PrimitiveAtom<TreeHandlers> & {
|
|
22
|
+
init: TreeHandlers;
|
|
23
|
+
}>;
|
|
24
|
+
/** The tree's current data — hook-owned, or the projection of a controlled
|
|
25
|
+
* `items` prop. */
|
|
26
|
+
export declare const treeItemsAtom: Family<import('jotai').PrimitiveAtom<TreeNode[]> & {
|
|
27
|
+
init: TreeNode[];
|
|
28
|
+
}>;
|
|
29
|
+
export declare const treeActiveIdAtom: Family<import('jotai').PrimitiveAtom<string | undefined> & {
|
|
30
|
+
init: string | undefined;
|
|
31
|
+
}>;
|
|
32
|
+
export declare const treeExpandedIdsAtom: Family<import('jotai').PrimitiveAtom<ReadonlySet<string>> & {
|
|
33
|
+
init: ReadonlySet<string>;
|
|
34
|
+
}>;
|
|
35
|
+
/** Raw rail fold. Read `treeCollapsedAtom` for the variant-masked value. */
|
|
36
|
+
export declare const treeRailCollapsedAtom: Family<import('jotai').PrimitiveAtom<boolean> & {
|
|
37
|
+
init: boolean;
|
|
38
|
+
}>;
|
|
39
|
+
export declare const treeRenamingIdAtom: Family<import('jotai').PrimitiveAtom<string | null> & {
|
|
40
|
+
init: string | null;
|
|
41
|
+
}>;
|
|
42
|
+
export declare const treeDraggedIdAtom: Family<import('jotai').PrimitiveAtom<string | null> & {
|
|
43
|
+
init: string | null;
|
|
44
|
+
}>;
|
|
45
|
+
export declare const treeDropTargetAtom: Family<import('jotai').PrimitiveAtom<TreeDropTarget | null> & {
|
|
46
|
+
init: TreeDropTarget | null;
|
|
47
|
+
}>;
|
|
48
|
+
/** @internal The only items atom `useTree` may subscribe to: empty while a
|
|
49
|
+
* controlled `items` prop owns the data, so the projection write never feeds
|
|
50
|
+
* back into the render that produced it. An inline `items={[…]}` array is a
|
|
51
|
+
* new reference every render, and a subscribed round-trip would loop. */
|
|
52
|
+
export declare const treeOwnedItemsAtom: Family<Atom<TreeNode[]>>;
|
|
53
|
+
/** Rail folded to icons — always `false` outside `sidebar`. */
|
|
54
|
+
export declare const treeCollapsedAtom: Family<Atom<boolean>>;
|
|
55
|
+
export declare const treeSectionedAtom: Family<Atom<boolean>>;
|
|
56
|
+
export declare const treeSectionIdsAtom: Family<Atom<string[]>>;
|
|
57
|
+
export declare const treeCanRenameAtom: Family<Atom<boolean>>;
|
|
58
|
+
export declare const treeCanMoveAtom: Family<Atom<boolean>>;
|
|
59
|
+
export declare const treeVariantAtom: Family<Atom<TreeVariant>>;
|
|
60
|
+
export declare const treeSoundAtom: Family<Atom<boolean>>;
|
|
61
|
+
/** Whether this one node's branch is open. */
|
|
62
|
+
export declare const treeNodeExpandedAtom: (id: TreeInstanceId, nodeId: string) => Atom<boolean>;
|
|
63
|
+
/** Whether this one node is the current entry. */
|
|
64
|
+
export declare const treeNodeActiveAtom: (id: TreeInstanceId, nodeId: string) => Atom<boolean>;
|
|
65
|
+
/** Whether this one node is in rename mode. */
|
|
66
|
+
export declare const treeNodeRenamingAtom: (id: TreeInstanceId, nodeId: string) => Atom<boolean>;
|
|
67
|
+
/** Whether this one node is the row in flight. */
|
|
68
|
+
export declare const treeNodeDraggingAtom: (id: TreeInstanceId, nodeId: string) => Atom<boolean>;
|
|
69
|
+
/** Where a drop on this one node would land, `null` when it is not hovered. */
|
|
70
|
+
export declare const treeNodeDropAtom: (id: TreeInstanceId, nodeId: string) => Atom<TreeDropPosition | null>;
|
|
71
|
+
/** The whole state of one tree. Components reading a single field should
|
|
72
|
+
* subscribe to that field's atom instead — this one changes on every edit. */
|
|
73
|
+
export declare const treeStateAtom: Family<Atom<TreeState>>;
|
|
74
|
+
export declare const expandTreeNodeAtom: Family<import('jotai').WritableAtom<null, [nodeId: string], void> & {
|
|
75
|
+
init: null;
|
|
76
|
+
}>;
|
|
77
|
+
export declare const collapseTreeNodeAtom: Family<import('jotai').WritableAtom<null, [nodeId: string], void> & {
|
|
78
|
+
init: null;
|
|
79
|
+
}>;
|
|
80
|
+
export declare const toggleTreeNodeAtom: Family<import('jotai').WritableAtom<null, [nodeId: string], void> & {
|
|
81
|
+
init: null;
|
|
82
|
+
}>;
|
|
83
|
+
export declare const expandAllTreeNodesAtom: Family<import('jotai').WritableAtom<null, [], void> & {
|
|
84
|
+
init: null;
|
|
85
|
+
}>;
|
|
86
|
+
export declare const collapseAllTreeNodesAtom: Family<import('jotai').WritableAtom<null, [], void> & {
|
|
87
|
+
init: null;
|
|
88
|
+
}>;
|
|
89
|
+
/** Open every ancestor of `nodeId` without touching the rest of the tree. */
|
|
90
|
+
export declare const revealTreeNodeAtom: Family<import('jotai').WritableAtom<null, [nodeId: string], void> & {
|
|
91
|
+
init: null;
|
|
92
|
+
}>;
|
|
93
|
+
/** @internal The same, silent. `useTree` runs it whenever the active id
|
|
94
|
+
* changes so a nested entry is never folded away — the hook has never
|
|
95
|
+
* reported that implicit reveal through `onExpandedChange`. */
|
|
96
|
+
export declare const revealTreeAncestorsAtom: Family<import('jotai').WritableAtom<null, [nodeId: string], void> & {
|
|
97
|
+
init: null;
|
|
98
|
+
}>;
|
|
99
|
+
export declare const setTreeCollapsedAtom: Family<import('jotai').WritableAtom<null, [collapsed: boolean], void> & {
|
|
100
|
+
init: null;
|
|
101
|
+
}>;
|
|
102
|
+
export declare const toggleTreeCollapsedAtom: Family<import('jotai').WritableAtom<null, [], void> & {
|
|
103
|
+
init: null;
|
|
104
|
+
}>;
|
|
105
|
+
/** Runs the node's own `onSelect` first, then `onNavigate` — the order a row
|
|
106
|
+
* press follows. Disabled and unknown nodes are inert. */
|
|
107
|
+
export declare const selectTreeNodeAtom: Family<import('jotai').WritableAtom<null, [nodeId: string], void> & {
|
|
108
|
+
init: null;
|
|
109
|
+
}>;
|
|
110
|
+
export declare const startTreeRenameAtom: Family<import('jotai').WritableAtom<null, [nodeId: string], void> & {
|
|
111
|
+
init: null;
|
|
112
|
+
}>;
|
|
113
|
+
export declare const cancelTreeRenameAtom: Family<import('jotai').WritableAtom<null, [], void> & {
|
|
114
|
+
init: null;
|
|
115
|
+
}>;
|
|
116
|
+
/** Commit a rename and leave rename mode. Blank or unchanged labels are
|
|
117
|
+
* dropped. */
|
|
118
|
+
export declare const renameTreeNodeAtom: Family<import('jotai').WritableAtom<null, [nodeId: string, label: string], void> & {
|
|
119
|
+
init: null;
|
|
120
|
+
}>;
|
|
121
|
+
export declare const moveTreeNodeAtom: Family<import('jotai').WritableAtom<null, [nodeId: string, parentId: string | null, index: number], void> & {
|
|
122
|
+
init: null;
|
|
123
|
+
}>;
|
|
124
|
+
/** Replace the data. Reports through `onItemsChange`; writes the atom only
|
|
125
|
+
* when no controlled `items` prop owns it. */
|
|
126
|
+
export declare const setTreeItemsAtom: Family<import('jotai').WritableAtom<null, [items: TreeNode[]], void> & {
|
|
127
|
+
init: null;
|
|
128
|
+
}>;
|
|
129
|
+
export declare const endTreeDragAtom: Family<import('jotai').WritableAtom<null, [], void> & {
|
|
130
|
+
init: null;
|
|
131
|
+
}>;
|
|
132
|
+
/** @internal Publish the latest options; seed the instance once. */
|
|
133
|
+
export declare const mountTreeAtom: Family<import('jotai').WritableAtom<null, [config: TreeConfig, seed: TreeSeed], void> & {
|
|
134
|
+
init: null;
|
|
135
|
+
}>;
|
|
136
|
+
/** @internal */
|
|
137
|
+
export declare const setTreeHandlersAtom: Family<import('jotai').WritableAtom<null, [handlers: TreeHandlers], void> & {
|
|
138
|
+
init: null;
|
|
139
|
+
}>;
|
|
140
|
+
/** @internal One-way projections of controlled props — no callbacks fire. */
|
|
141
|
+
export declare const projectTreeItemsAtom: Family<import('jotai').WritableAtom<null, [items: TreeNode[]], void> & {
|
|
142
|
+
init: null;
|
|
143
|
+
}>;
|
|
144
|
+
/** @internal */
|
|
145
|
+
export declare const projectTreeActiveIdAtom: Family<import('jotai').WritableAtom<null, [activeId: string | undefined], void> & {
|
|
146
|
+
init: null;
|
|
147
|
+
}>;
|
|
148
|
+
/** @internal */
|
|
149
|
+
export declare const projectTreeCollapsedAtom: Family<import('jotai').WritableAtom<null, [collapsed: boolean], void> & {
|
|
150
|
+
init: null;
|
|
151
|
+
}>;
|
|
152
|
+
/** Back to the values the instance mounted with. */
|
|
153
|
+
export declare const resetTreeAtom: Family<import('jotai').WritableAtom<null, [], void> & {
|
|
154
|
+
init: null;
|
|
155
|
+
}>;
|
|
156
|
+
/** Drop every atom for `id`. `useTree` calls this on unmount for trees it
|
|
157
|
+
* keyed itself; an explicit `treeId` outlives its component, so a rail's fold
|
|
158
|
+
* survives a route change. */
|
|
159
|
+
export declare function removeTreeInstance(id: TreeInstanceId): void;
|
|
160
|
+
export {};
|
|
@@ -4,4 +4,9 @@ export interface TreeRowProps {
|
|
|
4
4
|
node: TreeNode;
|
|
5
5
|
depth: number;
|
|
6
6
|
}
|
|
7
|
-
|
|
7
|
+
declare function TreeRowImpl({ node, depth }: TreeRowProps): React.ReactElement;
|
|
8
|
+
/** Rows are memoized so a re-render of the root — a rail measurement, a new
|
|
9
|
+
* `renderTrailing` — does not walk the whole tree. Each row's own state
|
|
10
|
+
* reaches it through its atoms instead. */
|
|
11
|
+
export declare const TreeRow: React.MemoExoticComponent<typeof TreeRowImpl>;
|
|
12
|
+
export {};
|