gridsmith-ui 0.32.0 → 0.33.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/CHANGELOG.md +33 -1
- package/README.md +4 -2
- package/dist/charts.d.ts +10 -1
- package/dist/charts.js +113 -48
- package/dist/charts.js.map +1 -1
- package/dist/chat.js +2 -2
- package/dist/{chunk-NGZJK57C.js → chunk-6NRLTG5W.js} +8 -7
- package/dist/chunk-6NRLTG5W.js.map +1 -0
- package/dist/{chunk-OVHM55JF.js → chunk-6XCWKLJZ.js} +40 -5
- package/dist/chunk-6XCWKLJZ.js.map +1 -0
- package/dist/{chunk-JHZ22HQP.js → chunk-AB4UQ4G5.js} +58 -219
- package/dist/chunk-AB4UQ4G5.js.map +1 -0
- package/dist/{chunk-SIEU4H3H.js → chunk-AVSP6NDX.js} +5 -5
- package/dist/{chunk-SIEU4H3H.js.map → chunk-AVSP6NDX.js.map} +1 -1
- package/dist/chunk-F2XMZOUP.js +81 -0
- package/dist/chunk-F2XMZOUP.js.map +1 -0
- package/dist/{chunk-XBVZIN26.js → chunk-FF57N3P7.js} +8 -6
- package/dist/chunk-FF57N3P7.js.map +1 -0
- package/dist/chunk-GIA4BMGI.js +18 -0
- package/dist/chunk-GIA4BMGI.js.map +1 -0
- package/dist/{chunk-DO6DLTFK.js → chunk-OWGF362U.js} +4 -4
- package/dist/{chunk-DO6DLTFK.js.map → chunk-OWGF362U.js.map} +1 -1
- package/dist/chunk-P3NUUIL6.js +9 -0
- package/dist/chunk-P3NUUIL6.js.map +1 -0
- package/dist/chunk-R7FG4ZQ5.js +16 -0
- package/dist/chunk-R7FG4ZQ5.js.map +1 -0
- package/dist/{chunk-QY2RA2HO.js → chunk-UBLBVCQN.js} +3 -3
- package/dist/{chunk-QY2RA2HO.js.map → chunk-UBLBVCQN.js.map} +1 -1
- package/dist/{chunk-HUVZQOU4.js → chunk-WD6T57ZJ.js} +3 -3
- package/dist/{chunk-HUVZQOU4.js.map → chunk-WD6T57ZJ.js.map} +1 -1
- package/dist/chunk-ZQV26NND.js +213 -0
- package/dist/chunk-ZQV26NND.js.map +1 -0
- package/dist/dashboard.d.ts +207 -0
- package/dist/dashboard.js +1210 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/data-grid.js +8 -7
- package/dist/data-grid.js.map +1 -1
- package/dist/index.d.ts +50 -6
- package/dist/index.js +190 -128
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +6 -6
- package/dist/resizable.js +7 -6
- package/dist/resizable.js.map +1 -1
- package/dist/utils.d.ts +51 -1
- package/dist/utils.js +55 -4
- package/dist/utils.js.map +1 -1
- package/dist/virtualized.js +6 -6
- package/package.json +6 -1
- package/dist/chunk-H732QL56.js +0 -71
- package/dist/chunk-H732QL56.js.map +0 -1
- package/dist/chunk-JHZ22HQP.js.map +0 -1
- package/dist/chunk-LJYSVZMI.js +0 -25
- package/dist/chunk-LJYSVZMI.js.map +0 -1
- package/dist/chunk-NGZJK57C.js.map +0 -1
- package/dist/chunk-OVHM55JF.js.map +0 -1
- package/dist/chunk-XBVZIN26.js.map +0 -1
package/dist/kanban.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { DropdownMenu } from './chunk-HUVZQOU4.js';
|
|
3
|
-
import { useFillHeight, FillContext } from './chunk-SS3C24IJ.js';
|
|
4
|
-
import { Badge } from './chunk-WSKPESAX.js';
|
|
5
|
-
import { useKeyboardScroll } from './chunk-H732QL56.js';
|
|
6
2
|
import { useFramesItself } from './chunk-RS624TD5.js';
|
|
7
|
-
import {
|
|
3
|
+
import { Badge } from './chunk-WSKPESAX.js';
|
|
4
|
+
import { useTextOverflow } from './chunk-R2IAK3J3.js';
|
|
5
|
+
import { DropdownMenu } from './chunk-WD6T57ZJ.js';
|
|
6
|
+
import { useFillHeight, FillContext } from './chunk-SS3C24IJ.js';
|
|
7
|
+
import { Button } from './chunk-FF57N3P7.js';
|
|
8
8
|
import './chunk-ZHUVLBCC.js';
|
|
9
9
|
import './chunk-7RKC5C7G.js';
|
|
10
|
-
import {
|
|
10
|
+
import { useKeyboardScroll } from './chunk-F2XMZOUP.js';
|
|
11
11
|
import { useRevealFocus, AutoTooltip } from './chunk-HCEHTJ5E.js';
|
|
12
12
|
import { Icon } from './chunk-53F7GVBQ.js';
|
|
13
13
|
import { cn, FOCUS_INSET, FOCUS_RING } from './chunk-2724SJO2.js';
|
package/dist/resizable.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import { useFillHeight, FillContext } from './chunk-SS3C24IJ.js';
|
|
4
|
-
import { useKeyboardScroll } from './chunk-H732QL56.js';
|
|
2
|
+
import { crumbGoes, useAppShell, useBulkBarHost, BulkBarHostCtx, BulkBarSpacer, Breadcrumbs, Drawer, bulkBarRoom, BULK_BAR_LAYER } from './chunk-AB4UQ4G5.js';
|
|
5
3
|
import './chunk-QOMP4D6V.js';
|
|
6
4
|
import './chunk-7QLXYRPD.js';
|
|
7
|
-
import './chunk-72SDAX54.js';
|
|
8
5
|
import { PANE_INSET, SurfaceBoundary } from './chunk-RS624TD5.js';
|
|
9
|
-
import
|
|
6
|
+
import './chunk-R2IAK3J3.js';
|
|
7
|
+
import { useCompact, useElementWidth, useBelow } from './chunk-ZQV26NND.js';
|
|
8
|
+
import './chunk-72SDAX54.js';
|
|
9
|
+
import { useFillHeight, FillContext } from './chunk-SS3C24IJ.js';
|
|
10
|
+
import { Button } from './chunk-FF57N3P7.js';
|
|
10
11
|
import { useBreakpoint } from './chunk-ZHUVLBCC.js';
|
|
11
12
|
import './chunk-7RKC5C7G.js';
|
|
12
|
-
import './chunk-
|
|
13
|
+
import { useKeyboardScroll } from './chunk-F2XMZOUP.js';
|
|
13
14
|
import './chunk-HCEHTJ5E.js';
|
|
14
15
|
import { Icon, warnOnce } from './chunk-53F7GVBQ.js';
|
|
15
16
|
import { cn, GROUP_FOCUS_RING, isTabStop, tabStops, rememberFocus, FOCUS_INSET } from './chunk-2724SJO2.js';
|
package/dist/resizable.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/components/ResizablePanels.tsx","../../../showcase/src/components/SplitView.tsx"],"names":["PanelGroup","PanelResizeHandle","useLayoutEffect","useRef","jsx","showDetail"],"mappings":"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","file":"resizable.js","sourcesContent":["import {\n Panel,\n Group as PanelGroup,\n Separator as PanelResizeHandle,\n} from \"react-resizable-panels\";\nimport { createContext, useContext, useLayoutEffect, useRef, type ComponentProps, type RefObject } from \"react\";\nimport { cn, GROUP_FOCUS_RING } from \"../lib/utils\";\nimport { useBreakpoint } from \"../lib/use-breakpoint\";\nimport { Icon } from \"../lib/icons\";\n\ntype PanelGroupProps = ComponentProps<typeof PanelGroup>;\n\ntype Direction = \"horizontal\" | \"vertical\";\nconst DirectionCtx = createContext<Direction>(\"horizontal\");\nconst MobileCtx = createContext(false);\n\nexport interface ResizablePanelGroupProps\n extends Omit<PanelGroupProps, \"className\" | \"orientation\"> {\n direction?: Direction;\n stackOnMobile?: boolean;\n className?: string;\n /** Map of panel id → percentage (0–100). Must be an object, never an array. Panels need matching id props. */\n defaultLayout?: { [panelId: string]: number };\n /** Called after resize ends. Receives { [panelId]: number }, not number[]. */\n onLayoutChanged?: (layout: { [panelId: string]: number }) => void;\n}\n\nexport function ResizablePanelGroup({\n className,\n direction = \"horizontal\",\n stackOnMobile = true,\n ...props\n}: ResizablePanelGroupProps) {\n const isMobile = useBreakpoint(\"sm\");\n const shouldStack = stackOnMobile && isMobile && direction === \"horizontal\";\n const effectiveDirection = shouldStack ? \"vertical\" : direction;\n\n return (\n <DirectionCtx.Provider value={effectiveDirection}>\n <MobileCtx.Provider value={isMobile}>\n <PanelGroup\n className={cn(\n \"flex h-full w-full\",\n effectiveDirection === \"vertical\" && \"flex-col\",\n className,\n )}\n orientation={effectiveDirection}\n {...props}\n />\n </MobileCtx.Provider>\n </DirectionCtx.Provider>\n );\n}\n\ntype PanelProps = ComponentProps<typeof Panel>;\n\nexport interface ResizablePanelProps extends Omit<PanelProps, \"className\"> {\n className?: string;\n id?: string;\n /** number = px. \"30%\" or \"30\" = percent. \"28rem\" / \"400px\" also valid. */\n defaultSize?: number | string;\n minSize?: number | string;\n maxSize?: number | string;\n collapsible?: boolean;\n}\n\nexport function ResizablePanel({ className, ...props }: ResizablePanelProps) {\n return <Panel className={cn(\"\", className)} {...props} />;\n}\n\ntype PanelResizeHandleProps = ComponentProps<typeof PanelResizeHandle>;\n\n/** The part of an element on screen, top to bottom: inside the window and every box around it that clips or scrolls. */\nfunction visibleRange(el: HTMLElement): { top: number; bottom: number } {\n const box = el.getBoundingClientRect();\n let top = Math.max(box.top, 0);\n let bottom = Math.min(box.bottom, window.innerHeight);\n for (let node = el.parentElement; node; node = node.parentElement) {\n if (!/(auto|scroll|hidden|clip|overlay)/.test(getComputedStyle(node).overflowY)) continue;\n const r = node.getBoundingClientRect();\n top = Math.max(top, r.top + node.clientTop);\n bottom = Math.min(bottom, r.top + node.clientTop + node.clientHeight);\n }\n return { top, bottom };\n}\n\n/**\n * Sprint 25.16 A42 (P31): the grip stays in the part of the divider on screen, at its middle, so a split taller than\n * the screen (a page that grows) never hides it. It moves with any scroll around it and stays inside the divider; it\n * goes back to the middle when the divider turns (stacked on a phone).\n */\nfunction useGripInView(gripRef: RefObject<HTMLDivElement | null>, enabled: boolean) {\n useLayoutEffect(() => {\n const grip = gripRef.current;\n const handle = grip?.parentElement;\n if (!enabled || !grip || !handle || typeof ResizeObserver === \"undefined\") return;\n let frame = 0;\n const place = () => {\n frame = 0;\n const box = handle.getBoundingClientRect();\n const { top, bottom } = visibleRange(handle);\n const room = (box.height - grip.offsetHeight) / 2;\n const offset = bottom > top ? Math.max(-room, Math.min(room, (top + bottom) / 2 - (box.top + box.height / 2))) : 0;\n grip.style.transform = Math.abs(offset) >= 1 ? `translateY(${Math.round(offset)}px)` : \"\";\n };\n const schedule = () => {\n if (!frame) frame = requestAnimationFrame(place);\n };\n place();\n const ro = new ResizeObserver(schedule);\n ro.observe(handle);\n // a scroll anywhere around it: scroll events don't bubble, so the document hears them as they go down\n document.addEventListener(\"scroll\", schedule, { capture: true, passive: true });\n window.addEventListener(\"resize\", schedule);\n return () => {\n ro.disconnect();\n document.removeEventListener(\"scroll\", schedule, { capture: true });\n window.removeEventListener(\"resize\", schedule);\n if (frame) cancelAnimationFrame(frame);\n grip.style.transform = \"\";\n };\n }, [gripRef, enabled]);\n}\n\nexport interface ResizableHandleProps\n extends Omit<PanelResizeHandleProps, \"className\"> {\n withHandle?: boolean;\n className?: string;\n}\n\nexport function ResizableHandle({\n withHandle,\n className,\n ...props\n}: ResizableHandleProps) {\n const direction = useContext(DirectionCtx);\n const isMobile = useContext(MobileCtx);\n const isVertical = direction === \"vertical\";\n const gripRef = useRef<HTMLDivElement>(null);\n // the grip is kept in view whenever it can show: always with withHandle, and on keyboard focus without it\n useGripInView(gripRef, !isVertical);\n\n return (\n <PanelResizeHandle\n className={cn(\n // a group: its keyboard focus is drawn round its grip (Sprint 30), as a full-length line's outline would be cut off\n // at both its ends by the panels it divides; the line itself shows no outline of its own\n \"group relative flex items-center justify-center bg-[var(--ds-border-default)] outline-none\",\n isVertical\n ? cn(\n \"h-[var(--ds-border-width)] w-full after:absolute after:left-0 after:right-0 after:content-['']\",\n isMobile ? \"after:-top-3 after:-bottom-3\" : \"after:-top-1 after:-bottom-1\"\n )\n : cn(\n \"w-[var(--ds-border-width)] after:absolute after:inset-y-0 after:content-['']\",\n isMobile ? \"after:-left-3 after:-right-3\" : \"after:-left-1 after:-right-1\"\n ),\n \"[&[data-resize-handle-state=drag]]:bg-[var(--ds-accent-primary)]\",\n \"[&[data-resize-handle-state=hover]]:bg-[var(--ds-accent-primary)]\",\n className,\n )}\n {...props}\n >\n {/* the grip: always with withHandle; without it, shown while the handle has keyboard focus, to carry its outline */}\n <div\n ref={gripRef}\n aria-hidden=\"true\"\n className={cn(\n \"z-10 items-center justify-center rounded-[var(--ds-radius-sm)]\",\n withHandle ? \"flex\" : \"hidden group-focus-visible:flex\",\n GROUP_FOCUS_RING,\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"bg-[var(--ds-bg-surface)]\",\n isVertical\n ? (isMobile ? \"h-4 w-8\" : \"h-3 w-4\")\n : (isMobile ? \"h-8 w-4\" : \"h-4 w-3\"),\n )}\n >\n <Icon\n name=\"grip-vertical\"\n size={isMobile ? 12 : 10}\n className={cn(\n \"text-[var(--ds-text-muted)]\",\n isVertical && \"rotate-90\",\n )}\n />\n </div>\n </PanelResizeHandle>\n );\n}\n","import { useCallback, useEffect, useLayoutEffect, useRef, useState, type CSSProperties, type KeyboardEvent, type ReactNode, type RefObject } from \"react\";\nimport { cn, FOCUS_INSET } from \"../lib/utils\";\nimport { useBelow, useCompact, useElementWidth } from \"../lib/use-compact\";\nimport { useBreakpoint } from \"../lib/use-breakpoint\";\nimport { ResizablePanelGroup, ResizablePanel, ResizableHandle } from \"./ResizablePanels\";\nimport { Button } from \"./Button\";\nimport { Drawer } from \"./Drawer\";\nimport { Icon } from \"../lib/icons\";\nimport { Breadcrumbs, crumbGoes, type BreadcrumbItem } from \"./Breadcrumbs\";\nimport { useAppShell } from \"./AppShell\";\nimport { PANE_INSET, SurfaceBoundary, type SplitListReport } from \"../lib/surface-context\";\nimport { isTabStop, rememberFocus, tabStops, type RememberedFocus } from \"../lib/focus\";\nimport { FillContext, useFillHeight } from \"../lib/use-fill-height\";\nimport { BulkBarHostCtx, BulkBarSpacer, useBulkBarHost, BULK_BAR_LAYER, bulkBarRoom } from \"../lib/bulk-bar-host\";\nimport { useKeyboardScroll } from \"../lib/use-keyboard-scroll\";\nimport { warnOnce } from \"../lib/dev-warn\";\n\nexport type SplitViewFrame = \"fill\" | \"page\";\n\n/**\n * How far past a threshold the layout must go before a collapsed part comes back, in px: a classic scrollbar's width\n * (15 px on a Mac with a mouse, 17 on Windows), whose coming and going with the aside moved the layout back and forth\n * across the threshold (round 27 review). No wider: inside the band the answer depends on the way the width came, so a\n * wider band could keep the aside collapsed at a width where it fits.\n */\nconst THRESHOLD_BAND = 17;\n\n/**\n * A pane's scroller, with the pane's inset (C1): what the keyboard reaches comes into view with room for its outline (Sprint\n * 30, P3). Each scroller adds FOCUS_INSET on its own tag, as every element given to useKeyboardScroll does.\n */\nconst paneScroll = (inset?: string) => cn(\"min-h-0 overflow-y-auto scroll-p-[4px]\", inset);\n\n/** How far a view reaches past the page's gutter on each side, in px (C3). */\ninterface Bleed { left: number; right: number }\n\nconst clear = (colour: string) => colour === \"transparent\" || /^rgba\\(.*,\\s*0\\)$/.test(colour);\n\n/** Whether an element draws something of its own (an edge, a fill, a shadow) or clips what reaches past it. */\nfunction drawsOrClips(el: HTMLElement): boolean {\n const cs = getComputedStyle(el);\n if (cs.display === \"contents\") return false;\n const edge = (width: string, style: string) => parseFloat(width) > 0 && style !== \"none\" && style !== \"hidden\";\n return edge(cs.borderLeftWidth, cs.borderLeftStyle) || edge(cs.borderRightWidth, cs.borderRightStyle)\n || edge(cs.borderTopWidth, cs.borderTopStyle) || edge(cs.borderBottomWidth, cs.borderBottomStyle)\n || cs.backgroundImage !== \"none\" || !clear(cs.backgroundColor) || cs.boxShadow !== \"none\" || cs.overflowX !== \"visible\";\n}\n\n/**\n * The page's gutter on each side when the view's parent spans the page column's content and nothing between the two\n * draws or clips, else null: a view in a Card, a grid's cell or a bordered box keeps its place (C3: frame=\"page\" is the\n * default there too, so the frame is never the key).\n */\nfunction pageBleed(parent: HTMLElement, column: HTMLElement): Bleed | null {\n for (let el: HTMLElement | null = parent; el && el !== column; el = el.parentElement) if (drawsOrClips(el)) return null;\n const cs = getComputedStyle(column);\n const left = parseFloat(cs.paddingLeft) || 0;\n const right = parseFloat(cs.paddingRight) || 0;\n if (left + right === 0) return null;\n if (parent !== column) {\n const p = parent.getBoundingClientRect();\n const c = column.getBoundingClientRect();\n const start = c.left + column.clientLeft + left;\n const end = c.left + column.clientLeft + column.clientWidth - right;\n if (Math.abs(p.left - start) > 1 || Math.abs(p.right - end) > 1) return null;\n }\n return { left, right };\n}\n\n/**\n * Sprint 25.33 C3 (run 97, the owner: \"On mobile there's too much padding inside the container\"): on a phone a page-frame\n * view that spans its PageContainer's column runs edge to edge, as a Dialog does there (Dialog.tsx), its content at the\n * page's gutter. Keyed on the screen's width and on spanning the column, never on `compact`: the view measures its own\n * width to collapse (with a 17 px band), and reaching two gutters wider would flip that back and forth. So this measures\n * the view's parent and the column, never the view, and its answer can't change with its own reach.\n */\nfunction usePageBleed(ref: RefObject<HTMLElement | null>, on: boolean): Bleed | null {\n const [bleed, setBleed] = useState<Bleed | null>(null);\n useLayoutEffect(() => {\n const parent = ref.current?.parentElement;\n const column = parent?.closest<HTMLElement>(\"[data-page-column]\");\n if (!on || !parent || !column) {\n setBleed(null);\n return;\n }\n const measure = () => {\n const next = pageBleed(parent, column);\n setBleed((prev) => (prev?.left === next?.left && prev?.right === next?.right ? prev : next));\n };\n measure();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(measure);\n observer.observe(column);\n observer.observe(parent);\n return () => observer.disconnect();\n }, [ref, on]);\n return on ? bleed : null;\n}\n\nexport interface SplitViewProps {\n /** The list (an inbox, a queue): it scrolls on its own. */\n list: ReactNode;\n /**\n * The selected item (a thread, a record): it fills the height and scrolls on its own. The pane insets it at the page's\n * gutter, so pass content with no padding classes; a SectionHeading variant=\"pane\" placed first is the item's header,\n * inset once, its rule reaching the pane's edges (Sprint 25.33 C1).\n */\n detail: ReactNode;\n /**\n * The detail is one full-bleed piece that runs to the pane's edges and owns its inset: a conversation with its header,\n * its own scroller and its composer, a preview, an editor. The pane then adds no inset of its own (Sprint 25.33 C1).\n */\n detailFlush?: boolean;\n /** Context beside the detail (a contact, properties). The pane insets it as the Drawer it collapses into does (the page's gutter, Sprint 25.14 A36), so pass content with no padding classes (round 8). Collapses to a toggle that opens it in a Drawer when the layout is narrower than `asideCollapseBelow`. */\n aside?: ReactNode;\n /** Names the aside's toggle and Drawer. */\n asideTitle?: string;\n /**\n * Below `collapseBelow` the list shows alone; with `detailOpen` the detail replaces it, with a Back button that calls\n * `onDetailClose` (detailMode \"stack\"). The page owns the selection, so it owns this flag.\n */\n detailOpen?: boolean;\n onDetailClose?: () => void;\n /** \"stack\" (default): the detail stacks over the list below the collapse width. \"route\": the app navigates to the detail's own route instead, and this renders the list alone there. */\n detailMode?: \"stack\" | \"route\";\n /**\n * \"shown\" (default): above the collapse width the detail pane is always there — an inbox's reading pane may show a\n * placeholder. \"hidden\" (Sprint 25.7, C3): `detailOpen` decides at every width. Closed, the list takes the whole\n * width; open, the pane appears beside it at the width the user last gave it, with a close control that calls\n * `onDetailClose`. For boards, timelines and lists of records. The list stays mounted, so a board or a timeline keeps\n * its scroll and zoom.\n */\n closedDetail?: \"shown\" | \"hidden\";\n /** The open pane's close control, named for a screen reader (closedDetail=\"hidden\"). Default \"Close\". */\n closeLabel?: string;\n backLabel?: string;\n /**\n * The open item's path (Sprint 25.16 A19, P11): crumbs from the top of what the list shows down to the open view's\n * parent, never the view itself (the owner's review of 1 October) — a document in a folder tree passes its folders\n * (\"Documents › Architecture\"), a view below an item passes the item as well (\"… › System Design Overview\", above its\n * metadata). The view's own title, its first heading, names it, as a page's title does under its PageHeader's\n * breadcrumbs. The view draws the path above the detail at every width, where the stacked Back would be, and its last\n * crumb is the way back: the stacked Back goes, and the detail draws no back of its own\n * (gs:breadcrumbs-and-back-button-2). A crumb that is a page takes its href and goes through the shell's navigate; an\n * item held in state, or a folder that isn't a page, takes an onClick (select it in the tree); a last crumb with\n * neither closes the detail. On a phone the path keeps its first crumb and its last two, so the parent always shows.\n * One crumb or more; with none, today's Back.\n */\n detailPath?: BreadcrumbItem[];\n /** Percent of the width the list takes; the divider is draggable. */\n listWidth?: number;\n listMinWidth?: number;\n asideWidth?: number;\n /** Below this width of the layout itself (px) the list and detail stop sitting side by side. */\n collapseBelow?: number;\n /** Below this width of the layout itself (px) the aside becomes a toggle. */\n asideCollapseBelow?: number;\n /**\n * The narrowest the open item's pane may be beside an aside (px). When the list and the aside would leave it less,\n * the aside becomes its toggle and Drawer, so the item keeps the room its content needs: the aside is the secondary\n * content (round 27, R27-13, the owner: \"which information is more important\"). An item that holds a wide table or a\n * card grid may need more: pass it.\n */\n detailMinWidth?: number;\n /** A bordered, rounded surface (inside a page with padding) instead of edge to edge (filling <main>). */\n bordered?: boolean;\n /** \"fill\": the page root, flush to the shell, h-full against main, each pane owns its inset. \"page\" (default): inside a PageContainer under a PageHeader. */\n frame?: SplitViewFrame;\n \"aria-label\"?: string;\n className?: string;\n}\n\n/**\n * The reading-pane composition (Sprint 25.2, R3): one surface with dividers —\n * list, detail and an optional aside — that fills the height it is given (an\n * AppShell's <main> already gives it) and never three cards with gaps. The\n * panels compose ResizablePanelGroup, so the dividers drag. Below the collapse\n * width, measured on the layout itself, the list shows alone and the detail\n * stacks over it (or the app routes to it); the aside collapses to a toggle.\n * The page owns the selection and assembles the contents; keyboard movement\n * through the list is the list's job (StackedList selectedId).\n */\nexport function SplitView({\n list,\n detail,\n detailFlush = false,\n aside,\n asideTitle = \"Details\",\n detailOpen = false,\n onDetailClose,\n detailMode = \"stack\",\n closedDetail = \"shown\",\n closeLabel = \"Close\",\n backLabel = \"Back\",\n detailPath,\n listWidth = 35,\n listMinWidth = 25,\n asideWidth = 25,\n collapseBelow = 768,\n asideCollapseBelow = 1024,\n detailMinWidth = 480,\n bordered = false,\n frame = \"page\",\n \"aria-label\": ariaLabel,\n className,\n}: SplitViewProps) {\n const rootRef = useRef<HTMLDivElement>(null);\n const compact = useCompact(rootRef, collapseBelow, THRESHOLD_BAND);\n const layoutWidth = useElementWidth(rootRef);\n // The panels' shares as the user left them (the review: the defaults were read, so a list dragged wider left the item\n // under its minimum beside the aside); the aside's last share stands in while it is collapsed.\n const [shares, setShares] = useState<{ list?: number; aside?: number }>({});\n const listShare = shares.list ?? listWidth;\n const asideShare = shares.aside ?? asideWidth;\n // the aside yields when the layout is narrow, or when beside it the item would have less than its minimum\n const itemShare = (100 - listShare - asideShare) / 100;\n const itemBesideAside = aside ? layoutWidth * itemShare : 0;\n // the item moves by its share of the scrollbar's width, so its band is that share of the layout's\n const itemSqueezed = useBelow(itemBesideAside, detailMinWidth, THRESHOLD_BAND * Math.max(0, itemShare));\n const asideCollapsed = useBelow(layoutWidth, asideCollapseBelow, THRESHOLD_BAND) || itemSqueezed;\n const [asideWantsOpen, setAsideWantsOpen] = useState(false);\n const hiding = closedDetail === \"hidden\";\n // Hidden: the aside belongs to the open item, so it (its pane, its toggle, its Drawer) goes with the pane, and a\n // Drawer left open does not come back with the next item (render-time state adjustment).\n const showAside = !!aside && (!hiding || detailOpen);\n if (hiding && !detailOpen && asideWantsOpen) setAsideWantsOpen(false);\n // on a phone the aside's Drawer belongs to the item on screen: Back closes it with the item\n if (compact && !detailOpen && asideWantsOpen) setAsideWantsOpen(false);\n const asideOpen = asideCollapsed && asideWantsOpen;\n const region = ariaLabel ? { role: \"region\" as const, \"aria-label\": ariaLabel } : {};\n // A19: the item's path stands in for Back, its last crumb (the view's parent) going up one level; its bar insets at the\n // page's gutter, as the aside's content does (Sprint 25.14 A36). A last crumb that goes nowhere of its own closes the\n // detail, as Back did, so the path is always a way back.\n const path = detailPath && detailPath.length > 0\n ? detailPath.map((crumb, i) => (i === detailPath.length - 1 && !crumbGoes(crumb) && onDetailClose ? { ...crumb, onClick: onDetailClose } : crumb))\n : null;\n // fill: the page root, flush to the shell on every side (no border, no radius, no padding of its own); h-full\n // resolves against <main> because the shell is a flex column down to it. page: inside a PageContainer under a\n // PageHeader, where `bordered` draws the surface. Each pane owns its own inset either way.\n const isFill = frame === \"fill\";\n // Sprint 25.14 A44 (P32): the list pane's content reports what it is, as a wrapped PageHeader does to its\n // PageContainer: content that draws its own frame or cards (a KanbanBoard, a CardGrid, a Table), or content with no\n // frame of its own that scrolls inside the pane (a StackedList, a Gantt). No frame around what frames itself: when the\n // pane holds only the first kind, the list sits on the canvas with nothing drawn behind it and the open item on the\n // surface, whatever `bordered` says. Anything that scrolls inside keeps the hairline, which shows where it scrolls.\n const listHolds = useRef({ framed: 0, scrolls: 0, edge: 0, inset: 0 });\n const [framesItself, setFramesItself] = useState(false);\n // Sprint 25.33 C1 (the owner: \"there's no one size fits all\"): a pane pads what's in it, unless the thing runs edge to\n // edge. The list pane is flush while it holds a list or a board, found at any depth by the same report: a list of\n // full-width bands (a StackedList, a VirtualizedList), a plan (a Gantt) or what frames itself (a KanbanBoard, a\n // CardGrid, a Table, a DataGrid). A tree, a form, text or a timeline there is padded.\n const [listFlush, setListFlush] = useState(false);\n const reportToList = useCallback<SplitListReport>((kind, present) => {\n const held = listHolds.current;\n held[kind] = Math.max(0, held[kind] + (present ? 1 : -1));\n // the fix pass of 25.33 (S-9): while nothing in the pane reports (an empty result, a spinner, a reload between lists),\n // the last decision stands, so a search row of the page's own above the list doesn't move as its list empties, nor\n // the view's frame. A tree reports it wants the inset, so a page that swaps its list for a tree pads again; a form or\n // text, which report nothing, keep the decision before them\n if (held.framed === 0 && held.scrolls === 0 && held.edge === 0 && held.inset === 0) return;\n setFramesItself(held.framed > 0 && held.scrolls === 0);\n setListFlush(held.framed > 0 || held.edge > 0);\n }, []);\n const listInset = listFlush ? undefined : PANE_INSET.list;\n // the detail pads at the page's gutter unless the page says it is one full-bleed piece (a thread, a preview, an editor)\n const detailInset = detailFlush ? undefined : PANE_INSET.detail;\n const onCanvas = isFill || framesItself;\n // In a shell with an app footer the children wrapper has no definite height, so h-full cannot resolve; the shell\n // publishes main's height and fill takes it (the footer then sits below the fold, as it must under a full pane).\n const shell = useAppShell();\n // Sprint 25.16 A42 (P31): a page frame that is the page's last content takes the height under its header, so its panes\n // scroll inside it and the page doesn't; what's inside the view takes its pane's height (FillContext)\n const pageFill = useFillHeight(rootRef, !isFill);\n // each pane scrolls inside the view: one with nothing in it to Tab to (a message's text) is a Tab stop of its own, so a\n // keyboard can scroll it (WCAG 2.1.1)\n const [listScroll, setListScroll] = useState<HTMLDivElement | null>(null);\n const [detailScroll, setDetailScroll] = useState<HTMLDivElement | null>(null);\n const [asideScroll, setAsideScroll] = useState<HTMLDivElement | null>(null);\n const [stackedListScroll, setStackedListScroll] = useState<HTMLDivElement | null>(null);\n // Sprint 25.29 item 16: with `detailOpen` and no `onDetailClose`, the phone's Back couldn't work, and a page that keeps\n // its detail open stranded a phone user away from the list (run 79's folder tree). Without the handler the view keeps\n // its own \"showing the list\" on phones, so Back works, and a press in the list shows the detail again; with it, the\n // page decides, as before.\n const [listShown, setListShown] = useState(false);\n if (listShown && (onDetailClose || !detailOpen || !compact)) setListShown(false);\n useEffect(() => {\n if (detailOpen && !onDetailClose && detailMode === \"stack\") {\n warnOnce(\"SplitView\", \"detailOpen is set without onDetailClose: below the collapse width, Back can only show the list again, and the page never hears of it. Pass onDetailClose to close the detail.\");\n }\n }, [detailOpen, onDetailClose, detailMode]);\n // On a phone, the detail giving way to the list (Back, the page's or the view's own) leaves focus on the list's chosen\n // item, else its first control, never on the page\n const detailOnPhone = compact && detailMode === \"stack\" && detailOpen && !listShown;\n const wasDetailOnPhone = useRef(detailOnPhone);\n useLayoutEffect(() => {\n const was = wasDetailOnPhone.current;\n wasDetailOnPhone.current = detailOnPhone;\n if (!was || detailOnPhone) return;\n const active = document.activeElement;\n if (active && active !== document.body && active.isConnected) return;\n const pane = stackedListScroll;\n const chosen = pane?.querySelector<HTMLElement>('[aria-current=\"true\"], [aria-current=\"page\"], [aria-selected=\"true\"]');\n const target = (chosen && (isTabStop(chosen) ? chosen : tabStops(chosen)[0])) || (pane ? tabStops(pane)[0] : undefined);\n (target ?? pane)?.focus();\n });\n const [stackedDetailScroll, setStackedDetailScroll] = useState<HTMLDivElement | null>(null);\n // named for what they hold (the review of 1 October): the list by the view's own name, the item by its title (its\n // first heading; the path ends at its parent, so never names it)\n const listName = ariaLabel ? `${ariaLabel} list` : \"List\";\n const itemName = ariaLabel ? `${ariaLabel} item` : \"Item\";\n useKeyboardScroll(listScroll, listName, !compact);\n useKeyboardScroll(detailScroll, itemName, !compact, true);\n useKeyboardScroll(asideScroll, asideTitle, !compact);\n useKeyboardScroll(stackedListScroll, listName, compact);\n useKeyboardScroll(stackedDetailScroll, itemName, compact, true);\n const fillStyle = isFill && shell?.hasFooter ? { height: \"var(--ds-main-height, 100%)\" } : pageFill != null ? { height: pageFill } : undefined;\n // C3: on a phone a page frame spanning its page's column runs edge to edge, dropping its side edges and its corners,\n // while it draws a surface: a board on the canvas keeps its place at the page's gutter until an item opens over it\n const phone = useBreakpoint(\"sm\");\n const bleed = usePageBleed(rootRef, phone && !isFill);\n const reach = bleed && (!onCanvas || detailOnPhone) ? bleed : null;\n const squared: CSSProperties | undefined = reach ? { borderLeftWidth: 0, borderRightWidth: 0, borderRadius: 0 } : undefined;\n const rootStyle: CSSProperties | undefined = reach\n ? { ...fillStyle, ...squared, marginLeft: -reach.left, marginRight: -reach.right, width: `calc(100% + ${reach.left + reach.right}px)` }\n : fillStyle;\n // Edge to edge the list sits on the page's canvas, like every other page, and the open item (its detail and its aside)\n // on the surface (round 27, R27-12, the owner: the whole split on the surface read as a different page). A page frame,\n // bordered or not, stays one surface: a card on the canvas. Beside a list that frames itself, a page frame's open item\n // is that card (rounded, and bordered when the view is), as the page's other cards are; edge to edge it is square.\n const itemSurface = !onCanvas ? undefined : isFill\n ? \"bg-[var(--ds-bg-surface)]\"\n : cn(\"bg-[var(--ds-bg-surface)] rounded-[var(--ds-radius-md)] overflow-hidden\", bordered && \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\");\n const surface = cn(\n \"h-full min-h-0 w-full\",\n !onCanvas && \"bg-[var(--ds-bg-surface)]\",\n isFill && \"rounded-none border-0\",\n bordered && !onCanvas && \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] rounded-[var(--ds-radius-md)] overflow-hidden\",\n className,\n );\n // each pane is a surface of its own: what a Card around the view, or the list pane, tells content stops at its edge;\n // each tells its content whether it pads it, so a pane header cancels the padding and a list lines up (C1)\n // Sprint 25.33 B2: a bulk-action bar in a pane floats at that pane's foot, so a list's bar never covers the open item\n // (its composer), and the pane keeps room for it under its last row\n const listBar = useBulkBarHost();\n const detailBar = useBulkBarHost();\n const barRoom = (room: number) => (room ? { scrollPaddingBottom: bulkBarRoom(room) } : undefined);\n const listContent = <><BulkBarHostCtx value={listBar.value}><SurfaceBoundary pane=\"list\" framer={reportToList} padded={!listFlush}>{list}</SurfaceBoundary></BulkBarHostCtx><BulkBarSpacer room={listBar.room} /></>;\n const detailContent = <><BulkBarHostCtx value={detailBar.value}><SurfaceBoundary pane=\"detail\" padded={!detailFlush}>{detail}</SurfaceBoundary></BulkBarHostCtx><BulkBarSpacer room={detailBar.room} /></>;\n const barLayer = (bar: ReturnType<typeof useBulkBarHost>) => <div ref={bar.setLayer} data-bulk-bar-layer=\"\" className={BULK_BAR_LAYER} />;\n\n // closedDetail=\"hidden\" (C3): the pane opens beside the list at the width the user last gave it; closing it returns\n // focus to the item the pane shows, or its neighbour if that item is gone (D14(e)): the list's selected item, else\n // the last list item that took focus, checked on each render while the pane is open, so switching items is followed.\n // A selection kept in the URL changes the path, so the item is remembered whatever the route does. With no item\n // (opened on load, or from outside the list) focus goes to the list's first Tab stop. No overlay layer: an\n // assistant opened earlier keeps Escape.\n const [listPct, setListPct] = useState(listWidth);\n const paneRef = useRef<HTMLDivElement>(null);\n const shown = useRef<RememberedFocus | null>(null);\n const lastInList = useRef<HTMLElement | null>(null);\n const wasOpen = useRef(false);\n useLayoutEffect(() => {\n if (!hiding) return;\n const listPane = rootRef.current?.querySelector<HTMLElement>('[data-pane=\"list\"]') ?? null;\n if (detailOpen) {\n wasOpen.current = true;\n const selected = listPane?.querySelector<HTMLElement>('[aria-current=\"true\"], [aria-selected=\"true\"]');\n const last = lastInList.current;\n const item = (selected && (isTabStop(selected) ? selected : tabStops(selected)[0]))\n || (last?.isConnected && listPane?.contains(last) ? last : null);\n if (item && item !== shown.current?.el) shown.current = rememberFocus(item, { ignoreRoute: true });\n return;\n }\n if (!wasOpen.current) return;\n wasOpen.current = false;\n const r = shown.current;\n shown.current = null;\n const active = document.activeElement;\n if (active && active !== document.body && active.isConnected) return;\n const first = listPane ? tabStops(listPane)[0] : undefined;\n if (!r?.restore(first)) first?.focus();\n });\n const onPaneKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key !== \"Escape\" || e.defaultPrevented || !onDetailClose) return;\n const t = e.target as HTMLElement;\n // the pane's own DOM only — a portalled popup inside it bubbles here in React's tree — and never from a field\n if (!paneRef.current?.contains(t) || t.closest(\"input, textarea, select, [contenteditable='true']\")) return;\n e.preventDefault();\n onDetailClose();\n };\n\n if (compact) {\n const showDetail = detailOnPhone;\n // on a phone the item's aside is a toggle beside Back that opens it in a Drawer, as it is on a narrow desktop (the\n // round 27 review: below the collapse width it could not be reached at all)\n const phoneAside = showDetail && !!aside;\n return (\n <FillContext value={true}>\n <div ref={rootRef} data-split-view={showDetail ? \"detail\" : \"list\"} data-frame={frame} data-fill={pageFill != null ? \"\" : undefined} data-edge-to-edge={reach ? \"\" : undefined} {...region} className={cn(surface, \"relative flex flex-col\")} style={rootStyle}>\n {showDetail && (\n <div className={cn(\"relative flex-1 min-h-0 flex flex-col\", itemSurface)} style={itemSurface ? squared : undefined}>\n <div className={cn(\"shrink-0 flex items-center justify-between gap-ds-2 py-ds-2 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\", path ? \"px-[var(--ds-page-gutter)]\" : \"px-ds-3\")}>\n {path\n ? <Breadcrumbs items={path} maxItems={3} aria-label=\"Path\" className=\"min-w-0\" />\n // a link, alone at the start of the header (Sprint 25.19 G4, page_composition#51): its words line up with the header's edge\n : <Button type=\"button\" variant=\"link\" size=\"sm\" iconLeft={<Icon name=\"arrow-left\" size={14} />} onClick={onDetailClose ?? (() => setListShown(true))}>{backLabel}</Button>}\n {phoneAside && <Button type=\"button\" variant=\"ghost\" size=\"sm\" iconLeft={<Icon name=\"info\" size={14} />} onClick={() => setAsideWantsOpen(true)} aria-expanded={asideWantsOpen}>{asideTitle}</Button>}\n </div>\n {/* C1: the phone's stacked panes pad as they do side by side */}\n <div ref={setStackedDetailScroll} data-pane-scroll=\"detail\" className={cn(\"flex-1\", paneScroll(detailInset), FOCUS_INSET)} style={barRoom(detailBar.room)}>{detailContent}</div>\n {barLayer(detailBar)}\n </div>\n )}\n {/* Sprint 25.14 A44 (the review of 30 September): the list stays mounted while the stacked detail is shown, as it\n does beside it on a wider screen, so a board keeps its scroll and its report (the view kept its frame\n off only while the board was on screen), and Back finds the list as the user left it */}\n <div ref={setStackedListScroll} data-pane-scroll=\"list\" className={cn(\"flex-1\", paneScroll(listInset), FOCUS_INSET)} hidden={showDetail || undefined} style={barRoom(listBar.room)}\n onClickCapture={onDetailClose ? undefined : () => setListShown(false)}>{listContent}</div>\n {/* the list's bar goes with the list while the item shows over it */}\n {!showDetail && barLayer(listBar)}\n {phoneAside && (\n <Drawer open={asideWantsOpen} onClose={() => setAsideWantsOpen(false)} title={asideTitle} position=\"right\">\n {aside}\n </Drawer>\n )}\n </div>\n </FillContext>\n );\n }\n\n const asideButton = showAside && asideCollapsed\n ? <Button type=\"button\" variant=\"ghost\" size=\"sm\" iconLeft={<Icon name=\"info\" size={14} />} onClick={() => setAsideWantsOpen(true)} aria-expanded={asideOpen}>{asideTitle}</Button>\n : null;\n const closeButton = hiding && onDetailClose\n ? <Button type=\"button\" variant=\"ghost\" size=\"icon-sm\" aria-label={closeLabel} onClick={onDetailClose}><Icon name=\"close\" size={14} /></Button>\n : null;\n const paneBar = path || asideButton || closeButton ? (\n <div className={cn(\"shrink-0 flex items-center gap-ds-1 py-ds-2 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\", path ? \"justify-between px-[var(--ds-page-gutter)]\" : \"justify-end px-ds-3\")}>\n {path && <Breadcrumbs items={path} aria-label=\"Path\" className=\"min-w-0\" />}\n {(asideButton || closeButton) && <div className=\"shrink-0 flex items-center gap-ds-1\">{asideButton}{closeButton}</div>}\n </div>\n ) : null;\n const showDetail = !hiding || detailOpen;\n\n return (\n <FillContext value={true}>\n <div ref={rootRef} data-split-view={hiding && !detailOpen ? \"list\" : \"split\"} data-frame={frame} data-fill={pageFill != null ? \"\" : undefined} data-edge-to-edge={reach ? \"\" : undefined} {...region} className={surface} style={rootStyle}>\n <ResizablePanelGroup\n direction=\"horizontal\"\n stackOnMobile={false}\n className=\"h-full\"\n // the width the user gives the list is kept, so a closed pane reopens at it; the shares decide when the aside yields\n onLayoutChanged={(layout) => {\n setShares((prev) => (prev.list === (layout.list ?? prev.list) && prev.aside === (layout.aside ?? prev.aside) ? prev : { list: layout.list ?? prev.list, aside: layout.aside ?? prev.aside }));\n if (hiding && layout.detail != null && layout.list != null) setListPct(layout.list);\n }}\n >\n <ResizablePanel id=\"list\" className=\"relative\" defaultSize={`${hiding ? (detailOpen ? listPct : 100) : listWidth}%`} minSize={`${listMinWidth}%`}>\n {/* scroll padding: what the keyboard reaches comes into view with room for its outline (Sprint 30, P3); a list's\n rows run to the pane's edges and draw their outline inside (StackedList), and anything else is padded (C1) */}\n <div ref={setListScroll} data-pane=\"list\" data-pane-scroll=\"list\" className={cn(\"h-full\", paneScroll(listInset), FOCUS_INSET)} style={barRoom(listBar.room)} onFocus={hiding ? (e) => { lastInList.current = e.target; } : undefined}>\n {listContent}\n </div>\n {barLayer(listBar)}\n </ResizablePanel>\n {showDetail && (\n <>\n <ResizableHandle withHandle />\n <ResizablePanel id=\"detail\" minSize=\"30%\">\n <div ref={paneRef} data-pane=\"detail\" className={cn(\"relative h-full min-h-0 flex flex-col\", itemSurface)} onKeyDown={hiding ? onPaneKeyDown : undefined}>\n {paneBar}\n <div ref={setDetailScroll} data-pane-scroll=\"detail\" className={cn(\"flex-1\", paneScroll(detailInset), FOCUS_INSET)} style={barRoom(detailBar.room)}>{detailContent}</div>\n {barLayer(detailBar)}\n </div>\n </ResizablePanel>\n </>\n )}\n {showAside && !asideCollapsed && (\n <>\n <ResizableHandle withHandle />\n <ResizablePanel id=\"aside\" defaultSize={`${asideWidth}%`} minSize=\"15%\">\n {/* the Drawer's body inset, so the aside's content sits where it will in the Drawer (Sprint 25.14 A36) */}\n <div ref={setAsideScroll} data-pane=\"aside\" data-pane-scroll=\"aside\" className={cn(\"h-full\", paneScroll(PANE_INSET.detail), itemSurface, FOCUS_INSET)}><SurfaceBoundary pane=\"aside\">{aside}</SurfaceBoundary></div>\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n {showAside && asideCollapsed && (\n <Drawer open={asideOpen} onClose={() => setAsideWantsOpen(false)} title={asideTitle} position=\"right\">\n {aside}\n </Drawer>\n )}\n </div>\n </FillContext>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/components/ResizablePanels.tsx","../../../showcase/src/components/SplitView.tsx"],"names":["PanelGroup","PanelResizeHandle","useLayoutEffect","useRef","jsx","showDetail"],"mappings":"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","file":"resizable.js","sourcesContent":["import {\n Panel,\n Group as PanelGroup,\n Separator as PanelResizeHandle,\n} from \"react-resizable-panels\";\nimport { createContext, useContext, useLayoutEffect, useRef, type ComponentProps, type RefObject } from \"react\";\nimport { cn, GROUP_FOCUS_RING } from \"../lib/utils\";\nimport { useBreakpoint } from \"../lib/use-breakpoint\";\nimport { Icon } from \"../lib/icons\";\n\ntype PanelGroupProps = ComponentProps<typeof PanelGroup>;\n\ntype Direction = \"horizontal\" | \"vertical\";\nconst DirectionCtx = createContext<Direction>(\"horizontal\");\nconst MobileCtx = createContext(false);\n\nexport interface ResizablePanelGroupProps\n extends Omit<PanelGroupProps, \"className\" | \"orientation\"> {\n direction?: Direction;\n stackOnMobile?: boolean;\n className?: string;\n /** Map of panel id → percentage (0–100). Must be an object, never an array. Panels need matching id props. */\n defaultLayout?: { [panelId: string]: number };\n /** Called after resize ends. Receives { [panelId]: number }, not number[]. */\n onLayoutChanged?: (layout: { [panelId: string]: number }) => void;\n}\n\nexport function ResizablePanelGroup({\n className,\n direction = \"horizontal\",\n stackOnMobile = true,\n ...props\n}: ResizablePanelGroupProps) {\n const isMobile = useBreakpoint(\"sm\");\n const shouldStack = stackOnMobile && isMobile && direction === \"horizontal\";\n const effectiveDirection = shouldStack ? \"vertical\" : direction;\n\n return (\n <DirectionCtx.Provider value={effectiveDirection}>\n <MobileCtx.Provider value={isMobile}>\n <PanelGroup\n className={cn(\n \"flex h-full w-full\",\n effectiveDirection === \"vertical\" && \"flex-col\",\n className,\n )}\n orientation={effectiveDirection}\n {...props}\n />\n </MobileCtx.Provider>\n </DirectionCtx.Provider>\n );\n}\n\ntype PanelProps = ComponentProps<typeof Panel>;\n\nexport interface ResizablePanelProps extends Omit<PanelProps, \"className\"> {\n className?: string;\n id?: string;\n /** number = px. \"30%\" or \"30\" = percent. \"28rem\" / \"400px\" also valid. */\n defaultSize?: number | string;\n minSize?: number | string;\n maxSize?: number | string;\n collapsible?: boolean;\n}\n\nexport function ResizablePanel({ className, ...props }: ResizablePanelProps) {\n return <Panel className={cn(\"\", className)} {...props} />;\n}\n\ntype PanelResizeHandleProps = ComponentProps<typeof PanelResizeHandle>;\n\n/** The part of an element on screen, top to bottom: inside the window and every box around it that clips or scrolls. */\nfunction visibleRange(el: HTMLElement): { top: number; bottom: number } {\n const box = el.getBoundingClientRect();\n let top = Math.max(box.top, 0);\n let bottom = Math.min(box.bottom, window.innerHeight);\n for (let node = el.parentElement; node; node = node.parentElement) {\n if (!/(auto|scroll|hidden|clip|overlay)/.test(getComputedStyle(node).overflowY)) continue;\n const r = node.getBoundingClientRect();\n top = Math.max(top, r.top + node.clientTop);\n bottom = Math.min(bottom, r.top + node.clientTop + node.clientHeight);\n }\n return { top, bottom };\n}\n\n/**\n * Sprint 25.16 A42 (P31): the grip stays in the part of the divider on screen, at its middle, so a split taller than\n * the screen (a page that grows) never hides it. It moves with any scroll around it and stays inside the divider; it\n * goes back to the middle when the divider turns (stacked on a phone).\n */\nfunction useGripInView(gripRef: RefObject<HTMLDivElement | null>, enabled: boolean) {\n useLayoutEffect(() => {\n const grip = gripRef.current;\n const handle = grip?.parentElement;\n if (!enabled || !grip || !handle || typeof ResizeObserver === \"undefined\") return;\n let frame = 0;\n const place = () => {\n frame = 0;\n const box = handle.getBoundingClientRect();\n const { top, bottom } = visibleRange(handle);\n const room = (box.height - grip.offsetHeight) / 2;\n const offset = bottom > top ? Math.max(-room, Math.min(room, (top + bottom) / 2 - (box.top + box.height / 2))) : 0;\n grip.style.transform = Math.abs(offset) >= 1 ? `translateY(${Math.round(offset)}px)` : \"\";\n };\n const schedule = () => {\n if (!frame) frame = requestAnimationFrame(place);\n };\n place();\n const ro = new ResizeObserver(schedule);\n ro.observe(handle);\n // a scroll anywhere around it: scroll events don't bubble, so the document hears them as they go down\n document.addEventListener(\"scroll\", schedule, { capture: true, passive: true });\n window.addEventListener(\"resize\", schedule);\n return () => {\n ro.disconnect();\n document.removeEventListener(\"scroll\", schedule, { capture: true });\n window.removeEventListener(\"resize\", schedule);\n if (frame) cancelAnimationFrame(frame);\n grip.style.transform = \"\";\n };\n }, [gripRef, enabled]);\n}\n\nexport interface ResizableHandleProps\n extends Omit<PanelResizeHandleProps, \"className\"> {\n withHandle?: boolean;\n className?: string;\n}\n\nexport function ResizableHandle({\n withHandle,\n className,\n ...props\n}: ResizableHandleProps) {\n const direction = useContext(DirectionCtx);\n const isMobile = useContext(MobileCtx);\n const isVertical = direction === \"vertical\";\n const gripRef = useRef<HTMLDivElement>(null);\n // the grip is kept in view whenever it can show: always with withHandle, and on keyboard focus without it\n useGripInView(gripRef, !isVertical);\n\n return (\n <PanelResizeHandle\n className={cn(\n // a group: its keyboard focus is drawn round its grip (Sprint 30), as a full-length line's outline would be cut off\n // at both its ends by the panels it divides; the line itself shows no outline of its own\n \"group relative flex items-center justify-center bg-[var(--ds-border-default)] outline-none\",\n isVertical\n ? cn(\n \"h-[var(--ds-border-width)] w-full after:absolute after:left-0 after:right-0 after:content-['']\",\n isMobile ? \"after:-top-3 after:-bottom-3\" : \"after:-top-1 after:-bottom-1\"\n )\n : cn(\n \"w-[var(--ds-border-width)] after:absolute after:inset-y-0 after:content-['']\",\n isMobile ? \"after:-left-3 after:-right-3\" : \"after:-left-1 after:-right-1\"\n ),\n \"[&[data-resize-handle-state=drag]]:bg-[var(--ds-accent-primary)]\",\n \"[&[data-resize-handle-state=hover]]:bg-[var(--ds-accent-primary)]\",\n className,\n )}\n {...props}\n >\n {/* the grip: always with withHandle; without it, shown while the handle has keyboard focus, to carry its outline */}\n <div\n ref={gripRef}\n aria-hidden=\"true\"\n className={cn(\n \"z-10 items-center justify-center rounded-[var(--ds-radius-sm)]\",\n withHandle ? \"flex\" : \"hidden group-focus-visible:flex\",\n GROUP_FOCUS_RING,\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"bg-[var(--ds-bg-surface)]\",\n isVertical\n ? (isMobile ? \"h-4 w-8\" : \"h-3 w-4\")\n : (isMobile ? \"h-8 w-4\" : \"h-4 w-3\"),\n )}\n >\n <Icon\n name=\"grip-vertical\"\n size={isMobile ? 12 : 10}\n className={cn(\n \"text-[var(--ds-text-muted)]\",\n isVertical && \"rotate-90\",\n )}\n />\n </div>\n </PanelResizeHandle>\n );\n}\n","import { useCallback, useEffect, useLayoutEffect, useRef, useState, type CSSProperties, type KeyboardEvent, type ReactNode, type RefObject } from \"react\";\nimport { cn, FOCUS_INSET } from \"../lib/utils\";\nimport { useBelow, useCompact, useElementWidth } from \"../lib/use-compact\";\nimport { useBreakpoint } from \"../lib/use-breakpoint\";\nimport { ResizablePanelGroup, ResizablePanel, ResizableHandle } from \"./ResizablePanels\";\nimport { Button } from \"./Button\";\nimport { Drawer } from \"./Drawer\";\nimport { Icon } from \"../lib/icons\";\nimport { Breadcrumbs, crumbGoes, type BreadcrumbItem } from \"./Breadcrumbs\";\nimport { useAppShell } from \"./AppShell\";\nimport { PANE_INSET, SurfaceBoundary, type SplitListReport } from \"../lib/surface-context\";\nimport { isTabStop, rememberFocus, tabStops, type RememberedFocus } from \"../lib/focus\";\nimport { FillContext, useFillHeight } from \"../lib/use-fill-height\";\nimport { BulkBarHostCtx, BulkBarSpacer, useBulkBarHost, BULK_BAR_LAYER, bulkBarRoom } from \"../lib/bulk-bar-host\";\nimport { useKeyboardScroll } from \"../lib/use-keyboard-scroll\";\nimport { warnOnce } from \"../lib/dev-warn\";\n\nexport type SplitViewFrame = \"fill\" | \"page\";\n\n/**\n * How far past a threshold the layout must go before a collapsed part comes back, in px: a classic scrollbar's width\n * (15 px on a Mac with a mouse, 17 on Windows), whose coming and going with the aside moved the layout back and forth\n * across the threshold (round 27 review). No wider: inside the band the answer depends on the way the width came, so a\n * wider band could keep the aside collapsed at a width where it fits.\n */\nconst THRESHOLD_BAND = 17;\n\n/**\n * A pane's scroller, with the pane's inset (C1): what the keyboard reaches comes into view with room for its outline (Sprint\n * 30, P3). Each scroller adds FOCUS_INSET on its own tag, as every element given to useKeyboardScroll does.\n */\nconst paneScroll = (inset?: string) => cn(\"min-h-0 overflow-y-auto scroll-p-[4px]\", inset);\n\n/** How far a view reaches past the page's gutter on each side, in px (C3). */\ninterface Bleed { left: number; right: number }\n\nconst clear = (colour: string) => colour === \"transparent\" || /^rgba\\(.*,\\s*0\\)$/.test(colour);\n\n/** Whether an element draws something of its own (an edge, a fill, a shadow) or clips what reaches past it. */\nfunction drawsOrClips(el: HTMLElement): boolean {\n const cs = getComputedStyle(el);\n if (cs.display === \"contents\") return false;\n const edge = (width: string, style: string) => parseFloat(width) > 0 && style !== \"none\" && style !== \"hidden\";\n return edge(cs.borderLeftWidth, cs.borderLeftStyle) || edge(cs.borderRightWidth, cs.borderRightStyle)\n || edge(cs.borderTopWidth, cs.borderTopStyle) || edge(cs.borderBottomWidth, cs.borderBottomStyle)\n || cs.backgroundImage !== \"none\" || !clear(cs.backgroundColor) || cs.boxShadow !== \"none\" || cs.overflowX !== \"visible\";\n}\n\n/**\n * The page's gutter on each side when the view's parent spans the page column's content and nothing between the two\n * draws or clips, else null: a view in a Card, a grid's cell or a bordered box keeps its place (C3: frame=\"page\" is the\n * default there too, so the frame is never the key).\n */\nfunction pageBleed(parent: HTMLElement, column: HTMLElement): Bleed | null {\n for (let el: HTMLElement | null = parent; el && el !== column; el = el.parentElement) if (drawsOrClips(el)) return null;\n const cs = getComputedStyle(column);\n const left = parseFloat(cs.paddingLeft) || 0;\n const right = parseFloat(cs.paddingRight) || 0;\n if (left + right === 0) return null;\n if (parent !== column) {\n const p = parent.getBoundingClientRect();\n const c = column.getBoundingClientRect();\n const start = c.left + column.clientLeft + left;\n const end = c.left + column.clientLeft + column.clientWidth - right;\n if (Math.abs(p.left - start) > 1 || Math.abs(p.right - end) > 1) return null;\n }\n return { left, right };\n}\n\n/**\n * Sprint 25.33 C3 (run 97, the owner: \"On mobile there's too much padding inside the container\"): on a phone a page-frame\n * view that spans its PageContainer's column runs edge to edge, as a Dialog does there (Dialog.tsx), its content at the\n * page's gutter. Keyed on the screen's width and on spanning the column, never on `compact`: the view measures its own\n * width to collapse (with a 17 px band), and reaching two gutters wider would flip that back and forth. So this measures\n * the view's parent and the column, never the view, and its answer can't change with its own reach.\n */\nfunction usePageBleed(ref: RefObject<HTMLElement | null>, on: boolean): Bleed | null {\n const [bleed, setBleed] = useState<Bleed | null>(null);\n useLayoutEffect(() => {\n const parent = ref.current?.parentElement;\n const column = parent?.closest<HTMLElement>(\"[data-page-column]\");\n if (!on || !parent || !column) {\n setBleed(null);\n return;\n }\n const measure = () => {\n const next = pageBleed(parent, column);\n setBleed((prev) => (prev?.left === next?.left && prev?.right === next?.right ? prev : next));\n };\n measure();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(measure);\n observer.observe(column);\n observer.observe(parent);\n return () => observer.disconnect();\n }, [ref, on]);\n return on ? bleed : null;\n}\n\nexport interface SplitViewProps {\n /** The list (an inbox, a queue): it scrolls on its own. */\n list: ReactNode;\n /**\n * The selected item (a thread, a record): it fills the height and scrolls on its own. The pane insets it at the page's\n * gutter, so pass content with no padding classes; a SectionHeading variant=\"pane\" placed first is the item's header,\n * inset once, its rule reaching the pane's edges (Sprint 25.33 C1).\n */\n detail: ReactNode;\n /**\n * The detail is one full-bleed piece that runs to the pane's edges and owns its inset: a conversation with its header,\n * its own scroller and its composer, a preview, an editor. The pane then adds no inset of its own (Sprint 25.33 C1).\n */\n detailFlush?: boolean;\n /** Context beside the detail (a contact, properties). The pane insets it as the Drawer it collapses into does (the page's gutter, Sprint 25.14 A36), so pass content with no padding classes (round 8). Collapses to a toggle that opens it in a Drawer when the layout is narrower than `asideCollapseBelow`. */\n aside?: ReactNode;\n /** Names the aside's toggle and Drawer. */\n asideTitle?: string;\n /**\n * Below `collapseBelow` the list shows alone; with `detailOpen` the detail replaces it, with a Back button that calls\n * `onDetailClose` (detailMode \"stack\"). The page owns the selection, so it owns this flag.\n */\n detailOpen?: boolean;\n onDetailClose?: () => void;\n /** \"stack\" (default): the detail stacks over the list below the collapse width. \"route\": the app navigates to the detail's own route instead, and this renders the list alone there. */\n detailMode?: \"stack\" | \"route\";\n /**\n * \"shown\" (default): above the collapse width the detail pane is always there — an inbox's reading pane may show a\n * placeholder. \"hidden\" (Sprint 25.7, C3): `detailOpen` decides at every width. Closed, the list takes the whole\n * width; open, the pane appears beside it at the width the user last gave it, with a close control that calls\n * `onDetailClose`. For boards, timelines and lists of records. The list stays mounted, so a board or a timeline keeps\n * its scroll and zoom.\n */\n closedDetail?: \"shown\" | \"hidden\";\n /** The open pane's close control, named for a screen reader (closedDetail=\"hidden\"). Default \"Close\". */\n closeLabel?: string;\n backLabel?: string;\n /**\n * The open item's path (Sprint 25.16 A19, P11): crumbs from the top of what the list shows down to the open view's\n * parent, never the view itself (the owner's review of 1 October) — a document in a folder tree passes its folders\n * (\"Documents › Architecture\"), a view below an item passes the item as well (\"… › System Design Overview\", above its\n * metadata). The view's own title, its first heading, names it, as a page's title does under its PageHeader's\n * breadcrumbs. The view draws the path above the detail at every width, where the stacked Back would be, and its last\n * crumb is the way back: the stacked Back goes, and the detail draws no back of its own\n * (gs:breadcrumbs-and-back-button-2). A crumb that is a page takes its href and goes through the shell's navigate; an\n * item held in state, or a folder that isn't a page, takes an onClick (select it in the tree); a last crumb with\n * neither closes the detail. On a phone the path keeps its first crumb and its last two, so the parent always shows.\n * One crumb or more; with none, today's Back.\n */\n detailPath?: BreadcrumbItem[];\n /** Percent of the width the list takes; the divider is draggable. */\n listWidth?: number;\n listMinWidth?: number;\n asideWidth?: number;\n /** Below this width of the layout itself (px) the list and detail stop sitting side by side. */\n collapseBelow?: number;\n /** Below this width of the layout itself (px) the aside becomes a toggle. */\n asideCollapseBelow?: number;\n /**\n * The narrowest the open item's pane may be beside an aside (px). When the list and the aside would leave it less,\n * the aside becomes its toggle and Drawer, so the item keeps the room its content needs: the aside is the secondary\n * content (round 27, R27-13, the owner: \"which information is more important\"). An item that holds a wide table or a\n * card grid may need more: pass it.\n */\n detailMinWidth?: number;\n /** A bordered, rounded surface (inside a page with padding) instead of edge to edge (filling <main>). */\n bordered?: boolean;\n /** \"fill\": the page root, flush to the shell, h-full against main, each pane owns its inset. \"page\" (default): inside a PageContainer under a PageHeader. */\n frame?: SplitViewFrame;\n \"aria-label\"?: string;\n className?: string;\n}\n\n/**\n * The reading-pane composition (Sprint 25.2, R3): one surface with dividers —\n * list, detail and an optional aside — that fills the height it is given (an\n * AppShell's <main> already gives it) and never three cards with gaps. The\n * panels compose ResizablePanelGroup, so the dividers drag. Below the collapse\n * width, measured on the layout itself, the list shows alone and the detail\n * stacks over it (or the app routes to it); the aside collapses to a toggle.\n * The page owns the selection and assembles the contents; keyboard movement\n * through the list is the list's job (StackedList selectedId).\n */\nexport function SplitView({\n list,\n detail,\n detailFlush = false,\n aside,\n asideTitle = \"Details\",\n detailOpen = false,\n onDetailClose,\n detailMode = \"stack\",\n closedDetail = \"shown\",\n closeLabel = \"Close\",\n backLabel = \"Back\",\n detailPath,\n listWidth = 35,\n listMinWidth = 25,\n asideWidth = 25,\n collapseBelow = 768,\n asideCollapseBelow = 1024,\n detailMinWidth = 480,\n bordered = false,\n frame = \"page\",\n \"aria-label\": ariaLabel,\n className,\n}: SplitViewProps) {\n const rootRef = useRef<HTMLDivElement>(null);\n const compact = useCompact(rootRef, collapseBelow, THRESHOLD_BAND);\n const layoutWidth = useElementWidth(rootRef);\n // The panels' shares as the user left them (the review: the defaults were read, so a list dragged wider left the item\n // under its minimum beside the aside); the aside's last share stands in while it is collapsed.\n const [shares, setShares] = useState<{ list?: number; aside?: number }>({});\n const listShare = shares.list ?? listWidth;\n const asideShare = shares.aside ?? asideWidth;\n // the aside yields when the layout is narrow, or when beside it the item would have less than its minimum\n const itemShare = (100 - listShare - asideShare) / 100;\n const itemBesideAside = aside ? layoutWidth * itemShare : 0;\n // the item moves by its share of the scrollbar's width, so its band is that share of the layout's\n const itemSqueezed = useBelow(itemBesideAside, detailMinWidth, THRESHOLD_BAND * Math.max(0, itemShare));\n const asideCollapsed = useBelow(layoutWidth, asideCollapseBelow, THRESHOLD_BAND) || itemSqueezed;\n const [asideWantsOpen, setAsideWantsOpen] = useState(false);\n const hiding = closedDetail === \"hidden\";\n // Hidden: the aside belongs to the open item, so it (its pane, its toggle, its Drawer) goes with the pane, and a\n // Drawer left open does not come back with the next item (render-time state adjustment).\n const showAside = !!aside && (!hiding || detailOpen);\n if (hiding && !detailOpen && asideWantsOpen) setAsideWantsOpen(false);\n // on a phone the aside's Drawer belongs to the item on screen: Back closes it with the item\n if (compact && !detailOpen && asideWantsOpen) setAsideWantsOpen(false);\n const asideOpen = asideCollapsed && asideWantsOpen;\n const region = ariaLabel ? { role: \"region\" as const, \"aria-label\": ariaLabel } : {};\n // A19: the item's path stands in for Back, its last crumb (the view's parent) going up one level; its bar insets at the\n // page's gutter, as the aside's content does (Sprint 25.14 A36). A last crumb that goes nowhere of its own closes the\n // detail, as Back did, so the path is always a way back.\n const path = detailPath && detailPath.length > 0\n ? detailPath.map((crumb, i) => (i === detailPath.length - 1 && !crumbGoes(crumb) && onDetailClose ? { ...crumb, onClick: onDetailClose } : crumb))\n : null;\n // fill: the page root, flush to the shell on every side (no border, no radius, no padding of its own); h-full\n // resolves against <main> because the shell is a flex column down to it. page: inside a PageContainer under a\n // PageHeader, where `bordered` draws the surface. Each pane owns its own inset either way.\n const isFill = frame === \"fill\";\n // Sprint 25.14 A44 (P32): the list pane's content reports what it is, as a wrapped PageHeader does to its\n // PageContainer: content that draws its own frame or cards (a KanbanBoard, a CardGrid, a Table), or content with no\n // frame of its own that scrolls inside the pane (a StackedList, a Gantt). No frame around what frames itself: when the\n // pane holds only the first kind, the list sits on the canvas with nothing drawn behind it and the open item on the\n // surface, whatever `bordered` says. Anything that scrolls inside keeps the hairline, which shows where it scrolls.\n const listHolds = useRef({ framed: 0, scrolls: 0, edge: 0, inset: 0 });\n const [framesItself, setFramesItself] = useState(false);\n // Sprint 25.33 C1 (the owner: \"there's no one size fits all\"): a pane pads what's in it, unless the thing runs edge to\n // edge. The list pane is flush while it holds a list or a board, found at any depth by the same report: a list of\n // full-width bands (a StackedList, a VirtualizedList), a plan (a Gantt) or what frames itself (a KanbanBoard, a\n // CardGrid, a Table, a DataGrid). A tree, a form, text or a timeline there is padded.\n const [listFlush, setListFlush] = useState(false);\n const reportToList = useCallback<SplitListReport>((kind, present) => {\n const held = listHolds.current;\n held[kind] = Math.max(0, held[kind] + (present ? 1 : -1));\n // the fix pass of 25.33 (S-9): while nothing in the pane reports (an empty result, a spinner, a reload between lists),\n // the last decision stands, so a search row of the page's own above the list doesn't move as its list empties, nor\n // the view's frame. A tree reports it wants the inset, so a page that swaps its list for a tree pads again; a form or\n // text, which report nothing, keep the decision before them\n if (held.framed === 0 && held.scrolls === 0 && held.edge === 0 && held.inset === 0) return;\n setFramesItself(held.framed > 0 && held.scrolls === 0);\n setListFlush(held.framed > 0 || held.edge > 0);\n }, []);\n const listInset = listFlush ? undefined : PANE_INSET.list;\n // the detail pads at the page's gutter unless the page says it is one full-bleed piece (a thread, a preview, an editor)\n const detailInset = detailFlush ? undefined : PANE_INSET.detail;\n const onCanvas = isFill || framesItself;\n // In a shell with an app footer the children wrapper has no definite height, so h-full cannot resolve; the shell\n // publishes main's height and fill takes it (the footer then sits below the fold, as it must under a full pane).\n const shell = useAppShell();\n // Sprint 25.16 A42 (P31): a page frame that is the page's last content takes the height under its header, so its panes\n // scroll inside it and the page doesn't; what's inside the view takes its pane's height (FillContext)\n const pageFill = useFillHeight(rootRef, !isFill);\n // each pane scrolls inside the view: one with nothing in it to Tab to (a message's text) is a Tab stop of its own, so a\n // keyboard can scroll it (WCAG 2.1.1)\n const [listScroll, setListScroll] = useState<HTMLDivElement | null>(null);\n const [detailScroll, setDetailScroll] = useState<HTMLDivElement | null>(null);\n const [asideScroll, setAsideScroll] = useState<HTMLDivElement | null>(null);\n const [stackedListScroll, setStackedListScroll] = useState<HTMLDivElement | null>(null);\n // Sprint 25.29 item 16: with `detailOpen` and no `onDetailClose`, the phone's Back couldn't work, and a page that keeps\n // its detail open stranded a phone user away from the list (run 79's folder tree). Without the handler the view keeps\n // its own \"showing the list\" on phones, so Back works, and a press in the list shows the detail again; with it, the\n // page decides, as before.\n const [listShown, setListShown] = useState(false);\n if (listShown && (onDetailClose || !detailOpen || !compact)) setListShown(false);\n useEffect(() => {\n if (detailOpen && !onDetailClose && detailMode === \"stack\") {\n warnOnce(\"SplitView\", \"detailOpen is set without onDetailClose: below the collapse width, Back can only show the list again, and the page never hears of it. Pass onDetailClose to close the detail.\");\n }\n }, [detailOpen, onDetailClose, detailMode]);\n // On a phone, the detail giving way to the list (Back, the page's or the view's own) leaves focus on the list's chosen\n // item, else its first control, never on the page\n const detailOnPhone = compact && detailMode === \"stack\" && detailOpen && !listShown;\n const wasDetailOnPhone = useRef(detailOnPhone);\n useLayoutEffect(() => {\n const was = wasDetailOnPhone.current;\n wasDetailOnPhone.current = detailOnPhone;\n if (!was || detailOnPhone) return;\n const active = document.activeElement;\n if (active && active !== document.body && active.isConnected) return;\n const pane = stackedListScroll;\n const chosen = pane?.querySelector<HTMLElement>('[aria-current=\"true\"], [aria-current=\"page\"], [aria-selected=\"true\"]');\n const target = (chosen && (isTabStop(chosen) ? chosen : tabStops(chosen)[0])) || (pane ? tabStops(pane)[0] : undefined);\n (target ?? pane)?.focus();\n });\n const [stackedDetailScroll, setStackedDetailScroll] = useState<HTMLDivElement | null>(null);\n // named for what they hold (the review of 1 October): the list by the view's own name, the item by its title (its\n // first heading; the path ends at its parent, so never names it)\n const listName = ariaLabel ? `${ariaLabel} list` : \"List\";\n const itemName = ariaLabel ? `${ariaLabel} item` : \"Item\";\n useKeyboardScroll(listScroll, listName, !compact);\n useKeyboardScroll(detailScroll, itemName, !compact, true);\n useKeyboardScroll(asideScroll, asideTitle, !compact);\n useKeyboardScroll(stackedListScroll, listName, compact);\n useKeyboardScroll(stackedDetailScroll, itemName, compact, true);\n const fillStyle = isFill && shell?.hasFooter ? { height: \"var(--ds-main-height, 100%)\" } : pageFill != null ? { height: pageFill } : undefined;\n // C3: on a phone a page frame spanning its page's column runs edge to edge, dropping its side edges and its corners,\n // while it draws a surface: a board on the canvas keeps its place at the page's gutter until an item opens over it\n const phone = useBreakpoint(\"sm\");\n const bleed = usePageBleed(rootRef, phone && !isFill);\n const reach = bleed && (!onCanvas || detailOnPhone) ? bleed : null;\n const squared: CSSProperties | undefined = reach ? { borderLeftWidth: 0, borderRightWidth: 0, borderRadius: 0 } : undefined;\n const rootStyle: CSSProperties | undefined = reach\n ? { ...fillStyle, ...squared, marginLeft: -reach.left, marginRight: -reach.right, width: `calc(100% + ${reach.left + reach.right}px)` }\n : fillStyle;\n // Edge to edge the list sits on the page's canvas, like every other page, and the open item (its detail and its aside)\n // on the surface (round 27, R27-12, the owner: the whole split on the surface read as a different page). A page frame,\n // bordered or not, stays one surface: a card on the canvas. Beside a list that frames itself, a page frame's open item\n // is that card (rounded, and bordered when the view is), as the page's other cards are; edge to edge it is square.\n const itemSurface = !onCanvas ? undefined : isFill\n ? \"bg-[var(--ds-bg-surface)]\"\n : cn(\"bg-[var(--ds-bg-surface)] rounded-[var(--ds-radius-md)] overflow-hidden\", bordered && \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\");\n const surface = cn(\n \"h-full min-h-0 w-full\",\n !onCanvas && \"bg-[var(--ds-bg-surface)]\",\n isFill && \"rounded-none border-0\",\n bordered && !onCanvas && \"border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] rounded-[var(--ds-radius-md)] overflow-hidden\",\n className,\n );\n // each pane is a surface of its own: what a Card around the view, or the list pane, tells content stops at its edge;\n // each tells its content whether it pads it, so a pane header cancels the padding and a list lines up (C1)\n // Sprint 25.33 B2: a bulk-action bar in a pane floats at that pane's foot, so a list's bar never covers the open item\n // (its composer), and the pane keeps room for it under its last row\n const listBar = useBulkBarHost();\n const detailBar = useBulkBarHost();\n const barRoom = (room: number) => (room ? { scrollPaddingBottom: bulkBarRoom(room) } : undefined);\n const listContent = <><BulkBarHostCtx value={listBar.value}><SurfaceBoundary pane=\"list\" framer={reportToList} padded={!listFlush}>{list}</SurfaceBoundary></BulkBarHostCtx><BulkBarSpacer room={listBar.room} /></>;\n const detailContent = <><BulkBarHostCtx value={detailBar.value}><SurfaceBoundary pane=\"detail\" padded={!detailFlush}>{detail}</SurfaceBoundary></BulkBarHostCtx><BulkBarSpacer room={detailBar.room} /></>;\n const barLayer = (bar: ReturnType<typeof useBulkBarHost>) => <div ref={bar.setLayer} data-bulk-bar-layer=\"\" className={BULK_BAR_LAYER} />;\n\n // closedDetail=\"hidden\" (C3): the pane opens beside the list at the width the user last gave it; closing it returns\n // focus to the item the pane shows, or its neighbour if that item is gone (D14(e)): the list's selected item, else\n // the last list item that took focus, checked on each render while the pane is open, so switching items is followed.\n // A selection kept in the URL changes the path, so the item is remembered whatever the route does. With no item\n // (opened on load, or from outside the list) focus goes to the list's first Tab stop. No overlay layer: an\n // assistant opened earlier keeps Escape.\n const [listPct, setListPct] = useState(listWidth);\n const paneRef = useRef<HTMLDivElement>(null);\n const shown = useRef<RememberedFocus | null>(null);\n const lastInList = useRef<HTMLElement | null>(null);\n const wasOpen = useRef(false);\n useLayoutEffect(() => {\n if (!hiding) return;\n const listPane = rootRef.current?.querySelector<HTMLElement>('[data-pane=\"list\"]') ?? null;\n if (detailOpen) {\n wasOpen.current = true;\n const selected = listPane?.querySelector<HTMLElement>('[aria-current=\"true\"], [aria-selected=\"true\"]');\n const last = lastInList.current;\n const item = (selected && (isTabStop(selected) ? selected : tabStops(selected)[0]))\n || (last?.isConnected && listPane?.contains(last) ? last : null);\n if (item && item !== shown.current?.el) shown.current = rememberFocus(item, { ignoreRoute: true });\n return;\n }\n if (!wasOpen.current) return;\n wasOpen.current = false;\n const r = shown.current;\n shown.current = null;\n const active = document.activeElement;\n if (active && active !== document.body && active.isConnected) return;\n const first = listPane ? tabStops(listPane)[0] : undefined;\n if (!r?.restore(first)) first?.focus();\n });\n const onPaneKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key !== \"Escape\" || e.defaultPrevented || !onDetailClose) return;\n const t = e.target as HTMLElement;\n // the pane's own DOM only — a portalled popup inside it bubbles here in React's tree — and never from a field\n if (!paneRef.current?.contains(t) || t.closest(\"input, textarea, select, [contenteditable='true']\")) return;\n e.preventDefault();\n onDetailClose();\n };\n\n if (compact) {\n const showDetail = detailOnPhone;\n // on a phone the item's aside is a toggle beside Back that opens it in a Drawer, as it is on a narrow desktop (the\n // round 27 review: below the collapse width it could not be reached at all)\n const phoneAside = showDetail && !!aside;\n return (\n <FillContext value={true}>\n <div ref={rootRef} data-split-view={showDetail ? \"detail\" : \"list\"} data-frame={frame} data-fill={pageFill != null ? \"\" : undefined} data-edge-to-edge={reach ? \"\" : undefined} {...region} className={cn(surface, \"relative flex flex-col\")} style={rootStyle}>\n {showDetail && (\n <div className={cn(\"relative flex-1 min-h-0 flex flex-col\", itemSurface)} style={itemSurface ? squared : undefined}>\n <div className={cn(\"shrink-0 flex items-center justify-between gap-ds-2 py-ds-2 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\", path ? \"px-[var(--ds-page-gutter)]\" : \"px-ds-3\")}>\n {path\n ? <Breadcrumbs items={path} maxItems={3} aria-label=\"Path\" className=\"min-w-0\" />\n // a link, alone at the start of the header (Sprint 25.19 G4, page_composition#51): its words line up with the header's edge\n : <Button type=\"button\" variant=\"link\" size=\"sm\" iconLeft={<Icon name=\"arrow-left\" size={14} />} onClick={onDetailClose ?? (() => setListShown(true))}>{backLabel}</Button>}\n {phoneAside && <Button type=\"button\" variant=\"ghost\" size=\"sm\" iconLeft={<Icon name=\"info\" size={14} />} onClick={() => setAsideWantsOpen(true)} aria-expanded={asideWantsOpen}>{asideTitle}</Button>}\n </div>\n {/* C1: the phone's stacked panes pad as they do side by side */}\n <div ref={setStackedDetailScroll} data-pane-scroll=\"detail\" className={cn(\"flex-1\", paneScroll(detailInset), FOCUS_INSET)} style={barRoom(detailBar.room)}>{detailContent}</div>\n {barLayer(detailBar)}\n </div>\n )}\n {/* Sprint 25.14 A44 (the review of 30 September): the list stays mounted while the stacked detail is shown, as it\n does beside it on a wider screen, so a board keeps its scroll and its report (the view kept its frame\n off only while the board was on screen), and Back finds the list as the user left it */}\n <div ref={setStackedListScroll} data-pane-scroll=\"list\" className={cn(\"flex-1\", paneScroll(listInset), FOCUS_INSET)} hidden={showDetail || undefined} style={barRoom(listBar.room)}\n onClickCapture={onDetailClose ? undefined : () => setListShown(false)}>{listContent}</div>\n {/* the list's bar goes with the list while the item shows over it */}\n {!showDetail && barLayer(listBar)}\n {phoneAside && (\n <Drawer open={asideWantsOpen} onClose={() => setAsideWantsOpen(false)} title={asideTitle} position=\"right\">\n {aside}\n </Drawer>\n )}\n </div>\n </FillContext>\n );\n }\n\n const asideButton = showAside && asideCollapsed\n ? <Button type=\"button\" variant=\"ghost\" size=\"sm\" iconLeft={<Icon name=\"info\" size={14} />} onClick={() => setAsideWantsOpen(true)} aria-expanded={asideOpen}>{asideTitle}</Button>\n : null;\n const closeButton = hiding && onDetailClose\n ? <Button type=\"button\" variant=\"ghost\" size=\"icon-sm\" aria-label={closeLabel} onClick={onDetailClose}><Icon name=\"close\" size={14} /></Button>\n : null;\n const paneBar = path || asideButton || closeButton ? (\n <div className={cn(\"shrink-0 flex items-center gap-ds-1 py-ds-2 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\", path ? \"justify-between px-[var(--ds-page-gutter)]\" : \"justify-end px-ds-3\")}>\n {path && <Breadcrumbs items={path} aria-label=\"Path\" className=\"min-w-0\" />}\n {(asideButton || closeButton) && <div className=\"shrink-0 flex items-center gap-ds-1\">{asideButton}{closeButton}</div>}\n </div>\n ) : null;\n const showDetail = !hiding || detailOpen;\n\n return (\n <FillContext value={true}>\n <div ref={rootRef} data-split-view={hiding && !detailOpen ? \"list\" : \"split\"} data-frame={frame} data-fill={pageFill != null ? \"\" : undefined} data-edge-to-edge={reach ? \"\" : undefined} {...region} className={surface} style={rootStyle}>\n <ResizablePanelGroup\n direction=\"horizontal\"\n stackOnMobile={false}\n className=\"h-full\"\n // the width the user gives the list is kept, so a closed pane reopens at it; the shares decide when the aside yields\n onLayoutChanged={(layout) => {\n setShares((prev) => (prev.list === (layout.list ?? prev.list) && prev.aside === (layout.aside ?? prev.aside) ? prev : { list: layout.list ?? prev.list, aside: layout.aside ?? prev.aside }));\n if (hiding && layout.detail != null && layout.list != null) setListPct(layout.list);\n }}\n >\n <ResizablePanel id=\"list\" className=\"relative\" defaultSize={`${hiding ? (detailOpen ? listPct : 100) : listWidth}%`} minSize={`${listMinWidth}%`}>\n {/* scroll padding: what the keyboard reaches comes into view with room for its outline (Sprint 30, P3); a list's\n rows run to the pane's edges and draw their outline inside (StackedList), and anything else is padded (C1) */}\n <div ref={setListScroll} data-pane=\"list\" data-pane-scroll=\"list\" className={cn(\"h-full\", paneScroll(listInset), FOCUS_INSET)} style={barRoom(listBar.room)} onFocus={hiding ? (e) => { lastInList.current = e.target; } : undefined}>\n {listContent}\n </div>\n {barLayer(listBar)}\n </ResizablePanel>\n {showDetail && (\n <>\n <ResizableHandle withHandle />\n <ResizablePanel id=\"detail\" minSize=\"30%\">\n <div ref={paneRef} data-pane=\"detail\" className={cn(\"relative h-full min-h-0 flex flex-col\", itemSurface)} onKeyDown={hiding ? onPaneKeyDown : undefined}>\n {paneBar}\n <div ref={setDetailScroll} data-pane-scroll=\"detail\" className={cn(\"flex-1\", paneScroll(detailInset), FOCUS_INSET)} style={barRoom(detailBar.room)}>{detailContent}</div>\n {barLayer(detailBar)}\n </div>\n </ResizablePanel>\n </>\n )}\n {showAside && !asideCollapsed && (\n <>\n <ResizableHandle withHandle />\n <ResizablePanel id=\"aside\" defaultSize={`${asideWidth}%`} minSize=\"15%\">\n {/* the Drawer's body inset, so the aside's content sits where it will in the Drawer (Sprint 25.14 A36) */}\n <div ref={setAsideScroll} data-pane=\"aside\" data-pane-scroll=\"aside\" className={cn(\"h-full\", paneScroll(PANE_INSET.detail), itemSurface, FOCUS_INSET)}><SurfaceBoundary pane=\"aside\">{aside}</SurfaceBoundary></div>\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n {showAside && asideCollapsed && (\n <Drawer open={asideOpen} onClose={() => setAsideWantsOpen(false)} title={asideTitle} position=\"right\">\n {aside}\n </Drawer>\n )}\n </div>\n </FillContext>\n );\n}\n"]}
|
package/dist/utils.d.ts
CHANGED
|
@@ -326,4 +326,54 @@ type CategoryKind = "names" | "scale";
|
|
|
326
326
|
*/
|
|
327
327
|
declare function categoryKind(labels: ReadonlyArray<unknown>, locale?: string): CategoryKind;
|
|
328
328
|
|
|
329
|
-
|
|
329
|
+
/**
|
|
330
|
+
* Sprint 32 (A2) — a dashboard's layout, as plain data: its widgets in reading order, each with a width in columns of 12
|
|
331
|
+
* and a height in rows of a fixed height. The grid lays them out as text is laid out: left to right, then the next row,
|
|
332
|
+
* each taking the first space after the one before that fits it (CSS grid's sparse auto-placement, never `dense`), so
|
|
333
|
+
* what's on screen, what a screen reader reads and where Tab goes are one order by construction.
|
|
334
|
+
*
|
|
335
|
+
* Server-safe: no React and no browser, so `gridsmith-ui/utils` exports the helpers (normaliseLayout, moveItem,
|
|
336
|
+
* resizeItem, addItem, removeItem) and a page that only adds a widget, or a test that checks a layout, needs no drag
|
|
337
|
+
* code. The rest is the grid's own: where widgets land (`placeLayout`, a copy of the browser's placement rule, held equal
|
|
338
|
+
* to Chrome's by a Chrome test), where a key or a pointer would take one (`stepTarget`, `nearestIndex`) and the words a
|
|
339
|
+
* screen reader hears for a size. Where things land is worked out here, from the layout, never measured from the
|
|
340
|
+
* screen: measuring a preview feeds back into it, the flicker sortable grids are known for.
|
|
341
|
+
*/
|
|
342
|
+
interface DashboardLayoutItem {
|
|
343
|
+
id: string;
|
|
344
|
+
/** Its width, in columns of 12. */
|
|
345
|
+
w: number;
|
|
346
|
+
/** Its height, in rows. */
|
|
347
|
+
h: number;
|
|
348
|
+
/** The narrowest it may be made, in columns (default 3, a quarter of the width; a widget is never narrower). */
|
|
349
|
+
minW?: number;
|
|
350
|
+
/** The shortest it may be made, in rows (default 2). */
|
|
351
|
+
minH?: number;
|
|
352
|
+
/** The widest it may be made, in columns (default 12). */
|
|
353
|
+
maxW?: number;
|
|
354
|
+
/** The tallest it may be made, in rows. */
|
|
355
|
+
maxH?: number;
|
|
356
|
+
}
|
|
357
|
+
type DashboardLayout = DashboardLayoutItem[];
|
|
358
|
+
/**
|
|
359
|
+
* The layout the grid draws (A2, "always valid"): whatever a page passes (a width past 12, a size under its minimum, a
|
|
360
|
+
* repeated id, an entry with no id), each widget once, in order, with whole sizes inside its limits and the 12 columns.
|
|
361
|
+
* Fields of the page's own on an entry are kept. Normalising twice changes nothing.
|
|
362
|
+
*/
|
|
363
|
+
declare function normaliseLayout(layout: readonly DashboardLayoutItem[] | null | undefined): DashboardLayout;
|
|
364
|
+
/** The layout with a widget moved to a place in the order (from 0; past either end, to that end). */
|
|
365
|
+
declare function moveItem(layout: readonly DashboardLayoutItem[], id: string, toIndex: number): DashboardLayout;
|
|
366
|
+
/** The layout with a widget given a new width, height or both, held to its limits. */
|
|
367
|
+
declare function resizeItem(layout: readonly DashboardLayoutItem[], id: string, size: {
|
|
368
|
+
w?: number;
|
|
369
|
+
h?: number;
|
|
370
|
+
}): DashboardLayout;
|
|
371
|
+
/**
|
|
372
|
+
* The layout with a widget added at a place in the order (from 0), else at the end. An id already in the layout isn't
|
|
373
|
+
* added again: ids are unique, and the widget there keeps its place.
|
|
374
|
+
*/
|
|
375
|
+
declare function addItem(layout: readonly DashboardLayoutItem[], item: DashboardLayoutItem, index?: number): DashboardLayout;
|
|
376
|
+
/** The layout without a widget; the rest flow up to fill its place. */
|
|
377
|
+
declare function removeItem(layout: readonly DashboardLayoutItem[], id: string): DashboardLayout;
|
|
378
|
+
|
|
379
|
+
export { ACTIVE_RING, type CategoryKind, type DashboardLayout, type DashboardLayoutItem, type DateInput, type DateRangeWords, ERROR_ACTIVE_RING, ERROR_FOCUS_RING, ERROR_FOCUS_WITHIN_RING, ERROR_HAS_FOCUS_RING, FIELD_FOCUS_RING, FIELD_FOCUS_WITHIN_RING, FIELD_HAS_FOCUS_RING, FOCUS_INSET, FOCUS_RING, FOCUS_WITHIN_RING, GLASS_BACKDROP, GLASS_DROPDOWN, GLASS_OVERLAY, GLASS_SURFACE, GROUP_FOCUS_RING, HAS_FOCUS_RING, type Occurrence, PEER_FOCUS_RING, type Recurrence, type RecurrenceFrequency, type RecurrencePreset, type RecurrenceScope, type RepeatChange, type RepeatingEvent, TIME_ZOOMS, type TimeZoom, type WeekOfMonth, type Weekday, addItem, canonicalTimeZone, categoryKind, cn, countEdited, dateOfDay, dayOf, deleteOccurrence, describeRecurrence, endDayOf, formatDateRange, moveItem, normaliseLayout, nthOf, occurrenceOn, occurrences, parseRRule, readRecurrence, recurrencePresets, removeItem, requestLocale, resizeItem, sameRecurrence, saveOccurrence, timeExtent, timeZoneOffset, toRRule };
|
package/dist/utils.js
CHANGED
|
@@ -668,9 +668,9 @@ function dayOf(value) {
|
|
|
668
668
|
return back.getUTCFullYear() === y && back.getUTCMonth() === mo && back.getUTCDate() === d ? day : NaN;
|
|
669
669
|
}
|
|
670
670
|
function dateOfDay(day) {
|
|
671
|
-
const
|
|
672
|
-
const u = new Date(
|
|
673
|
-
return new Date(u.getUTCFullYear(), u.getUTCMonth(), u.getUTCDate(), 0, 0, 0, Math.round((day -
|
|
671
|
+
const whole3 = Math.floor(day);
|
|
672
|
+
const u = new Date(whole3 * DAY_MS);
|
|
673
|
+
return new Date(u.getUTCFullYear(), u.getUTCMonth(), u.getUTCDate(), 0, 0, 0, Math.round((day - whole3) * DAY_MS));
|
|
674
674
|
}
|
|
675
675
|
function isWholeDay(value) {
|
|
676
676
|
return typeof value === "string" ? DATE_ONLY.test(value.trim()) : Number.isInteger(dayOf(value));
|
|
@@ -882,6 +882,57 @@ function categoryKind(labels, locale) {
|
|
|
882
882
|
return "scale";
|
|
883
883
|
}
|
|
884
884
|
|
|
885
|
-
|
|
885
|
+
// ../../showcase/src/lib/dashboard-layout.ts
|
|
886
|
+
var DASHBOARD_COLUMNS = 12;
|
|
887
|
+
var MIN_W = 3;
|
|
888
|
+
var DEFAULT_MIN_H = 2;
|
|
889
|
+
var DASHBOARD_MAX_ROWS = 100;
|
|
890
|
+
var clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
891
|
+
var whole2 = (value, fallback) => typeof value === "number" && Number.isFinite(value) ? Math.round(value) : fallback;
|
|
892
|
+
function sizeLimits(item) {
|
|
893
|
+
const minW = clamp(whole2(item.minW, MIN_W), MIN_W, DASHBOARD_COLUMNS);
|
|
894
|
+
const maxW = clamp(whole2(item.maxW, DASHBOARD_COLUMNS), minW, DASHBOARD_COLUMNS);
|
|
895
|
+
const minH = clamp(whole2(item.minH, DEFAULT_MIN_H), 1, DASHBOARD_MAX_ROWS);
|
|
896
|
+
const maxH = clamp(whole2(item.maxH, DASHBOARD_MAX_ROWS), minH, DASHBOARD_MAX_ROWS);
|
|
897
|
+
return { minW, maxW, minH, maxH };
|
|
898
|
+
}
|
|
899
|
+
function normaliseItem(item) {
|
|
900
|
+
const limits = sizeLimits(item);
|
|
901
|
+
const next = { ...item, w: clamp(whole2(item.w, limits.minW), limits.minW, limits.maxW), h: clamp(whole2(item.h, limits.minH), limits.minH, limits.maxH) };
|
|
902
|
+
for (const key of ["minW", "maxW", "minH", "maxH"]) if (item[key] !== void 0) next[key] = limits[key];
|
|
903
|
+
return next;
|
|
904
|
+
}
|
|
905
|
+
function normaliseLayout(layout) {
|
|
906
|
+
const seen = /* @__PURE__ */ new Set();
|
|
907
|
+
const out = [];
|
|
908
|
+
for (const item of Array.isArray(layout) ? layout : []) {
|
|
909
|
+
if (!item || typeof item.id !== "string" || item.id === "" || seen.has(item.id)) continue;
|
|
910
|
+
seen.add(item.id);
|
|
911
|
+
out.push(normaliseItem(item));
|
|
912
|
+
}
|
|
913
|
+
return out;
|
|
914
|
+
}
|
|
915
|
+
function moveItem(layout, id, toIndex) {
|
|
916
|
+
const items = normaliseLayout(layout);
|
|
917
|
+
const from = items.findIndex((item2) => item2.id === id);
|
|
918
|
+
if (from < 0) return items;
|
|
919
|
+
const [item] = items.splice(from, 1);
|
|
920
|
+
items.splice(clamp(whole2(toIndex, from), 0, items.length), 0, item);
|
|
921
|
+
return items;
|
|
922
|
+
}
|
|
923
|
+
function resizeItem(layout, id, size) {
|
|
924
|
+
return normaliseLayout(layout).map((item) => item.id === id ? normaliseItem({ ...item, ...size.w !== void 0 ? { w: size.w } : {}, ...size.h !== void 0 ? { h: size.h } : {} }) : item);
|
|
925
|
+
}
|
|
926
|
+
function addItem(layout, item, index) {
|
|
927
|
+
const items = normaliseLayout(layout);
|
|
928
|
+
if (!item || typeof item.id !== "string" || item.id === "" || items.some((it) => it.id === item.id)) return items;
|
|
929
|
+
items.splice(clamp(whole2(index, items.length), 0, items.length), 0, normaliseItem(item));
|
|
930
|
+
return items;
|
|
931
|
+
}
|
|
932
|
+
function removeItem(layout, id) {
|
|
933
|
+
return normaliseLayout(layout).filter((item) => item.id !== id);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
export { ACTIVE_RING, ERROR_ACTIVE_RING, ERROR_FOCUS_RING, ERROR_FOCUS_WITHIN_RING, ERROR_HAS_FOCUS_RING, FIELD_FOCUS_RING, FIELD_FOCUS_WITHIN_RING, FIELD_HAS_FOCUS_RING, FOCUS_INSET, FOCUS_RING, FOCUS_WITHIN_RING, GLASS_BACKDROP, GLASS_DROPDOWN, GLASS_OVERLAY, GLASS_SURFACE, GROUP_FOCUS_RING, HAS_FOCUS_RING, PEER_FOCUS_RING, TIME_ZOOMS, addItem, canonicalTimeZone, categoryKind, cn, countEdited, dateOfDay, dayOf, deleteOccurrence, describeRecurrence, endDayOf, formatDateRange, moveItem, normaliseLayout, nthOf, occurrenceOn, occurrences, parseRRule, readRecurrence, recurrencePresets, removeItem, requestLocale, resizeItem, sameRecurrence, saveOccurrence, timeExtent, timeZoneOffset, toRRule };
|
|
886
937
|
//# sourceMappingURL=utils.js.map
|
|
887
938
|
//# sourceMappingURL=utils.js.map
|