@exegia/corpora-ui 0.14.0 → 0.16.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.
@@ -1,4 +1,5 @@
1
1
  import { ShellLayout } from './shell-layout';
2
2
  export type * from './type';
3
+ export * from './use-shell-panels';
3
4
  export * from './utils';
4
5
  export { ShellLayout as default };
@@ -1,3 +1,3 @@
1
1
  import { ShellLayoutProps } from './type';
2
2
  import * as React from "react";
3
- export declare function ShellLayout({ children, open, defaultOpen, onOpenChange, rightDrawer, rightOpen, defaultRightOpen, onRightOpenChange, variant, className, }: ShellLayoutProps): React.ReactElement;
3
+ export declare function ShellLayout({ children, variant, panels, className, defaultOpen, ...panelControlProps }: ShellLayoutProps): React.ReactElement;
@@ -1,27 +1,73 @@
1
- import { default as React } from 'react';
1
+ import { ReactNode } from 'react';
2
+ import { AnimatedSidebarProviderProps, SidebarSide } from '../../motion/animated-sidebar';
2
3
  export interface ShellAction {
3
4
  id: string;
4
5
  label: string;
5
- icon: React.ReactNode;
6
- badge?: React.ReactNode;
6
+ icon: ReactNode;
7
+ badge?: ReactNode;
7
8
  onSelect?: () => void;
8
9
  }
9
10
  export interface ShellWorkspace {
10
11
  name: string;
11
- logo?: React.ReactNode;
12
- meta?: React.ReactNode;
12
+ logo?: ReactNode;
13
+ meta?: ReactNode;
13
14
  }
