@adea-ai/ui 0.123.0 → 0.124.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/NOTICE +18 -0
- package/dist/components/layout/split-layout/resize-controller-core-retry.d.ts +13 -0
- package/dist/components/layout/split-layout/resize-controller-core-retry.d.ts.map +1 -0
- package/dist/components/layout/split-layout/resize-controller-core-retry.js +63 -0
- package/dist/components/layout/split-layout/resize-controller-core-retry.js.map +1 -0
- package/dist/components/layout/split-layout/resize-controller-core.d.ts +13 -0
- package/dist/components/layout/split-layout/resize-controller-core.d.ts.map +1 -0
- package/dist/components/layout/split-layout/resize-controller-core.js +63 -0
- package/dist/components/layout/split-layout/resize-controller-core.js.map +1 -0
- package/dist/components/layout/split-layout/resize-controller-retry-2.d.ts +3 -0
- package/dist/components/layout/split-layout/resize-controller-retry-2.d.ts.map +1 -0
- package/dist/components/layout/split-layout/resize-controller-retry-2.js +2 -0
- package/dist/components/layout/split-layout/resize-controller-retry.d.ts +2 -0
- package/dist/components/layout/split-layout/resize-controller-retry.d.ts.map +1 -0
- package/dist/components/layout/split-layout/resize-controller-retry.js +2 -0
- package/dist/components/layout/split-layout/resize-controller.d.ts +2 -0
- package/dist/components/layout/split-layout/resize-controller.d.ts.map +1 -0
- package/dist/components/layout/split-layout/resize-controller.js +2 -0
- package/dist/components/layout/split-layout/split-layout.d.ts.map +1 -1
- package/dist/components/layout/split-layout/split-layout.js +171 -60
- package/dist/components/layout/split-layout/split-layout.js.map +1 -1
- package/dist/components/theme/appearance-panel.js +1 -1
- package/dist/components/theme/index.d.ts +1 -1
- package/dist/components/theme/index.d.ts.map +1 -1
- package/dist/components/theme/index.js +5 -2
- package/dist/components/theme/theme-context.d.ts +13 -0
- package/dist/components/theme/theme-context.d.ts.map +1 -0
- package/dist/components/theme/theme-context.js +41 -0
- package/dist/components/theme/theme-context.js.map +1 -0
- package/dist/components/theme/theme-document.d.ts +76 -0
- package/dist/components/theme/theme-document.d.ts.map +1 -0
- package/dist/components/theme/theme-document.js +93 -0
- package/dist/components/theme/theme-document.js.map +1 -0
- package/dist/components/theme/theme-persistence.d.ts +50 -0
- package/dist/components/theme/theme-persistence.d.ts.map +1 -0
- package/dist/components/theme/theme-persistence.js +86 -0
- package/dist/components/theme/theme-persistence.js.map +1 -0
- package/dist/components/theme/theme-provider.d.ts +43 -75
- package/dist/components/theme/theme-provider.d.ts.map +1 -1
- package/dist/components/theme/theme-provider.js +50 -116
- package/dist/components/theme/theme-provider.js.map +1 -1
- package/dist/components/theme/theme-state.d.ts +142 -0
- package/dist/components/theme/theme-state.d.ts.map +1 -0
- package/dist/components/theme/theme-state.js +104 -0
- package/dist/components/theme/theme-state.js.map +1 -0
- package/dist/components/theme/theme-toggle.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/lib/appearance-font-settings.d.ts +1 -1
- package/dist/lib/appearance-font-settings.d.ts.map +1 -1
- package/dist/lib/appearance-font-settings.js.map +1 -1
- package/dist/lib/themes.d.ts +48 -0
- package/dist/lib/themes.d.ts.map +1 -1
- package/dist/lib/themes.js +150 -36
- package/dist/lib/themes.js.map +1 -1
- package/dist/r/registry.json +46 -0
- package/dist/r/split-layout.json +26 -0
- package/dist/r/src/components/layout/split-layout/resize-controller-core-retry.tsx +66 -0
- package/dist/r/src/components/layout/split-layout/resize-controller-core.tsx +66 -0
- package/dist/r/src/components/layout/split-layout/resize-controller-retry-2.tsx +2 -0
- package/dist/r/src/components/layout/split-layout/resize-controller-retry.tsx +1 -0
- package/dist/r/src/components/layout/split-layout/resize-controller.tsx +1 -0
- package/dist/r/src/components/layout/split-layout/split-layout.tsx +197 -49
- package/dist/r/src/components/theme/index.ts +3 -0
- package/dist/r/src/components/theme/theme-context.ts +43 -0
- package/dist/r/src/components/theme/theme-document.ts +168 -0
- package/dist/r/src/components/theme/theme-persistence.ts +140 -0
- package/dist/r/src/components/theme/theme-provider.tsx +126 -253
- package/dist/r/src/components/theme/theme-state.ts +225 -0
- package/dist/r/src/lib/appearance-font-settings.ts +1 -1
- package/dist/r/src/lib/themes.ts +181 -40
- package/dist/r/theming.json +20 -0
- package/package.json +1 -1
- package/registry.json +46 -0
- package/src/components/layout/split-layout/resize-controller-core-retry.tsx +66 -0
- package/src/components/layout/split-layout/resize-controller-core.tsx +66 -0
- package/src/components/layout/split-layout/resize-controller-retry-2.tsx +2 -0
- package/src/components/layout/split-layout/resize-controller-retry.tsx +1 -0
- package/src/components/layout/split-layout/resize-controller.tsx +1 -0
- package/src/components/layout/split-layout/split-layout.tsx +197 -49
- package/src/components/theme/index.ts +3 -0
- package/src/components/theme/theme-context.ts +43 -0
- package/src/components/theme/theme-document.ts +168 -0
- package/src/components/theme/theme-persistence.ts +140 -0
- package/src/components/theme/theme-provider.tsx +126 -253
- package/src/components/theme/theme-state.ts +225 -0
- package/src/index.ts +3 -0
- package/src/lib/appearance-font-settings.ts +1 -1
- package/src/lib/themes.ts +181 -40
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"split-layout.js","names":["Resizable","For","createMemo","createComputed","createUniqueId","createSignal","onCleanup","on","Accessor","JSX","X","GripVertical","ActionButton","cn","computeLayoutFrames","LayoutRect","paneDropIntent","PaneDropIntent","PANE_DRAG_TYPE","DRAG_PREVIEW_MAX_WIDTH","DRAG_PREVIEW_MAX_HEIGHT","listLeaves","MIN_SPLIT_RATIO","MAX_SPLIT_RATIO","SplitLayoutBranch","SplitLayoutLeaf","SplitLayoutState","SplitLayoutProps","state","L","label","labelForLeaf","leaf","renderLeaf","Element","renderPaneLabel","paneTabIndex","labelForSeparator","branch","onResize","splitId","ratio","onFocus","leafId","onClose","onMove","targetId","intent","renderPaneActions","class","rectStyle","rect","CSSProperties","left","x","top","y","width","height","dragPreviewPlaceholder","source","HTMLElement","message","placeholder","document","createElement","className","getAttribute","setAttribute","localName","textContent","boundedSnapshotSize","sourceWidth","Math","max","sourceHeight","scale","min","round","cloneDragPreviewNode","Node","nodeType","TEXT_NODE","cloneNode","SVGElement","includes","undefined","HTMLImageElement","snapshot","size","naturalWidth","naturalHeight","complete","Error","context","getContext","drawImage","children","createDocumentFragment","child","childNodes","clone","append","length","attribute","removeAttribute","Array","from","attributes","test","name","HTMLCanvasElement","childClone","SplitLayout","props","root","HTMLDivElement","pendingFrame","refs","Map","domIds","prefix","nextDomId","nextDragId","dragPreview","drag","setDrag","id","token","drop","setDrop","clearDrag","remove","createDragPreview","preview","inert","body","domId","existing","get","created","set","leaves","center","leafMap","map","frames","branches","values","flatMap","frame","node","kind","current","has","target","allowedTarget","transfer","DataTransfer","types","dropLabel","placement","branchMap","schedule","action","cancelAnimationFrame","requestAnimationFrame","active","ownerDocument","activeElement","contains","field","HTMLTextAreaElement","HTMLInputElement","selection","start","selectionStart","end","selectionEnd","direction","selectionDirection","isConnected","focus","preventScroll","setSelectionRange","clear","close","next","_el$","_tmpl$","_el$2","firstChild","_$use","el","_$insert","_$createComponent","each","initial","content","paneLabel","actions","delete","_el$3","_tmpl$2","_el$4","_el$5","_el$6","_el$7","nextSibling","$$focusin","addEventListener","event","dataTransfer","clientX","clientY","currentTarget","getBoundingClientRect","accepted","getData","preventDefault","relatedTarget","dropEffect","_$setAttribute","setData","effectAllowed","setDragImage","previewFrame","scaleX","scaleY","_c$","_$memo","_c$2","variant","aria-label","tooltip","onClick","_c$3","_el$8","_tmpl$3","_$effect","_$className","_p$","_v$4","_v$5","_v$6","_v$7","focusedLeafId","_v$8","_v$9","_v$0","_v$1","_v$10","Boolean","_v$11","_v$12","e","t","a","o","i","n","s","h","_$style","r","d","l","orientation","sizes","keyboardDelta","onSizesChange","getClientRects","some","Number","isFinite","abs","style","Panel","minSize","maxSize","Handle","aria-orientation","aria-controls","join","aria-valuenow","_v$","_v$2","_v$3","_$delegateEvents","_$createComponent","_$memo","_$className","_$setAttribute","_$style","_$delegateEvents"],"sources":["../../../../src/components/layout/split-layout/split-layout.tsx"],"sourcesContent":["import Resizable from '@corvu/resizable'\nimport {\n For,\n createMemo,\n createComputed,\n createUniqueId,\n createSignal,\n onCleanup,\n on,\n type Accessor,\n type JSX,\n} from 'solid-js'\nimport { X, GripVertical } from 'lucide-solid'\nimport { ActionButton } from '../../composites/action-button'\nimport { cn } from '#lib/utils'\nimport { computeLayoutFrames, type LayoutRect } from './geometry'\nimport { paneDropIntent, type PaneDropIntent } from './drop'\nexport type { PaneDropIntent } from './drop'\nconst PANE_DRAG_TYPE = 'application/x-adea-pane-move'\nconst DRAG_PREVIEW_MAX_WIDTH = 384\nconst DRAG_PREVIEW_MAX_HEIGHT = 256\nimport {\n listLeaves,\n MIN_SPLIT_RATIO,\n MAX_SPLIT_RATIO,\n type SplitLayoutBranch,\n type SplitLayoutLeaf,\n type SplitLayoutState,\n} from './model'\n\nexport type SplitLayoutProps<L extends SplitLayoutLeaf> = {\n state: SplitLayoutState<L>\n label: string\n /** Accessible name for a pane region and its close button. */\n labelForLeaf: (leaf: L) => string\n /** Called once per stable leaf owner; the accessor tracks opaque payload replacement. */\n renderLeaf: (leaf: Accessor<L>) => JSX.Element\n /** Inline visible header composition, separate from the region and close-button name. */\n renderPaneLabel?: (leaf: Accessor<L>) => JSX.Element\n /** Whether pane regions participate in sequential keyboard navigation; defaults to programmatic focus only. */\n paneTabIndex?: 0 | -1\n /** Accessible splitter name; defaults to the current orientation-specific label. */\n labelForSeparator?: (branch: SplitLayoutBranch<L>) => string\n onResize: (splitId: string, ratio: number) => void\n onFocus?: (leafId: string) => void\n /** Host performs the model transition and returns the surviving focus destination. */\n onClose?: (leafId: string) => string | undefined\n /** Pointer placement only; the host supplies keyboard commands and performs the model transition. */\n onMove?: (leafId: string, targetId: string, intent: PaneDropIntent) => void\n /** Stable header composition for host-owned keyboard actions/capability feedback. */\n renderPaneActions?: (leaf: Accessor<L>) => JSX.Element\n class?: string\n}\nfunction rectStyle(rect: LayoutRect): JSX.CSSProperties {\n return {\n left: `${rect.x * 100}%`,\n top: `${rect.y * 100}%`,\n width: `${rect.width * 100}%`,\n height: `${rect.height * 100}%`,\n }\n}\nfunction dragPreviewPlaceholder(source: HTMLElement, message: string) {\n const placeholder = document.createElement('div')\n placeholder.className = cn(\n source.getAttribute('class'),\n 'flex min-h-8 min-w-0 items-center justify-center bg-muted px-2 text-center text-xs text-muted-foreground'\n )\n placeholder.setAttribute('data-split-drag-placeholder', source.localName)\n placeholder.textContent = message\n return placeholder\n}\nfunction boundedSnapshotSize(width: number, height: number) {\n const sourceWidth = Math.max(1, width)\n const sourceHeight = Math.max(1, height)\n const scale = Math.min(\n 1,\n DRAG_PREVIEW_MAX_WIDTH / sourceWidth,\n DRAG_PREVIEW_MAX_HEIGHT / sourceHeight\n )\n return {\n width: Math.max(1, Math.round(sourceWidth * scale)),\n height: Math.max(1, Math.round(sourceHeight * scale)),\n }\n}\nfunction cloneDragPreviewNode(source: Node): Node | undefined {\n if (source.nodeType === Node.TEXT_NODE) return source.cloneNode(false)\n if (!(source instanceof HTMLElement || source instanceof SVGElement))\n return source.cloneNode(false)\n\n if (['script', 'style', 'link', 'source', 'track', 'meta'].includes(source.localName))\n return undefined\n if (['iframe', 'video', 'audio', 'object', 'embed'].includes(source.localName))\n return dragPreviewPlaceholder(\n source as HTMLElement,\n 'Embedded content unavailable while moving'\n )\n if (source instanceof HTMLImageElement) {\n const snapshot = document.createElement('canvas')\n const size = boundedSnapshotSize(\n source.naturalWidth || source.width,\n source.naturalHeight || source.height\n )\n snapshot.width = size.width\n snapshot.height = size.height\n snapshot.className = source.getAttribute('class') ?? ''\n snapshot.setAttribute('data-split-drag-image', '')\n try {\n if (!source.complete || source.naturalWidth === 0)\n throw new Error('image has no decoded pixels')\n const context = snapshot.getContext('2d')\n if (!context) throw new Error('canvas snapshot context is unavailable')\n context.drawImage(source, 0, 0, snapshot.width, snapshot.height)\n return snapshot\n } catch {\n return dragPreviewPlaceholder(source, 'Image preview unavailable')\n }\n }\n\n // Copying a defined custom element can run its constructor; inserting it can\n // also reconnect a stream or terminal session. Flatten its display tree.\n if (source instanceof HTMLElement && source.localName.includes('-')) {\n const children = document.createDocumentFragment()\n for (const child of source.childNodes) {\n const clone = cloneDragPreviewNode(child)\n if (clone) children.append(clone)\n }\n return children.childNodes.length > 0\n ? children\n : dragPreviewPlaceholder(source, 'Live component preview unavailable while moving')\n }\n\n const clone = source.cloneNode(false) as HTMLElement | SVGElement\n for (const attribute of [\n 'id',\n 'style',\n 'draggable',\n 'data-pane-drag-handle',\n 'data-pane-id',\n 'src',\n 'srcset',\n 'href',\n 'xlink:href',\n 'data',\n 'poster',\n ])\n clone.removeAttribute(attribute)\n for (const attribute of Array.from(clone.attributes))\n if (/^on/i.test(attribute.name)) clone.removeAttribute(attribute.name)\n\n if (source instanceof HTMLCanvasElement && clone instanceof HTMLCanvasElement) {\n const size = boundedSnapshotSize(source.width, source.height)\n clone.width = size.width\n clone.height = size.height\n try {\n const context = clone.getContext('2d')\n if (!context) throw new Error('canvas snapshot context is unavailable')\n context.drawImage(source, 0, 0, clone.width, clone.height)\n } catch {\n return dragPreviewPlaceholder(source, 'Canvas preview unavailable while moving')\n }\n return clone\n }\n\n for (const child of source.childNodes) {\n const childClone = cloneDragPreviewNode(child)\n if (childClone) clone.append(childClone)\n }\n return clone\n}\n/** Muxy frame geometry keeps leaf owners stable; Corvu owns constrained separator interactions. */\nexport function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L>) {\n let root: HTMLDivElement | undefined\n let pendingFrame: number | undefined\n const refs = new Map<string, HTMLElement>()\n const domIds = new Map<string, string>()\n const prefix = createUniqueId()\n let nextDomId = 0\n let nextDragId = 0\n let dragPreview: HTMLElement | undefined\n const [drag, setDrag] = createSignal<{ id: string; token: string }>()\n const [drop, setDrop] = createSignal<{ id: string; intent: PaneDropIntent }>()\n const clearDrag = () => {\n setDrag(undefined)\n setDrop(undefined)\n dragPreview?.remove()\n dragPreview = undefined\n }\n const createDragPreview = (source: HTMLElement) => {\n dragPreview?.remove()\n const preview = cloneDragPreviewNode(source) as HTMLElement\n preview.className =\n 'pointer-events-none fixed -left-full top-0 z-(--z-dialog) flex h-64 max-h-screen w-96 max-w-screen min-h-0 min-w-0 flex-col overflow-hidden rounded-lg border border-border bg-card text-card-foreground shadow-xl'\n preview.removeAttribute('id')\n preview.removeAttribute('style')\n preview.removeAttribute('role')\n preview.removeAttribute('aria-label')\n preview.removeAttribute('data-pane-id')\n preview.removeAttribute('data-focused')\n preview.removeAttribute('data-drag-source')\n preview.removeAttribute('data-drop-direction')\n preview.removeAttribute('data-drop-placement')\n preview.setAttribute('data-split-drag-preview', '')\n preview.setAttribute('aria-hidden', 'true')\n preview.inert = true\n document.body.append(preview)\n dragPreview = preview\n return preview\n }\n const domId = (id: string) => {\n const existing = domIds.get(id)\n if (existing) return existing\n const created = `${prefix}-pane-${nextDomId++}`\n domIds.set(id, created)\n return created\n }\n const leaves = createMemo(() => listLeaves(props.state.center))\n const leafMap = createMemo(() => new Map(leaves().map((leaf) => [leaf.id, leaf])))\n const frames = createMemo(() => computeLayoutFrames(props.state.center))\n const branches = createMemo(() =>\n Array.from(frames().values()).flatMap((frame) =>\n frame.node.kind === 'split' ? [frame.node] : []\n )\n )\n createComputed(() => {\n const current = drag()\n if (current && (!props.onMove || !leafMap().has(current.id))) clearDrag()\n const target = drop()\n if (target && !leafMap().has(target.id)) setDrop(undefined)\n })\n const allowedTarget = (id: string, transfer: DataTransfer | null) => {\n const current = drag()\n return props.onMove &&\n current &&\n current.id !== id &&\n leafMap().has(current.id) &&\n leafMap().has(id) &&\n transfer?.types.includes(PANE_DRAG_TYPE)\n ? current\n : undefined\n }\n const dropLabel = createMemo(() => {\n const target = drop()\n const leaf = target ? leafMap().get(target.id) : undefined\n return target && leaf\n ? `Drop to place pane ${target.intent.placement} ${props.labelForLeaf(leaf)}`\n : ''\n })\n const branchMap = createMemo(() => new Map(branches().map((branch) => [branch.id, branch])))\n const schedule = (action: () => void) => {\n if (pendingFrame !== undefined) cancelAnimationFrame(pendingFrame)\n pendingFrame = requestAnimationFrame(() => {\n pendingFrame = undefined\n action()\n })\n }\n // Register before keyed children update: capture a focused editor before an\n // ordered DOM move can blur it. Never override a newer focus outside this root.\n createComputed(\n on(\n () => props.state.center,\n () => {\n const active = root?.ownerDocument.activeElement\n if (!root || !(active instanceof HTMLElement) || !root.contains(active)) return\n const field =\n active instanceof HTMLTextAreaElement || active instanceof HTMLInputElement\n ? active\n : undefined\n const selection = field\n ? {\n start: field.selectionStart,\n end: field.selectionEnd,\n direction: field.selectionDirection,\n }\n : undefined\n schedule(() => {\n if (!active.isConnected || !root?.contains(active)) return\n const current = active.ownerDocument.activeElement\n if (current !== active && current !== active.ownerDocument.body) return\n active.focus({ preventScroll: true })\n if (field && selection?.start !== null && selection?.end !== null && selection)\n field.setSelectionRange(\n selection.start,\n selection.end,\n selection.direction ?? undefined\n )\n })\n }\n )\n )\n onCleanup(() => {\n if (pendingFrame !== undefined) cancelAnimationFrame(pendingFrame)\n clearDrag()\n refs.clear()\n domIds.clear()\n })\n const close = (id: string) => {\n const next = props.onClose?.(id)\n if (next) schedule(() => refs.get(next)?.focus({ preventScroll: true }))\n }\n return (\n <div\n ref={(el) => {\n root = el\n }}\n role=\"group\"\n aria-label={props.label}\n data-slot=\"split-layout\"\n data-dragging={drag() ? '' : undefined}\n class={cn('relative size-full min-h-0 min-w-0 data-[dragging]:cursor-grabbing', props.class)}\n >\n <For each={leaves().map((leaf) => leaf.id)}>\n {(id) => {\n const initial = leafMap().get(id)!\n const leaf = () => leafMap().get(id) ?? initial\n const content = props.renderLeaf(leaf)\n const paneLabel = props.renderPaneLabel?.(leaf)\n const actions = props.renderPaneActions?.(leaf)\n const intent = () => (drop()?.id === id ? drop()?.intent : undefined)\n onCleanup(() => {\n refs.delete(id)\n domIds.delete(id)\n })\n return (\n <section\n ref={(el) => refs.set(id, el)}\n id={domId(id)}\n role=\"region\"\n aria-label={props.labelForLeaf(leaf())}\n tabIndex={props.paneTabIndex ?? -1}\n data-pane-id={id}\n data-focused={props.state.focusedLeafId === id ? '' : undefined}\n data-drag-source={drag()?.id === id ? '' : undefined}\n data-drop-direction={intent()?.direction}\n data-drop-placement={intent()?.placement}\n onDragOver={(event) => {\n if (!allowedTarget(id, event.dataTransfer)) return\n const next = paneDropIntent(\n event.clientX,\n event.clientY,\n event.currentTarget.getBoundingClientRect()\n )\n if (!next) {\n setDrop(undefined)\n return\n }\n event.preventDefault()\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'\n setDrop({ id, intent: next })\n }}\n onDragLeave={(event) => {\n if (\n event.relatedTarget instanceof Node &&\n event.currentTarget.contains(event.relatedTarget)\n )\n return\n if (drop()?.id === id) setDrop(undefined)\n }}\n onDrop={(event) => {\n const current = allowedTarget(id, event.dataTransfer)\n const next = paneDropIntent(\n event.clientX,\n event.clientY,\n event.currentTarget.getBoundingClientRect()\n )\n const accepted =\n current && next && event.dataTransfer?.getData(PANE_DRAG_TYPE) === current.token\n clearDrag()\n if (!accepted) return\n event.preventDefault()\n props.onMove?.(current.id, id, next)\n }}\n style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}\n class=\"absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border transition-opacity motion-reduce:transition-none data-[drag-source]:opacity-40 data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring\"\n onFocusIn={() => props.onFocus?.(id)}\n >\n <header class=\"flex min-w-0 shrink-0 items-center gap-2 bg-surface px-2\">\n <span\n data-pane-drag-handle=\"\"\n draggable={Boolean(props.onMove)}\n class={cn('flex min-w-0 flex-1 items-center gap-2 truncate text-sm', {\n 'cursor-grab': Boolean(props.onMove),\n 'cursor-grabbing': drag()?.id === id,\n })}\n title={props.onMove ? `Drag ${props.labelForLeaf(leaf())} to move` : undefined}\n onDragStart={(event) => {\n if (!props.onMove || !event.dataTransfer) {\n event.preventDefault()\n return\n }\n const token = `${prefix}-${++nextDragId}`\n setDrag({ id, token })\n event.dataTransfer.setData(PANE_DRAG_TYPE, token)\n event.dataTransfer.effectAllowed = 'move'\n // The native drag image carries this pane's actual content\n // in a bounded floating-window frame; the source recedes\n // independently as the browser follows the image pointer.\n const source = refs.get(id)\n const frame = source?.getBoundingClientRect()\n if (source && frame && typeof event.dataTransfer.setDragImage === 'function') {\n const preview = createDragPreview(source)\n const previewFrame = preview.getBoundingClientRect()\n const scaleX = previewFrame.width / frame.width\n const scaleY = previewFrame.height / frame.height\n event.dataTransfer.setDragImage(\n preview,\n Math.max(0, Math.round((event.clientX - frame.left) * scaleX)),\n Math.max(0, Math.round((event.clientY - frame.top) * scaleY))\n )\n preview.setAttribute('data-native-drag-image', '')\n }\n }}\n onDragEnd={clearDrag}\n >\n {props.onMove ? (\n <GripVertical class=\"size-3 shrink-0\" aria-hidden=\"true\" />\n ) : null}\n <span class=\"min-w-0 flex-1 truncate\">\n {paneLabel ?? props.labelForLeaf(leaf())}\n </span>\n </span>\n {actions}\n {props.onClose ? (\n <ActionButton\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={`Close ${props.labelForLeaf(leaf())}`}\n tooltip={`Close ${props.labelForLeaf(leaf())}.`}\n onClick={() => close(id)}\n >\n <X />\n </ActionButton>\n ) : null}\n </header>\n <div class=\"min-h-0 min-w-0 flex-1 overflow-auto\">{content}</div>\n {intent() ? (\n <div\n aria-hidden=\"true\"\n class={cn('pointer-events-none absolute border-2 border-primary bg-primary/10', {\n 'inset-y-0 left-0 w-1/2':\n intent()?.direction === 'row' && intent()?.placement === 'before',\n 'inset-y-0 right-0 w-1/2':\n intent()?.direction === 'row' && intent()?.placement === 'after',\n 'inset-x-0 top-0 h-1/2':\n intent()?.direction === 'column' && intent()?.placement === 'before',\n 'inset-x-0 bottom-0 h-1/2':\n intent()?.direction === 'column' && intent()?.placement === 'after',\n })}\n />\n ) : null}\n </section>\n )\n }}\n </For>\n <span class=\"sr-only\" role=\"status\">\n {dropLabel()}\n </span>\n <For each={branches().map((branch) => branch.id)}>\n {(id) => {\n const initial = branchMap().get(id)!\n const branch: Accessor<SplitLayoutBranch<L>> = () => branchMap().get(id) ?? initial\n return (\n <Resizable\n orientation={branch().direction === 'row' ? 'horizontal' : 'vertical'}\n sizes={[branch().ratio, 1 - branch().ratio]}\n keyboardDelta={0.05}\n onSizesChange={(sizes) => {\n // Corvu also reports panel registration/unregistration while\n // mounting or disposing a controller. Those incomplete or\n // hidden-host sizes are not user resize intent.\n if (!root?.isConnected || root.getClientRects().length === 0) return\n if (\n sizes.length !== 2 ||\n sizes.some((size) => !Number.isFinite(size)) ||\n Math.abs(sizes[0]! + sizes[1]! - 1) > 0.000001\n )\n return\n if (sizes[0] !== undefined && Math.abs(sizes[0] - branch().ratio) > 0.000001)\n props.onResize(id, sizes[0])\n }}\n style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}\n class=\"pointer-events-none absolute flex min-h-0 min-w-0 data-[orientation=vertical]:flex-col\"\n >\n <Resizable.Panel\n minSize={MIN_SPLIT_RATIO}\n maxSize={MAX_SPLIT_RATIO}\n aria-hidden=\"true\"\n />\n <Resizable.Handle\n aria-label={\n props.labelForSeparator?.(branch()) ??\n (branch().direction === 'row' ? 'Resize pane columns' : 'Resize pane rows')\n }\n aria-orientation={branch().direction === 'row' ? 'vertical' : 'horizontal'}\n aria-controls={listLeaves(branch())\n .map((leaf) => domId(leaf.id))\n .join(' ')}\n aria-valuemin={10}\n aria-valuemax={90}\n aria-valuenow={Math.round(branch().ratio * 100)}\n class=\"pointer-events-auto relative w-px shrink-0 bg-border after:absolute after:inset-y-0 after:-inset-x-1 after:w-3 focus-visible:bg-primary focus-visible:outline-none hover:bg-primary data-[orientation=vertical]:h-px data-[orientation=vertical]:w-full data-[orientation=vertical]:after:inset-x-0 data-[orientation=vertical]:after:-inset-y-1 data-[orientation=vertical]:after:h-3 data-[orientation=vertical]:after:w-full\"\n />\n <Resizable.Panel\n minSize={MIN_SPLIT_RATIO}\n maxSize={MAX_SPLIT_RATIO}\n aria-hidden=\"true\"\n />\n </Resizable>\n )\n }}\n </For>\n </div>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"split-layout.js","names":["For","createEffect","createComputed","createMemo","createUniqueId","createSignal","onMount","onCleanup","on","Show","Accessor","JSX","Dynamic","X","GripVertical","ActionButton","Button","cn","computeLayoutFrames","LayoutRect","paneDropIntent","PaneDropIntent","PANE_DRAG_TYPE","DRAG_PREVIEW_MAX_WIDTH","DRAG_PREVIEW_MAX_HEIGHT","listLeaves","SplitLayoutBranch","SplitLayoutLeaf","SplitLayoutState","SplitLayoutResizeControllerProps","ResizeController","props","L","Element","ResizeControllerState","SplitLayoutProps","state","label","labelForLeaf","leaf","renderLeaf","renderPaneLabel","paneTabIndex","labelForSeparator","branch","onResize","splitId","ratio","onFocus","leafId","onClose","onMove","targetId","intent","renderPaneActions","class","rectStyle","rect","CSSProperties","left","x","top","y","width","height","separatorPlaceholderStyle","horizontal","direction","transform","dragPreviewPlaceholder","source","HTMLElement","message","placeholder","document","createElement","className","getAttribute","setAttribute","localName","textContent","boundedSnapshotSize","sourceWidth","Math","max","sourceHeight","scale","min","round","cloneDragPreviewNode","Node","nodeType","TEXT_NODE","cloneNode","SVGElement","includes","undefined","HTMLImageElement","snapshot","size","naturalWidth","naturalHeight","complete","Error","context","getContext","drawImage","children","createDocumentFragment","child","childNodes","clone","append","length","attribute","removeAttribute","Array","from","attributes","test","name","HTMLCanvasElement","childClone","SplitLayout","root","HTMLDivElement","pendingFrame","disposed","resizeLoadGeneration","retryWithAlternateImport","alternateImportAttempts","focusHandleAfterRetry","focusRecoveryButtonAfterError","focusRestoreEpoch","focusEpoch","pendingFocusFrame","refs","Map","domIds","prefix","resizeReloadWarningId","nextDomId","nextDragId","dragPreview","drag","setDrag","id","token","drop","setDrop","resizeController","setResizeController","cancelPendingFocusRestore","cancelAnimationFrame","trackFocusChange","event","FocusEvent","target","body","addEventListener","removeEventListener","clearDrag","remove","createDragPreview","preview","inert","domId","existing","get","created","set","leaves","center","leafMap","map","frames","branches","values","flatMap","frame","node","kind","retry","generation","controllerImport","then","default","Controller","shouldFocusHandle","requestAnimationFrame","currentFocus","ownerDocument","activeElement","querySelector","focus","preventScroll","shouldFocusRetry","HTMLButtonElement","current","has","allowedTarget","transfer","DataTransfer","types","dropLabel","placement","branchMap","schedule","action","active","contains","field","HTMLTextAreaElement","HTMLInputElement","selection","start","selectionStart","end","selectionEnd","selectionDirection","isConnected","setSelectionRange","clear","close","next","_el$","_tmpl$","_el$2","firstChild","_$use","el","_$insert","_$createComponent","each","initial","content","paneLabel","actions","delete","_el$3","_tmpl$2","_el$4","_el$5","_el$6","_el$7","nextSibling","$$focusin","dataTransfer","clientX","clientY","currentTarget","getBoundingClientRect","accepted","getData","preventDefault","relatedTarget","dropEffect","_$setAttribute","setData","effectAllowed","setDragImage","previewFrame","scaleX","scaleY","_c$2","_$memo","_c$3","variant","aria-label","tooltip","onClick","_c$4","_el$8","_tmpl$3","_$effect","_$className","_p$","_v$4","_v$5","_v$6","_v$7","focusedLeafId","_v$8","_v$9","_v$0","_v$1","_v$10","Boolean","_v$11","_v$12","e","t","a","o","i","n","s","h","_$style","r","d","l","when","fallback","_el$9","_tmpl$4","_v$13","_v$14","_v$15","join","_v$16","_v$17","_v$18","component","_c$","_el$0","_tmpl$5","_el$1","_tmpl$6","window","location","reload","ownsFocus","_v$","_v$2","_v$3","_$delegateEvents","_$createComponent","_$memo","_$className","_$setAttribute","_$style","_$delegateEvents"],"sources":["../../../../src/components/layout/split-layout/split-layout.tsx"],"sourcesContent":["import {\n For,\n createEffect,\n createComputed,\n createMemo,\n createUniqueId,\n createSignal,\n onMount,\n onCleanup,\n on,\n Show,\n type Accessor,\n type JSX,\n} from 'solid-js'\nimport { Dynamic } from 'solid-js/web'\nimport { X, GripVertical } from 'lucide-solid'\nimport { ActionButton } from '../../composites/action-button'\nimport { Button } from '../../ui/button'\nimport { cn } from '#lib/utils'\nimport { computeLayoutFrames, type LayoutRect } from './geometry'\nimport { paneDropIntent, type PaneDropIntent } from './drop'\nexport type { PaneDropIntent } from './drop'\nconst PANE_DRAG_TYPE = 'application/x-adea-pane-move'\nconst DRAG_PREVIEW_MAX_WIDTH = 384\nconst DRAG_PREVIEW_MAX_HEIGHT = 256\nimport {\n listLeaves,\n type SplitLayoutBranch,\n type SplitLayoutLeaf,\n type SplitLayoutState,\n} from './model'\nimport type { SplitLayoutResizeControllerProps } from './resize-controller-core'\n\ntype ResizeController<L extends SplitLayoutLeaf> = (\n props: SplitLayoutResizeControllerProps<L>\n) => JSX.Element\ntype ResizeControllerState<L extends SplitLayoutLeaf> = ResizeController<L> | false | 'error'\n\nexport type SplitLayoutProps<L extends SplitLayoutLeaf> = {\n state: SplitLayoutState<L>\n label: string\n /** Accessible name for a pane region and its close button. */\n labelForLeaf: (leaf: L) => string\n /** Called once per stable leaf owner; the accessor tracks opaque payload replacement. */\n renderLeaf: (leaf: Accessor<L>) => JSX.Element\n /** Inline visible header composition, separate from the region and close-button name. */\n renderPaneLabel?: (leaf: Accessor<L>) => JSX.Element\n /** Whether pane regions participate in sequential keyboard navigation; defaults to programmatic focus only. */\n paneTabIndex?: 0 | -1\n /** Accessible splitter name; defaults to the current orientation-specific label. */\n labelForSeparator?: (branch: SplitLayoutBranch<L>) => string\n onResize: (splitId: string, ratio: number) => void\n onFocus?: (leafId: string) => void\n /** Host performs the model transition and returns the surviving focus destination. */\n onClose?: (leafId: string) => string | undefined\n /** Pointer placement only; the host supplies keyboard commands and performs the model transition. */\n onMove?: (leafId: string, targetId: string, intent: PaneDropIntent) => void\n /** Stable header composition for host-owned keyboard actions/capability feedback. */\n renderPaneActions?: (leaf: Accessor<L>) => JSX.Element\n class?: string\n}\nfunction rectStyle(rect: LayoutRect): JSX.CSSProperties {\n return {\n left: `${rect.x * 100}%`,\n top: `${rect.y * 100}%`,\n width: `${rect.width * 100}%`,\n height: `${rect.height * 100}%`,\n }\n}\nfunction separatorPlaceholderStyle(branch: SplitLayoutBranch, rect: LayoutRect): JSX.CSSProperties {\n const horizontal = branch.direction === 'row'\n return {\n left: `${(rect.x + (horizontal ? rect.width * branch.ratio : 0)) * 100}%`,\n top: `${(rect.y + (horizontal ? 0 : rect.height * branch.ratio)) * 100}%`,\n width: horizontal ? '1px' : `${rect.width * 100}%`,\n height: horizontal ? `${rect.height * 100}%` : '1px',\n transform: horizontal ? 'translateX(-50%)' : 'translateY(-50%)',\n }\n}\nfunction dragPreviewPlaceholder(source: HTMLElement, message: string) {\n const placeholder = document.createElement('div')\n placeholder.className = cn(\n source.getAttribute('class'),\n 'flex min-h-8 min-w-0 items-center justify-center bg-muted px-2 text-center text-xs text-muted-foreground'\n )\n placeholder.setAttribute('data-split-drag-placeholder', source.localName)\n placeholder.textContent = message\n return placeholder\n}\nfunction boundedSnapshotSize(width: number, height: number) {\n const sourceWidth = Math.max(1, width)\n const sourceHeight = Math.max(1, height)\n const scale = Math.min(\n 1,\n DRAG_PREVIEW_MAX_WIDTH / sourceWidth,\n DRAG_PREVIEW_MAX_HEIGHT / sourceHeight\n )\n return {\n width: Math.max(1, Math.round(sourceWidth * scale)),\n height: Math.max(1, Math.round(sourceHeight * scale)),\n }\n}\nfunction cloneDragPreviewNode(source: Node): Node | undefined {\n if (source.nodeType === Node.TEXT_NODE) return source.cloneNode(false)\n if (!(source instanceof HTMLElement || source instanceof SVGElement))\n return source.cloneNode(false)\n\n if (['script', 'style', 'link', 'source', 'track', 'meta'].includes(source.localName))\n return undefined\n if (['iframe', 'video', 'audio', 'object', 'embed'].includes(source.localName))\n return dragPreviewPlaceholder(\n source as HTMLElement,\n 'Embedded content unavailable while moving'\n )\n if (source instanceof HTMLImageElement) {\n const snapshot = document.createElement('canvas')\n const size = boundedSnapshotSize(\n source.naturalWidth || source.width,\n source.naturalHeight || source.height\n )\n snapshot.width = size.width\n snapshot.height = size.height\n snapshot.className = source.getAttribute('class') ?? ''\n snapshot.setAttribute('data-split-drag-image', '')\n try {\n if (!source.complete || source.naturalWidth === 0)\n throw new Error('image has no decoded pixels')\n const context = snapshot.getContext('2d')\n if (!context) throw new Error('canvas snapshot context is unavailable')\n context.drawImage(source, 0, 0, snapshot.width, snapshot.height)\n return snapshot\n } catch {\n return dragPreviewPlaceholder(source, 'Image preview unavailable')\n }\n }\n\n // Copying a defined custom element can run its constructor; inserting it can\n // also reconnect a stream or terminal session. Flatten its display tree.\n if (source instanceof HTMLElement && source.localName.includes('-')) {\n const children = document.createDocumentFragment()\n for (const child of source.childNodes) {\n const clone = cloneDragPreviewNode(child)\n if (clone) children.append(clone)\n }\n return children.childNodes.length > 0\n ? children\n : dragPreviewPlaceholder(source, 'Live component preview unavailable while moving')\n }\n\n const clone = source.cloneNode(false) as HTMLElement | SVGElement\n for (const attribute of [\n 'id',\n 'style',\n 'draggable',\n 'data-pane-drag-handle',\n 'data-pane-id',\n 'src',\n 'srcset',\n 'href',\n 'xlink:href',\n 'data',\n 'poster',\n ])\n clone.removeAttribute(attribute)\n for (const attribute of Array.from(clone.attributes))\n if (/^on/i.test(attribute.name)) clone.removeAttribute(attribute.name)\n\n if (source instanceof HTMLCanvasElement && clone instanceof HTMLCanvasElement) {\n const size = boundedSnapshotSize(source.width, source.height)\n clone.width = size.width\n clone.height = size.height\n try {\n const context = clone.getContext('2d')\n if (!context) throw new Error('canvas snapshot context is unavailable')\n context.drawImage(source, 0, 0, clone.width, clone.height)\n } catch {\n return dragPreviewPlaceholder(source, 'Canvas preview unavailable while moving')\n }\n return clone\n }\n\n for (const child of source.childNodes) {\n const childClone = cloneDragPreviewNode(child)\n if (childClone) clone.append(childClone)\n }\n return clone\n}\n/** Muxy frame geometry keeps leaf owners stable; Corvu owns constrained separator interactions. */\nexport function SplitLayout<L extends SplitLayoutLeaf>(props: SplitLayoutProps<L>) {\n let root: HTMLDivElement | undefined\n let pendingFrame: number | undefined\n let disposed = false\n let resizeLoadGeneration = 0\n let retryWithAlternateImport = false\n let alternateImportAttempts = 0\n let focusHandleAfterRetry = false\n let focusRecoveryButtonAfterError = false\n let focusRestoreEpoch = 0\n let focusEpoch = 0\n let pendingFocusFrame: number | undefined\n const refs = new Map<string, HTMLElement>()\n const domIds = new Map<string, string>()\n const prefix = createUniqueId()\n const resizeReloadWarningId = `${prefix}-resize-reload-warning`\n let nextDomId = 0\n let nextDragId = 0\n let dragPreview: HTMLElement | undefined\n const [drag, setDrag] = createSignal<{ id: string; token: string }>()\n const [drop, setDrop] = createSignal<{ id: string; intent: PaneDropIntent }>()\n const [resizeController, setResizeController] = createSignal<ResizeControllerState<L>>()\n const cancelPendingFocusRestore = () => {\n if (pendingFocusFrame !== undefined) cancelAnimationFrame(pendingFocusFrame)\n pendingFocusFrame = undefined\n }\n const trackFocusChange = (event: FocusEvent) => {\n if (event.target === document.body) return\n focusEpoch += 1\n focusHandleAfterRetry = false\n focusRecoveryButtonAfterError = false\n cancelPendingFocusRestore()\n }\n onMount(() => {\n document.addEventListener('focusin', trackFocusChange)\n onCleanup(() => document.removeEventListener('focusin', trackFocusChange))\n })\n const clearDrag = () => {\n setDrag(undefined)\n setDrop(undefined)\n dragPreview?.remove()\n dragPreview = undefined\n }\n const createDragPreview = (source: HTMLElement) => {\n dragPreview?.remove()\n const preview = cloneDragPreviewNode(source) as HTMLElement\n preview.className =\n 'pointer-events-none fixed -left-full top-0 z-(--z-dialog) flex h-64 max-h-screen w-96 max-w-screen min-h-0 min-w-0 flex-col overflow-hidden rounded-lg border border-border bg-card text-card-foreground shadow-xl'\n preview.removeAttribute('id')\n preview.removeAttribute('style')\n preview.removeAttribute('role')\n preview.removeAttribute('aria-label')\n preview.removeAttribute('data-pane-id')\n preview.removeAttribute('data-focused')\n preview.removeAttribute('data-drag-source')\n preview.removeAttribute('data-drop-direction')\n preview.removeAttribute('data-drop-placement')\n preview.setAttribute('data-split-drag-preview', '')\n preview.setAttribute('aria-hidden', 'true')\n preview.inert = true\n document.body.append(preview)\n dragPreview = preview\n return preview\n }\n const domId = (id: string) => {\n const existing = domIds.get(id)\n if (existing) return existing\n const created = `${prefix}-pane-${nextDomId++}`\n domIds.set(id, created)\n return created\n }\n const leaves = createMemo(() => listLeaves(props.state.center))\n const leafMap = createMemo(() => new Map(leaves().map((leaf) => [leaf.id, leaf])))\n const frames = createMemo(() => computeLayoutFrames(props.state.center))\n const branches = createMemo(() =>\n Array.from(frames().values()).flatMap((frame) =>\n frame.node.kind === 'split' ? [frame.node] : []\n )\n )\n createEffect(() => {\n if (branches().length === 0) {\n resizeLoadGeneration += 1\n focusHandleAfterRetry = false\n focusRecoveryButtonAfterError = false\n cancelPendingFocusRestore()\n // Keep a loaded controller so a later split does not re-import a facade\n // that may have failed before recovery. Clear only transient UI state.\n if (resizeController() === false || resizeController() === 'error')\n setResizeController(undefined)\n return\n }\n if (resizeController() !== undefined) return\n const retry = retryWithAlternateImport\n const generation = ++resizeLoadGeneration\n setResizeController(false)\n const controllerImport = retry\n ? alternateImportAttempts++ === 0\n ? import('./resize-controller-retry')\n : import('./resize-controller-retry-2')\n : import('./resize-controller')\n void controllerImport.then(\n ({ default: Controller }) => {\n if (disposed || generation !== resizeLoadGeneration || branches().length === 0) return\n const shouldFocusHandle = focusHandleAfterRetry && focusEpoch === focusRestoreEpoch\n focusHandleAfterRetry = false\n focusRecoveryButtonAfterError = false\n retryWithAlternateImport = false\n alternateImportAttempts = 0\n setResizeController(() => Controller)\n if (shouldFocusHandle)\n pendingFocusFrame = requestAnimationFrame(() => {\n pendingFocusFrame = undefined\n if (\n disposed ||\n generation !== resizeLoadGeneration ||\n branches().length === 0 ||\n focusEpoch !== focusRestoreEpoch\n )\n return\n const currentFocus = root?.ownerDocument.activeElement\n if (currentFocus && currentFocus !== root?.ownerDocument.body && currentFocus !== root)\n return\n root?.querySelector<HTMLElement>('[data-corvu-resizable-handle]')?.focus({\n preventScroll: true,\n })\n })\n },\n () => {\n // A rejected dynamic import can remain cached under its specifier.\n // The next split must start from the alternate module entry as well.\n retryWithAlternateImport = true\n if (!disposed && generation === resizeLoadGeneration && branches().length > 0) {\n setResizeController('error')\n const shouldFocusRetry = focusRecoveryButtonAfterError && focusEpoch === focusRestoreEpoch\n if (shouldFocusRetry)\n pendingFocusFrame = requestAnimationFrame(() => {\n pendingFocusFrame = undefined\n if (\n disposed ||\n generation !== resizeLoadGeneration ||\n branches().length === 0 ||\n focusEpoch !== focusRestoreEpoch\n )\n return\n root?.querySelector<HTMLButtonElement>('[data-resize-retry]')?.focus({\n preventScroll: true,\n })\n })\n }\n }\n )\n })\n createComputed(() => {\n const current = drag()\n if (current && (!props.onMove || !leafMap().has(current.id))) clearDrag()\n const target = drop()\n if (target && !leafMap().has(target.id)) setDrop(undefined)\n })\n const allowedTarget = (id: string, transfer: DataTransfer | null) => {\n const current = drag()\n return props.onMove &&\n current &&\n current.id !== id &&\n leafMap().has(current.id) &&\n leafMap().has(id) &&\n transfer?.types.includes(PANE_DRAG_TYPE)\n ? current\n : undefined\n }\n const dropLabel = createMemo(() => {\n const target = drop()\n const leaf = target ? leafMap().get(target.id) : undefined\n return target && leaf\n ? `Drop to place pane ${target.intent.placement} ${props.labelForLeaf(leaf)}`\n : ''\n })\n const branchMap = createMemo(() => new Map(branches().map((branch) => [branch.id, branch])))\n const schedule = (action: () => void) => {\n if (pendingFrame !== undefined) cancelAnimationFrame(pendingFrame)\n pendingFrame = requestAnimationFrame(() => {\n pendingFrame = undefined\n action()\n })\n }\n // Register before keyed children update: capture a focused editor before an\n // ordered DOM move can blur it. Never override a newer focus outside this root.\n createComputed(\n on(\n () => props.state.center,\n () => {\n const active = root?.ownerDocument.activeElement\n if (!root || !(active instanceof HTMLElement) || !root.contains(active)) return\n const field =\n active instanceof HTMLTextAreaElement || active instanceof HTMLInputElement\n ? active\n : undefined\n const selection = field\n ? {\n start: field.selectionStart,\n end: field.selectionEnd,\n direction: field.selectionDirection,\n }\n : undefined\n schedule(() => {\n if (!active.isConnected || !root?.contains(active)) return\n const current = active.ownerDocument.activeElement\n if (current !== active && current !== active.ownerDocument.body) return\n active.focus({ preventScroll: true })\n if (field && selection?.start !== null && selection?.end !== null && selection)\n field.setSelectionRange(\n selection.start,\n selection.end,\n selection.direction ?? undefined\n )\n })\n }\n )\n )\n onCleanup(() => {\n disposed = true\n focusHandleAfterRetry = false\n focusRecoveryButtonAfterError = false\n cancelPendingFocusRestore()\n if (pendingFrame !== undefined) cancelAnimationFrame(pendingFrame)\n clearDrag()\n refs.clear()\n domIds.clear()\n })\n const close = (id: string) => {\n const next = props.onClose?.(id)\n if (next) schedule(() => refs.get(next)?.focus({ preventScroll: true }))\n }\n return (\n <div\n ref={(el) => {\n root = el\n }}\n role=\"group\"\n aria-label={props.label}\n data-slot=\"split-layout\"\n data-dragging={drag() ? '' : undefined}\n class={cn('relative size-full min-h-0 min-w-0 data-[dragging]:cursor-grabbing', props.class)}\n >\n <For each={leaves().map((leaf) => leaf.id)}>\n {(id) => {\n const initial = leafMap().get(id)!\n const leaf = () => leafMap().get(id) ?? initial\n const content = props.renderLeaf(leaf)\n const paneLabel = props.renderPaneLabel?.(leaf)\n const actions = props.renderPaneActions?.(leaf)\n const intent = () => (drop()?.id === id ? drop()?.intent : undefined)\n onCleanup(() => {\n refs.delete(id)\n domIds.delete(id)\n })\n return (\n <section\n ref={(el) => refs.set(id, el)}\n id={domId(id)}\n role=\"region\"\n aria-label={props.labelForLeaf(leaf())}\n tabIndex={props.paneTabIndex ?? -1}\n data-pane-id={id}\n data-focused={props.state.focusedLeafId === id ? '' : undefined}\n data-drag-source={drag()?.id === id ? '' : undefined}\n data-drop-direction={intent()?.direction}\n data-drop-placement={intent()?.placement}\n onDragOver={(event) => {\n if (!allowedTarget(id, event.dataTransfer)) return\n const next = paneDropIntent(\n event.clientX,\n event.clientY,\n event.currentTarget.getBoundingClientRect()\n )\n if (!next) {\n setDrop(undefined)\n return\n }\n event.preventDefault()\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'\n setDrop({ id, intent: next })\n }}\n onDragLeave={(event) => {\n if (\n event.relatedTarget instanceof Node &&\n event.currentTarget.contains(event.relatedTarget)\n )\n return\n if (drop()?.id === id) setDrop(undefined)\n }}\n onDrop={(event) => {\n const current = allowedTarget(id, event.dataTransfer)\n const next = paneDropIntent(\n event.clientX,\n event.clientY,\n event.currentTarget.getBoundingClientRect()\n )\n const accepted =\n current && next && event.dataTransfer?.getData(PANE_DRAG_TYPE) === current.token\n clearDrag()\n if (!accepted) return\n event.preventDefault()\n props.onMove?.(current.id, id, next)\n }}\n style={rectStyle(frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 })}\n class=\"absolute flex min-h-0 min-w-0 flex-col overflow-hidden border border-border transition-opacity motion-reduce:transition-none data-[drag-source]:opacity-40 data-[focused]:border-primary bg-background text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring\"\n onFocusIn={() => props.onFocus?.(id)}\n >\n <header class=\"flex min-w-0 shrink-0 items-center gap-2 bg-surface px-2\">\n <span\n data-pane-drag-handle=\"\"\n draggable={Boolean(props.onMove)}\n class={cn('flex min-w-0 flex-1 items-center gap-2 truncate text-sm', {\n 'cursor-grab': Boolean(props.onMove),\n 'cursor-grabbing': drag()?.id === id,\n })}\n title={props.onMove ? `Drag ${props.labelForLeaf(leaf())} to move` : undefined}\n onDragStart={(event) => {\n if (!props.onMove || !event.dataTransfer) {\n event.preventDefault()\n return\n }\n const token = `${prefix}-${++nextDragId}`\n setDrag({ id, token })\n event.dataTransfer.setData(PANE_DRAG_TYPE, token)\n event.dataTransfer.effectAllowed = 'move'\n // The native drag image carries this pane's actual content\n // in a bounded floating-window frame; the source recedes\n // independently as the browser follows the image pointer.\n const source = refs.get(id)\n const frame = source?.getBoundingClientRect()\n if (source && frame && typeof event.dataTransfer.setDragImage === 'function') {\n const preview = createDragPreview(source)\n const previewFrame = preview.getBoundingClientRect()\n const scaleX = previewFrame.width / frame.width\n const scaleY = previewFrame.height / frame.height\n event.dataTransfer.setDragImage(\n preview,\n Math.max(0, Math.round((event.clientX - frame.left) * scaleX)),\n Math.max(0, Math.round((event.clientY - frame.top) * scaleY))\n )\n preview.setAttribute('data-native-drag-image', '')\n }\n }}\n onDragEnd={clearDrag}\n >\n {props.onMove ? (\n <GripVertical class=\"size-3 shrink-0\" aria-hidden=\"true\" />\n ) : null}\n <span class=\"min-w-0 flex-1 truncate\">\n {paneLabel ?? props.labelForLeaf(leaf())}\n </span>\n </span>\n {actions}\n {props.onClose ? (\n <ActionButton\n variant=\"ghost\"\n size=\"icon-xs\"\n aria-label={`Close ${props.labelForLeaf(leaf())}`}\n tooltip={`Close ${props.labelForLeaf(leaf())}.`}\n onClick={() => close(id)}\n >\n <X />\n </ActionButton>\n ) : null}\n </header>\n <div class=\"min-h-0 min-w-0 flex-1 overflow-auto\">{content}</div>\n {intent() ? (\n <div\n aria-hidden=\"true\"\n class={cn('pointer-events-none absolute border-2 border-primary bg-primary/10', {\n 'inset-y-0 left-0 w-1/2':\n intent()?.direction === 'row' && intent()?.placement === 'before',\n 'inset-y-0 right-0 w-1/2':\n intent()?.direction === 'row' && intent()?.placement === 'after',\n 'inset-x-0 top-0 h-1/2':\n intent()?.direction === 'column' && intent()?.placement === 'before',\n 'inset-x-0 bottom-0 h-1/2':\n intent()?.direction === 'column' && intent()?.placement === 'after',\n })}\n />\n ) : null}\n </section>\n )\n }}\n </For>\n <span class=\"sr-only\" role=\"status\">\n {dropLabel() ||\n (resizeController() === 'error'\n ? alternateImportAttempts >= 2\n ? 'Resize controls did not load after repeated attempts. Reloading may discard unsaved pane content.'\n : 'Resize controls did not load.'\n : '')}\n </span>\n <For each={branches().map((branch) => branch.id)}>\n {(id) => {\n const initial = branchMap().get(id)!\n const branch: Accessor<SplitLayoutBranch<L>> = () => branchMap().get(id) ?? initial\n const rect = () => frames().get(id)?.rect ?? { x: 0, y: 0, width: 0, height: 0 }\n return (\n <Show\n when={typeof resizeController() === 'function'}\n fallback={\n <div\n role=\"separator\"\n aria-label={\n props.labelForSeparator?.(branch()) ??\n (branch().direction === 'row' ? 'Resize pane columns' : 'Resize pane rows')\n }\n aria-orientation={branch().direction === 'row' ? 'vertical' : 'horizontal'}\n aria-controls={listLeaves(branch())\n .map((leaf) => domId(leaf.id))\n .join(' ')}\n aria-valuemin={10}\n aria-valuemax={90}\n aria-valuenow={Math.round(branch().ratio * 100)}\n aria-disabled=\"true\"\n tabIndex={-1}\n data-direction={branch().direction}\n style={separatorPlaceholderStyle(branch(), rect())}\n class=\"pointer-events-none absolute bg-border\"\n />\n }\n >\n <Dynamic\n component={resizeController() as ResizeController<L>}\n branch={branch}\n rect={() => rectStyle(rect())}\n domId={domId}\n root={() => root}\n labelForSeparator={props.labelForSeparator}\n onResize={props.onResize}\n />\n </Show>\n )\n }}\n </For>\n {resizeController() === 'error' ? (\n <div class=\"absolute top-2 right-2 z-(--z-menu) flex max-w-sm flex-col items-end gap-2\">\n {alternateImportAttempts >= 2 ? (\n <p\n id={resizeReloadWarningId}\n role=\"alert\"\n class=\"rounded-md border bg-background p-2 text-sm shadow-md\"\n >\n Reloading may discard unsaved pane content.\n </p>\n ) : null}\n <Button\n variant=\"outline\"\n size=\"sm\"\n data-resize-retry\n aria-describedby={alternateImportAttempts >= 2 ? resizeReloadWarningId : undefined}\n onClick={(event) => {\n if (alternateImportAttempts >= 2) {\n window.location.reload()\n return\n }\n const ownsFocus = document.activeElement === event.currentTarget\n focusHandleAfterRetry = ownsFocus\n focusRecoveryButtonAfterError = ownsFocus\n focusRestoreEpoch = focusEpoch\n retryWithAlternateImport = true\n setResizeController(undefined)\n }}\n >\n {alternateImportAttempts >= 2 ? 'Reload page to retry resizing' : 'Retry pane resizing'}\n </Button>\n </div>\n ) : null}\n </div>\n )\n}\n"],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ import { DEFAULT_APPEARANCE_EDITOR_FONT_SETTINGS } from "../../lib/appearance-fo
|
|
|
7
7
|
import { AccentSwatchGroups } from "../composites/appearance-editor/accent-swatch-groups.js";
|
|
8
8
|
import { AppearanceFontSettingsGroup } from "../composites/appearance-editor/font-settings-group.js";
|
|
9
9
|
import { ThemePicker } from "./theme-picker.js";
|
|
10
|
-
import { useTheme } from "./theme-
|
|
10
|
+
import { useTheme } from "./theme-context.js";
|
|
11
11
|
import { createComponent, insert, mergeProps, spread, template } from "solid-js/web";
|
|
12
12
|
import { Show, splitProps } from "solid-js";
|
|
13
13
|
import { RadioGroup } from "@kobalte/core/radio-group";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { AppearancePanel, type AppearancePanelProps } from './appearance-panel';
|
|
2
2
|
export { ThemePicker, ThemePreview, ThemeSwatch, type ThemePickerProps, type ThemePreviewProps, type ThemeSwatchProps, } from './theme-picker';
|
|
3
|
-
export { ThemeProvider, defaultThemeSelection, inlineScriptLiteral, resolvedDensity, themeScript, useTheme, type ThemeContextValue, type ThemeDensity, type ThemeProviderProps, type ThemeSelection, } from './theme-provider';
|
|
3
|
+
export { ThemeProvider, defaultThemeSelection, inlineScriptLiteral, localStoragePersistence, resolvedDensity, themeScript, useOptionalTheme, useTheme, type ThemeContextValue, type ThemeDensity, type ThemePersistence, type ThemeProviderProps, type ThemeSelection, } from './theme-provider';
|
|
4
4
|
export { ThemeToggle, type ThemeToggleProps } from './theme-toggle';
|
|
5
5
|
export { ThemeModeToggle, type ThemeModeToggleProps } from './theme-mode-toggle';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/theme/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC/E,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,QAAQ,EACR,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACnE,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/theme/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC/E,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,uBAAuB,EACvB,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACnE,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { ThemePicker, ThemePreview, ThemeSwatch } from "./theme-picker.js";
|
|
2
|
-
import {
|
|
2
|
+
import { useOptionalTheme, useTheme } from "./theme-context.js";
|
|
3
|
+
import { defaultThemeSelection, resolvedDensity } from "./theme-state.js";
|
|
4
|
+
import { localStoragePersistence } from "./theme-persistence.js";
|
|
5
|
+
import { ThemeProvider, inlineScriptLiteral, themeScript } from "./theme-provider.js";
|
|
3
6
|
import { AppearancePanel } from "./appearance-panel.js";
|
|
4
7
|
import { ThemeToggle } from "./theme-toggle.js";
|
|
5
8
|
import { ThemeModeToggle } from "./theme-mode-toggle.js";
|
|
6
|
-
export { AppearancePanel, ThemeModeToggle, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, defaultThemeSelection, inlineScriptLiteral, resolvedDensity, themeScript, useTheme };
|
|
9
|
+
export { AppearancePanel, ThemeModeToggle, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, defaultThemeSelection, inlineScriptLiteral, localStoragePersistence, resolvedDensity, themeScript, useOptionalTheme, useTheme };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Context } from 'solid-js';
|
|
2
|
+
import type { ThemeContextValue } from './theme-state';
|
|
3
|
+
export declare function themeContext(): Context<ThemeContextValue | undefined>;
|
|
4
|
+
export declare function useTheme(): ThemeContextValue;
|
|
5
|
+
/**
|
|
6
|
+
* The theme context, or `undefined` outside a `ThemeProvider`.
|
|
7
|
+
*
|
|
8
|
+
* For a component that can run both ways — a shared control rendered in a harness,
|
|
9
|
+
* a story, or a host that has not mounted a provider — and would rather degrade
|
|
10
|
+
* than throw.
|
|
11
|
+
*/
|
|
12
|
+
export declare function useOptionalTheme(): ThemeContextValue | undefined;
|
|
13
|
+
//# sourceMappingURL=theme-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-context.d.ts","sourceRoot":"","sources":["../../../src/components/theme/theme-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,OAAO,EAAE,MAAM,UAAU,CAAA;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAqBtD,wBAAgB,YAAY,IAAI,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAGrE;AAED,wBAAgB,QAAQ,IAAI,iBAAiB,CAI5C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,iBAAiB,GAAG,SAAS,CAEhE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createContext, useContext } from "solid-js";
|
|
2
|
+
//#region src/components/theme/theme-context.ts
|
|
3
|
+
/**
|
|
4
|
+
* Where the context object lives: on the global, under a registered symbol.
|
|
5
|
+
*
|
|
6
|
+
* A context is an object identity, and a bundle can legitimately load this module
|
|
7
|
+
* twice — a dev graph where a relative import and a package subpath are distinct
|
|
8
|
+
* module records, or two copies of the package at different versions. Each copy
|
|
9
|
+
* would then call `createContext` and own its own object; a provider from one and a
|
|
10
|
+
* `useOptionalTheme()` from the other would never meet, and the second would return
|
|
11
|
+
* `undefined` as though no provider were mounted. `Symbol.for` is shared across
|
|
12
|
+
* every copy in a realm, so they all find the one context the first created.
|
|
13
|
+
*
|
|
14
|
+
* Both copies must agree on its shape. The context value only ever grows, which is
|
|
15
|
+
* why a newer provider under an older reader is safe and the reverse is a missing
|
|
16
|
+
* member, not a mismatch.
|
|
17
|
+
*/
|
|
18
|
+
var CONTEXT_KEY = Symbol.for("adea.ui.theme");
|
|
19
|
+
function themeContext() {
|
|
20
|
+
const host = globalThis;
|
|
21
|
+
return host[CONTEXT_KEY] ??= createContext();
|
|
22
|
+
}
|
|
23
|
+
function useTheme() {
|
|
24
|
+
const value = useContext(themeContext());
|
|
25
|
+
if (!value) throw new Error("useTheme must be called inside a <ThemeProvider>.");
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The theme context, or `undefined` outside a `ThemeProvider`.
|
|
30
|
+
*
|
|
31
|
+
* For a component that can run both ways — a shared control rendered in a harness,
|
|
32
|
+
* a story, or a host that has not mounted a provider — and would rather degrade
|
|
33
|
+
* than throw.
|
|
34
|
+
*/
|
|
35
|
+
function useOptionalTheme() {
|
|
36
|
+
return useContext(themeContext());
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
export { themeContext, useOptionalTheme, useTheme };
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=theme-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-context.js","names":[],"sources":["../../../src/components/theme/theme-context.ts"],"sourcesContent":["import { createContext, useContext, type Context } from 'solid-js'\nimport type { ThemeContextValue } from './theme-state'\n\n/**\n * Where the context object lives: on the global, under a registered symbol.\n *\n * A context is an object identity, and a bundle can legitimately load this module\n * twice — a dev graph where a relative import and a package subpath are distinct\n * module records, or two copies of the package at different versions. Each copy\n * would then call `createContext` and own its own object; a provider from one and a\n * `useOptionalTheme()` from the other would never meet, and the second would return\n * `undefined` as though no provider were mounted. `Symbol.for` is shared across\n * every copy in a realm, so they all find the one context the first created.\n *\n * Both copies must agree on its shape. The context value only ever grows, which is\n * why a newer provider under an older reader is safe and the reverse is a missing\n * member, not a mismatch.\n */\nconst CONTEXT_KEY = Symbol.for('adea.ui.theme')\n\ntype ContextHost = { [CONTEXT_KEY]?: Context<ThemeContextValue | undefined> }\n\nexport function themeContext(): Context<ThemeContextValue | undefined> {\n const host = globalThis as ContextHost\n return (host[CONTEXT_KEY] ??= createContext<ThemeContextValue>())\n}\n\nexport function useTheme(): ThemeContextValue {\n const value = useContext(themeContext())\n if (!value) throw new Error('useTheme must be called inside a <ThemeProvider>.')\n return value\n}\n\n/**\n * The theme context, or `undefined` outside a `ThemeProvider`.\n *\n * For a component that can run both ways — a shared control rendered in a harness,\n * a story, or a host that has not mounted a provider — and would rather degrade\n * than throw.\n */\nexport function useOptionalTheme(): ThemeContextValue | undefined {\n return useContext(themeContext())\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAkBA,IAAM,cAAc,OAAO,IAAI,eAAe;AAI9C,SAAgB,eAAuD;CACrE,MAAM,OAAO;CACb,OAAQ,KAAK,iBAAiB,cAAiC;AACjE;AAEA,SAAgB,WAA8B;CAC5C,MAAM,QAAQ,WAAW,aAAa,CAAC;CACvC,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,mDAAmD;CAC/E,OAAO;AACT;;;;;;;;AASA,SAAgB,mBAAkD;CAChE,OAAO,WAAW,aAAa,CAAC;AAClC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type ThemeAppearance, type ThemeVariant } from '#lib/themes';
|
|
2
|
+
import { type ThemeSelection } from './theme-state';
|
|
3
|
+
/**
|
|
4
|
+
* The document half of the theme provider: the single writer of `<html>`.
|
|
5
|
+
*
|
|
6
|
+
* Written against the few members of an element it uses, so the rules can be tested
|
|
7
|
+
* on a stand-in and the provider's effect stays a one-line call.
|
|
8
|
+
*/
|
|
9
|
+
export type ThemeRoot = Pick<HTMLElement, 'classList' | 'dataset' | 'style' | 'removeAttribute' | 'setAttribute'>;
|
|
10
|
+
export type ThemeDocumentState = {
|
|
11
|
+
/** What the document shows: the committed selection, or a preview laid over it. */
|
|
12
|
+
selection: ThemeSelection;
|
|
13
|
+
appearance: ThemeAppearance;
|
|
14
|
+
variant: ThemeVariant;
|
|
15
|
+
};
|
|
16
|
+
export type ThemeDocumentOptions = {
|
|
17
|
+
/**
|
|
18
|
+
* Rewrites the custom properties just before they are written: the variant's
|
|
19
|
+
* roles with the accent laid over them. It sees every property of the pass and
|
|
20
|
+
* must return the full map; a name it drops is not written.
|
|
21
|
+
*/
|
|
22
|
+
transformTokens?: (tokens: Record<string, string>) => Record<string, string>;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* The custom properties a state paints: the variant's roles, with the accent
|
|
26
|
+
* selection laid over them, then `transformTokens`.
|
|
27
|
+
*
|
|
28
|
+
* The accent is applied *here* rather than left to the `[data-accent]` blocks in
|
|
29
|
+
* `theme.css`, because the properties are written inline and an inline declaration
|
|
30
|
+
* outranks every stylesheet selector however specific it is. The blocks still exist
|
|
31
|
+
* and are still correct — they are what styles the window before this runs — but
|
|
32
|
+
* they cannot win from here, so leaving the accent to them meant the attribute was
|
|
33
|
+
* set, the rules were present, and nothing changed on screen.
|
|
34
|
+
*/
|
|
35
|
+
export declare function themeDocumentTokens(state: ThemeDocumentState, options?: ThemeDocumentOptions): {
|
|
36
|
+
tokens: Record<string, string>;
|
|
37
|
+
accented: boolean;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Write a state onto a root and report which custom properties it owns.
|
|
41
|
+
*
|
|
42
|
+
* Pass the previous call's return as `previous` and any palette property that pass
|
|
43
|
+
* wrote and this one does not is removed. For the catalogue the two sets are the
|
|
44
|
+
* same, so nothing is ever removed; it matters for a host variant that carries
|
|
45
|
+
* `tokens` the catalogue does not, which would otherwise stay inline, beating the
|
|
46
|
+
* stylesheet, after the user switched away from it.
|
|
47
|
+
*/
|
|
48
|
+
export declare function applyThemeToRoot(root: ThemeRoot, state: ThemeDocumentState, options?: ThemeDocumentOptions, previous?: ReadonlySet<string>): ReadonlySet<string>;
|
|
49
|
+
/** What {@link applyWithoutTransitions} needs of a document. */
|
|
50
|
+
export type TransitionDocument = {
|
|
51
|
+
head: {
|
|
52
|
+
appendChild(node: unknown): unknown;
|
|
53
|
+
};
|
|
54
|
+
createElement(tag: 'style'): {
|
|
55
|
+
textContent: string | null;
|
|
56
|
+
offsetHeight?: number;
|
|
57
|
+
remove(): void;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Run `apply` with every CSS transition switched off for the frame that carries
|
|
62
|
+
* it, so a theme switch cannot animate page-wide.
|
|
63
|
+
*
|
|
64
|
+
* Without this, flipping the custom properties on `<html>` starts a transition on
|
|
65
|
+
* every element that declares one, and each fades from the old palette to the new
|
|
66
|
+
* over its own duration: a theme change that looks like a rendering fault. The
|
|
67
|
+
* rule is removed two frames later, after the browser has committed the new styles
|
|
68
|
+
* with transitions off, and `restore` runs it early (the provider calls it when it
|
|
69
|
+
* is disposed mid-switch).
|
|
70
|
+
*
|
|
71
|
+
* `schedule` is the frame source; it defaults to `requestAnimationFrame` and falls
|
|
72
|
+
* back to running at once where there is none, which leaves transitions on rather
|
|
73
|
+
* than off.
|
|
74
|
+
*/
|
|
75
|
+
export declare function applyWithoutTransitions(doc: TransitionDocument, apply: () => void, schedule?: (callback: () => void) => void): () => void;
|
|
76
|
+
//# sourceMappingURL=theme-document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-document.d.ts","sourceRoot":"","sources":["../../../src/components/theme/theme-document.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AAEpE;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,IAAI,CAC1B,WAAW,EACX,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,iBAAiB,GAAG,cAAc,CACvE,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,mFAAmF;IACnF,SAAS,EAAE,cAAc,CAAA;IACzB,UAAU,EAAE,eAAe,CAAA;IAC3B,OAAO,EAAE,YAAY,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7E,CAAA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,kBAAkB,EACzB,OAAO,GAAE,oBAAyB,GACjC;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAQvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,kBAAkB,EACzB,OAAO,GAAE,oBAAyB,EAClC,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAC7B,WAAW,CAAC,MAAM,CAAC,CAiCrB;AAED,gEAAgE;AAChE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE;QAAE,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;KAAE,CAAA;IAC7C,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG;QAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;QAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,MAAM,IAAI,IAAI,CAAA;KACf,CAAA;CACF,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,kBAAkB,EACvB,KAAK,EAAE,MAAM,IAAI,EACjB,QAAQ,GAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAsB,GACzD,MAAM,IAAI,CAqBZ"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { accentVariables, themeCssVariables } from "../../lib/themes.js";
|
|
2
|
+
import { applyAppearanceFontSettings, normalizeAppearanceEditorFontSettings } from "../../lib/appearance-font-settings.js";
|
|
3
|
+
import { resolvedDensity } from "./theme-state.js";
|
|
4
|
+
//#region src/components/theme/theme-document.ts
|
|
5
|
+
/**
|
|
6
|
+
* The custom properties a state paints: the variant's roles, with the accent
|
|
7
|
+
* selection laid over them, then `transformTokens`.
|
|
8
|
+
*
|
|
9
|
+
* The accent is applied *here* rather than left to the `[data-accent]` blocks in
|
|
10
|
+
* `theme.css`, because the properties are written inline and an inline declaration
|
|
11
|
+
* outranks every stylesheet selector however specific it is. The blocks still exist
|
|
12
|
+
* and are still correct — they are what styles the window before this runs — but
|
|
13
|
+
* they cannot win from here, so leaving the accent to them meant the attribute was
|
|
14
|
+
* set, the rules were present, and nothing changed on screen.
|
|
15
|
+
*/
|
|
16
|
+
function themeDocumentTokens(state, options = {}) {
|
|
17
|
+
const properties = { ...themeCssVariables(state.variant) };
|
|
18
|
+
const accent = accentVariables(state.selection.accent, state.appearance, state.selection);
|
|
19
|
+
if (accent) Object.assign(properties, accent);
|
|
20
|
+
return {
|
|
21
|
+
tokens: options.transformTokens ? options.transformTokens(properties) : properties,
|
|
22
|
+
accented: accent !== void 0
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Write a state onto a root and report which custom properties it owns.
|
|
27
|
+
*
|
|
28
|
+
* Pass the previous call's return as `previous` and any palette property that pass
|
|
29
|
+
* wrote and this one does not is removed. For the catalogue the two sets are the
|
|
30
|
+
* same, so nothing is ever removed; it matters for a host variant that carries
|
|
31
|
+
* `tokens` the catalogue does not, which would otherwise stay inline, beating the
|
|
32
|
+
* stylesheet, after the user switched away from it.
|
|
33
|
+
*/
|
|
34
|
+
function applyThemeToRoot(root, state, options = {}, previous) {
|
|
35
|
+
const { tokens, accented } = themeDocumentTokens(state, options);
|
|
36
|
+
for (const [name, value] of Object.entries(tokens)) root.style.setProperty(name, value);
|
|
37
|
+
if (previous) {
|
|
38
|
+
for (const name of previous) if (!(name in tokens)) root.style.removeProperty(name);
|
|
39
|
+
}
|
|
40
|
+
root.classList.toggle("dark", state.appearance === "dark");
|
|
41
|
+
root.dataset["theme"] = state.variant.id;
|
|
42
|
+
root.dataset["appearance"] = state.appearance;
|
|
43
|
+
root.style.colorScheme = state.appearance;
|
|
44
|
+
if (!accented) root.removeAttribute("data-accent");
|
|
45
|
+
else root.dataset["accent"] = state.selection.accent;
|
|
46
|
+
applyAppearanceFontSettings(root, normalizeAppearanceEditorFontSettings(state.selection.fonts, state.selection.font).settings);
|
|
47
|
+
if (resolvedDensity(state.selection) === "comfortable") root.removeAttribute("data-density");
|
|
48
|
+
else root.dataset["density"] = resolvedDensity(state.selection);
|
|
49
|
+
return new Set(Object.keys(tokens));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Run `apply` with every CSS transition switched off for the frame that carries
|
|
53
|
+
* it, so a theme switch cannot animate page-wide.
|
|
54
|
+
*
|
|
55
|
+
* Without this, flipping the custom properties on `<html>` starts a transition on
|
|
56
|
+
* every element that declares one, and each fades from the old palette to the new
|
|
57
|
+
* over its own duration: a theme change that looks like a rendering fault. The
|
|
58
|
+
* rule is removed two frames later, after the browser has committed the new styles
|
|
59
|
+
* with transitions off, and `restore` runs it early (the provider calls it when it
|
|
60
|
+
* is disposed mid-switch).
|
|
61
|
+
*
|
|
62
|
+
* `schedule` is the frame source; it defaults to `requestAnimationFrame` and falls
|
|
63
|
+
* back to running at once where there is none, which leaves transitions on rather
|
|
64
|
+
* than off.
|
|
65
|
+
*/
|
|
66
|
+
function applyWithoutTransitions(doc, apply, schedule = defaultSchedule) {
|
|
67
|
+
const style = doc.createElement("style");
|
|
68
|
+
style.textContent = "*{transition:none !important}";
|
|
69
|
+
doc.head.appendChild(style);
|
|
70
|
+
style.offsetHeight;
|
|
71
|
+
let removed = false;
|
|
72
|
+
const restore = () => {
|
|
73
|
+
if (removed) return;
|
|
74
|
+
removed = true;
|
|
75
|
+
style.remove();
|
|
76
|
+
};
|
|
77
|
+
try {
|
|
78
|
+
apply();
|
|
79
|
+
} catch (error) {
|
|
80
|
+
restore();
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
schedule(() => schedule(restore));
|
|
84
|
+
return restore;
|
|
85
|
+
}
|
|
86
|
+
function defaultSchedule(callback) {
|
|
87
|
+
if (typeof requestAnimationFrame === "function") requestAnimationFrame(callback);
|
|
88
|
+
else callback();
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
export { applyThemeToRoot, applyWithoutTransitions, themeDocumentTokens };
|
|
92
|
+
|
|
93
|
+
//# sourceMappingURL=theme-document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-document.js","names":[],"sources":["../../../src/components/theme/theme-document.ts"],"sourcesContent":["import {\n applyAppearanceFontSettings,\n normalizeAppearanceEditorFontSettings,\n} from '#lib/appearance-font-settings'\nimport {\n accentVariables,\n themeCssVariables,\n type ThemeAppearance,\n type ThemeVariant,\n} from '#lib/themes'\nimport { resolvedDensity, type ThemeSelection } from './theme-state'\n\n/**\n * The document half of the theme provider: the single writer of `<html>`.\n *\n * Written against the few members of an element it uses, so the rules can be tested\n * on a stand-in and the provider's effect stays a one-line call.\n */\nexport type ThemeRoot = Pick<\n HTMLElement,\n 'classList' | 'dataset' | 'style' | 'removeAttribute' | 'setAttribute'\n>\n\nexport type ThemeDocumentState = {\n /** What the document shows: the committed selection, or a preview laid over it. */\n selection: ThemeSelection\n appearance: ThemeAppearance\n variant: ThemeVariant\n}\n\nexport type ThemeDocumentOptions = {\n /**\n * Rewrites the custom properties just before they are written: the variant's\n * roles with the accent laid over them. It sees every property of the pass and\n * must return the full map; a name it drops is not written.\n */\n transformTokens?: (tokens: Record<string, string>) => Record<string, string>\n}\n\n/**\n * The custom properties a state paints: the variant's roles, with the accent\n * selection laid over them, then `transformTokens`.\n *\n * The accent is applied *here* rather than left to the `[data-accent]` blocks in\n * `theme.css`, because the properties are written inline and an inline declaration\n * outranks every stylesheet selector however specific it is. The blocks still exist\n * and are still correct — they are what styles the window before this runs — but\n * they cannot win from here, so leaving the accent to them meant the attribute was\n * set, the rules were present, and nothing changed on screen.\n */\nexport function themeDocumentTokens(\n state: ThemeDocumentState,\n options: ThemeDocumentOptions = {}\n): { tokens: Record<string, string>; accented: boolean } {\n const properties = { ...themeCssVariables(state.variant) }\n const accent = accentVariables(state.selection.accent, state.appearance, state.selection)\n if (accent) Object.assign(properties, accent)\n return {\n tokens: options.transformTokens ? options.transformTokens(properties) : properties,\n accented: accent !== undefined,\n }\n}\n\n/**\n * Write a state onto a root and report which custom properties it owns.\n *\n * Pass the previous call's return as `previous` and any palette property that pass\n * wrote and this one does not is removed. For the catalogue the two sets are the\n * same, so nothing is ever removed; it matters for a host variant that carries\n * `tokens` the catalogue does not, which would otherwise stay inline, beating the\n * stylesheet, after the user switched away from it.\n */\nexport function applyThemeToRoot(\n root: ThemeRoot,\n state: ThemeDocumentState,\n options: ThemeDocumentOptions = {},\n previous?: ReadonlySet<string>\n): ReadonlySet<string> {\n const { tokens, accented } = themeDocumentTokens(state, options)\n\n for (const [name, value] of Object.entries(tokens)) {\n root.style.setProperty(name, value)\n }\n if (previous) {\n for (const name of previous) {\n if (!(name in tokens)) root.style.removeProperty(name)\n }\n }\n\n root.classList.toggle('dark', state.appearance === 'dark')\n root.dataset['theme'] = state.variant.id\n root.dataset['appearance'] = state.appearance\n root.style.colorScheme = state.appearance\n\n if (!accented) root.removeAttribute('data-accent')\n else root.dataset['accent'] = state.selection.accent\n\n applyAppearanceFontSettings(\n root,\n normalizeAppearanceEditorFontSettings(state.selection.fonts, state.selection.font).settings\n )\n\n // Density is a pure token shift, so unlike the colour axes there is nothing to\n // compute: the attribute selects a block in `theme.css`. It is applied here for\n // the same reason as the others — this is the one place that knows what the\n // current selection is, and it is the only writer of these attributes.\n if (resolvedDensity(state.selection) === 'comfortable') root.removeAttribute('data-density')\n else root.dataset['density'] = resolvedDensity(state.selection)\n\n return new Set(Object.keys(tokens))\n}\n\n/** What {@link applyWithoutTransitions} needs of a document. */\nexport type TransitionDocument = {\n head: { appendChild(node: unknown): unknown }\n createElement(tag: 'style'): {\n textContent: string | null\n offsetHeight?: number\n remove(): void\n }\n}\n\n/**\n * Run `apply` with every CSS transition switched off for the frame that carries\n * it, so a theme switch cannot animate page-wide.\n *\n * Without this, flipping the custom properties on `<html>` starts a transition on\n * every element that declares one, and each fades from the old palette to the new\n * over its own duration: a theme change that looks like a rendering fault. The\n * rule is removed two frames later, after the browser has committed the new styles\n * with transitions off, and `restore` runs it early (the provider calls it when it\n * is disposed mid-switch).\n *\n * `schedule` is the frame source; it defaults to `requestAnimationFrame` and falls\n * back to running at once where there is none, which leaves transitions on rather\n * than off.\n */\nexport function applyWithoutTransitions(\n doc: TransitionDocument,\n apply: () => void,\n schedule: (callback: () => void) => void = defaultSchedule\n): () => void {\n const style = doc.createElement('style')\n style.textContent = '*{transition:none !important}'\n doc.head.appendChild(style)\n // Reading a layout property forces the browser to commit the rule before the\n // properties change; without it the two can be batched into one style recalc.\n void style.offsetHeight\n let removed = false\n const restore = () => {\n if (removed) return\n removed = true\n style.remove()\n }\n try {\n apply()\n } catch (error) {\n restore()\n throw error\n }\n schedule(() => schedule(restore))\n return restore\n}\n\nfunction defaultSchedule(callback: () => void): void {\n if (typeof requestAnimationFrame === 'function') requestAnimationFrame(callback)\n else callback()\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkDA,SAAgB,oBACd,OACA,UAAgC,CAAC,GACsB;CACvD,MAAM,aAAa,EAAE,GAAG,kBAAkB,MAAM,OAAO,EAAE;CACzD,MAAM,SAAS,gBAAgB,MAAM,UAAU,QAAQ,MAAM,YAAY,MAAM,SAAS;CACxF,IAAI,QAAQ,OAAO,OAAO,YAAY,MAAM;CAC5C,OAAO;EACL,QAAQ,QAAQ,kBAAkB,QAAQ,gBAAgB,UAAU,IAAI;EACxE,UAAU,WAAW,KAAA;CACvB;AACF;;;;;;;;;;AAWA,SAAgB,iBACd,MACA,OACA,UAAgC,CAAC,GACjC,UACqB;CACrB,MAAM,EAAE,QAAQ,aAAa,oBAAoB,OAAO,OAAO;CAE/D,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,MAAM,GAC/C,KAAK,MAAM,YAAY,MAAM,KAAK;CAEpC,IAAI,UACG;OAAA,MAAM,QAAQ,UACjB,IAAI,EAAE,QAAQ,SAAS,KAAK,MAAM,eAAe,IAAI;CAAA;CAIzD,KAAK,UAAU,OAAO,QAAQ,MAAM,eAAe,MAAM;CACzD,KAAK,QAAQ,WAAW,MAAM,QAAQ;CACtC,KAAK,QAAQ,gBAAgB,MAAM;CACnC,KAAK,MAAM,cAAc,MAAM;CAE/B,IAAI,CAAC,UAAU,KAAK,gBAAgB,aAAa;MAC5C,KAAK,QAAQ,YAAY,MAAM,UAAU;CAE9C,4BACE,MACA,sCAAsC,MAAM,UAAU,OAAO,MAAM,UAAU,IAAI,CAAC,CAAC,QACrF;CAMA,IAAI,gBAAgB,MAAM,SAAS,MAAM,eAAe,KAAK,gBAAgB,cAAc;MACtF,KAAK,QAAQ,aAAa,gBAAgB,MAAM,SAAS;CAE9D,OAAO,IAAI,IAAI,OAAO,KAAK,MAAM,CAAC;AACpC;;;;;;;;;;;;;;;;AA2BA,SAAgB,wBACd,KACA,OACA,WAA2C,iBAC/B;CACZ,MAAM,QAAQ,IAAI,cAAc,OAAO;CACvC,MAAM,cAAc;CACpB,IAAI,KAAK,YAAY,KAAK;CAG1B,MAAW;CACX,IAAI,UAAU;CACd,MAAM,gBAAgB;EACpB,IAAI,SAAS;EACb,UAAU;EACV,MAAM,OAAO;CACf;CACA,IAAI;EACF,MAAM;CACR,SAAS,OAAO;EACd,QAAQ;EACR,MAAM;CACR;CACA,eAAe,SAAS,OAAO,CAAC;CAChC,OAAO;AACT;AAEA,SAAS,gBAAgB,UAA4B;CACnD,IAAI,OAAO,0BAA0B,YAAY,sBAAsB,QAAQ;MAC1E,SAAS;AAChB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type ThemeSelection } from './theme-state';
|
|
2
|
+
/**
|
|
3
|
+
* Where a selection is kept between sessions.
|
|
4
|
+
*
|
|
5
|
+
* The provider never touches storage itself; it asks a `ThemePersistence`. The
|
|
6
|
+
* default is {@link localStoragePersistence}, which is what the provider always did.
|
|
7
|
+
* A host that stores the preference in a different shape, under a versioned
|
|
8
|
+
* envelope, or somewhere that is not `localStorage` supplies its own and the
|
|
9
|
+
* resolution and application rules stay the shared ones.
|
|
10
|
+
*
|
|
11
|
+
* The contract is deliberately narrow, so that an implementation cannot make the
|
|
12
|
+
* provider less safe than it was:
|
|
13
|
+
*
|
|
14
|
+
* - `read` is synchronous and runs once, when the provider is created. It may
|
|
15
|
+
* repair or quarantine what it finds, and it must not throw: the provider
|
|
16
|
+
* treats a throw as "nothing stored" and starts from the defaults.
|
|
17
|
+
* - `write` runs only from `setSelection`. Never on mount, never from `preview`,
|
|
18
|
+
* never as a side effect of reading, so the first write to a store is always a
|
|
19
|
+
* user's decision. A throw is swallowed, because a full or blocked store must
|
|
20
|
+
* not break the switch.
|
|
21
|
+
*/
|
|
22
|
+
export type ThemePersistence = {
|
|
23
|
+
read(): Partial<ThemeSelection> | undefined;
|
|
24
|
+
write(next: ThemeSelection): void;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The default persistence: one JSON document in `localStorage` under `key`.
|
|
28
|
+
*
|
|
29
|
+
* `read` is the provider's original `readSelection`, moved here unchanged — every
|
|
30
|
+
* stored id is validated against the catalogue, so a stale preference falls back to
|
|
31
|
+
* a default rather than reaching the document. `key` may be a function so a
|
|
32
|
+
* provider whose `storageKey` prop changes writes to the key it is now given.
|
|
33
|
+
*
|
|
34
|
+
* Blocked, full or absent storage is survivable in both directions: a read answers
|
|
35
|
+
* with the defaults and a write is dropped, so the preference simply lasts the
|
|
36
|
+
* session.
|
|
37
|
+
*/
|
|
38
|
+
export declare function localStoragePersistence(key: string | (() => string)): ThemePersistence;
|
|
39
|
+
/**
|
|
40
|
+
* What a persistence knows, or nothing.
|
|
41
|
+
*
|
|
42
|
+
* The seam's `read` must not throw, and the provider does not rely on that: a host
|
|
43
|
+
* persistence is code the design system has not seen, and a theme provider that
|
|
44
|
+
* fails to mount because a store misbehaved has turned a lost preference into a
|
|
45
|
+
* blank application.
|
|
46
|
+
*/
|
|
47
|
+
export declare function readPersisted(persistence: ThemePersistence): Partial<ThemeSelection> | undefined;
|
|
48
|
+
/** Hand a selection to the store; a store that throws loses the preference, not the switch. */
|
|
49
|
+
export declare function writePersisted(persistence: ThemePersistence, next: ThemeSelection): void;
|
|
50
|
+
//# sourceMappingURL=theme-persistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-persistence.d.ts","sourceRoot":"","sources":["../../../src/components/theme/theme-persistence.ts"],"names":[],"mappings":"AAGA,OAAO,EAA0C,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AAE3F;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,CAAA;IAC3C,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAAA;CAClC,CAAA;AA4DD;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,gBAAgB,CAatF;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,CAMhG;AAED,+FAA+F;AAC/F,wBAAgB,cAAc,CAAC,WAAW,EAAE,gBAAgB,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAOxF"}
|