@exegia/corpora-ui 0.19.0 → 0.21.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/__tests__/auth-state-atom.test.d.ts +1 -0
- 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/nav/sidebar/__tests__/ai-sidebar-atom.test.d.ts +1 -0
- package/dist-lib/components/blocks/nav/sidebar/__tests__/use-ai-sidebar.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/ai-sidebar.d.ts +11 -2
- 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 +191 -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 +27 -31
- package/dist-lib/components/blocks/nav/sidebar/utils.d.ts +6 -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/scaffold/constants.d.ts +5 -0
- package/dist-lib/components/blocks/scaffold/scaffold-canvas.d.ts +2 -0
- package/dist-lib/components/blocks/scaffold/scaffold-panel.d.ts +1 -1
- package/dist-lib/components/blocks/scaffold/scaffold-tab.d.ts +6 -1
- package/dist-lib/components/blocks/scaffold/type.d.ts +28 -0
- package/dist-lib/components/blocks/scaffold/use-panel-visibility.d.ts +19 -0
- package/dist-lib/components/blocks/scaffold/utils.d.ts +6 -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 -0
- 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/tree/__tests__/tree-atom.test.d.ts +1 -0
- package/dist-lib/components/composed/tree/__tests__/tree.test.d.ts +1 -0
- package/dist-lib/components/composed/tree/__tests__/use-tree.test.d.ts +1 -0
- package/dist-lib/components/composed/tree/constants.d.ts +35 -0
- package/dist-lib/components/composed/tree/index.d.ts +6 -0
- package/dist-lib/components/composed/tree/tree-atom.d.ts +160 -0
- package/dist-lib/components/composed/tree/tree-context.d.ts +4 -0
- package/dist-lib/components/composed/tree/tree-node.d.ts +12 -0
- package/dist-lib/components/composed/tree/tree.d.ts +19 -0
- package/dist-lib/components/composed/tree/type.d.ts +290 -0
- package/dist-lib/components/composed/tree/use-tree-dnd.d.ts +18 -0
- package/dist-lib/components/composed/tree/use-tree-state.d.ts +25 -0
- package/dist-lib/components/composed/tree/use-tree.d.ts +24 -0
- package/dist-lib/components/composed/tree/utils.d.ts +28 -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/audio-wave.d.ts +2 -0
- package/dist-lib/components/user-avatar/component.d.ts +3 -0
- package/dist-lib/components/user-avatar/fallback.d.ts +5 -0
- package/dist-lib/components/user-avatar/index.d.ts +18 -0
- package/dist-lib/components/user-avatar/presence-badge.d.ts +16 -0
- package/dist-lib/components/user-avatar/type.d.ts +71 -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 +32 -0
- package/dist-lib/components/user-avatar/user-avatar-atom.d.ts +55 -0
- package/dist-lib/components/user-avatar/utils.d.ts +2 -0
- package/dist-lib/index.d.ts +6 -2
- package/dist-lib/index.js +3576 -1366
- 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 +16 -12
- package/src/components/beste/piece/browser-frame.tsx +9 -6
- 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/nav/sidebar/__tests__/ai-sidebar-atom.test.tsx +325 -0
- package/src/components/blocks/nav/sidebar/__tests__/use-ai-sidebar.test.tsx +310 -0
- package/src/components/blocks/nav/sidebar/ai-sidebar-atom.ts +698 -0
- package/src/components/blocks/nav/sidebar/ai-sidebar.tsx +112 -76
- 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 +228 -29
- package/src/components/blocks/nav/sidebar/use-ai-sidebar-state.ts +123 -0
- package/src/components/blocks/nav/sidebar/use-ai-sidebar.ts +455 -225
- package/src/components/blocks/nav/sidebar/utils.ts +29 -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/scaffold/__tests__/scaffold.test.tsx +160 -1
- package/src/components/blocks/scaffold/constants.ts +7 -0
- package/src/components/blocks/scaffold/panel-menu-button.tsx +3 -0
- package/src/components/blocks/scaffold/scaffold-canvas.tsx +48 -5
- package/src/components/blocks/scaffold/scaffold-inspector.tsx +3 -2
- package/src/components/blocks/scaffold/scaffold-main.tsx +1 -1
- package/src/components/blocks/scaffold/scaffold-panel.tsx +41 -5
- package/src/components/blocks/scaffold/scaffold-root.tsx +18 -3
- package/src/components/blocks/scaffold/scaffold-sidebar.tsx +1 -1
- package/src/components/blocks/scaffold/scaffold-tab.tsx +45 -7
- package/src/components/blocks/scaffold/type.ts +28 -0
- package/src/components/blocks/scaffold/use-panel-visibility.ts +180 -0
- package/src/components/blocks/scaffold/utils.ts +19 -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 -0
- 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/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 +525 -0
- package/src/components/composed/tree/__tests__/use-tree.test.tsx +333 -0
- package/src/components/composed/tree/constants.ts +60 -0
- package/src/components/composed/tree/index.ts +51 -0
- package/src/components/composed/tree/tree-atom.ts +590 -0
- package/src/components/composed/tree/tree-context.ts +13 -0
- package/src/components/composed/tree/tree-node.tsx +490 -0
- package/src/components/composed/tree/tree.tsx +286 -0
- package/src/components/composed/tree/type.ts +322 -0
- package/src/components/composed/tree/use-tree-dnd.ts +179 -0
- package/src/components/composed/tree/use-tree-state.ts +105 -0
- package/src/components/composed/tree/use-tree.ts +307 -0
- package/src/components/composed/tree/utils.ts +172 -0
- package/src/components/composed/user-avatar.tsx +11 -96
- package/src/components/docs/component-preview.tsx +11 -11
- package/src/components/user-avatar/__tests__/user-avatar.test.tsx +245 -0
- package/src/components/user-avatar/audio-wave.tsx +22 -0
- package/src/components/user-avatar/component.tsx +152 -0
- package/src/components/user-avatar/fallback.tsx +26 -0
- package/src/components/user-avatar/index.ts +34 -0
- package/src/components/user-avatar/presence-badge.tsx +56 -0
- package/src/components/user-avatar/type.ts +85 -0
- package/src/components/user-avatar/use-user-avatar-state.ts +60 -0
- package/src/components/user-avatar/use-user-avatar.ts +144 -0
- package/src/components/user-avatar/user-avatar-atom.ts +198 -0
- package/src/components/user-avatar/utils.ts +8 -0
- package/src/index.css +211 -153
- package/src/index.ts +35 -2
- package/src/state/exegia-provider.tsx +79 -0
- package/src/state/index.ts +4 -0
- package/src/state/store.ts +19 -0
|
@@ -5,6 +5,11 @@ export declare const SCAFFOLD_INSPECTOR_WIDTH = 272;
|
|
|
5
5
|
/** Most panels the canvas holds at once — omit Actions' `onAdd` when the
|
|
6
6
|
* count reaches it so the Add segment hides. */
|
|
7
7
|
export declare const SCAFFOLD_PANEL_CAPACITY = 3;
|
|
8
|
+
/** Narrowest a panel may render, in px. When the canvas can't grant every
|
|
9
|
+
* panel this width, the scaffold hides panels until the rest fit. */
|
|
10
|
+
export declare const SCAFFOLD_PANEL_MIN_WIDTH = 320;
|
|
11
|
+
/** Gap in px between side-by-side panels on the canvas (`gap-2`). */
|
|
12
|
+
export declare const SCAFFOLD_CANVAS_GAP = 8;
|
|
8
13
|
/** Gap in px between the drawer/actions and the viewport edges. */
|
|
9
14
|
export declare const SCAFFOLD_EDGE_GUTTER = 10;
|
|
10
15
|
/** Vertical room in px reserved above the canvas for the actions cluster. */
|
|
@@ -3,5 +3,7 @@ import * as React from "react";
|
|
|
3
3
|
/**
|
|
4
4
|
* The panel row below the action cluster: 8px gutters, 8px gaps, panels
|
|
5
5
|
* side by side. Key each `Scaffold.Panel` child so closes animate out.
|
|
6
|
+
* Measures its own width and hides id'd panels (oldest activation first)
|
|
7
|
+
* whenever it can't grant each one `SCAFFOLD_PANEL_MIN_WIDTH`.
|
|
6
8
|
*/
|
|
7
9
|
export declare function ScaffoldCanvas({ className, children, ...rest }: ScaffoldCanvasProps): React.ReactElement;
|
|
@@ -7,4 +7,4 @@ import * as React from "react";
|
|
|
7
7
|
* the two cards with a layout morph — the strip glides up and grows into the
|
|
8
8
|
* primary slot while the primary card shrinks down into the strip.
|
|
9
9
|
*/
|
|
10
|
-
export declare function ScaffoldPanel({ children, SecondaryPanel, onSwap, onCloseSecondary, name, swapLabel, sound, className, }: ScaffoldPanelProps): React.ReactElement;
|
|
10
|
+
export declare function ScaffoldPanel({ id, children, SecondaryPanel, onSwap, onCloseSecondary, name, swapLabel, sound, className, }: ScaffoldPanelProps): React.ReactElement;
|
|
@@ -5,5 +5,10 @@ import * as React from "react";
|
|
|
5
5
|
* affordance. Render one per open panel as Actions children, keyed —
|
|
6
6
|
* closes animate out of the pill. Omit `onClose` on the last remaining
|
|
7
7
|
* panel's tab; the canvas keeps at least one panel open.
|
|
8
|
+
*
|
|
9
|
+
* With `panelId` (matching a `Scaffold.Panel`'s `id`), the tab also fronts
|
|
10
|
+
* that panel's visibility: a hidden panel dims its tab behind an eye-off
|
|
11
|
+
* icon, and pressing the label toggles the panel — showing one past
|
|
12
|
+
* capacity hides the least-recently-activated panel in its place.
|
|
8
13
|
*/
|
|
9
|
-
export declare function ScaffoldTab({ children, onClose, closeLabel, sound, className, ...rest }: ScaffoldTabProps): React.ReactElement;
|
|
14
|
+
export declare function ScaffoldTab({ children, panelId, onClose, closeLabel, sound, className, ...rest }: ScaffoldTabProps): React.ReactElement;
|
|
@@ -7,6 +7,25 @@ export interface ScaffoldContextValue {
|
|
|
7
7
|
inspectorWidth: number;
|
|
8
8
|
setInspectorOpen: (open: boolean) => void;
|
|
9
9
|
toggleInspector: () => void;
|
|
10
|
+
/** How many panels currently fit side by side, from the measured canvas
|
|
11
|
+
* width at `SCAFFOLD_PANEL_MIN_WIDTH` per panel (1..`SCAFFOLD_PANEL_CAPACITY`). */
|
|
12
|
+
panelCapacity: number;
|
|
13
|
+
/** Ids of id'd panels the scaffold is currently hiding — auto-hidden by
|
|
14
|
+
* capacity pressure or toggled away from a tab. */
|
|
15
|
+
hiddenPanelIds: readonly string[];
|
|
16
|
+
isPanelHidden: (id: string) => boolean;
|
|
17
|
+
/** Show/hide an id'd panel. Showing past capacity auto-hides the
|
|
18
|
+
* least-recently-activated visible panel; the last visible one never hides. */
|
|
19
|
+
togglePanelVisibility: (id: string) => void;
|
|
20
|
+
/** Id of the panel whose tab the pointer is resting on — the canvas
|
|
21
|
+
* spotlights it by fading every other id'd panel to 0.35 opacity. */
|
|
22
|
+
hoveredPanelId: string | null;
|
|
23
|
+
/** @internal Tabs report pointer enter/leave on their label. */
|
|
24
|
+
setPanelHovered: (id: string, hovered: boolean) => void;
|
|
25
|
+
/** @internal Canvas reports its ordered panel ids. */
|
|
26
|
+
registerPanelIds: (ids: readonly string[]) => void;
|
|
27
|
+
/** @internal Canvas reports its measured width. */
|
|
28
|
+
setCanvasWidth: (width: number) => void;
|
|
10
29
|
}
|
|
11
30
|
export interface ScaffoldRootProps extends ComponentProps<"div"> {
|
|
12
31
|
/** Controlled inspector state — pair with `onInspectorOpenChange`, or
|
|
@@ -41,6 +60,11 @@ export interface ScaffoldActionsProps extends MotionSafe<Omit<ComponentProps<"di
|
|
|
41
60
|
}
|
|
42
61
|
export type TScaffoldPanelChild<T extends ScaffoldSubPanelProps = ScaffoldSubPanelProps> = ReactElement<T, React.JSXElementConstructor<T>>;
|
|
43
62
|
export interface ScaffoldPanelProps {
|
|
63
|
+
/** Stable id opting the panel into responsive hiding: the canvas hides
|
|
64
|
+
* id'd panels when it can't grant each `SCAFFOLD_PANEL_MIN_WIDTH`, and a
|
|
65
|
+
* `Scaffold.Tab` with the matching `panelId` reflects and toggles it.
|
|
66
|
+
* Omitted, the panel always renders. */
|
|
67
|
+
id?: string;
|
|
44
68
|
/** The panel's content, rendered in a card with a drop shadow. */
|
|
45
69
|
children: ReactNode;
|
|
46
70
|
/** The panel's content, rendered in a card with a drop shadow. */
|
|
@@ -64,6 +88,10 @@ export interface ScaffoldPanelProps {
|
|
|
64
88
|
export interface ScaffoldTabProps extends MotionSafe<Omit<ComponentProps<"div">, "children">> {
|
|
65
89
|
/** The tab's label. */
|
|
66
90
|
children?: ReactNode;
|
|
91
|
+
/** Id of the panel this tab fronts (`Scaffold.Panel`'s `id`). The tab
|
|
92
|
+
* then shows whether the panel is hidden and pressing its label toggles
|
|
93
|
+
* visibility — showing past capacity hides another panel in its place. */
|
|
94
|
+
panelId?: string;
|
|
67
95
|
/** Renders the tab's close button. The button renders only while this
|
|
68
96
|
* is present — omit it to pin the tab, e.g. on the last remaining
|
|
69
97
|
* panel (the canvas keeps at least one open). */
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface PanelVisibility {
|
|
2
|
+
/** How many panels currently fit side by side (1..capacity cap). */
|
|
3
|
+
panelCapacity: number;
|
|
4
|
+
/** Ids of panels currently hidden (auto + user), for tabs to reflect. */
|
|
5
|
+
hiddenPanelIds: readonly string[];
|
|
6
|
+
isPanelHidden: (id: string) => boolean;
|
|
7
|
+
togglePanelVisibility: (id: string) => void;
|
|
8
|
+
/** Id of the panel whose tab is hovered — the canvas spotlights it. */
|
|
9
|
+
hoveredPanelId: string | null;
|
|
10
|
+
/** @internal Tabs report pointer enter/leave on their label. */
|
|
11
|
+
setPanelHovered: (id: string, hovered: boolean) => void;
|
|
12
|
+
/** @internal Canvas reports its ordered panel ids each render. */
|
|
13
|
+
registerPanelIds: (ids: readonly string[]) => void;
|
|
14
|
+
/** @internal Canvas reports its measured width. */
|
|
15
|
+
setCanvasWidth: (width: number) => void;
|
|
16
|
+
}
|
|
17
|
+
/** Owns which panels are hidden as the canvas gains and loses room.
|
|
18
|
+
* Lives in `Scaffold.Root`; Canvas and Tab reach it through context. */
|
|
19
|
+
export declare function usePanelVisibility(): PanelVisibility;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { Variants } from 'motion/react';
|
|
2
2
|
import { ClassNameValue } from 'tailwind-merge';
|
|
3
3
|
import { TSubPanelVariant } from './type.ts';
|
|
4
|
+
/**
|
|
5
|
+
* How many panels fit on a canvas of `width` px, granting each
|
|
6
|
+
* `SCAFFOLD_PANEL_MIN_WIDTH` plus the gaps between them. Clamped to
|
|
7
|
+
* [1, SCAFFOLD_PANEL_CAPACITY]; an unmeasured canvas (`null`) fits the cap.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getPanelCapacity(width: number | null): number;
|
|
4
10
|
/** Desktop backdrop the whole scaffold sits on — a soft warm-gray wash. */
|
|
5
11
|
export declare const scaffoldBackgroundClass: ClassNameValue;
|
|
6
12
|
/** Card surface shared by a panel's primary area and secondary strip. */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { AnimatedSidebarProviderProps } from './type';
|
|
2
|
-
export declare function AnimatedPanelProvider({ children, open, defaultOpen, onOpenChange, openMobile, defaultOpenMobile, onOpenMobileChange, className, style, ...props }: AnimatedSidebarProviderProps): import("react").JSX.Element;
|
|
2
|
+
export declare function AnimatedPanelProvider({ children, shellId, defaultPanelWidth, open, defaultOpen, onOpenChange, openMobile, defaultOpenMobile, onOpenMobileChange, onNarrowChange, className, style, ...props }: AnimatedSidebarProviderProps): import("react").JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { AnimatedSidebarProps } from './type';
|
|
2
|
-
export declare function AnimatedPanel({ side, variant, collapsible, ariaLabel, children, className, panelClassName, style, ref, ...props }: AnimatedSidebarProps): import("react").JSX.Element;
|
|
2
|
+
export declare function AnimatedPanel({ side, variant, collapsible, ariaLabel, children, className, panelClassName, style, ref, ...props }: AnimatedSidebarProps): import("react").JSX.Element | null;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { ShellLayout } from './shell-layout';
|
|
2
2
|
export type * from './type';
|
|
3
|
+
export * from './shell-metrics';
|
|
3
4
|
export * from './use-shell-panels';
|
|
5
|
+
export { useShellFit } from './use-shell-fit';
|
|
6
|
+
export { useShellFitActions, useShellFitState } from './use-shell-fit-state';
|
|
7
|
+
export { removeShellFitInstance, resetShellPanelWidthAtom, resizeShellPanelAtom, shellFitFitsAtom, shellFitMeasuredAtom, shellFitMetricsAtom, shellFitPanelBoundsAtom, shellFitPanelWidthAtom, shellFitRequestedWidthAtom, shellFitStateAtom, } from './shell-fit-atom';
|
|
4
8
|
export * from './utils';
|
|
5
9
|
export * from './animated-panel';
|
|
6
10
|
export * from './animated-panel-inset';
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ShellMetrics } from './shell-metrics';
|
|
2
|
+
import { ShellFitInstanceId, ShellFitPanelBounds, ShellFitSeed, ShellFitState } from './type';
|
|
3
|
+
/**
|
|
4
|
+
* A string-keyed atom family.
|
|
5
|
+
*
|
|
6
|
+
* `jotai/utils`' `atomFamily` is deprecated for Jotai v3, and we need only
|
|
7
|
+
* the string-keyed case with a `remove` — so this stays in-house rather than
|
|
8
|
+
* adding `jotai-family` as a second Jotai package to keep version-aligned.
|
|
9
|
+
* Dropping a key lets the store's WeakMap release that instance's state.
|
|
10
|
+
*/
|
|
11
|
+
type Family<AtomType> = ((id: ShellFitInstanceId) => AtomType) & {
|
|
12
|
+
remove: (id: ShellFitInstanceId) => void;
|
|
13
|
+
};
|
|
14
|
+
/** The shell's own measurement of its columns. `useShellFit` is the only
|
|
15
|
+
* writer; read `shellFitMeasuredAtom` to get it with the "no layout yet" case
|
|
16
|
+
* already resolved. */
|
|
17
|
+
export declare const shellFitMetricsAtom: Family<import('jotai').PrimitiveAtom<ShellMetrics> & {
|
|
18
|
+
init: ShellMetrics;
|
|
19
|
+
}>;
|
|
20
|
+
/** The width the user dragged to, before clamping — null while the panel sits
|
|
21
|
+
* at `--panel-width`. Read `shellFitPanelWidthAtom` for the width the panel
|
|
22
|
+
* actually renders at: clamping on read is what lets a narrowing viewport
|
|
23
|
+
* pull the panel down without forgetting the width they asked for. */
|
|
24
|
+
export declare const shellFitRequestedWidthAtom: Family<import('jotai').PrimitiveAtom<number | null> & {
|
|
25
|
+
init: number | null;
|
|
26
|
+
}>;
|
|
27
|
+
/** The metrics, or null when the shell has no layout to report — a server
|
|
28
|
+
* render, a `display: none` host, a test with no layout engine. A zero is not
|
|
29
|
+
* a width, and treating it as one would pin the panel to nothing. */
|
|
30
|
+
export declare const shellFitMeasuredAtom: Family<import('jotai').Atom<ShellMetrics | null>>;
|
|
31
|
+
/** Whether the shell can hold a secondary panel at all. */
|
|
32
|
+
export declare const shellFitFitsAtom: Family<import('jotai').Atom<boolean>>;
|
|
33
|
+
/** The range a resize may land in. */
|
|
34
|
+
export declare const shellFitPanelBoundsAtom: Family<import('jotai').Atom<ShellFitPanelBounds>>;
|
|
35
|
+
/** The width the secondary panel renders at, or null before the first
|
|
36
|
+
* measurement, where the caller falls back to `--panel-width`. */
|
|
37
|
+
export declare const shellFitPanelWidthAtom: Family<import('jotai').Atom<number | null>>;
|
|
38
|
+
/** The whole fit of one shell. This changes on every measurement, so a
|
|
39
|
+
* component that reads one field should subscribe to that field's atom
|
|
40
|
+
* instead: `useAtomValue(shellFitFitsAtom("app-shell"))`. */
|
|
41
|
+
export declare const shellFitStateAtom: Family<import('jotai').Atom<ShellFitState>>;
|
|
42
|
+
/** @internal The measurement's way in. Silent, and inert when the numbers did
|
|
43
|
+
* not move — a resize event that changes nothing must not re-render a shell. */
|
|
44
|
+
export declare const measureShellFitAtom: Family<import('jotai').WritableAtom<null, [metrics: ShellMetrics], void> & {
|
|
45
|
+
init: null;
|
|
46
|
+
}>;
|
|
47
|
+
/** Resize the secondary panel. Clamped on the way in, so a drag past the
|
|
48
|
+
* gutter parks at the bound instead of banking travel it has to give back —
|
|
49
|
+
* and a caller with no idea how wide the shell is can still ask for 900. */
|
|
50
|
+
export declare const resizeShellPanelAtom: Family<import('jotai').WritableAtom<null, [width: number], void> & {
|
|
51
|
+
init: null;
|
|
52
|
+
}>;
|
|
53
|
+
/** Back to the width the shell mounted with — `defaultPanelWidth`, or
|
|
54
|
+
* `--panel-width` when there was none. */
|
|
55
|
+
export declare const resetShellPanelWidthAtom: Family<import('jotai').WritableAtom<null, [], void> & {
|
|
56
|
+
init: null;
|
|
57
|
+
}>;
|
|
58
|
+
/** @internal Seed the instance once. A seed describes the mount, not every
|
|
59
|
+
* render, so a `defaultPanelWidth` that arrives later never overwrites a
|
|
60
|
+
* width the user dragged to. */
|
|
61
|
+
export declare const mountShellFitAtom: Family<import('jotai').WritableAtom<null, [seed: ShellFitSeed], void> & {
|
|
62
|
+
init: null;
|
|
63
|
+
}>;
|
|
64
|
+
/** Drop every atom for `id`. `useShellFit` calls this on unmount for shells it
|
|
65
|
+
* keyed itself; an explicit `shellId` is the app's key and outlives its
|
|
66
|
+
* component, so a resized panel survives a route change. */
|
|
67
|
+
export declare function removeShellFitInstance(id: ShellFitInstanceId): void;
|
|
68
|
+
export {};
|
|
@@ -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 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Transition, Variants } from 'motion/react';
|
|
2
|
+
/** `--ease-smooth-out` as a motion/react easing tuple. */
|
|
3
|
+
export declare const TREE_EASE: readonly [0.22, 1, 0.36, 1];
|
|
4
|
+
/** Branch open — `--duration-fast` territory (accordion open). */
|
|
5
|
+
export declare const TREE_OPEN_DURATION = 0.25;
|
|
6
|
+
/** Branch close — quicker than open, per open/close asymmetry. */
|
|
7
|
+
export declare const TREE_CLOSE_DURATION = 0.15;
|
|
8
|
+
/** Chevron flip and label fades. */
|
|
9
|
+
export declare const TREE_MICRO_DURATION = 0.15;
|
|
10
|
+
/** Sidebar rail label reveal/hide when `collapsed` flips. */
|
|
11
|
+
export declare const TREE_COLLAPSE_DURATION = 0.2;
|
|
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
|
+
/** Rail label text fade — starts as the width growth is finishing, so the
|
|
17
|
+
* label never reads as clipped mid-grow. */
|
|
18
|
+
export declare const TREE_LABEL_REVEAL_DELAY = 0.01;
|
|
19
|
+
/** A branch's children group: grows open with a soft stagger, folds shut
|
|
20
|
+
* faster. Height rides layout ("auto"), paint fades. */
|
|
21
|
+
export declare const TREE_BRANCH_VARIANTS: Variants;
|
|
22
|
+
/** Branch close — a plain target, NOT the "closed" variant label: a
|
|
23
|
+
* labeled exit orchestrates every variant child and AnimatePresence then
|
|
24
|
+
* waits on the whole subtree before unmounting. */
|
|
25
|
+
export declare const TREE_BRANCH_EXIT: {
|
|
26
|
+
height: number;
|
|
27
|
+
opacity: number;
|
|
28
|
+
transition: {
|
|
29
|
+
duration: number;
|
|
30
|
+
ease: readonly [0.22, 1, 0.36, 1];
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
/** One row inside an opening branch — a short blurred rise. */
|
|
34
|
+
export declare const TREE_ROW_VARIANTS: Variants;
|
|
35
|
+
export declare const TREE_MICRO_TRANSITION: Transition;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Tree } from './tree';
|
|
2
|
+
export { useTree } from './use-tree';
|
|
3
|
+
export { useTreeActions, useTreeState } from './use-tree-state';
|
|
4
|
+
export { moveNode, renameNode } from './utils';
|
|
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';
|