@dialpad/dialtone 9.177.1 → 9.178.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/css/dialtone-default-theme.css +75 -0
- package/dist/css/dialtone-default-theme.min.css +1 -1
- package/dist/css/dialtone.css +75 -0
- package/dist/css/dialtone.min.css +1 -1
- package/dist/css/tokens-docs.json +1 -1
- package/dist/tokens/doc.json +116900 -116900
- package/dist/vue3/{attachment_carousel-DMKCJe7S.cjs → attachment_carousel-BHxR7A76.cjs} +1 -1
- package/dist/vue3/{attachment_carousel-DMKCJe7S.cjs.map → attachment_carousel-BHxR7A76.cjs.map} +1 -1
- package/dist/vue3/{attachment_carousel-gV6IHYgP.js → attachment_carousel-CouFqFMw.js} +1 -1
- package/dist/vue3/{attachment_carousel-gV6IHYgP.js.map → attachment_carousel-CouFqFMw.js.map} +1 -1
- package/dist/vue3/component-documentation.json +1 -1
- package/dist/vue3/components/combobox_with_popover/combobox_with_popover.vue.d.ts +2 -0
- package/dist/vue3/components/combobox_with_popover/combobox_with_popover.vue.d.ts.map +1 -1
- package/dist/vue3/components/resizable/composables/computeLayout.d.ts +35 -0
- package/dist/vue3/components/resizable/composables/computeLayout.d.ts.map +1 -0
- package/dist/vue3/components/resizable/composables/constraintResolver.d.ts +22 -0
- package/dist/vue3/components/resizable/composables/constraintResolver.d.ts.map +1 -0
- package/dist/vue3/components/resizable/composables/index.d.ts +16 -0
- package/dist/vue3/components/resizable/composables/index.d.ts.map +1 -0
- package/dist/vue3/components/resizable/composables/useResizableAnnouncements.d.ts +6 -0
- package/dist/vue3/components/resizable/composables/useResizableAnnouncements.d.ts.map +1 -0
- package/dist/vue3/components/resizable/composables/useResizableCalculations.d.ts +14 -0
- package/dist/vue3/components/resizable/composables/useResizableCalculations.d.ts.map +1 -0
- package/dist/vue3/components/resizable/composables/useResizableDrag.d.ts +42 -0
- package/dist/vue3/components/resizable/composables/useResizableDrag.d.ts.map +1 -0
- package/dist/vue3/components/resizable/composables/useResizableGroup.d.ts +25 -0
- package/dist/vue3/components/resizable/composables/useResizableGroup.d.ts.map +1 -0
- package/dist/vue3/components/resizable/composables/useResizableKeyboard.d.ts +41 -0
- package/dist/vue3/components/resizable/composables/useResizableKeyboard.d.ts.map +1 -0
- package/dist/vue3/components/resizable/composables/useResizableOffset.d.ts +15 -0
- package/dist/vue3/components/resizable/composables/useResizableOffset.d.ts.map +1 -0
- package/dist/vue3/components/resizable/composables/useResizablePanelControls.d.ts +46 -0
- package/dist/vue3/components/resizable/composables/useResizablePanelControls.d.ts.map +1 -0
- package/dist/vue3/components/resizable/composables/useResizablePanelState.d.ts +9 -0
- package/dist/vue3/components/resizable/composables/useResizablePanelState.d.ts.map +1 -0
- package/dist/vue3/components/resizable/composables/useResizableStorage.d.ts +12 -0
- package/dist/vue3/components/resizable/composables/useResizableStorage.d.ts.map +1 -0
- package/dist/vue3/components/resizable/index.d.ts +6 -0
- package/dist/vue3/components/resizable/index.d.ts.map +1 -0
- package/dist/vue3/components/resizable/resizable.vue.d.ts +69 -0
- package/dist/vue3/components/resizable/resizable.vue.d.ts.map +1 -0
- package/dist/vue3/components/resizable/resizable_constants.d.ts +103 -0
- package/dist/vue3/components/resizable/resizable_constants.d.ts.map +1 -0
- package/dist/vue3/components/resizable/resizable_handle.vue.d.ts +22 -0
- package/dist/vue3/components/resizable/resizable_handle.vue.d.ts.map +1 -0
- package/dist/vue3/components/resizable/resizable_panel.vue.d.ts +44 -0
- package/dist/vue3/components/resizable/resizable_panel.vue.d.ts.map +1 -0
- package/dist/vue3/components/resizable/resizable_utils.d.ts +15 -0
- package/dist/vue3/components/resizable/resizable_utils.d.ts.map +1 -0
- package/dist/vue3/components/rich_text_editor/rich_text_editor.vue.d.ts +2 -0
- package/dist/vue3/components/rich_text_editor/rich_text_editor.vue.d.ts.map +1 -1
- package/dist/vue3/components/scroller/scroller.vue.d.ts +6 -8
- package/dist/vue3/components/scroller/scroller.vue.d.ts.map +1 -1
- package/dist/vue3/components/split_button/split_button.vue.d.ts +4 -4
- package/dist/vue3/dialtone-vue.cjs +1 -1
- package/dist/vue3/dialtone-vue.js +56 -51
- package/dist/vue3/index.d.ts +1 -0
- package/dist/vue3/lib/attachment-carousel/attachment-carousel.cjs +1 -1
- package/dist/vue3/lib/attachment-carousel/attachment-carousel.js +1 -1
- package/dist/vue3/lib/attachment-carousel/index.cjs +1 -1
- package/dist/vue3/lib/attachment-carousel/index.js +1 -1
- package/dist/vue3/lib/editor/editor.cjs +1 -1
- package/dist/vue3/lib/editor/editor.js +1 -1
- package/dist/vue3/lib/message-input/index.cjs +1 -1
- package/dist/vue3/lib/message-input/index.js +1 -1
- package/dist/vue3/lib/message-input/message-input.cjs +1 -1
- package/dist/vue3/lib/message-input/message-input.js +1 -1
- package/dist/vue3/lib/resizable/index.cjs +1 -0
- package/dist/vue3/lib/resizable/index.js +5 -0
- package/dist/vue3/lib/resizable/resizable-handle.cjs +1 -0
- package/dist/vue3/lib/resizable/resizable-handle.js +2 -0
- package/dist/vue3/lib/resizable/resizable-panel.cjs +2 -0
- package/dist/vue3/lib/resizable/resizable-panel.cjs.map +1 -0
- package/dist/vue3/lib/resizable/resizable-panel.js +132 -0
- package/dist/vue3/lib/resizable/resizable-panel.js.map +1 -0
- package/dist/vue3/lib/resizable/resizable.cjs +1 -0
- package/dist/vue3/lib/resizable/resizable.js +2 -0
- package/dist/vue3/lib/rich-text-editor/index.cjs +1 -1
- package/dist/vue3/lib/rich-text-editor/index.js +1 -1
- package/dist/vue3/lib/rich-text-editor/markdownRenderer.cjs +1 -7
- package/dist/vue3/lib/rich-text-editor/markdownRenderer.js +2 -62
- package/dist/vue3/lib/rich-text-editor/rich-text-editor.cjs +1 -1
- package/dist/vue3/lib/rich-text-editor/rich-text-editor.js +1 -1
- package/dist/vue3/lib/scroller/index.cjs +1 -1
- package/dist/vue3/lib/scroller/index.js +1 -1
- package/dist/vue3/lib/scroller/scroller.cjs +1 -1
- package/dist/vue3/lib/scroller/scroller.js +1 -1
- package/dist/vue3/lib/toast/index.cjs +1 -1
- package/dist/vue3/lib/toast/index.js +1 -1
- package/dist/vue3/lib/toast/toast.cjs +1 -1
- package/dist/vue3/lib/toast/toast.js +1 -1
- package/dist/vue3/markdownRenderer-DCgGQseq.cjs +31 -0
- package/dist/vue3/markdownRenderer-DCgGQseq.cjs.map +1 -0
- package/dist/vue3/markdownRenderer-D_P94RyM.js +322 -0
- package/dist/vue3/markdownRenderer-D_P94RyM.js.map +1 -0
- package/dist/vue3/{message_input-VmltTreF.cjs → message_input-AWgvtwMV.cjs} +2 -2
- package/dist/vue3/{message_input-VmltTreF.cjs.map → message_input-AWgvtwMV.cjs.map} +1 -1
- package/dist/vue3/{message_input-tVB6JYJm.js → message_input-CHlTsBGK.js} +2 -2
- package/dist/vue3/{message_input-tVB6JYJm.js.map → message_input-CHlTsBGK.js.map} +1 -1
- package/dist/vue3/node_modules/@tiptap/vue-3.cjs.map +1 -1
- package/dist/vue3/node_modules/@tiptap/vue-3.js +1 -1
- package/dist/vue3/node_modules/@tiptap/vue-3.js.map +1 -1
- package/dist/vue3/recipes/conversation_view/editor/editor.vue.d.ts +2 -0
- package/dist/vue3/recipes/conversation_view/editor/editor.vue.d.ts.map +1 -1
- package/dist/vue3/recipes/conversation_view/message_input/message_input.vue.d.ts +2 -0
- package/dist/vue3/recipes/conversation_view/message_input/message_input.vue.d.ts.map +1 -1
- package/dist/vue3/resizable-D4-peBOl.js +960 -0
- package/dist/vue3/resizable-D4-peBOl.js.map +1 -0
- package/dist/vue3/resizable-aOVGO_Os.cjs +2 -0
- package/dist/vue3/resizable-aOVGO_Os.cjs.map +1 -0
- package/dist/vue3/resizable_handle-BlKBiWnx.js +307 -0
- package/dist/vue3/resizable_handle-BlKBiWnx.js.map +1 -0
- package/dist/vue3/resizable_handle-RIKS8frB.cjs +2 -0
- package/dist/vue3/resizable_handle-RIKS8frB.cjs.map +1 -0
- package/dist/vue3/resizable_utils-BComtrMV.js +131 -0
- package/dist/vue3/resizable_utils-BComtrMV.js.map +1 -0
- package/dist/vue3/resizable_utils-DhuzXRdP.cjs +2 -0
- package/dist/vue3/resizable_utils-DhuzXRdP.cjs.map +1 -0
- package/dist/vue3/{rich_text_editor-CtCGNkSD.js → rich_text_editor-Ba67C4Uk.js} +421 -454
- package/dist/vue3/rich_text_editor-Ba67C4Uk.js.map +1 -0
- package/dist/vue3/rich_text_editor-DMP5eTlf.cjs +10 -0
- package/dist/vue3/rich_text_editor-DMP5eTlf.cjs.map +1 -0
- package/dist/vue3/{scroller-Ckquh-PU.js → scroller-BGVDh3sq.js} +1 -1
- package/dist/vue3/{scroller-Ckquh-PU.js.map → scroller-BGVDh3sq.js.map} +1 -1
- package/dist/vue3/{scroller-06ayn-64.cjs → scroller-CjAsgjl9.cjs} +1 -1
- package/dist/vue3/{scroller-06ayn-64.cjs.map → scroller-CjAsgjl9.cjs.map} +1 -1
- package/dist/vue3/{toast-B1zeUPtg.js → toast-DvPN-bCi.js} +1 -1
- package/dist/vue3/{toast-B1zeUPtg.js.map → toast-DvPN-bCi.js.map} +1 -1
- package/dist/vue3/{toast-0QfP90_3.cjs → toast-d8_zmgkL.cjs} +1 -1
- package/dist/vue3/{toast-0QfP90_3.cjs.map → toast-d8_zmgkL.cjs.map} +1 -1
- package/dist/vue3/useResizableCalculations-BDITle3Q.cjs +2 -0
- package/dist/vue3/useResizableCalculations-BDITle3Q.cjs.map +1 -0
- package/dist/vue3/useResizableCalculations-DAajatT4.js +80 -0
- package/dist/vue3/useResizableCalculations-DAajatT4.js.map +1 -0
- package/package.json +1 -1
- package/dist/vue3/lib/rich-text-editor/markdownRenderer.cjs.map +0 -1
- package/dist/vue3/lib/rich-text-editor/markdownRenderer.js.map +0 -1
- package/dist/vue3/rich_text_editor-CEwKDuzw.cjs +0 -10
- package/dist/vue3/rich_text_editor-CEwKDuzw.cjs.map +0 -1
- package/dist/vue3/rich_text_editor-CtCGNkSD.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resizable_utils-BComtrMV.js","names":[],"sources":["../components/resizable/resizable_constants.ts","../components/resizable/resizable_utils.ts"],"sourcesContent":["/**\n * Resizable panel system — types and injection keys.\n *\n * @see resizable.vue — provides all keys\n * @see resizable_panel.vue — consumes panel/layout keys\n * @see resizable_handle.vue — consumes handle/resize keys\n */\nimport type { InjectionKey, ComputedRef, ComponentInternalInstance } from 'vue';\nimport type { LayoutResult } from './composables/computeLayout';\n\n// ─── Sizing Types ──────────────────────────────────────────────────────────\n\n/**\n * Resizable panels accept size tokens (numeric strings mapped to pixel values)\n * or percentage values with 'p' suffix (e.g., '50p').\n * parseSizeToPixels() warns for unrecognized values.\n */\nexport type ResizableSizeValue = string;\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport type ResizableDirection = 'row' | 'column';\n\nexport interface ResizablePanelConfig {\n /** Panel identifier. Auto-generated by ResizableGroup if not provided. */\n id: string;\n /** Initial size - size token (e.g., '925') or percentage with 'p' suffix (e.g., '50p') */\n initialSize?: ResizableSizeValue;\n\n // ─── User Drag Limits (Absolute Boundaries) ───\n /** Hard floor for user dragging. User cannot drag panel smaller than this. */\n userMinSize?: ResizableSizeValue;\n /** Hard ceiling for user dragging. User cannot drag panel larger than this. */\n userMaxSize?: ResizableSizeValue;\n\n // ─── System Scaling Limits (Operating Range) ───\n /**\n * System scaling floor. System won't compress panel below this during viewport resize.\n * Must be >= userMinSize. Falls back to userMinSize if not specified.\n */\n systemMinSize?: ResizableSizeValue;\n /**\n * System scaling ceiling. System won't expand panel above this during viewport resize.\n * Must be <= userMaxSize. Falls back to userMaxSize if not specified.\n */\n systemMaxSize?: ResizableSizeValue;\n\n // ─── Auto-Collapse ───\n /**\n * Container width threshold for auto-collapse.\n * When container width drops below this value, panel auto-collapses.\n * This is the container width, not the panel width.\n */\n collapseSize?: ResizableSizeValue;\n\n // ─── Behavior Flags ───\n /** Whether this panel can be resized by user dragging */\n resizable?: boolean;\n /** Whether this panel can be manually collapsed via UI */\n collapsible?: boolean;\n /** Initial collapsed state */\n collapsed?: boolean;\n\n}\n\nexport interface ResizablePanelState extends ResizablePanelConfig {\n // ─── Core State ───\n /** Current size in pixels (primary storage) */\n pixelSize: number;\n\n // ─── User Drag Constraints (Computed Pixels) ───\n /** Computed pixel value for userMinSize (absolute floor for user dragging) */\n userMinSizePixels?: number;\n /** Computed pixel value for userMaxSize (absolute ceiling for user dragging) */\n userMaxSizePixels?: number;\n\n // ─── System Scaling Constraints (Computed Pixels) ───\n /** Computed pixel value for systemMinSize (system scaling floor) */\n systemMinSizePixels?: number;\n /** Computed pixel value for systemMaxSize (system scaling ceiling) */\n systemMaxSizePixels?: number;\n\n // ─── Auto-Collapse State ───\n /** Computed pixel value for collapseSize (container width threshold) */\n collapseSizePixels?: number;\n /** True if panel was auto-collapsed (vs manually collapsed via UI) */\n autoCollapsed?: boolean;\n\n // ─── Manual Resize Tracking ───\n /**\n * Internal: Stores the user's preferred pixel size when they drag a panel.\n * Used by the drag system to track intent before converting to ratio.\n * Not exposed as a component prop.\n */\n manualTargetSize?: number;\n /**\n * Stores the user's preferred ratio (0–1) when they drag a panel.\n * - undefined: no manual target, panel scales proportionally with viewport\n * - number: panel targets (ratio × containerSize) pixels on each render,\n * still subject to min/max constraints.\n *\n * Enables correct proportional scaling when the viewport changes.\n * Panel feels \"sticky\" at the chosen proportion.\n */\n manualTargetRatio?: number;\n\n // ─── Storage Restoration ───\n /**\n * True if this panel's state was loaded from localStorage on the current\n * initialization pass. Prevents double-restoration when loadFromStorage is\n * called multiple times (e.g. the deferred 100ms retry in useResizableCore).\n */\n restoredFromStorage?: boolean;\n\n}\n\nexport interface ResizableHandleConfig {\n id: string;\n beforePanelId: string;\n afterPanelId: string;\n direction: ResizableDirection;\n}\n\nexport type ResizableSizeMode = 'percentage' | 'pixels';\n\n\nexport interface ResizableGroupConfig {\n direction: ResizableDirection;\n panels: ResizablePanelConfig[];\n storageKey?: string; // Optional localStorage key for persistence\n sizeMode?: ResizableSizeMode; // Whether to use percentage or pixel-based sizing\n limitToParent?: boolean; // Limit resizing to parent viewport bounds\n}\n\nexport interface ResizableGroupState {\n direction: ResizableDirection;\n panels: ResizablePanelState[];\n containerSize: number; // Total container size in pixels\n isResizing: boolean;\n activeHandleId?: string;\n}\n\nexport interface ResizableEvents {\n 'panel-resize': (panelId: string, size: number) => void;\n 'panel-collapse': (panelId: string, collapsed: boolean) => void;\n 'resize-start': (handleId: string) => void;\n 'resize-end': (handleId: string) => void;\n}\n\n/**\n * Defines collapse behavior for a panel during space constraints.\n * Used to determine which panels collapse first when viewport shrinks.\n */\nexport interface CollapseRule {\n /** Panel ID this rule applies to */\n panelId: string;\n /** Collapse priority - lower numbers collapse first */\n priority: number;\n /** Optional threshold that triggers collapse (overrides panel's userMinSize) */\n minSizeBeforeCollapse?: ResizableSizeValue;\n}\n\n/**\n// ─── Defaults ─────────────────────────────────────────────────────────────\n\n/** Default panel size when no initialSize is specified (50% of container). */\nexport const DEFAULT_PANEL_SIZE = '50p';\n\n/** Minimum panel size in pixels below which a resize is rejected. */\nexport const MIN_PANEL_SIZE_PX = 10;\n\n// ─── Storage Adapter ───────────────────────────────────────────────────────\n\n/**\n * Interface for pluggable storage backends.\n * Implement this to persist panel layouts to Pinia, Vuex, IndexedDB, etc.\n * The built-in `localStorageAdapter(key)` factory creates a localStorage-backed adapter.\n */\nexport interface ResizableStorageAdapter {\n /** Persist the current panel layout. */\n save(data: ResizableStoragePanelData[]): void;\n /** Load a previously saved layout. Returns null if nothing is stored. */\n load(): ResizableStoragePanelData[] | null;\n /** Remove all persisted data for this layout. */\n clear(): void;\n}\n\n/**\n * Shape of a single panel's persisted data.\n * Intentionally minimal — only what's needed to restore a layout.\n */\nexport interface ResizableStoragePanelData {\n id: string;\n pixelSize: number;\n collapsed?: boolean;\n autoCollapsed?: boolean;\n manualTargetRatio?: number;\n}\n\n// ─── Injection Context ──────────────────────────────────────────────────────\n// Single context object for provide/inject between ResizableGroup, Panel, Handle.\n\nexport interface ResizableContext {\n // Reactive state\n layout: ComputedRef<LayoutResult>;\n panels: ComputedRef<ResizablePanelState[]>;\n panelMap: ComputedRef<Map<string, ResizablePanelState>>;\n direction: ComputedRef<ResizableDirection>;\n containerSize: ComputedRef<number>;\n containerElement: ComputedRef<HTMLElement | null>;\n isResizing: ComputedRef<boolean>;\n activeHandleId: ComputedRef<string | undefined>;\n isInitializing: ComputedRef<boolean>;\n messages: Record<string, string>;\n\n // Offset (from fixed header/toolbar)\n offsetHandleStyles: ComputedRef<Record<string, string>>;\n offsetContentStyles: ComputedRef<Record<string, string>>;\n\n // Operations\n startResize: (handleId: string) => void;\n resetPanels: (\n beforePanelId?: string,\n afterPanelId?: string,\n behavior?: 'both' | 'before' | 'after' | 'all',\n ) => void;\n registerHandle: (instance: ComponentInternalInstance | null) => void;\n unregisterHandle: (instance: ComponentInternalInstance | null) => void;\n registerPanel: (config: ResizablePanelConfig) => void;\n unregisterPanel: (id: string) => void;\n saveToStorage: () => void;\n announce: (message: string) => void;\n collapsePanel: (panelId: string, collapsed: boolean) => void;\n emitPanelResize: (panelId: string, size: number) => void;\n commitPanelSize: (panelId: string, pixels: number) => void;\n updateSavedPanel: (panelId: string, updates: Partial<ResizableStoragePanelData>) => void;\n}\n\nexport const RESIZABLE_CONTEXT_KEY: InjectionKey<ResizableContext> = Symbol('resizable-context');\n\n/**\n * Build a composite handle ID from the before and after panel IDs.\n * Handles use the format \"{beforePanelId}:{afterPanelId}\" throughout the system.\n */\nexport function buildHandleId(beforeId: string, afterId: string): string {\n return `${beforeId}:${afterId}`;\n}\n","import type { ResizableSizeValue } from './resizable_constants';\n\n// ─── Size Token Resolution ─────────────────────────────────────────────────\n// Resolves Dialtone size tokens (e.g., '925') to pixel values.\n// Reads --dt-size-{token} CSS custom properties at runtime to stay in sync\n// with the token pipeline. Falls back to a static map in environments where\n// CSS custom properties aren't available (tests, SSR).\n//\n// Will map to --dt-layout-* tokens when they land on the `next` branch.\n\n/** Cache for resolved token pixel values (populated on first use). */\nconst tokenCache = new Map<string, number>();\n\n/** Root font size cache — read once from getComputedStyle. */\nlet cachedRootFontSize: number | null = null;\n\nfunction getRootFontSize(): number {\n if (cachedRootFontSize !== null) return cachedRootFontSize;\n if (typeof document !== 'undefined') {\n cachedRootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize) || 10;\n } else {\n cachedRootFontSize = 10; // Dialtone default\n }\n return cachedRootFontSize;\n}\n\n/**\n * Resolve a Dialtone size token to pixels via CSS custom properties.\n * Falls back to FALLBACK_SIZE_TOKENS when CSS isn't available.\n */\nfunction resolveTokenPixels(token: string): number | undefined {\n if (tokenCache.has(token)) return tokenCache.get(token);\n\n // Try runtime CSS resolution\n if (typeof document !== 'undefined') {\n const cssValue = getComputedStyle(document.documentElement)\n .getPropertyValue(`--dt-size-${token}`)\n .trim();\n\n if (cssValue) {\n const remMatch = cssValue.match(/^([\\d.]+)rem$/);\n if (remMatch) {\n const px = parseFloat(remMatch[1]) * getRootFontSize();\n tokenCache.set(token, px);\n return px;\n }\n const pxMatch = cssValue.match(/^([\\d.]+)px$/);\n if (pxMatch) {\n const px = parseFloat(pxMatch[1]);\n tokenCache.set(token, px);\n return px;\n }\n }\n }\n\n // Fallback: static map mirrors --dt-size-* tokens from dialtone-tokens\n // Kept for jsdom tests and SSR where CSS custom properties aren't loaded.\n if (token in FALLBACK_SIZE_TOKENS) {\n const px = FALLBACK_SIZE_TOKENS[token];\n tokenCache.set(token, px);\n return px;\n }\n\n return undefined;\n}\n\n/**\n * Static fallback map — mirrors Dialtone size tokens (base/default.json).\n * Only used when CSS custom properties are unavailable (tests, SSR).\n */\nconst FALLBACK_SIZE_TOKENS: Record<string, number> = {\n '0': 0, '50': 0.5, '100': 1, '200': 2, '300': 4, '350': 6,\n '400': 8, '450': 12, '500': 16, '525': 20, '550': 24, '600': 32,\n '625': 42, '650': 48, '700': 64, '720': 72, '730': 84, '750': 96,\n '760': 102, '775': 114, '800': 128, '825': 164, '850': 192, '875': 216,\n '900': 256, '905': 264, '925': 332, '950': 384, '975': 464, '1000': 512,\n '1020': 628, '1040': 764, '1050': 768, '1060': 828, '1080': 912,\n '1100': 1024, '1115': 1140, '1120': 1268, '1125': 1280, '1130': 1340,\n '1150': 1536, '1200': 2048,\n};\n\n// ─── Percentage Resolution ─────────────────────────────────────────────────\n// Percentage tokens use a simple pattern: numeric value + 'p' suffix.\n\nfunction parsePercentage(value: string): number | undefined {\n if (!value.endsWith('p')) return undefined;\n const num = parseFloat(value.slice(0, -1));\n return isFinite(num) && num >= 0 && num <= 100 ? num : undefined;\n}\n\n// ─── Token Helpers ──────────────────────────────────────────────────────────\n\nfunction isSizeToken(value: string): boolean {\n return resolveTokenPixels(value) !== undefined;\n}\n\nfunction isPercentageToken(value: string): boolean {\n return parsePercentage(value) !== undefined;\n}\n\nexport function isValidSizing(value: string): boolean {\n return isSizeToken(value) || isPercentageToken(value);\n}\n\nfunction parseTokenToPixels(value: string, containerSize: number): number {\n const sizePixels = resolveTokenPixels(value);\n if (sizePixels !== undefined) return sizePixels;\n\n const percentage = parsePercentage(value);\n if (percentage !== undefined) return (percentage / 100) * containerSize;\n\n console.warn(`[resizable] Invalid sizing value: ${value}`);\n return 0;\n}\n\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport interface ParseSizeOptions {\n /**\n * When true, clamps the result to container size.\n * Panels cannot exceed their parent container.\n * @default true\n */\n clampToContainer?: boolean;\n}\n\n/**\n * Parses a ResizableSizeValue and returns the pixel value.\n * Handles size tokens (e.g., '925') and percentage tokens (e.g., '50p').\n *\n * Size tokens resolve from --dt-size-{token} CSS custom properties at runtime,\n * falling back to a static map in test/SSR environments.\n *\n * @param value - Size token or percentage token\n * @param containerSize - Container size in pixels\n * @param options - Optional configuration\n * @returns Pixel value, clamped to container by default\n *\n * @example\n * parseSizeToPixels('925', 1000) // Returns 332 (from --dt-size-925)\n * parseSizeToPixels('50p', 1000) // Returns 500 (50% of 1000)\n * parseSizeToPixels('1100', 1000) // Returns 1000 (clamped from 1024px)\n */\nexport function parseSizeToPixels(\n value: ResizableSizeValue,\n containerSize: number,\n options?: ParseSizeOptions\n): number {\n const { clampToContainer = true } = options ?? {};\n const validatedContainerSize = validateContainerSize(containerSize);\n\n if (isCollapsedPanel(validatedContainerSize, value)) {\n return 0;\n }\n\n const calculationContainerSize = validatedContainerSize === 0 ? 1000 : validatedContainerSize;\n\n if (typeof value === 'string' && isValidSizing(value)) {\n const result = parseTokenToPixels(value, calculationContainerSize);\n return validatePixelResult(result, value, validatedContainerSize, clampToContainer);\n }\n\n console.warn(\n `[resizable] Invalid ResizableSizeValue: ${value}. Expected a size token or percentage with 'p' suffix.`\n );\n return 0;\n}\n\nexport function validateContainerSize(containerSize: number): number {\n if (!isFinite(containerSize) || containerSize < 0) {\n console.warn(`[resizable] Invalid containerSize: ${containerSize}. Using fallback value of 1000px.`);\n return 1000;\n }\n\n if (containerSize > 10000) {\n console.warn(`[resizable] Unusually large containerSize: ${containerSize}px. Capping at 10000px.`);\n return 10000;\n }\n\n return containerSize;\n}\n\nfunction isCollapsedPanel(containerSize: number, value: ResizableSizeValue): boolean {\n return containerSize === 0 && value === '0';\n}\n\nfunction validatePixelResult(\n result: number,\n value: ResizableSizeValue,\n containerSize: number,\n clampToContainer: boolean\n): number {\n if (!isFinite(result) || result < 0) {\n console.warn(\n `[resizable] Invalid pixel calculation result: ${result} for value: ${value}, containerSize: ${containerSize}`\n );\n return 0;\n }\n\n if (clampToContainer && containerSize > 0 && result > containerSize) {\n console.warn(\n `[resizable] Size value '${value}' (${result}px) exceeds container (${containerSize}px). Clamping to container.`\n );\n return containerSize;\n }\n\n return result;\n}\n\nexport function isPercentageValue(value: ResizableSizeValue): boolean {\n return isPercentageToken(value);\n}\n\nexport function isCSSValue(value: ResizableSizeValue): boolean {\n return isSizeToken(value);\n}\n\nexport function pixelsToPercentage(pixels: number, containerSize: number): number {\n return (pixels / containerSize) * 100;\n}\n\n/**\n * Checks if a panel's userMinSize is percentage-based (e.g., '50p').\n */\nexport function hasPercentageMinSize(panel: { userMinSize?: ResizableSizeValue }): boolean {\n if (!panel.userMinSize) return false;\n return isPercentageToken(panel.userMinSize);\n}\n\n/**\n * Invalidate the token cache. Call when the theme changes or\n * when token values may have been updated at runtime.\n */\nexport function invalidateTokenCache(): void {\n tokenCache.clear();\n cachedRootFontSize = null;\n}\n"],"mappings":";AAsKA,IAAa,IAAqB,OAGrB,IAAoB,IAqEpB,IAAwD,OAAO,oBAAoB;AAMhG,SAAgB,EAAc,GAAkB,GAAyB;AACvE,QAAO,GAAG,EAAS,GAAG;;;;AC1OxB,IAAM,oBAAa,IAAI,KAAqB,EAGxC,IAAoC;AAExC,SAAS,IAA0B;AAOjC,QANI,MAAuB,SAC3B,AAGE,IAHE,OAAO,WAAa,OACD,WAAW,iBAAiB,SAAS,gBAAgB,CAAC,SAAS,IAE/D,KAJiB;;AAa1C,SAAS,EAAmB,GAAmC;AAC7D,KAAI,EAAW,IAAI,EAAM,CAAE,QAAO,EAAW,IAAI,EAAM;AAGvD,KAAI,OAAO,WAAa,KAAa;EACnC,IAAM,IAAW,iBAAiB,SAAS,gBAAgB,CACxD,iBAAiB,aAAa,IAAQ,CACtC,MAAM;AAET,MAAI,GAAU;GACZ,IAAM,IAAW,EAAS,MAAM,gBAAgB;AAChD,OAAI,GAAU;IACZ,IAAM,IAAK,WAAW,EAAS,GAAG,GAAG,GAAiB;AAEtD,WADA,EAAW,IAAI,GAAO,EAAG,EAClB;;GAET,IAAM,IAAU,EAAS,MAAM,eAAe;AAC9C,OAAI,GAAS;IACX,IAAM,IAAK,WAAW,EAAQ,GAAG;AAEjC,WADA,EAAW,IAAI,GAAO,EAAG,EAClB;;;;AAOb,KAAI,KAAS,GAAsB;EACjC,IAAM,IAAK,EAAqB;AAEhC,SADA,EAAW,IAAI,GAAO,EAAG,EAClB;;;AAUX,IAAM,IAA+C;CACnD,GAAK;CAAG,IAAM;CAAK,KAAO;CAAG,KAAO;CAAG,KAAO;CAAG,KAAO;CACxD,KAAO;CAAG,KAAO;CAAI,KAAO;CAAI,KAAO;CAAI,KAAO;CAAI,KAAO;CAC7D,KAAO;CAAI,KAAO;CAAI,KAAO;CAAI,KAAO;CAAI,KAAO;CAAI,KAAO;CAC9D,KAAO;CAAK,KAAO;CAAK,KAAO;CAAK,KAAO;CAAK,KAAO;CAAK,KAAO;CACnE,KAAO;CAAK,KAAO;CAAK,KAAO;CAAK,KAAO;CAAK,KAAO;CAAK,KAAQ;CACpE,MAAQ;CAAK,MAAQ;CAAK,MAAQ;CAAK,MAAQ;CAAK,MAAQ;CAC5D,MAAQ;CAAM,MAAQ;CAAM,MAAQ;CAAM,MAAQ;CAAM,MAAQ;CAChE,MAAQ;CAAM,MAAQ;CACvB;AAKD,SAAS,EAAgB,GAAmC;AAC1D,KAAI,CAAC,EAAM,SAAS,IAAI,CAAE;CAC1B,IAAM,IAAM,WAAW,EAAM,MAAM,GAAG,GAAG,CAAC;AAC1C,QAAO,SAAS,EAAI,IAAI,KAAO,KAAK,KAAO,MAAM,IAAM,KAAA;;AAKzD,SAAS,EAAY,GAAwB;AAC3C,QAAO,EAAmB,EAAM,KAAK,KAAA;;AAGvC,SAAS,EAAkB,GAAwB;AACjD,QAAO,EAAgB,EAAM,KAAK,KAAA;;AAGpC,SAAgB,EAAc,GAAwB;AACpD,QAAO,EAAY,EAAM,IAAI,EAAkB,EAAM;;AAGvD,SAAS,EAAmB,GAAe,GAA+B;CACxE,IAAM,IAAa,EAAmB,EAAM;AAC5C,KAAI,MAAe,KAAA,EAAW,QAAO;CAErC,IAAM,IAAa,EAAgB,EAAM;AAIzC,QAHI,MAAe,KAAA,KAEnB,QAAQ,KAAK,qCAAqC,IAAQ,EACnD,KAH+B,IAAa,MAAO;;AAkC5D,SAAgB,EACd,GACA,GACA,GACQ;CACR,IAAM,EAAE,sBAAmB,OAAS,KAAW,EAAE,EAC3C,IAAyB,EAAsB,EAAc;AAEnE,KAAI,EAAiB,GAAwB,EAAM,CACjD,QAAO;CAGT,IAAM,IAA2B,MAA2B,IAAI,MAAO;AAUvE,QARI,OAAO,KAAU,YAAY,EAAc,EAAM,GAE5C,EADQ,EAAmB,GAAO,EAAyB,EAC/B,GAAO,GAAwB,EAAiB,IAGrF,QAAQ,KACN,2CAA2C,EAAM,wDAClD,EACM;;AAGT,SAAgB,EAAsB,GAA+B;AAWnE,QAVI,CAAC,SAAS,EAAc,IAAI,IAAgB,KAC9C,QAAQ,KAAK,sCAAsC,EAAc,mCAAmC,EAC7F,OAGL,IAAgB,OAClB,QAAQ,KAAK,8CAA8C,EAAc,yBAAyB,EAC3F,OAGF;;AAGT,SAAS,EAAiB,GAAuB,GAAoC;AACnF,QAAO,MAAkB,KAAK,MAAU;;AAG1C,SAAS,EACP,GACA,GACA,GACA,GACQ;AAeR,QAdI,CAAC,SAAS,EAAO,IAAI,IAAS,KAChC,QAAQ,KACN,iDAAiD,EAAO,cAAc,EAAM,mBAAmB,IAChG,EACM,KAGL,KAAoB,IAAgB,KAAK,IAAS,KACpD,QAAQ,KACN,2BAA2B,EAAM,KAAK,EAAO,yBAAyB,EAAc,6BACrF,EACM,KAGF;;AAGT,SAAgB,EAAkB,GAAoC;AACpE,QAAO,EAAkB,EAAM;;AAGjC,SAAgB,EAAW,GAAoC;AAC7D,QAAO,EAAY,EAAM;;AAG3B,SAAgB,EAAmB,GAAgB,GAA+B;AAChF,QAAQ,IAAS,IAAiB;;AAMpC,SAAgB,EAAqB,GAAsD;AAEzF,QADK,EAAM,cACJ,EAAkB,EAAM,YAAY,GADZ;;AAQjC,SAAgB,IAA6B;AAE3C,CADA,EAAW,OAAO,EAClB,IAAqB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=`50p`,t=10,n=Symbol(`resizable-context`);function r(e,t){return`${e}:${t}`}var i=new Map,a=null;function o(){return a===null&&(a=typeof document<`u`&&parseFloat(getComputedStyle(document.documentElement).fontSize)||10),a}function s(e){if(i.has(e))return i.get(e);if(typeof document<`u`){let t=getComputedStyle(document.documentElement).getPropertyValue(`--dt-size-${e}`).trim();if(t){let n=t.match(/^([\d.]+)rem$/);if(n){let t=parseFloat(n[1])*o();return i.set(e,t),t}let r=t.match(/^([\d.]+)px$/);if(r){let t=parseFloat(r[1]);return i.set(e,t),t}}}if(e in c){let t=c[e];return i.set(e,t),t}}var c={0:0,50:.5,100:1,200:2,300:4,350:6,400:8,450:12,500:16,525:20,550:24,600:32,625:42,650:48,700:64,720:72,730:84,750:96,760:102,775:114,800:128,825:164,850:192,875:216,900:256,905:264,925:332,950:384,975:464,1e3:512,1020:628,1040:764,1050:768,1060:828,1080:912,1100:1024,1115:1140,1120:1268,1125:1280,1130:1340,1150:1536,1200:2048};function l(e){if(!e.endsWith(`p`))return;let t=parseFloat(e.slice(0,-1));return isFinite(t)&&t>=0&&t<=100?t:void 0}function u(e){return s(e)!==void 0}function d(e){return l(e)!==void 0}function f(e){return u(e)||d(e)}function p(e,t){let n=s(e);if(n!==void 0)return n;let r=l(e);return r===void 0?(console.warn(`[resizable] Invalid sizing value: ${e}`),0):r/100*t}function m(e,t,n){let{clampToContainer:r=!0}=n??{},i=h(t);if(g(i,e))return 0;let a=i===0?1e3:i;return typeof e==`string`&&f(e)?_(p(e,a),e,i,r):(console.warn(`[resizable] Invalid ResizableSizeValue: ${e}. Expected a size token or percentage with 'p' suffix.`),0)}function h(e){return!isFinite(e)||e<0?(console.warn(`[resizable] Invalid containerSize: ${e}. Using fallback value of 1000px.`),1e3):e>1e4?(console.warn(`[resizable] Unusually large containerSize: ${e}px. Capping at 10000px.`),1e4):e}function g(e,t){return e===0&&t===`0`}function _(e,t,n,r){return!isFinite(e)||e<0?(console.warn(`[resizable] Invalid pixel calculation result: ${e} for value: ${t}, containerSize: ${n}`),0):r&&n>0&&e>n?(console.warn(`[resizable] Size value '${t}' (${e}px) exceeds container (${n}px). Clamping to container.`),n):e}function v(e){return d(e)}function y(e){return u(e)}function b(e,t){return e/t*100}function x(e){return e.userMinSize?d(e.userMinSize):!1}function S(){i.clear(),a=null}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return e}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return t}});
|
|
2
|
+
//# sourceMappingURL=resizable_utils-DhuzXRdP.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resizable_utils-DhuzXRdP.cjs","names":[],"sources":["../components/resizable/resizable_constants.ts","../components/resizable/resizable_utils.ts"],"sourcesContent":["/**\n * Resizable panel system — types and injection keys.\n *\n * @see resizable.vue — provides all keys\n * @see resizable_panel.vue — consumes panel/layout keys\n * @see resizable_handle.vue — consumes handle/resize keys\n */\nimport type { InjectionKey, ComputedRef, ComponentInternalInstance } from 'vue';\nimport type { LayoutResult } from './composables/computeLayout';\n\n// ─── Sizing Types ──────────────────────────────────────────────────────────\n\n/**\n * Resizable panels accept size tokens (numeric strings mapped to pixel values)\n * or percentage values with 'p' suffix (e.g., '50p').\n * parseSizeToPixels() warns for unrecognized values.\n */\nexport type ResizableSizeValue = string;\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport type ResizableDirection = 'row' | 'column';\n\nexport interface ResizablePanelConfig {\n /** Panel identifier. Auto-generated by ResizableGroup if not provided. */\n id: string;\n /** Initial size - size token (e.g., '925') or percentage with 'p' suffix (e.g., '50p') */\n initialSize?: ResizableSizeValue;\n\n // ─── User Drag Limits (Absolute Boundaries) ───\n /** Hard floor for user dragging. User cannot drag panel smaller than this. */\n userMinSize?: ResizableSizeValue;\n /** Hard ceiling for user dragging. User cannot drag panel larger than this. */\n userMaxSize?: ResizableSizeValue;\n\n // ─── System Scaling Limits (Operating Range) ───\n /**\n * System scaling floor. System won't compress panel below this during viewport resize.\n * Must be >= userMinSize. Falls back to userMinSize if not specified.\n */\n systemMinSize?: ResizableSizeValue;\n /**\n * System scaling ceiling. System won't expand panel above this during viewport resize.\n * Must be <= userMaxSize. Falls back to userMaxSize if not specified.\n */\n systemMaxSize?: ResizableSizeValue;\n\n // ─── Auto-Collapse ───\n /**\n * Container width threshold for auto-collapse.\n * When container width drops below this value, panel auto-collapses.\n * This is the container width, not the panel width.\n */\n collapseSize?: ResizableSizeValue;\n\n // ─── Behavior Flags ───\n /** Whether this panel can be resized by user dragging */\n resizable?: boolean;\n /** Whether this panel can be manually collapsed via UI */\n collapsible?: boolean;\n /** Initial collapsed state */\n collapsed?: boolean;\n\n}\n\nexport interface ResizablePanelState extends ResizablePanelConfig {\n // ─── Core State ───\n /** Current size in pixels (primary storage) */\n pixelSize: number;\n\n // ─── User Drag Constraints (Computed Pixels) ───\n /** Computed pixel value for userMinSize (absolute floor for user dragging) */\n userMinSizePixels?: number;\n /** Computed pixel value for userMaxSize (absolute ceiling for user dragging) */\n userMaxSizePixels?: number;\n\n // ─── System Scaling Constraints (Computed Pixels) ───\n /** Computed pixel value for systemMinSize (system scaling floor) */\n systemMinSizePixels?: number;\n /** Computed pixel value for systemMaxSize (system scaling ceiling) */\n systemMaxSizePixels?: number;\n\n // ─── Auto-Collapse State ───\n /** Computed pixel value for collapseSize (container width threshold) */\n collapseSizePixels?: number;\n /** True if panel was auto-collapsed (vs manually collapsed via UI) */\n autoCollapsed?: boolean;\n\n // ─── Manual Resize Tracking ───\n /**\n * Internal: Stores the user's preferred pixel size when they drag a panel.\n * Used by the drag system to track intent before converting to ratio.\n * Not exposed as a component prop.\n */\n manualTargetSize?: number;\n /**\n * Stores the user's preferred ratio (0–1) when they drag a panel.\n * - undefined: no manual target, panel scales proportionally with viewport\n * - number: panel targets (ratio × containerSize) pixels on each render,\n * still subject to min/max constraints.\n *\n * Enables correct proportional scaling when the viewport changes.\n * Panel feels \"sticky\" at the chosen proportion.\n */\n manualTargetRatio?: number;\n\n // ─── Storage Restoration ───\n /**\n * True if this panel's state was loaded from localStorage on the current\n * initialization pass. Prevents double-restoration when loadFromStorage is\n * called multiple times (e.g. the deferred 100ms retry in useResizableCore).\n */\n restoredFromStorage?: boolean;\n\n}\n\nexport interface ResizableHandleConfig {\n id: string;\n beforePanelId: string;\n afterPanelId: string;\n direction: ResizableDirection;\n}\n\nexport type ResizableSizeMode = 'percentage' | 'pixels';\n\n\nexport interface ResizableGroupConfig {\n direction: ResizableDirection;\n panels: ResizablePanelConfig[];\n storageKey?: string; // Optional localStorage key for persistence\n sizeMode?: ResizableSizeMode; // Whether to use percentage or pixel-based sizing\n limitToParent?: boolean; // Limit resizing to parent viewport bounds\n}\n\nexport interface ResizableGroupState {\n direction: ResizableDirection;\n panels: ResizablePanelState[];\n containerSize: number; // Total container size in pixels\n isResizing: boolean;\n activeHandleId?: string;\n}\n\nexport interface ResizableEvents {\n 'panel-resize': (panelId: string, size: number) => void;\n 'panel-collapse': (panelId: string, collapsed: boolean) => void;\n 'resize-start': (handleId: string) => void;\n 'resize-end': (handleId: string) => void;\n}\n\n/**\n * Defines collapse behavior for a panel during space constraints.\n * Used to determine which panels collapse first when viewport shrinks.\n */\nexport interface CollapseRule {\n /** Panel ID this rule applies to */\n panelId: string;\n /** Collapse priority - lower numbers collapse first */\n priority: number;\n /** Optional threshold that triggers collapse (overrides panel's userMinSize) */\n minSizeBeforeCollapse?: ResizableSizeValue;\n}\n\n/**\n// ─── Defaults ─────────────────────────────────────────────────────────────\n\n/** Default panel size when no initialSize is specified (50% of container). */\nexport const DEFAULT_PANEL_SIZE = '50p';\n\n/** Minimum panel size in pixels below which a resize is rejected. */\nexport const MIN_PANEL_SIZE_PX = 10;\n\n// ─── Storage Adapter ───────────────────────────────────────────────────────\n\n/**\n * Interface for pluggable storage backends.\n * Implement this to persist panel layouts to Pinia, Vuex, IndexedDB, etc.\n * The built-in `localStorageAdapter(key)` factory creates a localStorage-backed adapter.\n */\nexport interface ResizableStorageAdapter {\n /** Persist the current panel layout. */\n save(data: ResizableStoragePanelData[]): void;\n /** Load a previously saved layout. Returns null if nothing is stored. */\n load(): ResizableStoragePanelData[] | null;\n /** Remove all persisted data for this layout. */\n clear(): void;\n}\n\n/**\n * Shape of a single panel's persisted data.\n * Intentionally minimal — only what's needed to restore a layout.\n */\nexport interface ResizableStoragePanelData {\n id: string;\n pixelSize: number;\n collapsed?: boolean;\n autoCollapsed?: boolean;\n manualTargetRatio?: number;\n}\n\n// ─── Injection Context ──────────────────────────────────────────────────────\n// Single context object for provide/inject between ResizableGroup, Panel, Handle.\n\nexport interface ResizableContext {\n // Reactive state\n layout: ComputedRef<LayoutResult>;\n panels: ComputedRef<ResizablePanelState[]>;\n panelMap: ComputedRef<Map<string, ResizablePanelState>>;\n direction: ComputedRef<ResizableDirection>;\n containerSize: ComputedRef<number>;\n containerElement: ComputedRef<HTMLElement | null>;\n isResizing: ComputedRef<boolean>;\n activeHandleId: ComputedRef<string | undefined>;\n isInitializing: ComputedRef<boolean>;\n messages: Record<string, string>;\n\n // Offset (from fixed header/toolbar)\n offsetHandleStyles: ComputedRef<Record<string, string>>;\n offsetContentStyles: ComputedRef<Record<string, string>>;\n\n // Operations\n startResize: (handleId: string) => void;\n resetPanels: (\n beforePanelId?: string,\n afterPanelId?: string,\n behavior?: 'both' | 'before' | 'after' | 'all',\n ) => void;\n registerHandle: (instance: ComponentInternalInstance | null) => void;\n unregisterHandle: (instance: ComponentInternalInstance | null) => void;\n registerPanel: (config: ResizablePanelConfig) => void;\n unregisterPanel: (id: string) => void;\n saveToStorage: () => void;\n announce: (message: string) => void;\n collapsePanel: (panelId: string, collapsed: boolean) => void;\n emitPanelResize: (panelId: string, size: number) => void;\n commitPanelSize: (panelId: string, pixels: number) => void;\n updateSavedPanel: (panelId: string, updates: Partial<ResizableStoragePanelData>) => void;\n}\n\nexport const RESIZABLE_CONTEXT_KEY: InjectionKey<ResizableContext> = Symbol('resizable-context');\n\n/**\n * Build a composite handle ID from the before and after panel IDs.\n * Handles use the format \"{beforePanelId}:{afterPanelId}\" throughout the system.\n */\nexport function buildHandleId(beforeId: string, afterId: string): string {\n return `${beforeId}:${afterId}`;\n}\n","import type { ResizableSizeValue } from './resizable_constants';\n\n// ─── Size Token Resolution ─────────────────────────────────────────────────\n// Resolves Dialtone size tokens (e.g., '925') to pixel values.\n// Reads --dt-size-{token} CSS custom properties at runtime to stay in sync\n// with the token pipeline. Falls back to a static map in environments where\n// CSS custom properties aren't available (tests, SSR).\n//\n// Will map to --dt-layout-* tokens when they land on the `next` branch.\n\n/** Cache for resolved token pixel values (populated on first use). */\nconst tokenCache = new Map<string, number>();\n\n/** Root font size cache — read once from getComputedStyle. */\nlet cachedRootFontSize: number | null = null;\n\nfunction getRootFontSize(): number {\n if (cachedRootFontSize !== null) return cachedRootFontSize;\n if (typeof document !== 'undefined') {\n cachedRootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize) || 10;\n } else {\n cachedRootFontSize = 10; // Dialtone default\n }\n return cachedRootFontSize;\n}\n\n/**\n * Resolve a Dialtone size token to pixels via CSS custom properties.\n * Falls back to FALLBACK_SIZE_TOKENS when CSS isn't available.\n */\nfunction resolveTokenPixels(token: string): number | undefined {\n if (tokenCache.has(token)) return tokenCache.get(token);\n\n // Try runtime CSS resolution\n if (typeof document !== 'undefined') {\n const cssValue = getComputedStyle(document.documentElement)\n .getPropertyValue(`--dt-size-${token}`)\n .trim();\n\n if (cssValue) {\n const remMatch = cssValue.match(/^([\\d.]+)rem$/);\n if (remMatch) {\n const px = parseFloat(remMatch[1]) * getRootFontSize();\n tokenCache.set(token, px);\n return px;\n }\n const pxMatch = cssValue.match(/^([\\d.]+)px$/);\n if (pxMatch) {\n const px = parseFloat(pxMatch[1]);\n tokenCache.set(token, px);\n return px;\n }\n }\n }\n\n // Fallback: static map mirrors --dt-size-* tokens from dialtone-tokens\n // Kept for jsdom tests and SSR where CSS custom properties aren't loaded.\n if (token in FALLBACK_SIZE_TOKENS) {\n const px = FALLBACK_SIZE_TOKENS[token];\n tokenCache.set(token, px);\n return px;\n }\n\n return undefined;\n}\n\n/**\n * Static fallback map — mirrors Dialtone size tokens (base/default.json).\n * Only used when CSS custom properties are unavailable (tests, SSR).\n */\nconst FALLBACK_SIZE_TOKENS: Record<string, number> = {\n '0': 0, '50': 0.5, '100': 1, '200': 2, '300': 4, '350': 6,\n '400': 8, '450': 12, '500': 16, '525': 20, '550': 24, '600': 32,\n '625': 42, '650': 48, '700': 64, '720': 72, '730': 84, '750': 96,\n '760': 102, '775': 114, '800': 128, '825': 164, '850': 192, '875': 216,\n '900': 256, '905': 264, '925': 332, '950': 384, '975': 464, '1000': 512,\n '1020': 628, '1040': 764, '1050': 768, '1060': 828, '1080': 912,\n '1100': 1024, '1115': 1140, '1120': 1268, '1125': 1280, '1130': 1340,\n '1150': 1536, '1200': 2048,\n};\n\n// ─── Percentage Resolution ─────────────────────────────────────────────────\n// Percentage tokens use a simple pattern: numeric value + 'p' suffix.\n\nfunction parsePercentage(value: string): number | undefined {\n if (!value.endsWith('p')) return undefined;\n const num = parseFloat(value.slice(0, -1));\n return isFinite(num) && num >= 0 && num <= 100 ? num : undefined;\n}\n\n// ─── Token Helpers ──────────────────────────────────────────────────────────\n\nfunction isSizeToken(value: string): boolean {\n return resolveTokenPixels(value) !== undefined;\n}\n\nfunction isPercentageToken(value: string): boolean {\n return parsePercentage(value) !== undefined;\n}\n\nexport function isValidSizing(value: string): boolean {\n return isSizeToken(value) || isPercentageToken(value);\n}\n\nfunction parseTokenToPixels(value: string, containerSize: number): number {\n const sizePixels = resolveTokenPixels(value);\n if (sizePixels !== undefined) return sizePixels;\n\n const percentage = parsePercentage(value);\n if (percentage !== undefined) return (percentage / 100) * containerSize;\n\n console.warn(`[resizable] Invalid sizing value: ${value}`);\n return 0;\n}\n\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport interface ParseSizeOptions {\n /**\n * When true, clamps the result to container size.\n * Panels cannot exceed their parent container.\n * @default true\n */\n clampToContainer?: boolean;\n}\n\n/**\n * Parses a ResizableSizeValue and returns the pixel value.\n * Handles size tokens (e.g., '925') and percentage tokens (e.g., '50p').\n *\n * Size tokens resolve from --dt-size-{token} CSS custom properties at runtime,\n * falling back to a static map in test/SSR environments.\n *\n * @param value - Size token or percentage token\n * @param containerSize - Container size in pixels\n * @param options - Optional configuration\n * @returns Pixel value, clamped to container by default\n *\n * @example\n * parseSizeToPixels('925', 1000) // Returns 332 (from --dt-size-925)\n * parseSizeToPixels('50p', 1000) // Returns 500 (50% of 1000)\n * parseSizeToPixels('1100', 1000) // Returns 1000 (clamped from 1024px)\n */\nexport function parseSizeToPixels(\n value: ResizableSizeValue,\n containerSize: number,\n options?: ParseSizeOptions\n): number {\n const { clampToContainer = true } = options ?? {};\n const validatedContainerSize = validateContainerSize(containerSize);\n\n if (isCollapsedPanel(validatedContainerSize, value)) {\n return 0;\n }\n\n const calculationContainerSize = validatedContainerSize === 0 ? 1000 : validatedContainerSize;\n\n if (typeof value === 'string' && isValidSizing(value)) {\n const result = parseTokenToPixels(value, calculationContainerSize);\n return validatePixelResult(result, value, validatedContainerSize, clampToContainer);\n }\n\n console.warn(\n `[resizable] Invalid ResizableSizeValue: ${value}. Expected a size token or percentage with 'p' suffix.`\n );\n return 0;\n}\n\nexport function validateContainerSize(containerSize: number): number {\n if (!isFinite(containerSize) || containerSize < 0) {\n console.warn(`[resizable] Invalid containerSize: ${containerSize}. Using fallback value of 1000px.`);\n return 1000;\n }\n\n if (containerSize > 10000) {\n console.warn(`[resizable] Unusually large containerSize: ${containerSize}px. Capping at 10000px.`);\n return 10000;\n }\n\n return containerSize;\n}\n\nfunction isCollapsedPanel(containerSize: number, value: ResizableSizeValue): boolean {\n return containerSize === 0 && value === '0';\n}\n\nfunction validatePixelResult(\n result: number,\n value: ResizableSizeValue,\n containerSize: number,\n clampToContainer: boolean\n): number {\n if (!isFinite(result) || result < 0) {\n console.warn(\n `[resizable] Invalid pixel calculation result: ${result} for value: ${value}, containerSize: ${containerSize}`\n );\n return 0;\n }\n\n if (clampToContainer && containerSize > 0 && result > containerSize) {\n console.warn(\n `[resizable] Size value '${value}' (${result}px) exceeds container (${containerSize}px). Clamping to container.`\n );\n return containerSize;\n }\n\n return result;\n}\n\nexport function isPercentageValue(value: ResizableSizeValue): boolean {\n return isPercentageToken(value);\n}\n\nexport function isCSSValue(value: ResizableSizeValue): boolean {\n return isSizeToken(value);\n}\n\nexport function pixelsToPercentage(pixels: number, containerSize: number): number {\n return (pixels / containerSize) * 100;\n}\n\n/**\n * Checks if a panel's userMinSize is percentage-based (e.g., '50p').\n */\nexport function hasPercentageMinSize(panel: { userMinSize?: ResizableSizeValue }): boolean {\n if (!panel.userMinSize) return false;\n return isPercentageToken(panel.userMinSize);\n}\n\n/**\n * Invalidate the token cache. Call when the theme changes or\n * when token values may have been updated at runtime.\n */\nexport function invalidateTokenCache(): void {\n tokenCache.clear();\n cachedRootFontSize = null;\n}\n"],"mappings":"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"}
|