14
- export interface ShellLayoutProps {
15
- children?: React.ReactNode;
16
- open?: boolean;
15
+ export interface IPanel {
16
+ id: string;
17
+ name: string;
18
+ component: ReactNode;
19
+ /** Replaces the default icon inside the panel's header trigger. The shell
20
+ * keeps the trigger button itself (toggle wiring, aria-label) — this only
21
+ * swaps what renders inside it. */
22
+ trigger?: ReactNode;
23
+ open: boolean;
17
24
  defaultOpen?: boolean;
18
- onOpenChange?: (open: boolean) => void;
19
- /** Content of the right drawer. It has no icon rail — it is either fully
20
- * shown or fully hidden. */
21
- rightDrawer?: React.ReactNode;
22
- rightOpen?: boolean;
23
- defaultRightOpen?: boolean;
24
- onRightOpenChange?: (open: boolean) => void;
25
+ side: "left" | "bottom" | "right" | "sidebar";
26
+ }
27
+ /** The side a panel docks to, as a value union (`IPanel["side"]`).
28
+ * `Pick<IPanel, "side">` would be the object type `{ side: ... }`, which can
29
+ * neither key a Record nor travel as a plain callback argument. */
30
+ export type TPanelSide = IPanel["side"];
31
+ /** Panel content keyed by the side it docks to. `Side` narrows the map to
32
+ * the sides a surface actually renders (the shell renders left and right).
33
+ * Entries are optional — a shell with no bottom dock simply has no `bottom`
34
+ * key. Where an entry's own `side` field disagrees with its key, the key
35
+ * wins. */
36
+ export type TPanelMap<Side extends TPanelSide = TPanelSide> = Partial<Record<Side, IPanel>>;
37
+ /** The open/close surface of the shell's panels, lifted straight from
38
+ * AnimatedSidebarProvider — every prop is keyed by side, there are no
39
+ * explicit per-side props. `useShellPanels` produces the controlled subset
40
+ * of these as `providerProps`. */
41
+ export type ShellPanelControlProps = Pick<AnimatedSidebarProviderProps, "open" | "defaultOpen" | "onOpenChange" | "openMobile" | "defaultOpenMobile" | "onOpenMobileChange">;
42
+ export interface UseShellPanelsOptions {
43
+ /** Initial desktop open state per side, merged over
44
+ * `{ left: true, right: false }`. */
45
+ defaultOpen?: AnimatedSidebarProviderProps["defaultOpen"];
46
+ /** Initial mobile overlay state per side — every side starts closed. */
47
+ defaultOpenMobile?: AnimatedSidebarProviderProps["defaultOpenMobile"];
48
+ /** Panel change event returning both the next open state and the side of
49
+ * the panel the change comes from. Mobile overlay changes report the same
50
+ * side as their desktop counterpart. */
51
+ onPanelChange?: (open: boolean, side: TPanelSide) => void;
52
+ }
53
+ export interface ShellPanelControls {
54
+ /** Live desktop open state, keyed by side. */
55
+ open: Record<SidebarSide, boolean>;
56
+ /** Live mobile overlay state, keyed by side. */
57
+ openMobile: Record<SidebarSide, boolean>;
58
+ setOpen: (open: boolean, side: SidebarSide) => void;
59
+ setOpenMobile: (open: boolean, side: SidebarSide) => void;
60
+ /** Desktop-only convenience — the in-shell triggers already pick the
61
+ * mobile state themselves when the viewport is narrow. */
62
+ toggle: (side: SidebarSide) => void;
63
+ /** Spread onto ShellLayout (or AnimatedSidebarProvider directly). */
64
+ providerProps: ShellPanelControlProps;
65
+ }
66
+ export interface ShellLayoutProps extends ShellPanelControlProps {
67
+ children?: ReactNode;
68
+ /** Content for the shell's panels, keyed by the side. The shell renders
69
+ * the `left` rail and the `right` drawer; other sides are reserved. */
70
+ panels?: TPanelMap;
25
71
  className?: string;
26
- variant: 'web' | 'desktop';
72
+ variant?: "web" | "desktop";
27
73
  }
@@ -0,0 +1,9 @@
1
+ import { ShellPanelControls, UseShellPanelsOptions } from './type';
2
+ /**
3
+ * Owns the open/close state of the shell's panels, keyed by side, and
4
+ * reports every change through a single `onPanelChange(open, side)`
5
+ * callback. Spread the returned `providerProps` onto ShellLayout; the
6
+ * setters and `toggle` are for UI that lives outside the shell (title-bar
7
+ * buttons, command palette, shortcuts).
8
+ */
9
+ export declare function useShellPanels({ defaultOpen, defaultOpenMobile, onPanelChange, }?: UseShellPanelsOptions): ShellPanelControls;
@@ -1,26 +1,24 @@
1
1
  import { HTMLMotionProps } from 'motion/react';
2
2
  import { ButtonHTMLAttributes, CSSProperties, HTMLAttributes, ReactNode } from 'react';
3
- type SidebarState = "expanded" | "collapsed";
4
- type SidebarSide = "left" | "right";
3
+ export type SidebarSide = "left" | "right";
4
+ /** Open flags keyed by the side. Sides left out stay uncontrolled / at their
5
+ * default — there is no per-side prop, the record IS the API. */
6
+ export type SidebarOpenState = Partial<Record<SidebarSide, boolean>>;
5
7
  type SidebarVariant = "sidebar" | "floating" | "inset";
6
8
  type SidebarCollapsible = "offcanvas" | "icon" | "none";
7
9
  interface AnimatedSidebarContextValue {
8
10
  isMobile: boolean;
9
11
  layoutId: string;
10
- open: boolean;
11
- openMobile: boolean;
12
- /** The right panel is a single hidden/shown state — no icon rail, no
13
- * separate mobile state. */
14
- openRight: boolean;
12
+ /** Desktop open state, keyed by side. */
13
+ open: Record<SidebarSide, boolean>;
14
+ /** Mobile overlay open state, keyed by side. */
15
+ openMobile: Record<SidebarSide, boolean>;
15
16
  reduce: boolean;
16
- setOpen: (open: boolean) => void;
17
- setOpenMobile: (open: boolean) => void;
18
- setOpenRight: (open: boolean) => void;
19
- state: SidebarState;
20
- toggleSidebar: () => void;
21
- toggleRightSidebar: () => void;
22
- triggerRef: React.RefObject<HTMLButtonElement | null>;
23
- rightTriggerRef: React.RefObject<HTMLButtonElement | null>;
17
+ setOpen: (open: boolean, side: SidebarSide) => void;
18
+ setOpenMobile: (open: boolean, side: SidebarSide) => void;
19
+ /** Mobile-aware: toggles the overlay below md, the docked panel above. */
20
+ toggleSidebar: (side: SidebarSide) => void;
21
+ triggerRefs: Record<SidebarSide, React.RefObject<HTMLButtonElement | null>>;
24
22
  }
25
23
  export declare function useAnimatedSidebar(): AnimatedSidebarContextValue;
26
24
  type SidebarProviderStyle = CSSProperties & {
@@ -29,18 +27,20 @@ type SidebarProviderStyle = CSSProperties & {
29
27
  "--sidebar-width-mobile"?: string;
30
28
  };
31
29
  export interface AnimatedSidebarProviderProps extends HTMLAttributes<HTMLDivElement> {
32
- open?: boolean;
33
- defaultOpen?: boolean;
34
- onOpenChange?: (open: boolean) => void;
35
- openMobile?: boolean;
36
- defaultOpenMobile?: boolean;
37
- onOpenMobileChange?: (open: boolean) => void;
38
- openRight?: boolean;
39
- defaultOpenRight?: boolean;
40
- onOpenRightChange?: (open: boolean) => void;
30
+ /** Controlled desktop open state, keyed by the side. A side left undefined
31
+ * stays uncontrolled. */
32
+ open?: SidebarOpenState;
33
+ /** Initial desktop open state, merged over `{ left: true, right: false }`. */
34
+ defaultOpen?: SidebarOpenState;
35
+ onOpenChange?: (open: boolean, side: SidebarSide) => void;
36
+ /** Controlled mobile overlay state, keyed by side. */
37
+ openMobile?: SidebarOpenState;
38
+ /** Initial mobile overlay state — every side starts closed. */
39
+ defaultOpenMobile?: SidebarOpenState;
40
+ onOpenMobileChange?: (open: boolean, side: SidebarSide) => void;
41
41
  style?: SidebarProviderStyle;
42
42
  }
43
- export declare function AnimatedSidebarProvider({ children, open, defaultOpen, onOpenChange, openMobile, defaultOpenMobile, onOpenMobileChange, openRight, defaultOpenRight, onOpenRightChange, className, style, ...props }: AnimatedSidebarProviderProps): import("react").JSX.Element;
43
+ export declare function AnimatedSidebarProvider({ children, open, defaultOpen, onOpenChange, openMobile, defaultOpenMobile, onOpenMobileChange, className, style, ...props }: AnimatedSidebarProviderProps): import("react").JSX.Element;
44
44
  export interface AnimatedSidebarProps extends Omit<HTMLMotionProps<"aside">, "children"> {
45
45
  children?: ReactNode;
46
46
  side?: SidebarSide;