@broadpaper/editor 0.1.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/create-designer.tsx","../src/state/session.ts","../src/state/observable.ts","../src/options.ts","../src/ReportDesigner.tsx","../src/state/context.tsx","../src/ui/floating.tsx","../src/ui/icons.tsx","../src/state/actions.ts","../src/toolbar/Toolbar.tsx","../src/ui/primitives.tsx","../src/ui/use-element-size.ts","../src/toolbar/SaveIndicator.tsx","../src/toolbar/density.ts","../src/toolbar/zoom.ts","../src/panels/LeftPanel.tsx","../src/dnd/drag-manager.ts","../src/canvas/Canvas.tsx","../src/canvas/PageView.tsx","../src/canvas/Overlays.tsx","../src/canvas/geometry.ts","../src/canvas/InlineEditor.tsx","../src/richtext/editor.ts","../src/richtext/schema.ts","../src/richtext/autocomplete.ts","../src/richtext/TokenSuggestions.tsx","../src/inspector/DataPicker.tsx","../src/inspector/fields/ColorField.tsx","../src/dnd/drag-controller.ts","../src/canvas/Breadcrumb.tsx","../src/canvas/DesignLegend.tsx","../src/inspector/NodeInspector.tsx","../src/inspector/fields/FieldRenderer.tsx","../src/inspector/fields/BindingField.tsx","../src/inspector/fields/ImageField.tsx","../src/inspector/fields/ConditionBuilder.tsx","../src/inspector/fields/ListEditors.tsx","../src/inspector/StyleGroups.tsx","../src/inspector/DocumentInspector.tsx","../src/inspector/Inspector.tsx","../src/ui/PanelResizer.tsx","../src/ui/Boundary.tsx","../src/styles/generated-css.ts"],"sourcesContent":["import { createRoot, type Root } from \"react-dom/client\";\nimport { createElement } from \"react\";\nimport { ensureStyle, DOCUMENT_CSS } from \"@broadpaper/renderer\";\nimport type { ReportTemplate } from \"@broadpaper/core\";\nimport { EditorSession } from \"./state/session.js\";\nimport { ReportDesignerRoot } from \"./ReportDesigner.js\";\nimport { createActions } from \"./state/actions.js\";\nimport { EDITOR_CSS } from \"./styles/generated-css.js\";\nimport type { ReportDesignerApi, ReportDesignerOptions } from \"./options.js\";\n\nexport interface ReportDesignerInstance extends ReportDesignerApi {\n /** The React root; exposed for advanced hosts (testing, devtools). */\n readonly element: HTMLElement;\n}\n\n/**\n * Mounts the report designer into an element. Framework-neutral: the React\n * and Angular packages are thin wrappers around this function.\n *\n * const designer = createReportDesigner(el, { dataSources, theme, onChange });\n * designer.getTemplate();\n * designer.destroy();\n */\nexport function createReportDesigner(element: HTMLElement, options: ReportDesignerOptions = {}): ReportDesignerInstance {\n const doc = element.ownerDocument;\n ensureStyle(doc, \"bpe-styles\", EDITOR_CSS);\n ensureStyle(doc, \"bp-document-css\", DOCUMENT_CSS);\n const session = new EditorSession(doc, options);\n const actions = createActions(session);\n // Mount into our own child so repeated mount/unmount on the same host (React strict mode) never reuses a root container.\n const mountEl = doc.createElement(\"div\");\n mountEl.style.cssText = \"width:100%;height:100%;\";\n element.appendChild(mountEl);\n let root: Root | null = createRoot(mountEl);\n root.render(createElement(ReportDesignerRoot, { session }));\n\n const api: ReportDesignerInstance = {\n element,\n getTemplate: () => session.store.template,\n setTemplate: (t) => session.setTemplate(t),\n getStore: () => session.store,\n setTheme: (theme) => {\n const themes = session.options.get().themes ?? [];\n session.options.set({ theme, themes: themes.some((t) => t.id === theme.id) ? themes : [theme, ...themes] });\n session.setTheme(theme.id);\n },\n setThemes: (themes) => {\n session.options.set({ themes });\n if (!themes.some((t) => t.id === session.ui.get().activeThemeId) && themes[0]) session.setTheme(themes[0].id);\n },\n setSampleData: (data) => {\n session.options.set({ sampleData: data });\n const sets = session.sampleSets;\n if (!sets.some((s) => s.id === session.ui.get().activeSampleId)) session.ui.patch({ activeSampleId: sets[0]?.id ?? null });\n session.requestLayout();\n },\n setDataSources: (dataSources) => {\n session.options.set({ dataSources });\n session.scheduleValidation();\n },\n registerBlock: (def) => session.registerBlock(def),\n validate: () => session.validateNow(),\n undo: () => actions.undo(),\n redo: () => actions.redo(),\n setMode: (mode) => session.setMode(mode),\n getMode: () => session.store.getState().mode,\n select: (ids) => session.store.select(ids),\n exportPdf: () => actions.exportPdf(),\n print: () => actions.print(),\n getLayout: () => session.layout.get(),\n update: (patch) => {\n session.options.set(patch);\n if (patch.template) session.setTemplate(patch.template as ReportTemplate);\n if (patch.theme) api.setTheme(patch.theme);\n if (patch.blocks) for (const b of patch.blocks) session.registerBlock(b);\n session.scheduleValidation();\n },\n destroy: () => {\n const r = root;\n root = null;\n // Defer: hosts often destroy from a React effect cleanup, where a synchronous unmount is illegal.\n setTimeout(() => {\n r?.unmount();\n mountEl.remove();\n }, 0);\n session.destroy();\n }\n };\n session.scheduleValidation();\n queueMicrotask(() => options.onReady?.(api));\n return api;\n}\n","import {\n BlockRegistry,\n EditorStore,\n createTemplate,\n migrateTemplate,\n mergeTheme,\n validateTemplate,\n checkOutput,\n resolveTemplate,\n type BlockDefinition,\n type DataSource,\n type Issue,\n type ReportData,\n type ReportTemplate,\n type Theme,\n type AnyVersionTemplate,\n type EditorState,\n type ResolvedNode\n} from \"@broadpaper/core\";\nimport { builtInBlocks } from \"@broadpaper/blocks\";\nimport { DomMeasurer, layoutDocumentAsync, waitForFonts, ensureStyle, fontFaceCss, type AsyncMeasurer, type LayoutResult } from \"@broadpaper/renderer\";\nimport { Observable } from \"./observable.js\";\nimport { OptionsStore, DEFAULT_FEATURES, normaliseSampleData, type EditorMeasurer, type FeatureFlags, type ReportDesignerOptions, type SampleDataSet } from \"../options.js\";\n\nexport type LeftTab = \"blocks\" | \"layouts\" | \"data\" | \"layers\" | \"library\";\n\nexport interface SaveState {\n status: \"idle\" | \"saving\" | \"saved\" | \"error\";\n /** When the last successful save finished. */\n at?: number;\n /** Why the last save failed. */\n message?: string;\n}\n\nexport interface DragState {\n kind: \"new\" | \"move\" | \"row\" | \"library\" | \"field\";\n /** Block type for \"new\"; node id for \"move\"; layout for \"row\"; library id for \"library\"; expression for \"field\". */\n payload: string | number[] | { expr: string; label: string; type?: string };\n label: string;\n icon?: string;\n x: number;\n y: number;\n}\n\nexport interface DropTarget {\n /** Parent node id (container) or null for the region root. */\n parentId: string | null;\n region: \"body\" | \"header\" | \"header:first\" | \"footer\" | \"footer:first\";\n index: number;\n /** Indicator geometry in canvas-scroll coordinates. */\n line: { x: number; y: number; width: number } | null;\n zone: { x: number; y: number; width: number; height: number } | null;\n valid: boolean;\n /** For field drops onto text blocks. */\n textTargetId?: string;\n}\n\nexport interface UiState {\n leftTab: LeftTab;\n leftOpen: boolean;\n rightOpen: boolean;\n guides: boolean;\n activeThemeId: string | null;\n activeSampleId: string | null;\n drag: DragState | null;\n dropTarget: DropTarget | null;\n issues: Issue[];\n toast: { id: number; message: string; tone?: \"info\" | \"error\" | \"success\" } | null;\n inspectorTab: \"content\" | \"style\";\n exporting: boolean;\n /**\n * What the save button last did. Separate from `dirty`, which answers\n * \"is there anything to save\"; this answers \"what happened when I tried\".\n */\n save: SaveState;\n /** Panel visibility to restore when leaving preview. */\n panelsBeforePreview: { leftOpen: boolean; rightOpen: boolean } | null;\n /**\n * Whether there is room for the panels beside the canvas.\n *\n * Measured from the designer's own element, not the window, because it is\n * embedded and the window says nothing about how much room it was given.\n * When this is true the panels are drawers over the canvas rather than\n * columns next to it, and only one can be open at a time — which is why the\n * flag lives here rather than staying local to the shell that measures it.\n */\n narrow: boolean;\n /** Panel widths in pixels, as dragged by the user. */\n leftWidth: number;\n rightWidth: number;\n /** Increments to force the canvas to scroll a node into view. */\n revealRequest: { id: string; seq: number } | null;\n /** Where a click in the canvas placed the insertion caret, if anywhere. */\n insertion: InsertionPoint | null;\n}\n\n/**\n * A position in the document chosen by clicking rather than by selecting.\n *\n * Selection answers \"what am I editing\"; this answers \"where does the next\n * block go\". Keeping them apart is what lets you click a gap between two\n * blocks and insert there without first selecting one of them.\n */\nexport interface InsertionPoint {\n parentId: string | null;\n region: DropTarget[\"region\"];\n index: number;\n line: { x: number; y: number; width: number };\n}\n\n/**\n * Everything one mounted designer needs. Framework-neutral; the React tree only\n * subscribes to it.\n */\nexport class EditorSession {\n readonly options: OptionsStore;\n readonly store: EditorStore;\n readonly registry: BlockRegistry;\n readonly ui: Observable<UiState>;\n readonly layout = new Observable<LayoutResult | null>(null);\n readonly layoutVersion = new Observable(0);\n private measurer: DomMeasurer | null = null;\n private previewMeasurer: EditorMeasurer | null = null;\n private layoutQueued = false;\n private validateTimer: ReturnType<typeof setTimeout> | null = null;\n private disposed = false;\n readonly doc: Document;\n private readonly unsubscribe: Array<() => void> = [];\n\n constructor(doc: Document, options: ReportDesignerOptions) {\n this.doc = doc;\n this.options = new OptionsStore(options);\n this.registry = new BlockRegistry([...builtInBlocks, ...(options.blocks ?? [])], { enabledTiers: options.enabledTiers });\n const template = loadTemplate(options.template);\n this.store = new EditorStore({\n template,\n onChange: (t, entry) => {\n this.options.get().onChange?.(t, { reason: entry?.label ?? \"change\" });\n }\n });\n const samples = normaliseSampleData(options.sampleData);\n this.ui = new Observable<UiState>({\n leftTab: \"blocks\",\n leftOpen: true,\n rightOpen: true,\n guides: false,\n activeThemeId: options.theme?.id ?? options.themes?.[0]?.id ?? null,\n activeSampleId: samples[0]?.id ?? null,\n drag: null,\n dropTarget: null,\n issues: [],\n toast: null,\n inspectorTab: \"content\",\n exporting: false,\n save: { status: \"idle\" },\n panelsBeforePreview: null,\n narrow: false,\n leftWidth: 272,\n rightWidth: 296,\n revealRequest: null,\n insertion: null\n });\n\n this.unsubscribe.push(\n this.store.subscribe((state, prev) => {\n if (state.template !== prev.template || state.mode !== prev.mode) this.requestLayout();\n if (state.template !== prev.template) this.scheduleValidation();\n if (state.selection !== prev.selection) this.options.get().onSelectionChange?.(state.selection);\n if (state.mode !== prev.mode) this.options.get().onModeChange?.(state.mode);\n })\n );\n this.unsubscribe.push(this.options.subscribe(() => this.requestLayout()));\n this.unsubscribe.push(\n this.ui.subscribe(() => {\n /* theme / sample switches trigger layout via explicit calls */\n })\n );\n this.unsubscribe.push(this.registry.subscribe(() => this.requestLayout()));\n }\n\n /* ------------------------------------------------------------ */\n\n get features(): FeatureFlags {\n return { ...DEFAULT_FEATURES, ...(this.options.get().features ?? {}) };\n }\n\n get dataSources(): DataSource[] {\n return this.options.get().dataSources ?? [];\n }\n\n get themes(): Theme[] {\n const o = this.options.get();\n const list = [...(o.themes ?? [])];\n if (o.theme && !list.some((t) => t.id === o.theme!.id)) list.unshift(o.theme);\n return list;\n }\n\n get activeTheme(): Theme {\n const id = this.ui.get().activeThemeId;\n const found = this.themes.find((t) => t.id === id) ?? this.options.get().theme ?? this.themes[0];\n return mergeTheme(found);\n }\n\n get sampleSets(): SampleDataSet[] {\n return normaliseSampleData(this.options.get().sampleData);\n }\n\n get activeSample(): ReportData {\n const id = this.ui.get().activeSampleId;\n const sets = this.sampleSets;\n return (sets.find((s) => s.id === id) ?? sets[0])?.data ?? {};\n }\n\n setTheme(id: string): void {\n this.ui.patch({ activeThemeId: id });\n this.options.get().onThemeChange?.(this.activeTheme);\n this.requestLayout();\n }\n\n setSample(id: string): void {\n this.ui.patch({ activeSampleId: id });\n this.requestLayout();\n // Output warnings are about this data set, so they change with it.\n this.scheduleValidation();\n }\n\n /**\n * Switches mode, taking the editing furniture with it.\n *\n * Preview answers \"what does the reader get\", and a block palette and an\n * empty properties panel are not part of that answer — they take a third of\n * the width to say nothing. The panels are restored on the way back rather\n * than reset, because whichever ones you had open is a preference you set\n * once and should not have to set again after every preview.\n */\n setMode(mode: \"design\" | \"preview\"): void {\n const state = this.store.getState();\n if (mode === state.mode) return;\n const u = this.ui.get();\n if (mode === \"preview\") {\n this.ui.patch({ panelsBeforePreview: { leftOpen: u.leftOpen, rightOpen: u.rightOpen }, leftOpen: false, rightOpen: false });\n } else if (u.panelsBeforePreview) {\n this.ui.patch({ ...u.panelsBeforePreview, panelsBeforePreview: null });\n }\n this.store.setMode(mode);\n }\n\n toast(message: string, tone: \"info\" | \"error\" | \"success\" = \"info\"): void {\n const id = Date.now();\n this.ui.patch({ toast: { id, message, tone } });\n setTimeout(() => {\n if (this.ui.get().toast?.id === id) this.ui.patch({ toast: null });\n }, 2600);\n }\n\n /**\n * Applies a zoom fit and lands the viewport on a whole page.\n *\n * The toolbar owns the button; only the canvas knows the scroller, the\n * padding around the page stack and which page you were looking at, so the\n * canvas registers the implementation here and the toolbar asks for it.\n */\n fit: ((mode: \"width\" | \"page\") => void) | null = null;\n\n reveal(id: string): void {\n this.ui.patch({ revealRequest: { id, seq: (this.ui.get().revealRequest?.seq ?? 0) + 1 } });\n }\n\n /* ------------------------------ layout ------------------------------ */\n\n attachMeasurer(container: HTMLElement): void {\n this.measurer?.destroy();\n this.previewMeasurer?.destroy?.();\n this.measurer = new DomMeasurer(this.doc, container);\n // A host measurer paginates the canvas exactly as the PDF will, but only\n // design mode's own affordances stand in its way — badges, dashed outlines\n // and drop targets are styled by the document stylesheet, which an engine\n // outside the browser never sees and so cannot measure. Design mode\n // therefore measures with the browser, which is what draws it; preview\n // mode, which draws what the PDF draws, measures with the engine.\n const make = this.options.get().createMeasurer;\n this.previewMeasurer = make ? make({ document: this.doc, container }) : null;\n // Web fonts arriving after the first layout change line breaks: re-measure everything.\n const fonts = (this.doc as Document & { fonts?: FontFaceSet }).fonts;\n if (fonts && !this.fontListener) {\n this.fontListener = () => {\n this.measurer?.clearCache();\n this.previewMeasurer?.clearCache?.();\n this.requestLayout();\n };\n fonts.addEventListener(\"loadingdone\", this.fontListener);\n }\n this.requestLayout();\n }\n private fontListener: (() => void) | null = null;\n\n requestLayout(): void {\n if (this.layoutQueued || this.disposed) return;\n this.layoutQueued = true;\n const run = () => {\n this.layoutQueued = false;\n void this.runLayout();\n };\n if (typeof requestAnimationFrame === \"function\") requestAnimationFrame(run);\n else setTimeout(run, 0);\n }\n\n private layoutSeq = 0;\n private async runLayout(): Promise<void> {\n if (!this.measurer || this.disposed) return;\n const seq = ++this.layoutSeq;\n const theme = this.activeTheme;\n ensureStyle(this.doc, \"bp-theme-fonts\", fontFaceCss(theme));\n const families = [...(theme.fonts ?? []).map((f) => f.family), ...themeFontFamilies(theme)];\n await waitForFonts(this.doc, families);\n if (seq !== this.layoutSeq || this.disposed) return;\n const state = this.store.getState();\n const o = this.options.get();\n try {\n // One pipeline for both kinds of measurer: the DOM answers immediately,\n // an engine-backed one takes a moment, and awaiting costs the former\n // nothing that this already-async method was not paying anyway.\n const m: EditorMeasurer = (state.mode === \"preview\" && this.previewMeasurer) || this.measurer;\n const measurer: AsyncMeasurer = {\n setOptions: (opts) => m.setOptions?.(opts),\n measure: async (sections, width) => m.measure(sections, width)\n };\n const result = await layoutDocumentAsync(\n {\n template: state.template,\n registry: this.registry,\n theme,\n dataSources: this.dataSources,\n data: state.mode === \"preview\" ? this.activeSample : undefined,\n sampleData: this.activeSample,\n mode: state.mode,\n now: o.now,\n locale: o.locale,\n currency: o.currency,\n timeZone: o.timeZone,\n allowStyleOverrides: this.features.styleOverrides,\n minPages: 1\n },\n measurer\n );\n // A newer layout may have finished while the engine was measuring.\n if (seq !== this.layoutSeq || this.disposed) return;\n this.layout.set(result);\n this.layoutVersion.set((v) => v + 1);\n } catch (e) {\n console.error(\"[broadpaper] layout failed\", e);\n }\n }\n\n /* ---------------------------- validation ---------------------------- */\n\n scheduleValidation(): void {\n if (this.validateTimer) clearTimeout(this.validateTimer);\n this.validateTimer = setTimeout(() => this.validateNow(), 250);\n }\n\n validateNow(): Issue[] {\n if (!this.features.validation) return [];\n const template = validateTemplate({ template: this.store.template, registry: this.registry, dataSources: this.dataSources, theme: this.activeTheme, skipSchema: true }).issues.map((i) => ({ ...i, source: i.source ?? (\"template\" as const) }));\n const issues = [...template, ...this.outputIssues()];\n this.ui.patch({ issues });\n this.options.get().onValidate?.(issues);\n return issues;\n }\n\n /**\n * What the active sample data does to the report, as opposed to whether the\n * template is sound. Needs its own preview resolution: the canvas is resolved\n * in design mode, which fills gaps in the sample with synthesised values and\n * would hide exactly the blanks we are looking for.\n */\n private outputIssues(): Issue[] {\n const sets = this.sampleSets;\n if (sets.length === 0) return [];\n const active = sets.find((s) => s.id === this.ui.get().activeSampleId) ?? sets[0]!;\n const o = this.options.get();\n try {\n const resolved = resolveTemplate({\n template: this.store.template,\n registry: this.registry,\n theme: this.activeTheme,\n dataSources: this.dataSources,\n data: active.data,\n mode: \"preview\",\n now: o.now,\n locale: o.locale,\n currency: o.currency,\n timeZone: o.timeZone,\n allowStyleOverrides: this.features.styleOverrides\n });\n return checkOutput({ resolved, registry: this.registry, dataLabel: active.label });\n } catch {\n // A template that cannot resolve is already an error the structural pass\n // reports; failing to also list its blanks is not worth a broken panel.\n return [];\n }\n }\n\n /* ------------------------------ helpers ----------------------------- */\n\n resolvedNode(id: string): ResolvedNode | undefined {\n const l = this.layout.get();\n if (!l) return undefined;\n for (const n of l.nodesByKey.values()) if (n.nodeId === id) return n;\n return undefined;\n }\n\n registerBlock(def: BlockDefinition<any>): void {\n if (this.registry.has(def.type)) this.registry.replace(def);\n else this.registry.register(def);\n }\n\n setTemplate(t: ReportTemplate | AnyVersionTemplate): void {\n this.store.load(loadTemplate(t));\n this.scheduleValidation();\n }\n\n getState(): EditorState {\n return this.store.getState();\n }\n\n destroy(): void {\n this.disposed = true;\n for (const u of this.unsubscribe) u();\n this.measurer?.destroy();\n this.previewMeasurer?.destroy?.();\n if (this.validateTimer) clearTimeout(this.validateTimer);\n const fonts = (this.doc as Document & { fonts?: FontFaceSet }).fonts;\n if (fonts && this.fontListener) fonts.removeEventListener(\"loadingdone\", this.fontListener);\n }\n}\n\n/** Font family names referenced by a theme's typography (first family of each stack). */\nfunction themeFontFamilies(theme: Theme): string[] {\n const out: string[] = [];\n for (const stack of [theme.typography.headingFont, theme.typography.bodyFont, theme.typography.monoFont ?? \"\"]) {\n const first = stack.split(\",\")[0]?.trim().replace(/^['\"]|['\"]$/g, \"\");\n if (first && ![\"system-ui\", \"sans-serif\", \"serif\", \"monospace\"].includes(first)) out.push(first);\n }\n return out;\n}\n\nexport function loadTemplate(input: ReportTemplate | AnyVersionTemplate | undefined): ReportTemplate {\n if (!input) return createTemplate();\n return migrateTemplate(input).template;\n}\n","import { useSyncExternalStore } from \"react\";\n\n/** Tiny observable value store with React binding. */\nexport class Observable<T> {\n private listeners = new Set<() => void>();\n constructor(private value: T) {}\n get(): T {\n return this.value;\n }\n set(next: T | ((prev: T) => T)): void {\n const v = typeof next === \"function\" ? (next as (p: T) => T)(this.value) : next;\n if (Object.is(v, this.value)) return;\n this.value = v;\n for (const l of this.listeners) l();\n }\n patch(partial: Partial<T>): void {\n this.set({ ...(this.value as object), ...(partial as object) } as T);\n }\n subscribe(fn: () => void): () => void {\n this.listeners.add(fn);\n return () => {\n this.listeners.delete(fn);\n };\n }\n}\n\nexport function useObservable<T, S = T>(obs: Observable<T>, selector?: (v: T) => S): S {\n const sel = selector ?? ((v: T) => v as unknown as S);\n return useSyncExternalStore(\n (cb) => obs.subscribe(cb),\n () => sel(obs.get()),\n () => sel(obs.get())\n );\n}\n","import type { AnyVersionTemplate, BlockDefinition, DataSource, Issue, LibraryItem, ReportData, ReportTemplate, Theme, EditorStore, LicenseTier } from \"@broadpaper/core\";\nimport type { AsyncMeasurer, LayoutResult } from \"@broadpaper/renderer\";\nimport type { GeometryMap, Measurer, RenderTreeOptions, ResolvedNode } from \"@broadpaper/core\";\n\n/**\n * What the editor needs of a measurer: the `Measurer` contract, optionally\n * asynchronous, plus two lifecycle hooks it will call when it has them.\n */\nexport interface EditorMeasurer {\n measure(sections: ResolvedNode[], width: number): GeometryMap | Promise<GeometryMap>;\n setOptions?(opts: RenderTreeOptions): void;\n /** Invalidates cached geometry, e.g. when a web font finishes loading. */\n clearCache?(): void;\n destroy?(): void;\n}\n\nexport interface SampleDataSet {\n id: string;\n label: string;\n description?: string;\n data: ReportData;\n}\n\nexport interface FeatureFlags {\n /** Show the Export menu (PDF service / print). */\n pdfExport: boolean;\n /** Theme switcher in the toolbar. */\n themes: boolean;\n /** Show custom blocks in the palette. */\n customBlocks: boolean;\n /** Reusable library panel. */\n library: boolean;\n /** Per-block style overrides in the inspector. */\n styleOverrides: boolean;\n /** Page settings (size, margins, regions). */\n pageSettings: boolean;\n /** Document styles editor (H1..caption, table, card). */\n documentStyles: boolean;\n /** Header/footer regions editable. */\n headerFooter: boolean;\n /** Layers panel. */\n layers: boolean;\n /** Data panel. */\n dataPanel: boolean;\n /** Validation issues in the toolbar. */\n validation: boolean;\n /** JSON view of the template. */\n jsonView: boolean;\n /** Advanced expression editing (free-form expressions). */\n expressions: boolean;\n /** Hide the BroadPaper mark in the toolbar (white-label). */\n whiteLabel: boolean;\n}\n\nexport const DEFAULT_FEATURES: FeatureFlags = {\n pdfExport: true,\n themes: true,\n customBlocks: true,\n library: true,\n styleOverrides: true,\n pageSettings: true,\n documentStyles: true,\n headerFooter: true,\n layers: true,\n dataPanel: true,\n validation: true,\n jsonView: true,\n expressions: true,\n whiteLabel: false\n};\n\nexport interface ExportContext {\n template: ReportTemplate;\n theme: Theme;\n data: ReportData;\n dataSources: DataSource[];\n layout: LayoutResult | null;\n /** Renders the current preview through the browser print dialog. */\n print(): void;\n}\n\nexport interface ReportDesignerOptions {\n /** Initial template. A new one is created when omitted. Old schema versions are migrated. */\n template?: ReportTemplate | AnyVersionTemplate;\n dataSources?: DataSource[];\n /** Sample data used by design mode and preview. One data set or several to switch between. */\n sampleData?: ReportData | SampleDataSet[];\n /** The active theme. */\n theme?: Theme;\n /** Themes offered in the switcher. The active theme is added automatically. */\n themes?: Theme[];\n /** Custom block definitions. */\n blocks?: Array<BlockDefinition<any>>;\n /** Host-provided reusable content. */\n library?: LibraryItem[];\n features?: Partial<FeatureFlags>;\n /** Licence tiers enabled for this host. */\n enabledTiers?: LicenseTier[];\n locale?: string;\n currency?: string;\n timeZone?: string;\n /** \"light\" | \"dark\" | \"system\". Default \"light\". */\n appearance?: \"light\" | \"dark\" | \"system\";\n /** Initial zoom (1 = 100%). Default fits the page width. */\n zoom?: number | \"fit\";\n /** Extra class on the root element. */\n className?: string;\n /**\n * Supplies the measurer the canvas pages with.\n *\n * The default measures in the browser, which is fast and needs nothing extra.\n * Pass a factory to measure with the same engine that renders the PDF, and\n * the canvas breaks pages exactly where the file does — worth the extra\n * milliseconds when the two disagreeing would be worse than a slower canvas.\n * The container is the element the measurer may mount into; engine-backed\n * measurers will not need it.\n */\n createMeasurer?(ctx: { document: Document; container: HTMLElement }): EditorMeasurer;\n\n /**\n * Whether charts respond to a pointer and to the keyboard on screen.\n *\n * The drawing does not change — the same SVG the PDF contains gains a hover,\n * a focus ring and a tooltip — so this cannot make the canvas and the file\n * disagree. \"preview\" is the default: design mode draws sample data, and a\n * tooltip quoting a synthesised figure reads as a real one.\n */\n interactiveCharts?: \"preview\" | \"always\" | \"off\";\n\n /**\n * Where an uploaded image goes.\n *\n * Without this the designer reads the file in the browser and stores it as a\n * `data:` URL inside the template, which needs no server and is the right\n * answer for a logo or a signature. It is the wrong answer for anything\n * large: the bytes travel with the template everywhere it goes — the host's\n * database, every save, every render request — so the built-in path refuses\n * files over `MAX_INLINE_IMAGE_BYTES` rather than quietly making documents\n * that are expensive to move around.\n *\n * Return an address the renderer can fetch and the designer stores that\n * instead, with no size limit of its own: a host with somewhere to put files\n * knows better than the designer does what belongs there. Returning null, or\n * throwing, cancels the upload — throw with a message worth reading, because\n * it is shown under the field.\n */\n onUploadImage?(file: File): string | null | Promise<string | null>;\n\n /** Fixed clock for previews (tests, screenshots). */\n now?: Date;\n /** PDF service for the built-in export. When absent, export falls back to the browser print dialog. */\n pdfService?: { url: string; token?: string };\n\n onChange?(template: ReportTemplate, info: { reason: string }): void;\n onSave?(template: ReportTemplate): void | Promise<void>;\n /**\n * One sentence describing where saving actually goes, shown next to the save\n * indicator. Only the host knows — the designer hands over a template and has\n * no idea whether that reaches a database, a file or nothing at all — and\n * saying nothing invites the user to assume the safest possible answer.\n */\n saveDescription?: string;\n /** Host-driven export. Return false to fall back to the built-in behaviour. */\n onExportPdf?(ctx: ExportContext): void | boolean | Promise<void | boolean>;\n onSelectionChange?(ids: string[]): void;\n onValidate?(issues: Issue[]): void;\n onModeChange?(mode: \"design\" | \"preview\"): void;\n onThemeChange?(theme: Theme): void;\n onReady?(api: ReportDesignerApi): void;\n}\n\nexport interface ReportDesignerApi {\n getTemplate(): ReportTemplate;\n setTemplate(template: ReportTemplate | AnyVersionTemplate): void;\n getStore(): EditorStore;\n setTheme(theme: Theme): void;\n setThemes(themes: Theme[]): void;\n setSampleData(data: ReportData | SampleDataSet[]): void;\n setDataSources(dataSources: DataSource[]): void;\n registerBlock(def: BlockDefinition<any>): void;\n validate(): Issue[];\n undo(): void;\n redo(): void;\n setMode(mode: \"design\" | \"preview\"): void;\n getMode(): \"design\" | \"preview\";\n select(ids: string[]): void;\n exportPdf(): Promise<void>;\n print(): void;\n getLayout(): LayoutResult | null;\n update(options: Partial<ReportDesignerOptions>): void;\n destroy(): void;\n}\n\n/** A minimal observable holder for host options so React can subscribe to changes. */\nexport class OptionsStore {\n private listeners = new Set<() => void>();\n constructor(public value: ReportDesignerOptions) {}\n get(): ReportDesignerOptions {\n return this.value;\n }\n set(patch: Partial<ReportDesignerOptions>): void {\n this.value = { ...this.value, ...patch };\n for (const l of this.listeners) l();\n }\n subscribe(fn: () => void): () => void {\n this.listeners.add(fn);\n return () => {\n this.listeners.delete(fn);\n };\n }\n}\n\nexport function normaliseSampleData(sample: ReportDesignerOptions[\"sampleData\"]): SampleDataSet[] {\n if (!sample) return [];\n if (Array.isArray(sample)) return sample;\n return [{ id: \"default\", label: \"Sample data\", data: sample }];\n}\n","import { useEffect, useMemo, useRef, useState, type CSSProperties } from \"react\";\nimport { SessionContext, useUi, useOptions, useSession } from \"./state/context.js\";\nimport { PortalContext } from \"./ui/floating.js\";\nimport type { EditorSession } from \"./state/session.js\";\nimport { createActions } from \"./state/actions.js\";\nimport { Toolbar } from \"./toolbar/Toolbar.js\";\nimport { LeftPanel } from \"./panels/LeftPanel.js\";\nimport { Canvas } from \"./canvas/Canvas.js\";\nimport { Inspector } from \"./inspector/Inspector.js\";\nimport { PanelResizer } from \"./ui/PanelResizer.js\";\nimport { Boundary } from \"./ui/Boundary.js\";\nimport { useElementWidth } from \"./ui/use-element-size.js\";\n\n/** Width below which the panels become drawers over the canvas. See `isNarrow`. */\nconst NARROW_BELOW = 820;\n\n/** The React root of the designer. Hosts should use `createReportDesigner` or `@broadpaper/react`. */\nexport function ReportDesignerRoot({ session }: { session: EditorSession }) {\n const actions = useMemo(() => createActions(session), [session]);\n return (\n <SessionContext.Provider value={session}>\n <Shell actions={actions} />\n </SessionContext.Provider>\n );\n}\n\nfunction Shell({ actions }: { actions: ReturnType<typeof createActions> }) {\n const options = useOptions();\n const [portal, setPortal] = useState<HTMLElement | null>(null);\n const session = useSession();\n const leftOpen = useUi((u) => u.leftOpen);\n const rightOpen = useUi((u) => u.rightOpen);\n const leftWidth = useUi((u) => u.leftWidth);\n const rightWidth = useUi((u) => u.rightWidth);\n const narrow = useUi((u) => u.narrow);\n const rootRef = useRef<HTMLDivElement>(null);\n const width = useElementWidth(rootRef);\n\n /**\n * Below this there is not room for a page between two panels: the defaults\n * alone are 272 + 296, and an A4 page at 100 % is another 794. Anything\n * narrower was being given a canvas of a few dozen pixels, which is how the\n * designer came to be unusable on a phone rather than merely cramped.\n *\n * `width === 0` is \"not measured yet\", not \"very narrow\" — collapsing on the\n * first frame and expanding on the second reads as a glitch.\n */\n const isNarrow = width > 0 && width < NARROW_BELOW;\n\n useEffect(() => {\n if (isNarrow === narrow) return;\n // Entering narrow closes both panels, because a drawer covering the canvas\n // is not what someone wants to arrive at; leaving it restores neither, on\n // the grounds that reopening a panel is one click and having one appear\n // unbidden is a surprise.\n session.ui.patch(isNarrow ? { narrow: true, leftOpen: false, rightOpen: false } : { narrow: false });\n }, [isNarrow, narrow, session]);\n const appearance = options.appearance === \"system\" ? (typeof matchMedia === \"function\" && matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\") : options.appearance ?? \"light\";\n\n // Global shortcuts that should work even when focus is in a panel.\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n const mod = e.metaKey || e.ctrlKey;\n const target = e.target as HTMLElement;\n const root = target.closest(\".bpe\");\n if (!root) return;\n if (target.closest(\"input, textarea, select, [contenteditable=true], .ProseMirror\")) return;\n if (mod && e.key.toLowerCase() === \"z\") {\n e.preventDefault();\n if (e.shiftKey) actions.redo();\n else actions.undo();\n } else if (mod && e.key.toLowerCase() === \"y\") {\n e.preventDefault();\n actions.redo();\n } else if (mod && e.key.toLowerCase() === \"s\") {\n e.preventDefault();\n void actions.save();\n }\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [actions]);\n\n const cls = [\n \"bpe\",\n !leftOpen && \"bpe--no-left\",\n !rightOpen && \"bpe--no-right\",\n narrow && \"bpe--narrow\",\n options.className\n ]\n .filter(Boolean)\n .join(\" \");\n // A drawer is only over the canvas when there is no room beside it; the rest\n // of the time the panels are columns and there is nothing to dismiss.\n const scrim = narrow && (leftOpen || rightOpen);\n return (\n <PortalContext.Provider value={portal}>\n <div ref={rootRef} className={cls} data-appearance={appearance} style={{ \"--bpe-panel-w\": `${leftWidth}px`, \"--bpe-inspector-w\": `${rightWidth}px` } as CSSProperties}>\n <Boundary area=\"The toolbar\" slot=\"toolbar\"><Toolbar actions={actions} /></Boundary>\n {leftOpen ? (\n <>\n <Boundary area=\"The insert panel\" slot=\"left\"><LeftPanel actions={actions} /></Boundary>\n {/* Dragging an edge is meaningless for a drawer that is already as\n wide as the room allows, and the handle would sit under a thumb. */}\n {!narrow ? (\n <PanelResizer side=\"left\" width={leftWidth} min={200} max={420} label=\"Resize the insert panel\" onChange={(leftWidth) => session.ui.patch({ leftWidth })} />\n ) : null}\n </>\n ) : (\n <div />\n )}\n <Boundary area=\"The canvas\" slot=\"canvas\"><Canvas actions={actions} /></Boundary>\n {rightOpen ? (\n <>\n {!narrow ? (\n <PanelResizer side=\"right\" width={rightWidth} min={260} max={560} label=\"Resize the properties panel\" onChange={(rightWidth) => session.ui.patch({ rightWidth })} />\n ) : null}\n <Boundary area=\"The properties panel\" slot=\"right\"><Inspector actions={actions} /></Boundary>\n </>\n ) : (\n <div />\n )}\n {scrim ? (\n <button\n type=\"button\"\n className=\"bpe-scrim\"\n aria-label=\"Close the panel\"\n onClick={() => session.ui.patch({ leftOpen: false, rightOpen: false })}\n />\n ) : null}\n <div className=\"bpe-portal bpe-scope\" data-appearance={appearance} ref={setPortal} />\n </div>\n </PortalContext.Provider>\n );\n}\n","import { createContext, useContext, useSyncExternalStore, useMemo } from \"react\";\nimport { createSchemaScope, humaniseLabel, type EditorState, type Node, type NodeEntry, type ReportTemplate } from \"@broadpaper/core\";\nimport type { LayoutResult } from \"@broadpaper/renderer\";\nimport type { EditorSession, UiState } from \"./session.js\";\nimport { useObservable } from \"./observable.js\";\nimport type { ReportDesignerOptions, FeatureFlags } from \"../options.js\";\nimport { DEFAULT_FEATURES } from \"../options.js\";\n\nexport const SessionContext = createContext<EditorSession | null>(null);\n\nexport function useSession(): EditorSession {\n const s = useContext(SessionContext);\n if (!s) throw new Error(\"BroadPaper components must be rendered inside a ReportDesigner\");\n return s;\n}\n\n/** Subscribes to a slice of the editor store. Re-renders only when the slice changes (Object.is). */\nexport function useEditorState<S>(selector: (state: EditorState) => S): S {\n const session = useSession();\n return useSyncExternalStore(\n (cb) => session.store.subscribe(cb),\n () => selector(session.store.getState()),\n () => selector(session.store.getState())\n );\n}\n\nexport function useTemplate(): ReportTemplate {\n return useEditorState((s) => s.template);\n}\n\nexport function useSelection(): string[] {\n return useEditorState((s) => s.selection);\n}\n\nexport function useMode(): \"design\" | \"preview\" {\n return useEditorState((s) => s.mode);\n}\n\nexport function useNode(id: string | null | undefined): NodeEntry | undefined {\n const session = useSession();\n const version = useEditorState((s) => s.version);\n return useMemo(() => (id ? session.store.index().get(id) : undefined), [session, id, version]);\n}\n\nexport function useOptions(): ReportDesignerOptions {\n const session = useSession();\n return useSyncExternalStore(\n (cb) => session.options.subscribe(cb),\n () => session.options.get(),\n () => session.options.get()\n );\n}\n\nexport function useFeatures(): FeatureFlags {\n const o = useOptions();\n return useMemo(() => ({ ...DEFAULT_FEATURES, ...(o.features ?? {}) }), [o.features]);\n}\n\nexport function useUi<S = UiState>(selector?: (u: UiState) => S): S {\n const session = useSession();\n return useObservable(session.ui, selector);\n}\n\nexport function useLayout(): LayoutResult | null {\n const session = useSession();\n return useObservable(session.layout);\n}\n\nexport function useLayoutVersion(): number {\n const session = useSession();\n return useObservable(session.layoutVersion);\n}\n\nexport function useRegistryVersion(): number {\n const session = useSession();\n return useSyncExternalStore(\n (cb) => session.registry.subscribe(cb),\n () => session.registry.list().length,\n () => session.registry.list().length\n );\n}\n\n/**\n * What to call a node in the layer tree, the breadcrumb and the inspector.\n *\n * Blocks label themselves from their own props, which means a table announces\n * itself as \"Table · portfolio.allocation\" — the path the designer typed, not\n * the name the data source gives it. Running that through `humaniseLabel` turns\n * it into \"Table · Portfolio › Asset allocation\" using the same wording the\n * canvas already prints inside its token chips.\n */\nexport function nodeLabel(session: EditorSession, node: Node): string {\n const def = session.registry.get(node.type);\n if (node.name) return node.name;\n if (def?.canvas?.label) {\n try {\n const l = def.canvas.label({ ...(typeof def.defaultProps === \"function\" ? def.defaultProps() : def.defaultProps), ...node.props });\n if (l) return humaniseLabel(l, createSchemaScope(session.dataSources));\n } catch {\n /* ignore */\n }\n }\n return def?.name ?? node.type;\n}\n\n/**\n * The technical version of the same thing — block type, and the expressions it\n * is bound to — for tooltips and secondary lines. Readable names are the right\n * default; the paths are what you need the moment something is wrong.\n */\nexport function nodeDetail(session: EditorSession, node: Node): string {\n const def = session.registry.get(node.type);\n const props = { ...(typeof def?.defaultProps === \"function\" ? def.defaultProps() : def?.defaultProps), ...node.props } as Record<string, unknown>;\n const exprs = session.registry\n .bindingsOf(node.type)\n .map((b) => props[b.prop])\n .filter((v): v is string => typeof v === \"string\" && v.trim() !== \"\");\n return [def?.name ?? node.type, ...exprs].join(\" · \");\n}\n","import { cloneElement, createContext, isValidElement, useContext, useState, type ReactElement, type ReactNode, type HTMLAttributes } from \"react\";\nimport { autoUpdate, flip, offset, shift, useClick, useDismiss, useFloating, useFocus, useHover, useInteractions, useMergeRefs, useRole, FloatingPortal, FloatingFocusManager, safePolygon, type Placement, size as sizeMw } from \"@floating-ui/react\";\nimport { Icon } from \"./icons.js\";\n\n/**\n * Where floating UI is portalled. Provided by each designer instance so several\n * editors on one page keep their own — and correctly themed — portal target.\n */\nexport const PortalContext = createContext<HTMLElement | null>(null);\n\nfunction useRootEl(): HTMLElement | null {\n const fromContext = useContext(PortalContext);\n const [fallback] = useState<HTMLElement | null>(() => (typeof document !== \"undefined\" ? document.body : null));\n return fromContext ?? fallback;\n}\n\n/**\n * React 19 made `ref` an ordinary prop, which quietly broke anchoring here.\n * Spreading the child's props over the floating reference — `{ ref: setReference,\n * ...children.props }` — now overwrites that ref with the child's own, so a\n * child that sets `ref` at all (every `Button`, because `forwardRef` passes one\n * through even when the caller gave none) left the tooltip with no anchor and it\n * never opened. Setting the ref last and merging the two keeps both.\n */\nfunction useReferenceRef(children: ReactElement, setReference: (node: HTMLElement | null) => void) {\n const own = (children as ReactElement & { props?: { ref?: unknown } }).props?.ref;\n return useMergeRefs([setReference, (own ?? null) as never]);\n}\n\nexport function Tooltip({ content, shortcut, children, placement = \"bottom\" }: { content: ReactNode; shortcut?: string; children: ReactElement; placement?: Placement }) {\n const [open, setOpen] = useState(false);\n const { refs, floatingStyles, context, isPositioned } = useFloating({ open, onOpenChange: setOpen, placement, middleware: [offset(6), flip(), shift({ padding: 6 })], whileElementsMounted: autoUpdate });\n const hover = useHover(context, { delay: { open: 450, close: 60 }, move: false });\n const focus = useFocus(context);\n const role = useRole(context, { role: \"tooltip\" });\n const dismiss = useDismiss(context);\n const { getReferenceProps, getFloatingProps } = useInteractions([hover, focus, role, dismiss]);\n const root = useRootEl();\n const referenceRef = useReferenceRef(children, refs.setReference);\n if (!isValidElement(children)) return children;\n return (\n <>\n {cloneElement(children as ReactElement<HTMLAttributes<HTMLElement>>, getReferenceProps({ ...(children.props as HTMLAttributes<HTMLElement>), ref: referenceRef }))}\n {open ? (\n <FloatingPortal root={root}>\n <div ref={refs.setFloating} style={{ ...floatingStyles, visibility: isPositioned ? \"visible\" : \"hidden\" }} className={`bpe-scope bpe-tooltip ${isPositioned ? \"bpe-floating--in\" : \"\"}`} {...getFloatingProps()}>\n {content}\n {shortcut ? <kbd className=\"bpe-kbd\">{shortcut}</kbd> : null}\n </div>\n </FloatingPortal>\n ) : null}\n </>\n );\n}\n\nexport interface PopoverProps {\n trigger: ReactElement;\n children: ReactNode | ((close: () => void) => ReactNode);\n placement?: Placement;\n className?: string;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Match the trigger width. */\n matchWidth?: boolean;\n hoverable?: boolean;\n initialFocus?: number | false;\n}\n\nexport function Popover({ trigger, children, placement = \"bottom-start\", className, open: controlledOpen, onOpenChange, matchWidth, hoverable, initialFocus = 0 }: PopoverProps) {\n const [uncontrolled, setUncontrolled] = useState(false);\n const open = controlledOpen ?? uncontrolled;\n const setOpen = (v: boolean) => {\n setUncontrolled(v);\n onOpenChange?.(v);\n };\n const { refs, floatingStyles, context, isPositioned } = useFloating({\n open,\n onOpenChange: setOpen,\n placement,\n middleware: [offset(6), flip({ padding: 8 }), shift({ padding: 8 }), sizeMw({ apply({ rects, elements, availableHeight }) { Object.assign(elements.floating.style, { maxHeight: `${Math.max(160, availableHeight - 8)}px`, ...(matchWidth ? { width: `${rects.reference.width}px` } : {}) }); } })],\n whileElementsMounted: autoUpdate\n });\n const click = useClick(context);\n const hover = useHover(context, { enabled: !!hoverable, handleClose: safePolygon() });\n const dismiss = useDismiss(context, { outsidePress: (e) => !(e.target as HTMLElement | null)?.closest?.(\".bpe-popover\") });\n const role = useRole(context, { role: \"dialog\" });\n const { getReferenceProps, getFloatingProps } = useInteractions([click, hover, dismiss, role]);\n const root = useRootEl();\n const referenceRef = useReferenceRef(trigger, refs.setReference);\n return (\n <>\n {cloneElement(trigger as ReactElement<HTMLAttributes<HTMLElement>>, getReferenceProps({ ...(trigger.props as HTMLAttributes<HTMLElement>), ref: referenceRef }))}\n {open ? (\n <FloatingPortal root={root}>\n <FloatingFocusManager context={context} modal={false} initialFocus={initialFocus === false ? -1 : initialFocus} returnFocus>\n <div ref={refs.setFloating} style={{ ...floatingStyles, overflow: \"auto\", visibility: isPositioned ? \"visible\" : \"hidden\" }} className={`bpe-scope bpe-popover ${isPositioned ? \"bpe-floating--in\" : \"\"} ${className ?? \"\"}`} {...getFloatingProps()}>\n {typeof children === \"function\" ? children(() => setOpen(false)) : children}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n ) : null}\n </>\n );\n}\n\nexport interface MenuItem {\n id: string;\n label: ReactNode;\n icon?: string;\n /** Short, right-aligned: a keyboard shortcut or a count. */\n hint?: string;\n /** Longer prose, rendered on a second line under the label. */\n description?: string;\n danger?: boolean;\n disabled?: boolean;\n onSelect?: () => void;\n separatorBefore?: boolean;\n}\n\nexport function Menu({ trigger, items, placement, label }: { trigger: ReactElement; items: MenuItem[]; placement?: Placement; label?: string }) {\n return (\n <Popover trigger={trigger} placement={placement} className=\"bpe-menu\">\n {(close) => (\n <div role=\"menu\" aria-label={label}>\n {items.map((it) => (\n <div key={it.id}>\n {it.separatorBefore ? <div className=\"bpe-menu__sep\" /> : null}\n <button\n type=\"button\"\n role=\"menuitem\"\n className={`bpe-menu__item ${it.description ? \"bpe-menu__item--stacked\" : \"\"} ${it.danger ? \"bpe-menu__item--danger\" : \"\"}`}\n disabled={it.disabled}\n title={it.description}\n onClick={() => {\n close();\n it.onSelect?.();\n }}\n >\n {it.icon ? <Icon name={it.icon} size={14} /> : null}\n <span className=\"bpe-menu__body\">\n <span className=\"bpe-menu__label-text\">{it.label}</span>\n {it.description ? <span className=\"bpe-menu__desc\">{it.description}</span> : null}\n </span>\n {it.hint ? <span className=\"bpe-menu__hint\">{it.hint}</span> : null}\n </button>\n </div>\n ))}\n </div>\n )}\n </Popover>\n );\n}\n","import type { ComponentType, SVGProps } from \"react\";\nimport {\n Heading, Type, Image, BadgeCheck, Minus, MoveVertical, MousePointerClick, MessageSquareWarning, Quote, Tag, TrendingUp, PenLine, Calendar, Hash, Clock,\n SquareDashed, PanelTop, Scissors, Link, GitBranch, Repeat, Table, List, BarChart3, Gauge, Columns3, RectangleHorizontal, RectangleVertical,\n AlignLeft, AlignCenter, AlignRight, AlignJustify, AlignStartVertical, AlignCenterVertical, AlignEndVertical, StretchVertical,\n BarChartHorizontal, LineChart, AreaChart, PieChart, CircleDot,\n Undo2, Redo2, Save, Download, Printer, Eye, Pencil, ZoomIn, ZoomOut, Maximize, Settings, Palette, ChevronDown, ChevronRight, ChevronUp, Search, X, Plus, Trash2, Copy, GripVertical, ArrowUp, ArrowDown, Lock, Unlock, Layers, Database, Blocks, LayoutGrid, BookMarked, AlertTriangle, AlertCircle, Info, CheckCircle2, Check, MoreHorizontal, Braces, Bold, Italic, Underline, Strikethrough, Code, ListOrdered, Sparkles, Box, FileText, Braces as BracesIcon, ExternalLink, Wand2, Sun, Moon, PanelLeft, PanelRight, RotateCcw, CornerDownRight, Eraser, Ruler, ChevronsUpDown, Folder, FolderOpen, Hash as HashIcon, ToggleLeft, CalendarDays, Sigma, ListTree, Percent, Coins, Text, Binary, Layout, FileOutput, ArrowUpRight, SquareStack, Shield, MoveHorizontal, ChevronLeft, Eye as EyeIcon, Info as InfoIcon, Upload\n} from \"lucide-react\";\n\nexport type IconComponent = ComponentType<SVGProps<SVGSVGElement> & { size?: number | string; strokeWidth?: number }>;\n\nconst MAP: Record<string, IconComponent> = {\n heading: Heading, text: Type, type: Type, image: Image, \"badge-check\": BadgeCheck, minus: Minus, \"move-vertical\": MoveVertical, \"mouse-pointer-click\": MousePointerClick,\n \"message-square-warning\": MessageSquareWarning, quote: Quote, tag: Tag, \"trending-up\": TrendingUp, \"pen-line\": PenLine, calendar: Calendar, hash: Hash, clock: Clock,\n \"square-dashed\": SquareDashed, \"panel-top\": PanelTop, scissors: Scissors, link: Link, \"git-branch\": GitBranch, repeat: Repeat, table: Table, list: List, \"bar-chart-3\": BarChart3, gauge: Gauge,\n \"columns-3\": Columns3, \"rectangle-horizontal\": RectangleHorizontal, \"rectangle-vertical\": RectangleVertical,\n \"align-left\": AlignLeft, \"align-center\": AlignCenter, \"align-right\": AlignRight, \"align-justify\": AlignJustify, \"align-start-vertical\": AlignStartVertical, \"align-center-vertical\": AlignCenterVertical, \"align-end-vertical\": AlignEndVertical, \"stretch-vertical\": StretchVertical,\n \"bar-chart-horizontal\": BarChartHorizontal, \"line-chart\": LineChart, \"area-chart\": AreaChart, \"pie-chart\": PieChart, \"circle-dot\": CircleDot,\n undo: Undo2, redo: Redo2, save: Save, download: Download, printer: Printer, eye: Eye, pencil: Pencil, \"zoom-in\": ZoomIn, \"zoom-out\": ZoomOut, maximize: Maximize, settings: Settings, palette: Palette,\n \"chevron-down\": ChevronDown, \"chevron-right\": ChevronRight, \"chevron-up\": ChevronUp, \"chevrons-up-down\": ChevronsUpDown, search: Search, x: X, plus: Plus, trash: Trash2, copy: Copy, grip: GripVertical, \"arrow-up\": ArrowUp, \"arrow-down\": ArrowDown, lock: Lock, unlock: Unlock,\n layers: Layers, database: Database, blocks: Blocks, \"layout-grid\": LayoutGrid, \"book-marked\": BookMarked, \"alert-triangle\": AlertTriangle, \"alert-circle\": AlertCircle, info: Info, \"check-circle\": CheckCircle2, check: Check, more: MoreHorizontal, braces: Braces,\n bold: Bold, italic: Italic, underline: Underline, strikethrough: Strikethrough, code: Code, \"list-ordered\": ListOrdered, sparkles: Sparkles, box: Box, \"file-text\": FileText, \"external-link\": ExternalLink, wand: Wand2, sun: Sun, moon: Moon, \"panel-left\": PanelLeft, \"panel-right\": PanelRight, \"rotate-ccw\": RotateCcw, \"corner-down-right\": CornerDownRight, eraser: Eraser, ruler: Ruler,\n folder: Folder, \"folder-open\": FolderOpen, \"toggle-left\": ToggleLeft, \"calendar-days\": CalendarDays, sigma: Sigma, \"list-tree\": ListTree, percent: Percent, coins: Coins, \"text-icon\": Text, binary: Binary, layout: Layout, \"file-output\": FileOutput, \"arrow-up-right\": ArrowUpRight, \"square-stack\": SquareStack, shield: Shield,\n \"hash-icon\": HashIcon, \"braces-icon\": BracesIcon, \"move-horizontal\": MoveHorizontal, \"chevron-left\": ChevronLeft, \"eye-icon\": EyeIcon, \"info-icon\": InfoIcon, upload: Upload\n};\n\nexport const FIELD_TYPE_ICONS: Record<string, string> = {\n string: \"text-icon\",\n number: \"hash\",\n currency: \"coins\",\n percent: \"percent\",\n date: \"calendar\",\n datetime: \"calendar-days\",\n boolean: \"toggle-left\",\n image: \"image\",\n url: \"link\",\n richtext: \"type\",\n object: \"folder\",\n array: \"list-tree\"\n};\n\nexport interface IconProps extends SVGProps<SVGSVGElement> {\n name?: string;\n size?: number;\n strokeWidth?: number;\n}\n\n/**\n * Renders a lucide icon by kebab-case name, or an inline SVG string supplied by a\n * custom block. Unknown names fall back to a generic block icon.\n */\nexport function Icon({ name, size = 15, strokeWidth = 1.75, ...rest }: IconProps) {\n if (name && name.trim().startsWith(\"<svg\")) {\n return <span aria-hidden=\"true\" style={{ display: \"inline-flex\", width: size, height: size }} dangerouslySetInnerHTML={{ __html: sanitizeSvg(name) }} />;\n }\n const C = (name && MAP[name]) || Box;\n return <C width={size} height={size} strokeWidth={strokeWidth} aria-hidden=\"true\" {...rest} />;\n}\n\n/** Strips scripts and event handlers from an inline SVG icon string. */\nfunction sanitizeSvg(svg: string): string {\n return svg\n .replace(/<script[\\s\\S]*?<\\/script>/gi, \"\")\n .replace(/\\son\\w+=\"[^\"]*\"/gi, \"\")\n .replace(/\\son\\w+='[^']*'/gi, \"\")\n .replace(/javascript:/gi, \"\");\n}\n","import { cloneWithNewIds, createId, createNode, createRow, createSection, type Node, type NodeLocation, type RegionId, type LibraryItem } from \"@broadpaper/core\";\nimport { documentToHtml, printReport, createPdfClient, downloadBlob } from \"@broadpaper/renderer\";\nimport type { EditorSession } from \"./session.js\";\n\nconst CLIPBOARD_MIME = \"application/x-broadpaper-nodes+json\";\nlet memoryClipboard: Node[] | null = null;\n\nexport function createActions(session: EditorSession) {\n const store = session.store;\n\n const selectedEntries = () => {\n const idx = store.index();\n return store.getState().selection.map((id) => idx.get(id)).filter((e): e is NonNullable<typeof e> => !!e);\n };\n\n /** Where a new block should go for the current selection: after the selected block, or at the end of the last section. */\n /** Forgets the caret: once something is inserted its position is stale. */\n const clearInsertion = () => {\n if (session.ui.get().insertion) session.ui.patch({ insertion: null });\n };\n\n const insertionPoint = (): NodeLocation => {\n // A caret placed by clicking wins over the selection: it is the more\n // specific statement of intent, and the more recent one.\n const caret = session.ui.get().insertion;\n if (caret) {\n const parentPath = caret.parentId ? store.locationOf(caret.parentId)?.path : undefined;\n if (!caret.parentId) return { region: caret.region, path: [caret.index] };\n if (parentPath) return { region: caret.region, path: [...parentPath, caret.index] };\n }\n const sel = selectedEntries()[0];\n if (sel) {\n const def = session.registry.get(sel.node.type);\n if (def?.container && sel.node.type !== \"row\") return { region: sel.region, path: [...sel.path, sel.node.children?.length ?? 0] };\n return { region: sel.region, path: [...sel.path.slice(0, -1), sel.index + 1] };\n }\n const body = store.template.body;\n if (body.length === 0) return { region: \"body\", path: [0] };\n const last = body[body.length - 1]!;\n return { region: \"body\", path: [body.length - 1, last.children?.length ?? 0] };\n };\n\n const ensureSection = (region: RegionId) => {\n const t = store.template;\n const list = region === \"body\" ? t.body : region === \"header\" ? t.header.default : region === \"header:first\" ? t.header.firstPage ?? [] : region === \"footer\" ? t.footer.default : t.footer.firstPage ?? [];\n if (list.length === 0) store.dispatch({ type: \"insertNode\", node: createSection(), at: { region, path: [0] } }, { label: \"Add section\" });\n };\n\n const actions = {\n insertionPoint,\n\n insertBlock(type: string, at?: NodeLocation, props?: Record<string, unknown>): string | undefined {\n const def = session.registry.get(type);\n if (!def) return undefined;\n const node = createNode(session.registry, type, { props });\n const target = at ?? insertionPoint();\n store.transaction(`Add ${def.name}`, () => {\n if (target.path.length === 1 && target.region) {\n // Inserting at region root: wrap non-sections into a section.\n if (type !== \"section\") {\n ensureSection(target.region);\n const list = target.region === \"body\" ? store.template.body : [];\n const sectionIndex = Math.min(target.path[0]!, Math.max(0, list.length - 1));\n const section = list[sectionIndex];\n store.dispatch({ type: \"insertNode\", node, at: { region: target.region, path: [sectionIndex, section?.children?.length ?? 0] } });\n return;\n }\n }\n store.dispatch({ type: \"insertNode\", node, at: target });\n });\n store.select([node.id]);\n clearInsertion();\n session.reveal(node.id);\n return node.id;\n },\n\n insertRow(layout: number[], at?: NodeLocation): string {\n const row = createRow(layout);\n store.transaction(\"Add columns\", () => store.dispatch({ type: \"insertNode\", node: row, at: at ?? insertionPoint() }));\n store.select([row.id]);\n clearInsertion();\n session.reveal(row.id);\n return row.id;\n },\n\n addSection(region: RegionId = \"body\", index?: number): string {\n const section = createSection();\n const list = region === \"body\" ? store.template.body : [];\n store.dispatch({ type: \"insertNode\", node: section, at: { region, path: [index ?? list.length] } }, { label: \"Add section\" });\n store.select([section.id]);\n session.reveal(section.id);\n return section.id;\n },\n\n insertNodeAt(node: Node, at: NodeLocation, label = \"Insert\"): void {\n store.transaction(label, () => {\n if (at.path.length === 1 && node.type !== \"section\") {\n ensureSection(at.region);\n const list = at.region === \"body\" ? store.template.body : at.region === \"header\" ? store.template.header.default : at.region === \"footer\" ? store.template.footer.default : [];\n const si = Math.min(at.path[0]!, Math.max(0, list.length - 1));\n store.dispatch({ type: \"insertNode\", node, at: { region: at.region, path: [si, list[si]?.children?.length ?? 0] } });\n } else store.dispatch({ type: \"insertNode\", node, at });\n });\n store.select([node.id]);\n clearInsertion();\n session.reveal(node.id);\n },\n\n moveNode(id: string, to: NodeLocation): void {\n const entry = store.index().get(id);\n if (!entry || entry.node.locked) return;\n store.dispatch({ type: \"moveNode\", id, to }, { label: \"Move\" });\n store.select([id]);\n },\n\n deleteSelection(): void {\n const ids = store.getState().selection.filter((id) => !store.index().get(id)?.node.locked);\n if (ids.length === 0) return;\n // Select the neighbour so the user can keep working with the keyboard.\n const first = store.index().get(ids[0]!);\n const parentId = first?.parent?.id ?? null;\n const siblings = first ? (first.parent ? first.parent.children ?? [] : []) : [];\n const neighbour = siblings[first!.index + 1] ?? siblings[first!.index - 1];\n store.dispatch({ type: \"removeNodes\", ids }, { label: ids.length > 1 ? `Delete ${ids.length} blocks` : \"Delete\" });\n store.select(neighbour && !ids.includes(neighbour.id) ? [neighbour.id] : parentId ? [parentId] : []);\n },\n\n duplicateSelection(): void {\n const entries = selectedEntries();\n if (!entries.length) return;\n const ids: string[] = [];\n store.transaction(\"Duplicate\", () => {\n for (const e of entries) {\n const newId = createId(e.node.type === \"section\" ? \"sec\" : e.node.type === \"row\" ? \"row\" : \"n\");\n store.dispatch({ type: \"duplicateNode\", id: e.node.id, newId });\n ids.push(newId);\n }\n });\n store.select(ids);\n },\n\n async copySelection(): Promise<void> {\n const nodes = selectedEntries().map((e) => structuredClone(e.node));\n if (!nodes.length) return;\n memoryClipboard = nodes;\n try {\n const payload = JSON.stringify({ broadpaper: 1, nodes });\n if (navigator.clipboard && \"write\" in navigator.clipboard && typeof ClipboardItem !== \"undefined\") {\n await navigator.clipboard.write([new ClipboardItem({ \"text/plain\": new Blob([payload], { type: \"text/plain\" }), [CLIPBOARD_MIME]: new Blob([payload], { type: CLIPBOARD_MIME }) })]).catch(() => navigator.clipboard.writeText(payload));\n } else await navigator.clipboard?.writeText(payload);\n } catch {\n /* clipboard may be unavailable; memory clipboard still works */\n }\n session.toast(nodes.length === 1 ? \"Copied block\" : `Copied ${nodes.length} blocks`);\n },\n\n async cutSelection(): Promise<void> {\n await actions.copySelection();\n actions.deleteSelection();\n },\n\n async pasteFromClipboard(text?: string): Promise<void> {\n let nodes: Node[] | null = null;\n const raw = text ?? (await navigator.clipboard?.readText?.().catch(() => \"\")) ?? \"\";\n if (raw) {\n try {\n const parsed = JSON.parse(raw) as { broadpaper?: number; nodes?: Node[] };\n if (parsed.broadpaper === 1 && Array.isArray(parsed.nodes)) nodes = parsed.nodes;\n } catch {\n /* not ours */\n }\n }\n nodes ??= memoryClipboard;\n if (!nodes?.length) return;\n actions.pasteNodes(nodes);\n },\n\n pasteNodes(nodes: Node[]): void {\n const copies = nodes.map(cloneWithNewIds);\n const ids: string[] = [];\n store.transaction(copies.length > 1 ? `Paste ${copies.length} blocks` : \"Paste\", () => {\n let at = insertionPoint();\n for (const n of copies) {\n if (n.type === \"section\") at = { region: at.region, path: [at.path[0]! + 1] };\n else if (at.path.length === 1) {\n ensureSection(at.region);\n const list = store.template.body;\n const si = Math.min(at.path[0]!, list.length - 1);\n at = { region: at.region, path: [si, list[si]?.children?.length ?? 0] };\n }\n store.dispatch({ type: \"insertNode\", node: n, at });\n ids.push(n.id);\n at = { region: at.region, path: [...at.path.slice(0, -1), at.path[at.path.length - 1]! + 1] };\n }\n });\n store.select(ids);\n // Library items and pasted blocks land wherever the caret is, which may\n // be a page away from what you are looking at.\n if (ids[0]) session.reveal(ids[0]);\n },\n\n moveSelection(direction: -1 | 1): void {\n const entry = selectedEntries()[0];\n if (!entry || entry.node.locked) return;\n const list = entry.parent ? entry.parent.children ?? [] : entry.region === \"body\" ? store.template.body : [];\n const target = entry.index + direction;\n if (target < 0 || target >= list.length) return;\n store.dispatch({ type: \"moveNode\", id: entry.node.id, to: { region: entry.region, path: [...entry.path.slice(0, -1), direction > 0 ? target + 1 : target] } }, { label: direction > 0 ? \"Move down\" : \"Move up\" });\n store.select([entry.node.id]);\n },\n\n selectParent(): void {\n const entry = selectedEntries()[0];\n if (entry?.parent) store.select([entry.parent.id]);\n },\n\n selectSibling(direction: -1 | 1): void {\n const entry = selectedEntries()[0];\n if (!entry) {\n const first = store.template.body[0]?.children?.[0] ?? store.template.body[0];\n if (first) store.select([first.id]);\n return;\n }\n const list = entry.parent ? entry.parent.children ?? [] : store.template.body;\n const next = list[entry.index + direction];\n if (next) {\n store.select([next.id]);\n session.reveal(next.id);\n }\n },\n\n selectFirstChild(): void {\n const entry = selectedEntries()[0];\n const child = entry?.node.children?.[0];\n if (child) store.select([child.id]);\n },\n\n wrapSelectionIn(type: \"container\" | \"card\" | \"keepTogether\" | \"conditional\"): void {\n const entries = selectedEntries().filter((e) => e.node.type !== \"section\" && e.node.type !== \"column\");\n if (!entries.length) return;\n const wrapper = createNode(session.registry, type);\n store.dispatch({ type: \"wrapNodes\", ids: entries.map((e) => e.node.id), wrapper }, { label: `Wrap in ${session.registry.get(type)?.name ?? type}` });\n store.select([wrapper.id]);\n },\n\n saveSelectionToLibrary(name: string, description?: string): void {\n const entry = selectedEntries()[0];\n if (!entry) return;\n const item: LibraryItem = { id: createId(\"lib\"), name, description, node: cloneWithNewIds(entry.node) };\n store.dispatch({ type: \"addLibraryItem\", item }, { label: \"Save to library\" });\n session.toast(`Saved \"${name}\" to the library`, \"success\");\n },\n\n toggleLock(): void {\n const entry = selectedEntries()[0];\n if (!entry) return;\n store.dispatch({ type: \"setLocked\", id: entry.node.id, locked: !entry.node.locked });\n },\n\n undo(): void {\n if (store.undo()) session.toast(`Undo ${store.redoLabel() ?? \"\"}`.trim());\n },\n redo(): void {\n if (store.redo()) session.toast(`Redo ${store.undoLabel() ?? \"\"}`.trim());\n },\n\n async save(): Promise<void> {\n const o = session.options.get();\n if (!o.onSave) return;\n session.ui.patch({ save: { status: \"saving\" } });\n try {\n await o.onSave(store.template);\n store.markClean();\n session.ui.patch({ save: { status: \"saved\", at: Date.now() } });\n } catch (e) {\n // No toast: the message belongs next to the button that failed, where\n // it stays until the next attempt, rather than disappearing in 2.6s.\n session.ui.patch({ save: { status: \"error\", message: (e as Error).message } });\n }\n },\n\n print(): void {\n const layout = session.layout.get();\n if (!layout) return;\n const state = store.getState();\n // Print always uses preview mode with real data.\n if (state.mode !== \"preview\") {\n session.toast(\"Switch to Preview to print with data\", \"info\");\n }\n // Asynchronous because it checks the licence before writing the page —\n // \"Save as PDF\" in the browser's dialog produces a PDF like any other\n // export and is marked on the same terms. Nothing here waits for the\n // dialog, so the promise is deliberately dropped; a failure to open it\n // is reported by the browser, not by us.\n void printReport(layout, { title: store.template.name });\n },\n\n previewHtml(): string | null {\n const layout = session.layout.get();\n return layout ? documentToHtml(layout, { title: store.template.name }) : null;\n },\n\n async exportPdf(): Promise<void> {\n const o = session.options.get();\n const layout = session.layout.get();\n const theme = session.activeTheme;\n const data = session.activeSample;\n if (o.onExportPdf) {\n const handled = await o.onExportPdf({ template: store.template, theme, data, dataSources: session.dataSources, layout, print: () => actions.print() });\n if (handled !== false) return;\n }\n if (o.pdfService?.url) {\n session.ui.patch({ exporting: true });\n try {\n const client = createPdfClient({ baseUrl: o.pdfService.url, token: o.pdfService.token });\n const { blob, pages } = await client.render({ template: store.template, data, theme, dataSources: session.dataSources, locale: o.locale, currency: o.currency, timeZone: o.timeZone, metadata: { title: store.template.name } });\n downloadBlob(blob, `${store.template.name.replace(/[^\\w.-]+/g, \"_\") || \"report\"}.pdf`);\n session.toast(`Exported ${pages} page${pages === 1 ? \"\" : \"s\"}`, \"success\");\n } catch (e) {\n session.toast(`PDF export failed: ${(e as Error).message}`, \"error\");\n } finally {\n session.ui.patch({ exporting: false });\n }\n return;\n }\n actions.print();\n }\n };\n return actions;\n}\n\nexport type EditorActions = ReturnType<typeof createActions>;\n","import { useRef, useState } from \"react\";\nimport type { Issue } from \"@broadpaper/core\";\nimport { useSession, useEditorState, useUi, useFeatures, useOptions, useLayout } from \"../state/context.js\";\nimport type { EditorActions } from \"../state/actions.js\";\nimport { Button, Segmented, Badge } from \"../ui/primitives.js\";\nimport { Menu, Popover, type MenuItem } from \"../ui/floating.js\";\nimport { Icon } from \"../ui/icons.js\";\nimport { useElementWidth } from \"../ui/use-element-size.js\";\nimport { SaveIndicator } from \"./SaveIndicator.js\";\nimport { densityFor, shows } from \"./density.js\";\nimport { fitZoom } from \"./zoom.js\";\n\nexport function Toolbar({ actions }: { actions: EditorActions }) {\n const session = useSession();\n const options = useOptions();\n const features = useFeatures();\n const mode = useEditorState((s) => s.mode);\n const zoom = useEditorState((s) => s.zoom);\n const version = useEditorState((s) => s.version);\n const name = useEditorState((s) => s.template.name);\n const issues = useUi((u) => u.issues);\n const exporting = useUi((u) => u.exporting);\n const activeThemeId = useUi((u) => u.activeThemeId);\n const activeSampleId = useUi((u) => u.activeSampleId);\n const layout = useLayout();\n const endRef = useRef<HTMLDivElement>(null);\n const startRef = useRef<HTMLDivElement>(null);\n const density = densityFor(useElementWidth(endRef));\n // The leading group has its own budget: the report name is the only thing in\n // it that can shrink, so the save wording survives long after the trailing\n // group has given up its labels.\n const startWidth = useElementWidth(startRef);\n const showSaveText = startWidth < 0 || startWidth >= 380;\n const [nameDraft, setNameDraft] = useState<string | null>(null);\n void version;\n\n const themes = session.themes;\n const theme = session.activeTheme;\n const samples = session.sampleSets;\n const sample = samples.find((s) => s.id === activeSampleId);\n const errors = issues.filter((i) => i.severity === \"error\").length;\n const warnings = issues.filter((i) => i.severity === \"warning\").length;\n const canUndo = session.store.canUndo();\n const canRedo = session.store.canRedo();\n const showThemes = features.themes && themes.length > 0;\n const showSamples = samples.length > 1;\n const inline = shows.pickersInline(density);\n const narrow = useUi((u) => u.narrow);\n\n const setZoomFit = (fit: \"width\" | \"page\") => {\n if (session.fit) return session.fit(fit);\n // No canvas mounted yet: still set a sensible zoom rather than nothing.\n const el = session.doc.querySelector<HTMLElement>(\".bpe-canvas__scroll\");\n if (el && layout) session.store.setZoom(fitZoom(fit, el, layout.page));\n };\n\n const themeItems: MenuItem[] = themes.map((t) => ({ id: t.id, label: t.name, icon: t.id === activeThemeId ? \"check\" : \"palette\", onSelect: () => session.setTheme(t.id) }));\n const sampleItems: MenuItem[] = samples.map((s) => ({ id: s.id, label: s.label, description: s.description, icon: s.id === activeSampleId ? \"check\" : \"database\", onSelect: () => session.setSample(s.id) }));\n\n const overflowItems: MenuItem[] = [\n ...(!inline && showThemes ? themeItems.map((i) => ({ ...i, id: `theme-${i.id}` })) : []),\n ...(!inline && showSamples ? sampleItems.map((i, n) => ({ ...i, id: `sample-${i.id}`, separatorBefore: n === 0 && showThemes })) : []),\n // Narrow, the panels are drawers over the canvas and only one fits, so one\n // item toggling both would either cover the canvas twice over or be the\n // wrong one. Wide, they are columns that sit together and a single item is\n // what people reach for.\n ...(narrow\n ? [\n {\n id: \"panel-left\",\n label: \"Insert blocks\",\n icon: \"panel-left\",\n separatorBefore: !inline && (showThemes || showSamples),\n onSelect: () => {\n const open = !session.ui.get().leftOpen;\n session.ui.patch({ leftOpen: open, rightOpen: false });\n }\n },\n {\n id: \"panel-right\",\n label: \"Properties\",\n icon: \"panel-right\",\n onSelect: () => {\n const open = !session.ui.get().rightOpen;\n session.ui.patch({ rightOpen: open, leftOpen: false });\n }\n }\n ]\n : [\n {\n id: \"panels\",\n label: \"Show or hide the side panels\",\n icon: \"panel-left\",\n separatorBefore: !inline && (showThemes || showSamples),\n onSelect: () => {\n const u = session.ui.get();\n const open = !(u.leftOpen && u.rightOpen);\n session.ui.patch({ leftOpen: open, rightOpen: open });\n }\n }\n ]),\n { id: \"guides\", label: \"Show page margins\", icon: \"ruler\", onSelect: () => session.ui.patch({ guides: !session.ui.get().guides }) }\n ];\n\n return (\n <header className=\"bpe-toolbar\" role=\"toolbar\" aria-label=\"Report designer toolbar\">\n <div ref={startRef} className=\"bpe-toolbar__group bpe-toolbar__group--start\">\n {!features.whiteLabel ? (\n <div className=\"bpe-toolbar__brand\">\n {/*\n The BroadPaper mark: a sheet with its corner turned down. The\n silhouette is the logo's, without the monogram, because at 24px\n the letterforms would be mud — and because keeping the outlines\n in one place (the site's logo.json) means this cannot drift from\n them. It is the product's own attribution, so the red is\n hard-coded rather than themed; `whiteLabel` removes it entirely.\n */}\n <span className=\"bpe-toolbar__mark\" title=\"Made with BroadPaper\">\n <svg viewBox=\"0 0 44 36\" role=\"img\" aria-label=\"BroadPaper\">\n <path d=\"M2 0H35L44 9V34Q44 36 42 36H2Q0 36 0 34V2Q0 0 2 0Z\" fill=\"#d5451b\" />\n <path d=\"M35 0V9H44Z\" fill=\"#171511\" />\n </svg>\n </span>\n </div>\n ) : null}\n <input\n className=\"bpe-toolbar__name\"\n aria-label=\"Report name\"\n title={name}\n value={nameDraft ?? name}\n onChange={(e) => setNameDraft(e.target.value)}\n onBlur={() => {\n if (nameDraft !== null && nameDraft.trim() && nameDraft !== name) session.store.dispatch({ type: \"setTemplateName\", name: nameDraft.trim() });\n setNameDraft(null);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") (e.target as HTMLInputElement).blur();\n if (e.key === \"Escape\") setNameDraft(null);\n }}\n />\n <SaveIndicator compact={!showSaveText} canSave={!!options.onSave} onSave={() => actions.save()} />\n <span className=\"bpe-toolbar__sep\" />\n <Button variant=\"ghost\" icon=\"undo\" tooltip={canUndo ? `Undo ${session.store.undoLabel() ?? \"\"}` : \"Nothing to undo\"} shortcut=\"⌘Z\" disabled={!canUndo} onClick={() => actions.undo()} aria-label=\"Undo\" />\n <Button variant=\"ghost\" icon=\"redo\" tooltip={canRedo ? `Redo ${session.store.redoLabel() ?? \"\"}` : \"Nothing to redo\"} shortcut=\"⇧⌘Z\" disabled={!canRedo} onClick={() => actions.redo()} aria-label=\"Redo\" />\n </div>\n\n <div className=\"bpe-toolbar__group bpe-toolbar__group--centre\">\n <Segmented\n className=\"bpe-mode\"\n /* Icon-only narrow: the two labels cost about ninety pixels the\n centre row does not have at 360px, and `iconOnly` keeps the\n accessible name on `aria-label`, so Design and Preview are\n still what a screen reader and a test find. */\n iconOnly={narrow}\n value={mode}\n onChange={(m) => session.setMode(m as \"design\" | \"preview\")}\n ariaLabel=\"Editor mode\"\n exclusive\n options={[\n { value: \"design\", label: \"Design\", icon: \"pencil\" },\n { value: \"preview\", label: \"Preview\", icon: \"eye\" }\n ]}\n />\n <span className=\"bpe-toolbar__sep\" />\n <div className=\"bpe-zoom\">\n <Button variant=\"ghost\" icon=\"zoom-out\" tooltip=\"Zoom out\" shortcut=\"⌘−\" onClick={() => session.store.setZoom(zoom - 0.1)} aria-label=\"Zoom out\" />\n <Menu\n label=\"Zoom\"\n trigger={<button type=\"button\" className=\"bpe-btn bpe-btn--ghost bpe-zoom__value\" aria-label={`Zoom: ${Math.round(zoom * 100)} per cent`}>{Math.round(zoom * 100)}%</button>}\n items={[\n { id: \"fit-page\", label: \"Fit page\", icon: \"maximize\", onSelect: () => setZoomFit(\"page\") },\n { id: \"fit-width\", label: \"Fit width\", icon: \"move-horizontal\", onSelect: () => setZoomFit(\"width\") },\n ...[50, 75, 100, 125, 150, 200].map((z) => ({ id: String(z), label: `${z}%`, hint: z === 100 ? \"⌘0\" : undefined, separatorBefore: z === 50, onSelect: () => session.store.setZoom(z / 100) }))\n ]}\n />\n <Button variant=\"ghost\" icon=\"zoom-in\" tooltip=\"Zoom in\" shortcut=\"⌘+\" onClick={() => session.store.setZoom(zoom + 0.1)} aria-label=\"Zoom in\" />\n <Button variant=\"ghost\" icon=\"move-horizontal\" tooltip=\"Fit width\" onClick={() => setZoomFit(\"width\")} aria-label=\"Fit width\" />\n <Button variant=\"ghost\" icon=\"maximize\" tooltip=\"Fit page\" onClick={() => setZoomFit(\"page\")} aria-label=\"Fit page\" />\n </div>\n </div>\n\n <div ref={endRef} className=\"bpe-toolbar__group bpe-toolbar__group--end\">\n {showThemes && inline ? (\n <Menu\n label=\"Brand theme\"\n placement=\"bottom-end\"\n trigger={\n <button type=\"button\" className=\"bpe-theme-select\" aria-label={`Brand theme: ${theme.name}`} title={`Brand theme: ${theme.name}`}>\n <span className=\"bpe-swatches\" aria-hidden=\"true\">\n <span className=\"bpe-swatch\" style={{ background: theme.colors.primary }} />\n <span className=\"bpe-swatch\" style={{ background: theme.colors.secondary }} />\n <span className=\"bpe-swatch\" style={{ background: theme.colors.accent }} />\n </span>\n {shows.themeName(density) ? <span className=\"bpe-truncate bpe-theme-select__name\">{theme.name}</span> : null}\n <Icon name=\"chevron-down\" size={12} />\n </button>\n }\n items={themeItems}\n />\n ) : null}\n {showSamples && inline ? (\n <Menu\n label=\"Sample data\"\n placement=\"bottom-end\"\n trigger={\n <Button variant=\"ghost\" icon=\"database\" tooltip={`Sample data: ${sample?.label ?? \"none\"}`} aria-label={`Sample data: ${sample?.label ?? \"none\"}`}>\n {shows.sampleLabel(density) ? sample?.label ?? \"Sample data\" : null}\n </Button>\n }\n items={sampleItems}\n />\n ) : null}\n {features.validation ? <IssuesPopover issues={issues} errors={errors} warnings={warnings} /> : null}\n <Menu\n label=\"More options\"\n placement=\"bottom-end\"\n trigger={<Button variant=\"ghost\" icon=\"more\" tooltip=\"More options\" aria-label=\"More options\" />}\n items={overflowItems}\n />\n <span className=\"bpe-toolbar__sep\" />\n {options.onSave ? <Button icon=\"save\" tooltip=\"Save\" shortcut=\"⌘S\" onClick={() => actions.save()} aria-label=\"Save\">{shows.saveText(density) ? \"Save\" : null}</Button> : null}\n {features.pdfExport ? (\n <Menu\n placement=\"bottom-end\"\n label=\"Export\"\n trigger={<Button variant=\"primary\" icon={exporting ? \"clock\" : \"download\"} disabled={exporting} aria-label={exporting ? \"Exporting\" : \"Export\"}>{exporting ? (shows.exportText(density) ? \"Exporting…\" : null) : shows.exportText(density) ? \"Export\" : null}</Button>}\n items={[\n { id: \"pdf\", label: options.pdfService?.url || options.onExportPdf ? \"Download PDF\" : \"Print / Save as PDF\", icon: \"file-output\", hint: layout ? `${layout.paged.totalPages} pages` : undefined, onSelect: () => actions.exportPdf() },\n ...(options.pdfService?.url || options.onExportPdf ? [{ id: \"print\", label: \"Print…\", icon: \"printer\", onSelect: () => actions.print() }] : []),\n ...(features.jsonView ? [{ id: \"json\", label: \"Copy template JSON\", icon: \"braces\", separatorBefore: true, onSelect: () => { navigator.clipboard?.writeText(JSON.stringify(session.store.template, null, 2)); session.toast(\"Template JSON copied\", \"success\"); } }] : [])\n ]}\n />\n ) : null}\n </div>\n </header>\n );\n}\n\n/* ------------------------------------------------------------------ */\n\n/**\n * Two lists, not one. \"Your template has a broken binding\" and \"this client has\n * no phone number\" are different problems with different owners, and a single\n * count that mixes them tells you neither. The old panel reported \"0 validation\n * issues\" over a report that said \"Values as at .\" — technically true, and\n * exactly the wrong thing to have been counting.\n */\nfunction IssuesPopover({ issues, errors, warnings }: { issues: Issue[]; errors: number; warnings: number }) {\n const session = useSession();\n const template = issues.filter((i) => (i.source ?? \"template\") === \"template\");\n const output = issues.filter((i) => i.source === \"output\");\n const label = errors ? `${errors} error${errors === 1 ? \"\" : \"s\"}` : warnings ? `${warnings} warning${warnings === 1 ? \"\" : \"s\"}` : \"no issues\";\n\n return (\n <Popover\n placement=\"bottom-end\"\n className=\"bpe-picker bpe-issues\"\n trigger={\n <button type=\"button\" className=\"bpe-btn bpe-btn--ghost\" aria-label={`Checks: ${label}`} title={`Checks: ${label}`}>\n <Icon name={errors ? \"alert-circle\" : warnings ? \"alert-triangle\" : \"check-circle\"} style={{ color: errors ? \"var(--bpe-danger)\" : warnings ? \"var(--bpe-warning)\" : \"var(--bpe-success)\" }} />\n {errors || warnings ? <Badge tone={errors ? \"danger\" : \"warning\"}>{errors || warnings}</Badge> : null}\n </button>\n }\n >\n {(close) => (\n <div className=\"bpe-picker__list\" style={{ maxHeight: 420 }}>\n <IssueGroup\n title=\"Template\"\n blurb=\"Problems with the design itself, true for every report it produces.\"\n emptyTitle=\"Template checks out.\"\n emptyBody=\"Bindings, blocks and theme tokens are all valid.\"\n issues={template}\n close={close}\n session={session}\n />\n <IssueGroup\n title=\"This data\"\n blurb=\"What the selected sample does to the output. Switch samples to check another client.\"\n emptyTitle=\"Nothing missing.\"\n emptyBody=\"Every bound field has a value in this data set.\"\n issues={output}\n close={close}\n session={session}\n />\n </div>\n )}\n </Popover>\n );\n}\n\nfunction IssueGroup({ title, blurb, emptyTitle, emptyBody, issues, close, session }: { title: string; blurb: string; emptyTitle: string; emptyBody: string; issues: Issue[]; close: () => void; session: ReturnType<typeof useSession> }) {\n return (\n <div className=\"bpe-issues__group\">\n <div className=\"bpe-issues__head\">\n <span className=\"bpe-issues__title\">{title}</span>\n <Badge tone={issues.some((i) => i.severity === \"error\") ? \"danger\" : issues.length ? \"warning\" : \"success\"}>{issues.length}</Badge>\n </div>\n <p className=\"bpe-issues__blurb\">{blurb}</p>\n {issues.length === 0 ? (\n <div className=\"bpe-issues__ok\">\n <Icon name=\"check-circle\" size={13} />\n <span><strong>{emptyTitle}</strong> {emptyBody}</span>\n </div>\n ) : null}\n {issues.map((i, k) => {\n const node = i.nodeId ? session.store.getNode(i.nodeId) : undefined;\n const where = node ? session.registry.get(node.type)?.name ?? node.type : i.nodeId;\n return (\n <button\n key={k}\n type=\"button\"\n className={`bpe-issue bpe-issue--${i.severity}`}\n disabled={!i.nodeId}\n onClick={() => {\n if (!i.nodeId) return;\n session.store.select([i.nodeId]);\n session.reveal(i.nodeId);\n close();\n }}\n >\n <Icon name={i.severity === \"error\" ? \"alert-circle\" : i.severity === \"warning\" ? \"alert-triangle\" : \"info\"} />\n <span>\n {i.message}\n {i.nodeId ? <span className=\"bpe-issue__meta\">{where}{i.prop ? ` · ${i.prop}` : \"\"} · click to open</span> : null}\n </span>\n </button>\n );\n })}\n </div>\n );\n}\n","import { forwardRef, useId, useState, type ButtonHTMLAttributes, type InputHTMLAttributes, type ReactNode, type SelectHTMLAttributes, type TextareaHTMLAttributes, type CSSProperties, type KeyboardEvent } from \"react\";\nimport { Icon } from \"./icons.js\";\nimport { Tooltip } from \"./floating.js\";\n\nexport function cx(...parts: Array<string | false | null | undefined>): string {\n return parts.filter(Boolean).join(\" \");\n}\n\n/* ------------------------------ Button ------------------------------ */\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: \"default\" | \"primary\" | \"ghost\" | \"danger\";\n size?: \"sm\" | \"md\";\n icon?: string;\n active?: boolean;\n tooltip?: ReactNode;\n shortcut?: string;\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button({ variant = \"default\", size = \"md\", icon, active, tooltip, shortcut, className, children, type = \"button\", ...rest }, ref) {\n // An icon-only button has no text for a screen reader to read, and a tooltip\n // is not a name — it only exists while a pointer hovers it. Where the caller\n // gave a plain-text tooltip and no explicit label, that text is the name.\n const iconOnly = !children && !!icon;\n const label = rest[\"aria-label\"] ?? (iconOnly && typeof tooltip === \"string\" ? tooltip : undefined);\n const btn = (\n <button ref={ref} type={type} className={cx(\"bpe-btn\", variant !== \"default\" && `bpe-btn--${variant}`, size === \"sm\" && \"bpe-btn--sm\", iconOnly && \"bpe-btn--icon\", active && \"bpe-btn--active\", className)} {...rest} aria-label={label}>\n {icon ? <Icon name={icon} /> : null}\n {children}\n </button>\n );\n if (tooltip) return <Tooltip content={tooltip} shortcut={shortcut}>{btn}</Tooltip>;\n return btn;\n});\n\n/* ------------------------------- Inputs ------------------------------ */\n\nexport interface TextInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, \"onChange\" | \"value\"> {\n value: string;\n onChange: (value: string) => void;\n /** Commit on blur/enter instead of every keystroke. */\n lazy?: boolean;\n invalid?: boolean;\n suffix?: ReactNode;\n mono?: boolean;\n}\n\nexport const TextInput = forwardRef<HTMLInputElement, TextInputProps>(function TextInput({ value, onChange, lazy, invalid, suffix, mono, className, onBlur, onKeyDown, ...rest }, ref) {\n const [draft, setDraft] = useState<string | null>(null);\n const shown = lazy && draft !== null ? draft : value;\n const input = (\n <input\n ref={ref}\n className={cx(\"bpe-input\", invalid && \"bpe-input--invalid\", mono && \"bpe-expr\", className)}\n value={shown}\n onChange={(e) => (lazy ? setDraft(e.target.value) : onChange(e.target.value))}\n onBlur={(e) => {\n if (lazy && draft !== null && draft !== value) onChange(draft);\n setDraft(null);\n onBlur?.(e);\n }}\n onKeyDown={(e) => {\n if (lazy && e.key === \"Enter\") {\n if (draft !== null && draft !== value) onChange(draft);\n setDraft(null);\n (e.target as HTMLInputElement).blur();\n }\n if (e.key === \"Escape\") {\n setDraft(null);\n (e.target as HTMLInputElement).blur();\n }\n onKeyDown?.(e);\n }}\n {...rest}\n />\n );\n if (!suffix) return input;\n return (\n <div className=\"bpe-input-group\">\n {input}\n <span className=\"bpe-input-group__suffix\">{suffix}</span>\n </div>\n );\n});\n\nexport interface NumberInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, \"onChange\" | \"value\"> {\n value: number | null | undefined;\n onChange: (value: number | null) => void;\n min?: number;\n max?: number;\n step?: number;\n unit?: string;\n allowEmpty?: boolean;\n}\n\nexport function NumberInput({ value, onChange, min, max, step = 1, unit, allowEmpty = true, className, ...rest }: NumberInputProps) {\n const [draft, setDraft] = useState<string | null>(null);\n const shown = draft !== null ? draft : value === null || value === undefined ? \"\" : String(value);\n const commit = (raw: string) => {\n setDraft(null);\n if (raw.trim() === \"\") {\n if (allowEmpty) onChange(null);\n return;\n }\n let n = Number(raw);\n if (!Number.isFinite(n)) return;\n if (min !== undefined) n = Math.max(min, n);\n if (max !== undefined) n = Math.min(max, n);\n if (n !== value) onChange(n);\n };\n return (\n <div className=\"bpe-input-group bpe-number\">\n <input\n type=\"text\"\n inputMode=\"decimal\"\n className={cx(\"bpe-input\", className)}\n value={shown}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={(e) => commit(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") commit((e.target as HTMLInputElement).value);\n if (e.key === \"Escape\") setDraft(null);\n if (e.key === \"ArrowUp\" || e.key === \"ArrowDown\") {\n e.preventDefault();\n const base = draft !== null ? Number(draft) : value ?? 0;\n const delta = (e.key === \"ArrowUp\" ? 1 : -1) * (e.shiftKey ? step * 10 : step);\n commit(String(Math.round((base + delta) * 1000) / 1000));\n }\n }}\n {...rest}\n />\n {unit ? <span className=\"bpe-input-group__suffix\">{unit}</span> : null}\n </div>\n );\n}\n\nexport interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, \"onChange\" | \"value\"> {\n value: string;\n onChange: (value: string) => void;\n options: Array<{ value: string; label: string; disabled?: boolean }>;\n placeholder?: string;\n}\n\nexport function Select({ value, onChange, options, placeholder, className, ...rest }: SelectProps) {\n return (\n <select className={cx(\"bpe-select\", className)} value={value} onChange={(e) => onChange(e.target.value)} {...rest}>\n {placeholder ? <option value=\"\">{placeholder}</option> : null}\n {options.map((o) => (\n <option key={String(o.value)} value={o.value} disabled={o.disabled}>\n {o.label}\n </option>\n ))}\n </select>\n );\n}\n\nexport function TextArea({ className, ...rest }: TextareaHTMLAttributes<HTMLTextAreaElement>) {\n return <textarea className={cx(\"bpe-textarea\", className)} {...rest} />;\n}\n\nexport function Switch({ checked, onChange, label, disabled }: { checked: boolean; onChange: (v: boolean) => void; label?: string; disabled?: boolean }) {\n return <button type=\"button\" role=\"switch\" aria-checked={checked} aria-label={label} className=\"bpe-switch\" disabled={disabled} onClick={() => onChange(!checked)} />;\n}\n\nexport interface SegmentedOption {\n value: string;\n label: string;\n icon?: string;\n title?: string;\n}\n\n/**\n * A row of mutually exclusive choices.\n *\n * `exclusive` switches it from a group of independent toggles to a radio group,\n * which is what Design/Preview actually is: a screen reader then says \"Design,\n * radio button, 1 of 2, selected\" instead of announcing two separate buttons\n * that each happen to be pressed or not. Radio semantics also come with the\n * expectation of arrow-key navigation, so that is implemented rather than left\n * as an unmet promise, and only the selected option stays in the tab order.\n */\nexport function Segmented({ value, onChange, options, className, iconOnly, ariaLabel, exclusive }: { value: string; onChange: (v: string) => void; options: SegmentedOption[]; className?: string; iconOnly?: boolean; ariaLabel?: string; exclusive?: boolean }) {\n const selectedIndex = Math.max(0, options.findIndex((o) => o.value === value));\n const onKeyDown = (e: KeyboardEvent<HTMLButtonElement>, index: number) => {\n if (!exclusive) return;\n const delta = e.key === \"ArrowRight\" || e.key === \"ArrowDown\" ? 1 : e.key === \"ArrowLeft\" || e.key === \"ArrowUp\" ? -1 : 0;\n if (!delta) return;\n e.preventDefault();\n const next = options[(index + delta + options.length) % options.length]!;\n onChange(next.value);\n const buttons = e.currentTarget.parentElement?.querySelectorAll<HTMLButtonElement>(\".bpe-segmented__item\");\n buttons?.[(index + delta + options.length) % options.length]?.focus();\n };\n return (\n <div className={cx(\"bpe-segmented\", className)} role={exclusive ? \"radiogroup\" : \"group\"} aria-label={ariaLabel}>\n {options.map((o, i) => {\n const selected = o.value === value;\n return (\n <button\n key={o.value}\n type=\"button\"\n className=\"bpe-segmented__item\"\n role={exclusive ? \"radio\" : undefined}\n aria-checked={exclusive ? selected : undefined}\n aria-pressed={exclusive ? undefined : selected}\n tabIndex={exclusive ? (i === selectedIndex ? 0 : -1) : undefined}\n title={o.title ?? (iconOnly ? o.label : undefined)}\n aria-label={iconOnly ? o.label : undefined}\n onKeyDown={(e) => onKeyDown(e, i)}\n onClick={() => onChange(o.value)}\n >\n {o.icon ? <Icon name={o.icon} size={13} /> : null}\n {iconOnly && o.icon ? null : o.label}\n </button>\n );\n })}\n </div>\n );\n}\n\n/* -------------------------------- Field ------------------------------ */\n\n/**\n * A labelled control.\n *\n * The label column is 96px, which is enough for \"Width\" and not for \"Message\n * when empty\" — that one was reaching the user as \"Message when em…\". Rather\n * than widen every row for the sake of the longest label, a label that will not\n * fit moves above its control, which is where a long label belongs anyway.\n */\nconst LABEL_FITS = 17;\n\nexport function Field({ label, children, hint, error, stacked, htmlFor }: { label: ReactNode; children: ReactNode; hint?: ReactNode; error?: ReactNode; stacked?: boolean; htmlFor?: string }) {\n const id = useId();\n const tooLong = typeof label === \"string\" && label.length > LABEL_FITS;\n return (\n <div className={cx(\"bpe-field\", (stacked || tooLong) && \"bpe-field--stacked\")}>\n <label className=\"bpe-field__label\" htmlFor={htmlFor ?? id} title={typeof label === \"string\" ? label : undefined}>\n {label}\n </label>\n <div className=\"bpe-field__control\">{children}</div>\n {hint ? <div className=\"bpe-field__hint\">{hint}</div> : null}\n {error ? <div className=\"bpe-field__error\">{error}</div> : null}\n </div>\n );\n}\n\n/* ------------------------------ Section ----------------------------- */\n\nexport function Section({ title, children, defaultOpen = true, actions, icon }: { title: ReactNode; children: ReactNode; defaultOpen?: boolean; actions?: ReactNode; icon?: string }) {\n const [open, setOpen] = useState(defaultOpen);\n const id = useId();\n return (\n <div className=\"bpe-section\">\n <div className=\"bpe-section__head\">\n <button type=\"button\" className=\"bpe-section__toggle\" aria-expanded={open} aria-controls={id} onClick={() => setOpen(!open)}>\n {icon ? <Icon name={icon} size={13} /> : null}\n <span>{title}</span>\n <Icon name=\"chevron-down\" className=\"bpe-section__chev\" />\n </button>\n {actions ? <span className=\"bpe-section__actions\">{actions}</span> : null}\n </div>\n {open ? (\n <div className=\"bpe-section__body\" id={id}>\n {children}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport function Badge({ tone, children, style }: { tone?: \"accent\" | \"warning\" | \"danger\" | \"success\"; children: ReactNode; style?: CSSProperties }) {\n return (\n <span className={cx(\"bpe-badge\", tone && `bpe-badge--${tone}`)} style={style}>\n {children}\n </span>\n );\n}\n\nexport function EmptyState({ icon, title, children }: { icon?: string; title: ReactNode; children?: ReactNode }) {\n return (\n <div className=\"bpe-empty\">\n {icon ? <Icon name={icon} size={22} /> : null}\n <div className=\"bpe-empty__title\">{title}</div>\n {children ? <div>{children}</div> : null}\n </div>\n );\n}\n\nexport function Kbd({ children }: { children: ReactNode }) {\n return <kbd className=\"bpe-kbd\">{children}</kbd>;\n}\n","import { useEffect, useState, type RefObject } from \"react\";\n\n/** Returned until the element has actually been measured. See `useElementWidth`. */\nexport const UNMEASURED = -1;\n\n/**\n * The width of an element, tracked as it changes.\n *\n * The designer is embedded, so it can be any width inside any host at any\n * viewport. A media query would answer a question nobody asked — \"how big is\n * the screen\" — when the one that matters is \"how much room have I got\".\n *\n * Unmeasured is `UNMEASURED`, not `0`, because those are different facts and\n * conflating them was a real bug: a toolbar group in a `1fr` track really can\n * measure zero when the neighbouring track has taken everything, and callers\n * that read zero as \"not measured yet, assume room\" then laid out at their\n * widest in no room at all — off the side of the screen.\n */\nexport function useElementWidth(ref: RefObject<HTMLElement | null>): number {\n const [width, setWidth] = useState(UNMEASURED);\n useEffect(() => {\n const el = ref.current;\n if (!el || typeof ResizeObserver !== \"function\") return;\n setWidth(el.clientWidth);\n const ro = new ResizeObserver(() => setWidth(el.clientWidth));\n ro.observe(el);\n return () => ro.disconnect();\n }, [ref]);\n return width;\n}\n","import { useEditorState, useUi, useOptions } from \"../state/context.js\";\nimport type { SaveState } from \"../state/session.js\";\nimport { Icon } from \"../ui/icons.js\";\nimport { Tooltip } from \"../ui/floating.js\";\n\nconst IDLE: SaveState = { status: \"idle\" };\n\n/**\n * Says what has happened to the document, in words.\n *\n * The previous version was an orange dot with a `title` — which told you\n * something was different but not what, not whether anything had been written\n * anywhere, and not whether the last attempt had failed. Saving is the host's\n * job in this SDK, so the text has to be honest about that: with no `onSave`\n * handler there is nothing to save and the indicator says so rather than\n * implying a persistence layer that does not exist.\n */\nexport function SaveIndicator({ compact, canSave, onSave }: { compact?: boolean; canSave: boolean; onSave: () => void }) {\n const dirty = useEditorState((s) => s.dirty);\n // Nothing here may assume the UI store is fully populated. A host that swaps\n // options mid-render, or a designer mounted before its first patch lands, can\n // hand this component a state without a save slice — and reading .status off\n // it threw during render, which unmounted the whole editor and left a blank\n // panel where the document had been.\n const save = useUi((u) => u?.save) ?? IDLE;\n const options = useOptions() ?? {};\n const note = options.saveDescription;\n\n const state = !canSave\n ? { tone: \"muted\", icon: \"info\", text: \"Not saved anywhere\", detail: note ?? \"This designer has no save handler, so changes live in the page until you export or the host stores the template.\" }\n : save.status === \"saving\"\n ? { tone: \"busy\", icon: \"clock\", text: \"Saving…\", detail: note ?? \"Handing the template to the host application.\" }\n : save.status === \"error\"\n ? { tone: \"error\", icon: \"alert-circle\", text: \"Save failed\", detail: save.message ?? \"The host rejected the template. Try again.\" }\n : dirty\n ? { tone: \"dirty\", icon: \"pen-line\", text: \"Unsaved changes\", detail: note ?? \"Save to hand the template to the host application.\" }\n : { tone: \"clean\", icon: \"check-circle\", text: save.at ? `Saved ${time(save.at)}` : \"Saved\", detail: note ?? \"Nothing has changed since the last save.\" };\n\n const body = (\n <span className={`bpe-save bpe-save--${state.tone}`} role=\"status\" aria-live=\"polite\">\n <Icon name={state.icon} size={13} />\n {compact ? null : <span className=\"bpe-save__text\">{state.text}</span>}\n <span className=\"bpe-sr-only\">{state.text}. {state.detail}</span>\n </span>\n );\n\n // Failure is the one state where the indicator is worth clicking: the retry\n // is the whole point, and hunting for the Save button after a failure is not.\n if (canSave && save.status === \"error\") {\n return (\n <Tooltip content={`${state.detail} Click to try again.`}>\n <button type=\"button\" className={`bpe-save bpe-save--${state.tone} bpe-save--action`} onClick={onSave} aria-label={`Save failed: ${state.detail}. Try again`}>\n <Icon name={state.icon} size={13} />\n {compact ? null : <span className=\"bpe-save__text\">{state.text}</span>}\n </button>\n </Tooltip>\n );\n }\n\n return <Tooltip content={state.detail}>{body}</Tooltip>;\n}\n\nfunction time(at: number): string {\n return new Date(at).toLocaleTimeString(undefined, { hour: \"2-digit\", minute: \"2-digit\" });\n}\n","/**\n * How much of itself the trailing toolbar group can afford to show.\n *\n * Measured against the width of that group's own grid track, not the window:\n * the designer is embedded, so the window says nothing useful, and the track is\n * exactly the room the group has. The track is a `minmax(0, 1fr)` share of the\n * leftover space, so it does not move when the contents change — measuring it\n * cannot start a loop where shrinking the contents frees space that grows them\n * back.\n *\n * The order things are given up in is the order they are least used in: the\n * sample-data label, then the brand name, then the Save and Export words, and\n * only at the very end do the brand and sample pickers move into the overflow\n * menu. Design/Preview, zoom and Export are never shed — they live in the\n * centre track and a fixed-width button, which is what \"protect space\" means\n * in practice.\n *\n * The numbers come from measuring the real controls: ~646px for the trailing\n * group with every label, ~430 once the sample label goes, ~300 icon-only.\n */\nexport type Density = \"full\" | \"labels\" | \"icons\" | \"overflow\";\n\nexport function densityFor(trackWidth: number): Density {\n // Nothing measured yet. Assume room, because a toolbar that renders collapsed\n // and expands one frame later reads as a glitch. A *measured* zero is the\n // opposite situation and falls through to `overflow` below: the track really\n // has no room, which is what happens on a phone once the centre group has\n // taken the width, and assuming room there put the pickers off-screen.\n if (trackWidth < 0) return \"full\";\n if (trackWidth >= 620) return \"full\";\n if (trackWidth >= 420) return \"labels\";\n if (trackWidth >= 300) return \"icons\";\n return \"overflow\";\n}\n\n/** Whether a given piece of chrome survives at this density. */\nexport const shows = {\n sampleLabel: (d: Density) => d === \"full\",\n themeName: (d: Density) => d === \"full\" || d === \"labels\",\n saveText: (d: Density) => d === \"full\",\n exportText: (d: Density) => d !== \"icons\" && d !== \"overflow\",\n pickersInline: (d: Density) => d !== \"overflow\"\n};\n","/**\n * Geometry of the page stack inside the canvas scroller. These mirror\n * `.bpe-canvas__inner`'s padding and the gap `PageView` puts under each page;\n * they are here because both the zoom maths and the scroll maths need them and\n * disagreeing about them is what leaves the viewport parked between two pages.\n */\nexport const CANVAS_PAD_TOP = 32;\nexport const CANVAS_PAD_BOTTOM = 80;\nexport const PAGE_GAP = 28;\n/** Horizontal padding either side, from the same rule. */\nconst CANVAS_PAD_X = 40;\n\n/**\n * The zoom that makes a page fit the visible canvas.\n *\n * \"Fit width\" is what you want while writing — the page as wide as it will go.\n * \"Fit page\" is what you want while checking pagination, because a whole page\n * at once is the only way to see where the break actually landed. So fit-page\n * has to leave room for the whole page and nothing may round it back up: at two\n * decimal places, rounding to nearest can add half a percent of height, which\n * is enough to push the last line of an A4 page out of view and defeat the\n * entire point of the button.\n */\nexport function fitZoom(mode: \"width\" | \"page\", scroller: { clientWidth: number; clientHeight: number }, page: { width: number; height: number }): number {\n const byWidth = (scroller.clientWidth - CANVAS_PAD_X * 2) / page.width;\n // A page is centred vertically when it fits, so only one page's worth of\n // padding has to be accounted for, not the full top-plus-bottom.\n const byHeight = (scroller.clientHeight - CANVAS_PAD_TOP * 2) / page.height;\n const raw = mode === \"width\" ? byWidth : Math.min(byWidth, byHeight);\n return Math.min(2, Math.max(0.25, Math.floor(raw * 100) / 100));\n}\n\n/** Distance from the top of the scroller's content to the top of page `index`. */\nexport function pageTop(index: number, pageHeight: number, zoom: number): number {\n return CANVAS_PAD_TOP + index * (pageHeight * zoom + PAGE_GAP);\n}\n\n/**\n * Where to scroll so page `index` is the page you are looking at: centred when\n * it fits, top-aligned when it does not.\n */\nexport function scrollTopForPage(index: number, pageHeight: number, zoom: number, viewportHeight: number): number {\n const scaled = pageHeight * zoom;\n const slack = Math.max(0, (viewportHeight - scaled) / 2);\n return Math.max(0, pageTop(index, pageHeight, zoom) - slack);\n}\n","import { useMemo, useState } from \"react\";\nimport { ROW_LAYOUTS, type BlockDefinition, type DataSource, type FieldSchema, type LibraryItem, type Node } from \"@broadpaper/core\";\nimport { useSession, useUi, useFeatures, useTemplate, useEditorState, useRegistryVersion, nodeLabel, nodeDetail } from \"../state/context.js\";\nimport type { EditorActions } from \"../state/actions.js\";\nimport type { LeftTab } from \"../state/session.js\";\nimport { beginDrag } from \"../dnd/drag-manager.js\";\nimport { Icon, FIELD_TYPE_ICONS } from \"../ui/icons.js\";\nimport { Button, TextInput, EmptyState } from \"../ui/primitives.js\";\n\nconst TABS: Array<{ id: LeftTab; label: string; icon: string; feature?: \"library\" | \"layers\" | \"dataPanel\" }> = [\n { id: \"blocks\", label: \"Blocks\", icon: \"blocks\" },\n { id: \"layouts\", label: \"Layout\", icon: \"layout-grid\" },\n { id: \"data\", label: \"Data\", icon: \"database\", feature: \"dataPanel\" },\n { id: \"layers\", label: \"Layers\", icon: \"layers\", feature: \"layers\" },\n { id: \"library\", label: \"Library\", icon: \"book-marked\", feature: \"library\" }\n];\n\nexport function LeftPanel({ actions }: { actions: EditorActions }) {\n const session = useSession();\n const tab = useUi((u) => u.leftTab);\n const features = useFeatures();\n const tabs = TABS.filter((t) => !t.feature || features[t.feature]);\n return (\n <aside className=\"bpe-left\" aria-label=\"Insert and navigate\">\n {/* Every tab keeps its name. Showing the label only on the selected tab\n made the other four an icon quiz — the one thing you did not need\n spelled out was the panel already in front of you. */}\n <div className=\"bpe-tabs\" role=\"tablist\" aria-label=\"Panels\">\n {tabs.map((t) => (\n <button\n key={t.id}\n type=\"button\"\n role=\"tab\"\n id={`bpe-tab-${t.id}`}\n className=\"bpe-tab\"\n aria-selected={tab === t.id}\n aria-controls=\"bpe-left-panel\"\n tabIndex={tab === t.id ? 0 : -1}\n onKeyDown={(e) => {\n const delta = e.key === \"ArrowRight\" ? 1 : e.key === \"ArrowLeft\" ? -1 : 0;\n if (!delta) return;\n e.preventDefault();\n const next = tabs[(tabs.findIndex((x) => x.id === tab) + delta + tabs.length) % tabs.length]!;\n session.ui.patch({ leftTab: next.id });\n session.doc.getElementById(`bpe-tab-${next.id}`)?.focus();\n }}\n onClick={() => session.ui.patch({ leftTab: t.id })}\n >\n <Icon name={t.icon} />\n <span>{t.label}</span>\n </button>\n ))}\n </div>\n <div className=\"bpe-left__body\" role=\"tabpanel\" id=\"bpe-left-panel\" aria-labelledby={`bpe-tab-${tab}`}>\n {tab === \"blocks\" ? <BlocksPanel actions={actions} /> : null}\n {tab === \"layouts\" ? <LayoutsPanel actions={actions} /> : null}\n {tab === \"data\" ? <DataPanel actions={actions} /> : null}\n {tab === \"layers\" ? <LayersPanel actions={actions} /> : null}\n {tab === \"library\" ? <LibraryPanel actions={actions} /> : null}\n </div>\n </aside>\n );\n}\n\n/* --------------------------------- blocks --------------------------------- */\n\nconst CATEGORY_ORDER: Array<{ id: BlockDefinition[\"category\"]; label: string }> = [\n { id: \"content\", label: \"Content\" },\n { id: \"data\", label: \"Data\" },\n { id: \"layout\", label: \"Layout\" },\n { id: \"visualisation\", label: \"Charts\" },\n { id: \"custom\", label: \"Custom blocks\" }\n];\n\nfunction BlocksPanel({ actions }: { actions: EditorActions }) {\n const session = useSession();\n const features = useFeatures();\n useRegistryVersion();\n const [q, setQ] = useState(\"\");\n const defs = session.registry.palette().filter((d) => features.customBlocks || d.category !== \"custom\");\n const filtered = q.trim() ? defs.filter((d) => [d.name, d.description ?? \"\", ...(d.keywords ?? [])].join(\" \").toLowerCase().includes(q.toLowerCase())) : defs;\n return (\n <div className=\"bpe-palette\">\n <div className=\"bpe-search\">\n <Icon name=\"search\" />\n <TextInput value={q} onChange={setQ} placeholder=\"Search blocks…\" aria-label=\"Search blocks\" />\n </div>\n {CATEGORY_ORDER.map((cat) => {\n const items = filtered.filter((d) => d.category === cat.id);\n if (!items.length) return null;\n return (\n <div key={cat.id} className=\"bpe-palette__group\">\n <div className=\"bpe-palette__title\">{cat.label}</div>\n <div className=\"bpe-palette__grid\">\n {items.map((d) => {\n const tier = d.license && d.license !== \"community\" ? d.license : null;\n // The badge used to be a CSS ::after — invisible to a screen\n // reader and impossible to explain. Whether the tier is enabled\n // is something the registry knows, so say which it is rather\n // than leaving \"PRO\" to be read as \"you cannot have this\".\n const enabled = !tier || session.registry.isTierEnabled(d.license);\n return (\n <button\n key={d.type}\n type=\"button\"\n className={`bpe-palette__item ${tier ? \"bpe-palette__item--pro\" : \"\"} ${enabled ? \"\" : \"bpe-palette__item--locked\"}`}\n title={`${d.description ?? d.name}\\nClick to insert, or drag onto the page.${tier ? `\\n\\n${tierNote(tier, enabled)}` : \"\"}`}\n disabled={!enabled}\n onPointerDown={(e) => enabled && beginDrag(session, e, { kind: \"new\", payload: d.type, label: d.name, icon: d.icon })}\n onClick={() => (d.type === \"row\" ? actions.insertRow([6, 6]) : actions.insertBlock(d.type))}\n onKeyDown={(e) => e.key === \"Enter\" && (d.type === \"row\" ? actions.insertRow([6, 6]) : actions.insertBlock(d.type))}\n >\n <Icon name={d.icon ?? \"box\"} size={16} />\n <span className=\"bpe-palette__item-name\">{d.name}</span>\n {tier ? <span className=\"bpe-palette__tier\" title={tierNote(tier, enabled)} aria-label={tierNote(tier, enabled)}>{tier === \"pro\" ? \"PRO\" : \"ENT\"}</span> : null}\n </button>\n );\n })}\n </div>\n </div>\n );\n })}\n {filtered.length === 0 ? <EmptyState icon=\"search\" title=\"No blocks match\">Try a different search.</EmptyState> : null}\n </div>\n );\n}\n\n/**\n * What a tier badge means here, which depends on what the host has turned on.\n * Claiming a block \"requires a licence\" while it inserts and works perfectly\n * well in the editor in front of you is a licensing claim the editor is in no\n * position to make.\n */\nfunction tierNote(tier: string, enabled: boolean): string {\n const name = tier === \"pro\" ? \"Pro\" : \"Enterprise\";\n return enabled\n ? `In the ${name} tier, and enabled in this editor — insert it and it works.`\n : `In the ${name} tier, which this editor has not enabled.`;\n}\n\n/* --------------------------------- layouts -------------------------------- */\n\nfunction LayoutsPanel({ actions }: { actions: EditorActions }) {\n const session = useSession();\n const template = useTemplate();\n const selection = useEditorState((s) => s.selection);\n return (\n <div className=\"bpe-palette\">\n <div className=\"bpe-palette__group\">\n <div className=\"bpe-palette__title\">Columns</div>\n <div className=\"bpe-layouts__grid\">\n {ROW_LAYOUTS.map((l) => (\n <button key={l.id} type=\"button\" className=\"bpe-layout-item\" title=\"Click to insert, or drag onto the page\" onPointerDown={(e) => beginDrag(session, e, { kind: \"row\", payload: l.layout, label: l.label, icon: \"columns-3\" })} onClick={() => actions.insertRow(l.layout)}>\n <div className=\"bpe-layout-item__cols\" style={{ gridTemplateColumns: l.layout.map((c) => `${c}fr`).join(\" \") }}>\n {l.layout.map((_, i) => <div key={i} className=\"bpe-layout-item__col\" />)}\n </div>\n <span className=\"bpe-layout-item__name\">{l.label}</span>\n </button>\n ))}\n </div>\n </div>\n <div className=\"bpe-palette__group\">\n <div className=\"bpe-palette__title\">Sections</div>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n <Button icon=\"plus\" onClick={() => actions.addSection(\"body\")}>Add section at end</Button>\n {selection[0] ? <Button icon=\"corner-down-right\" onClick={() => { const e = session.store.index().get(selection[0]!); actions.addSection(\"body\", e ? e.path[0]! + 1 : undefined); }}>Add section after selection</Button> : null}\n <Button icon=\"scissors\" onClick={() => actions.insertBlock(\"pageBreak\")}>Insert page break</Button>\n </div>\n <div className=\"bpe-field__hint\" style={{ marginTop: 8 }}>{template.body.length} section{template.body.length === 1 ? \"\" : \"s\"} in the body. Sections stack vertically and can be reordered from the Layers panel.</div>\n </div>\n <div className=\"bpe-palette__group\">\n <div className=\"bpe-palette__title\">Header & footer</div>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n <Button icon=\"panel-top\" onClick={() => { if (template.header.default.length === 0) actions.addSection(\"header\"); else session.store.select([template.header.default[0]!.id]); }}>Edit header</Button>\n <Button icon=\"panel-top\" onClick={() => { if (template.footer.default.length === 0) actions.addSection(\"footer\"); else session.store.select([template.footer.default[0]!.id]); }}>Edit footer</Button>\n </div>\n </div>\n </div>\n );\n}\n\n/* ---------------------------------- data ---------------------------------- */\n\n/**\n * One row of the data tree, flattened out of the host's schemas.\n *\n * Search runs over this tree rather than over the rendering, so a field buried\n * two levels down is findable by its own name and still arrives with the path\n * that says where it lives. Matching only what a row happened to render was why\n * searching \"value\" found nothing useful: the fields inside a list were never\n * part of the search at all, and a group was drawn whether or not anything\n * inside it had survived the filter.\n */\ninterface DataNode {\n key: string;\n /** Full human path, e.g. \"Portfolio › Holdings › Value\". */\n label: string;\n /** Leaf name, which is what the row shows. */\n name: string;\n type: FieldSchema[\"type\"];\n /** The expression to insert. Absent for rows that are only a heading. */\n expr?: string;\n /** Set for fields inside a list, where the expression needs a row alias. */\n itemOf?: string;\n kind: \"field\" | \"group\" | \"list\";\n children: DataNode[];\n}\n\nfunction buildNodes(fields: Record<string, FieldSchema>, prefix: string, labels: string[]): DataNode[] {\n return Object.entries(fields).map(([key, f]): DataNode => {\n const name = f.label ?? key;\n const expr = prefix + \".\" + key;\n const label = [...labels, name].join(\" › \");\n if (f.type === \"object\" && f.fields) {\n return { key, label, name, type: f.type, kind: \"group\", children: buildNodes(f.fields, expr, [...labels, name]) };\n }\n if (f.type === \"array\" && f.itemSchema?.type === \"object\" && f.itemSchema.fields) {\n // A list's own expression is what a table or repeater binds to; the fields\n // inside it are addressed through that block's row alias, so they are\n // listed and searchable but not insertable on their own.\n const children = Object.entries(f.itemSchema.fields).map(([k2, f2]): DataNode => ({\n key: k2,\n label: [...labels, name, f2.label ?? k2].join(\" › \"),\n name: f2.label ?? k2,\n type: f2.type,\n itemOf: name,\n kind: \"field\",\n children: []\n }));\n return { key, label, name, type: f.type, expr, kind: \"list\", children };\n }\n return { key, label, name, type: f.type, expr, kind: \"field\", children: [] };\n });\n}\n\n/** Keeps every node that matches, and every ancestor of one that does. */\nfunction filterNodes(nodes: DataNode[], q: string): DataNode[] {\n if (!q) return nodes;\n const out: DataNode[] = [];\n for (const n of nodes) {\n const self = n.label.toLowerCase().includes(q) || (n.expr ?? \"\").toLowerCase().includes(q);\n const children = filterNodes(n.children, q);\n // A group that matches on its own name keeps all of its children, so\n // searching \"holdings\" shows what is in it rather than an empty folder.\n if (self) out.push({ ...n, children: children.length ? children : n.children });\n else if (children.length) out.push({ ...n, children });\n }\n return out;\n}\n\nfunction DataPanel({ actions }: { actions: EditorActions }) {\n const session = useSession();\n const [q, setQ] = useState(\"\");\n const sources = session.dataSources;\n const query = q.trim().toLowerCase();\n const trees = useMemo(() => sources.map((s) => ({ source: s, nodes: filterNodes(buildNodes(s.schema, s.id, [s.label]), query) })), [sources, query]);\n if (sources.length === 0) return <EmptyState icon=\"database\" title=\"No data sources\">Pass <code>dataSources</code> to the designer to bind fields.</EmptyState>;\n const found = trees.reduce((a, t) => a + t.nodes.length, 0);\n return (\n <div>\n <div className=\"bpe-search\">\n <Icon name=\"search\" />\n <TextInput value={q} onChange={setQ} placeholder=\"Search fields…\" aria-label=\"Search fields\" />\n </div>\n <div className=\"bpe-data-tree\">\n {/* A source with nothing matching is not a folder worth showing. */}\n {trees.map(({ source, nodes }) => (nodes.length ? <DataSourceTree key={source.id} source={source} nodes={nodes} searching={!!query} actions={actions} /> : null))}\n {query && found === 0 ? <EmptyState icon=\"search\" title=\"No fields match\">Try part of a field or source name, such as “value” or “holdings”.</EmptyState> : null}\n <div className=\"bpe-field__hint\" style={{ padding: \"8px 6px\" }}>Drag a field onto the page to add it, or drop it into a text block to insert a token. Lists become tables.</div>\n </div>\n </div>\n );\n}\n\nfunction DataSourceTree({ source, nodes, searching, actions }: { source: DataSource; nodes: DataNode[]; searching: boolean; actions: EditorActions }) {\n const [open, setOpen] = useState(true);\n // While searching, a collapsed source would hide the very row you searched for.\n const expanded = open || searching;\n return (\n <div className=\"bpe-data-source\">\n <button type=\"button\" className=\"bpe-data-source__head\" aria-expanded={expanded} onClick={() => setOpen(!open)}>\n <Icon name={expanded ? \"folder-open\" : \"folder\"} />\n <span className=\"bpe-truncate\">{source.label}</span>\n <span className=\"bpe-data-field__type\">{source.id}</span>\n </button>\n {expanded ? <FieldList nodes={nodes} actions={actions} /> : null}\n </div>\n );\n}\n\nfunction FieldList({ nodes, actions, depth = 0 }: { nodes: DataNode[]; actions: EditorActions; depth?: number }) {\n const session = useSession();\n return (\n <div className={depth > 0 ? \"bpe-data-children\" : undefined}>\n {nodes.map((n) => {\n if (n.kind === \"group\") {\n return (\n <div key={n.key}>\n <div className=\"bpe-data-field bpe-data-field--group\" title={n.label}>\n <Icon name=\"folder\" className=\"bpe-data-field__icon\" />\n <span className=\"bpe-truncate\">{n.name}</span>\n </div>\n <FieldList nodes={n.children} actions={actions} depth={depth + 1} />\n </div>\n );\n }\n if (n.itemOf) {\n return (\n <div key={n.key} className=\"bpe-data-field bpe-data-field--group\" title={n.label + \"\\nAvailable inside a repeater or table over \" + n.itemOf}>\n <Icon name={FIELD_TYPE_ICONS[n.type] ?? \"box\"} className=\"bpe-data-field__icon\" />\n <span className=\"bpe-truncate\">{n.name}</span>\n <span className=\"bpe-data-field__type\">{n.type}</span>\n </div>\n );\n }\n const expr = n.expr!;\n const isList = n.kind === \"list\";\n return (\n <div key={n.key}>\n <button\n type=\"button\"\n className=\"bpe-data-field\"\n title={n.label + \"\\n\" + expr + \"\\nClick to insert, or drag onto the page.\"}\n onPointerDown={(e) => beginDrag(session, e, { kind: \"field\", payload: { expr, label: n.label, type: n.type }, label: n.name, icon: FIELD_TYPE_ICONS[n.type] })}\n onClick={() => (isList ? actions.insertBlock(\"table\", undefined, { source: expr }) : actions.insertBlock(\"field\", undefined, { label: n.name, value: expr }))}\n >\n <Icon name={FIELD_TYPE_ICONS[n.type] ?? \"box\"} className=\"bpe-data-field__icon\" />\n <span className=\"bpe-truncate\">{n.name}</span>\n <span className=\"bpe-data-field__type\">{n.type}</span>\n </button>\n {n.children.length ? <FieldList nodes={n.children} actions={actions} depth={depth + 1} /> : null}\n </div>\n );\n })}\n </div>\n );\n}\n\n/* --------------------------------- layers --------------------------------- */\n\nfunction LayersPanel({ actions }: { actions: EditorActions }) {\n const session = useSession();\n const template = useTemplate();\n const selection = useEditorState((s) => s.selection);\n const hoverId = useEditorState((s) => s.hoverId);\n const regions: Array<{ id: string; label: string; nodes: Node[] }> = [\n { id: \"header\", label: \"Header\", nodes: template.header.default },\n { id: \"body\", label: \"Body\", nodes: template.body },\n { id: \"footer\", label: \"Footer\", nodes: template.footer.default }\n ];\n return (\n <div className=\"bpe-layers\" role=\"tree\" aria-label=\"Document layers\">\n {regions.map((r) =>\n r.nodes.length || r.id === \"body\" ? (\n <div key={r.id}>\n <div className=\"bpe-palette__title\">{r.label}</div>\n {r.nodes.length === 0 ? <div className=\"bpe-field__hint\" style={{ padding: \"2px 8px 8px\" }}>Empty</div> : null}\n {r.nodes.map((n) => <LayerRow key={n.id} node={n} depth={0} selection={selection} hoverId={hoverId} session={session} actions={actions} />)}\n </div>\n ) : null\n )}\n </div>\n );\n}\n\nfunction LayerRow({ node, depth, selection, hoverId, session, actions }: { node: Node; depth: number; selection: string[]; hoverId: string | null; session: ReturnType<typeof useSession>; actions: EditorActions }) {\n const [open, setOpen] = useState(depth < 2);\n const def = session.registry.get(node.type);\n const kids = node.children ?? [];\n const selected = selection.includes(node.id);\n const label = nodeLabel(session, node);\n const typeName = (def?.name ?? node.type).toLowerCase();\n return (\n <div role=\"treeitem\" aria-selected={selected} aria-expanded={kids.length ? open : undefined}>\n <div\n className={`bpe-layer ${selected ? \"bpe-layer--selected\" : \"\"} ${hoverId === node.id ? \"bpe-layer--hover\" : \"\"}`}\n // Readable name on the row, the expressions behind it on hover.\n title={nodeDetail(session, node)}\n style={{ paddingLeft: 4 + depth * 14 }}\n onClick={(e) => {\n if (e.shiftKey || e.metaKey || e.ctrlKey) session.store.toggleSelect(node.id);\n else session.store.select([node.id]);\n session.reveal(node.id);\n }}\n onPointerDown={(e) => {\n if (node.locked || node.type === \"column\") return;\n beginDrag(session, e, { kind: \"move\", payload: node.id, label: nodeLabel(session, node), icon: def?.icon }, { threshold: 6 });\n }}\n onMouseEnter={() => session.store.hover(node.id)}\n onMouseLeave={() => session.store.hover(null)}\n onDoubleClick={() => def?.canvas?.inlineEdit && session.store.setEditing(node.id)}\n >\n <button type=\"button\" className=\"bpe-layer__toggle\" aria-expanded={open} aria-label={`${open ? \"Collapse\" : \"Expand\"} ${label}`} style={{ visibility: kids.length ? \"visible\" : \"hidden\" }} onClick={(e) => { e.stopPropagation(); setOpen(!open); }}>\n <Icon name=\"chevron-down\" />\n </button>\n <Icon name={def?.icon ?? \"box\"} className=\"bpe-layer__icon\" />\n <span className=\"bpe-layer__name\">{label}</span>\n {node.visibleWhen ? <Icon name=\"git-branch\" size={11} className=\"bpe-layer__icon\" /> : null}\n {node.locked ? <Icon name=\"lock\" size={11} className=\"bpe-layer__icon\" /> : null}\n {kids.length ? <span className=\"bpe-layer__meta\">{kids.length}</span> : null}\n {node.type === \"column\" ? null : (\n <span className=\"bpe-layer__actions\">\n <Button size=\"sm\" variant=\"ghost\" icon=\"arrow-up\" tooltip={`Move ${typeName} up`} disabled={!!node.locked} onPointerDown={(e) => e.stopPropagation()} onClick={(e) => { e.stopPropagation(); session.store.select([node.id]); actions.moveSelection(-1); }} />\n <Button size=\"sm\" variant=\"ghost\" icon=\"arrow-down\" tooltip={`Move ${typeName} down`} disabled={!!node.locked} onPointerDown={(e) => e.stopPropagation()} onClick={(e) => { e.stopPropagation(); session.store.select([node.id]); actions.moveSelection(1); }} />\n <Button size=\"sm\" variant=\"ghost\" icon=\"trash\" className=\"bpe-btn--danger\" tooltip={`Delete ${typeName}`} disabled={!!node.locked} onPointerDown={(e) => e.stopPropagation()} onClick={(e) => { e.stopPropagation(); session.store.select([node.id]); actions.deleteSelection(); }} />\n </span>\n )}\n </div>\n {open && kids.length ? <div role=\"group\">{kids.map((c) => <LayerRow key={c.id} node={c} depth={depth + 1} selection={selection} hoverId={hoverId} session={session} actions={actions} />)}</div> : null}\n </div>\n );\n}\n\n/* --------------------------------- library -------------------------------- */\n\nfunction LibraryPanel({ actions }: { actions: EditorActions }) {\n const session = useSession();\n const template = useTemplate();\n const selection = useEditorState((s) => s.selection);\n const hostItems = session.options.get().library ?? [];\n const items: Array<LibraryItem & { source: \"host\" | \"template\" }> = [...hostItems.map((i) => ({ ...i, source: \"host\" as const })), ...(template.library ?? []).map((i) => ({ ...i, source: \"template\" as const }))];\n const groups = useMemo(() => {\n const m = new Map<string, typeof items>();\n for (const it of items) m.set(it.category ?? (it.source === \"host\" ? \"Shared\" : \"This report\"), [...(m.get(it.category ?? (it.source === \"host\" ? \"Shared\" : \"This report\")) ?? []), it]);\n return [...m.entries()];\n }, [items]);\n return (\n <div style={{ paddingTop: 8 }}>\n {selection.length === 1 ? (\n <div style={{ padding: \"0 8px 8px\" }}>\n <Button icon=\"book-marked\" style={{ width: \"100%\" }} onClick={() => { const name = window.prompt(\"Name this reusable block\"); if (name) actions.saveSelectionToLibrary(name); }}>Save selection to library</Button>\n </div>\n ) : null}\n {items.length === 0 ? <EmptyState icon=\"book-marked\" title=\"Nothing saved yet\">Select a block or section and save it here to reuse it. Hosts can also supply shared sections.</EmptyState> : null}\n {groups.map(([g, list]) => (\n <div key={g}>\n <div className=\"bpe-palette__title\" style={{ padding: \"8px 10px 6px\" }}>{g}</div>\n {list.map((it) => (\n <div key={it.id} className=\"bpe-library__item\" title=\"Click to insert, or drag onto the page\" onPointerDown={(e) => beginDrag(session, e, { kind: \"library\", payload: it.id, label: it.name, icon: \"book-marked\" })} onClick={() => { const node = it.node; actions.pasteNodes([node]); }}>\n <Icon name={session.registry.get(it.node.type)?.icon ?? \"book-marked\"} />\n <div style={{ minWidth: 0, flex: 1 }}>\n <div className=\"bpe-library__name bpe-truncate\">{it.name}</div>\n {it.description ? <div className=\"bpe-library__desc bpe-truncate\">{it.description}</div> : null}\n </div>\n {it.source === \"template\" ? <Button size=\"sm\" variant=\"ghost\" icon=\"trash\" tooltip=\"Remove\" onClick={(e) => { e.stopPropagation(); session.store.dispatch({ type: \"removeLibraryItem\", id: it.id }); }} onPointerDown={(e) => e.stopPropagation()} /> : null}\n </div>\n ))}\n </div>\n ))}\n </div>\n );\n}\n","import type { EditorSession, DragState, DropTarget } from \"../state/session.js\";\n\nexport interface DragHandlers {\n resolve(x: number, y: number, drag: DragState): DropTarget | null;\n drop(target: DropTarget, drag: DragState): void;\n autoScroll?(x: number, y: number): void;\n}\n\nconst handlers = new WeakMap<EditorSession, DragHandlers>();\n\nexport function registerDragHandlers(session: EditorSession, h: DragHandlers | null): void {\n if (h) handlers.set(session, h);\n else handlers.delete(session);\n}\n\n/**\n * Starts a pointer-driven drag. Call from a pointerdown handler; the drag\n * activates after a small movement threshold so clicks still work.\n */\nexport function beginDrag(session: EditorSession, e: PointerEvent | React.PointerEvent, initial: Omit<DragState, \"x\" | \"y\">, opts: { threshold?: number; immediate?: boolean } = {}): void {\n if (e.button !== 0) return;\n const threshold = opts.threshold ?? 4;\n const startX = e.clientX;\n const startY = e.clientY;\n const doc = (e.target as Element).ownerDocument;\n let active = !!opts.immediate;\n let raf = 0;\n let last: { x: number; y: number } | null = null;\n let scrollTimer: number | null = null;\n\n const update = () => {\n raf = 0;\n if (!last) return;\n const h = handlers.get(session);\n const drag = { ...initial, x: last.x, y: last.y };\n session.ui.patch({ drag, dropTarget: h ? h.resolve(last.x, last.y, drag) : null });\n };\n\n const onMove = (ev: PointerEvent) => {\n if (!active) {\n if (Math.hypot(ev.clientX - startX, ev.clientY - startY) < threshold) return;\n active = true;\n doc.body.classList.add(\"bpe-dragging\");\n session.ui.patch({ drag: { ...initial, x: ev.clientX, y: ev.clientY } });\n }\n last = { x: ev.clientX, y: ev.clientY };\n if (!raf) raf = requestAnimationFrame(update);\n if (scrollTimer === null) {\n scrollTimer = window.setInterval(() => {\n if (last) handlers.get(session)?.autoScroll?.(last.x, last.y);\n }, 50);\n }\n };\n\n const finish = (ev: PointerEvent, cancelled: boolean) => {\n doc.removeEventListener(\"pointermove\", onMove, true);\n doc.removeEventListener(\"pointerup\", onUp, true);\n doc.removeEventListener(\"pointercancel\", onCancel, true);\n doc.removeEventListener(\"keydown\", onKey, true);\n doc.body.classList.remove(\"bpe-dragging\");\n if (raf) cancelAnimationFrame(raf);\n if (scrollTimer !== null) clearInterval(scrollTimer);\n if (!active) return;\n const h = handlers.get(session);\n const drag = { ...initial, x: ev.clientX, y: ev.clientY };\n const target = cancelled ? null : (h ? h.resolve(ev.clientX, ev.clientY, drag) : null);\n session.ui.patch({ drag: null, dropTarget: null });\n if (target && target.valid && h) h.drop(target, drag);\n };\n const onUp = (ev: PointerEvent) => finish(ev, false);\n const onCancel = (ev: PointerEvent) => finish(ev, true);\n const onKey = (ev: KeyboardEvent) => {\n if (ev.key === \"Escape\") finish(new PointerEvent(\"pointerup\", { clientX: -1, clientY: -1 }), true);\n };\n\n doc.addEventListener(\"pointermove\", onMove, true);\n doc.addEventListener(\"pointerup\", onUp, true);\n doc.addEventListener(\"pointercancel\", onCancel, true);\n doc.addEventListener(\"keydown\", onKey, true);\n if (opts.immediate) session.ui.patch({ drag: { ...initial, x: startX, y: startY } });\n}\n","import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { cloneWithNewIds, createNode, createRow, richTextFromTemplate, isRichTextDoc, type Node, type RichTextDoc } from \"@broadpaper/core\";\nimport { useSession, useEditorState, useLayout, useLayoutVersion, useUi, nodeLabel } from \"../state/context.js\";\nimport type { EditorActions } from \"../state/actions.js\";\nimport { PageView } from \"./PageView.js\";\nimport { Overlays } from \"./Overlays.js\";\nimport { InlineEditor } from \"./InlineEditor.js\";\nimport { nodeIdAt } from \"./geometry.js\";\nimport { registerDragHandlers, beginDrag } from \"../dnd/drag-manager.js\";\nimport { computeDropTarget, computeInsertion, nodeForDrop } from \"../dnd/drag-controller.js\";\nimport { Icon } from \"../ui/icons.js\";\nimport { Button } from \"../ui/primitives.js\";\nimport { fitZoom, scrollTopForPage } from \"../toolbar/zoom.js\";\nimport { Breadcrumb } from \"./Breadcrumb.js\";\nimport { DesignLegend } from \"./DesignLegend.js\";\n\nexport function Canvas({ actions }: { actions: EditorActions }) {\n const session = useSession();\n const layout = useLayout();\n const version = useLayoutVersion();\n const mode = useEditorState((s) => s.mode);\n const zoom = useEditorState((s) => s.zoom);\n const selection = useEditorState((s) => s.selection);\n const editingId = useEditorState((s) => s.editingId);\n const hoverId = useEditorState((s) => s.hoverId);\n const drag = useUi((u) => u.drag);\n const guides = useUi((u) => u.guides);\n const reveal = useUi((u) => u.revealRequest);\n const toast = useUi((u) => u.toast);\n const activeSampleId = useUi((u) => u.activeSampleId);\n const sampleLabel = session.sampleSets.find((x) => x.id === activeSampleId)?.label ?? \"sample data\";\n // Design mode draws a *sample*, and a tooltip quoting a synthesised figure\n // reads exactly like a real one, so interactivity waits for preview unless\n // the host asks otherwise.\n const chartMode = session.options.get().interactiveCharts ?? \"preview\";\n const interactiveCharts = chartMode === \"always\" || (chartMode === \"preview\" && mode === \"preview\");\n const scrollRef = useRef<HTMLDivElement>(null);\n const innerRef = useRef<HTMLDivElement>(null);\n const pagesRef = useRef<HTMLDivElement>(null);\n const measureHostRef = useRef<HTMLDivElement>(null);\n const [visibleRange, setVisibleRange] = useState<[number, number]>([0, 3]);\n const [currentPage, setCurrentPage] = useState(0);\n const [, setTick] = useState(0);\n const bump = useCallback(() => setTick((t) => t + 1), []);\n /** Page index to scroll back to once a new layout lands. */\n const pendingPage = useRef<number | null>(null);\n\n // Attach the measurer to a hidden host inside the editor (inherits fonts/CSS).\n useEffect(() => {\n if (measureHostRef.current) session.attachMeasurer(measureHostRef.current);\n }, [session]);\n\n // Fit-to-width on first layout.\n const fitted = useRef(false);\n useEffect(() => {\n if (!layout || fitted.current || !scrollRef.current) return;\n fitted.current = true;\n const o = session.options.get();\n if (typeof o.zoom === \"number\") session.store.setZoom(o.zoom);\n else {\n const avail = scrollRef.current.clientWidth - 80;\n session.store.setZoom(Math.min(1.25, Math.max(0.3, avail / layout.page.width)));\n }\n }, [layout, session]);\n\n // Virtualisation: which pages are near the viewport.\n const updateVisible = useCallback(() => {\n const sc = scrollRef.current;\n if (!sc || !layout) return;\n const pageH = layout.page.height * zoom + 28;\n const top = sc.scrollTop - 32;\n const first = Math.max(0, Math.floor(top / pageH) - 1);\n const last = Math.min(layout.paged.totalPages - 1, Math.ceil((top + sc.clientHeight) / pageH) + 1);\n setVisibleRange((r) => (r[0] === first && r[1] === last ? r : [first, last]));\n // Which page you would say you were looking at: the one covering the middle\n // of the viewport, not the one that happens to touch the top edge.\n const middle = sc.scrollTop + sc.clientHeight / 2 - 32;\n setCurrentPage(Math.max(0, Math.min(layout.paged.totalPages - 1, Math.floor(middle / pageH))));\n bump();\n }, [layout, zoom, bump]);\n useEffect(() => {\n updateVisible();\n const sc = scrollRef.current;\n if (!sc) return;\n sc.addEventListener(\"scroll\", updateVisible, { passive: true });\n const ro = new ResizeObserver(updateVisible);\n ro.observe(sc);\n return () => {\n sc.removeEventListener(\"scroll\", updateVisible);\n ro.disconnect();\n };\n }, [updateVisible]);\n useLayoutEffect(() => bump(), [version, zoom, selection, hoverId, bump]);\n\n /**\n * Scrolls to page `index`: centred when the whole page fits, top-aligned when\n * it does not. The offset has to include the padding above the first page, or\n * every jump lands one padding short and leaves the join between two pages\n * across the middle of the viewport.\n */\n const goToPage = useCallback(\n (index: number) => {\n const sc = scrollRef.current;\n if (!sc || !layout) return;\n const clamped = Math.max(0, Math.min(layout.paged.totalPages - 1, index));\n sc.scrollTop = scrollTopForPage(clamped, layout.page.height, zoom, sc.clientHeight);\n },\n [layout, zoom]\n );\n\n // Zooming should magnify what you are looking at, not send you somewhere\n // else. Scroll offsets are in scaled pixels, so leaving scrollTop alone as\n // the scale changes moves the document under the viewport.\n const lastZoom = useRef(zoom);\n /** Page to land on once the new zoom has been applied, for \"fit page\". */\n const snapPage = useRef<number | null>(null);\n useLayoutEffect(() => {\n const sc = scrollRef.current;\n if (!sc || lastZoom.current === zoom) return;\n const ratio = zoom / lastZoom.current;\n lastZoom.current = zoom;\n const centre = sc.scrollTop + sc.clientHeight / 2;\n sc.scrollTop = Math.max(0, centre * ratio - sc.clientHeight / 2);\n }, [zoom]);\n\n // Declared after the effect above so it runs after it: \"fit page\" means a\n // whole page in view, and preserving the old scroll centre through the zoom\n // change is exactly what would leave you looking at the join between two.\n useLayoutEffect(() => {\n if (snapPage.current === null) return;\n const target = snapPage.current;\n snapPage.current = null;\n goToPage(target);\n }, [zoom, goToPage]);\n\n // The toolbar's fit buttons: the canvas is what knows the scroller and the\n // page you are on, so it supplies the implementation.\n useEffect(() => {\n session.fit = (mode) => {\n const sc = scrollRef.current;\n if (!sc || !layout) return;\n const next = fitZoom(mode, sc, layout.page);\n if (mode === \"page\") snapPage.current = currentPage;\n if (next === zoom) {\n // Already at that zoom: the button still has to do the landing part.\n if (mode === \"page\") {\n snapPage.current = null;\n goToPage(currentPage);\n }\n return;\n }\n session.store.setZoom(next);\n };\n return () => {\n session.fit = null;\n };\n }, [session, layout, currentPage, zoom, goToPage]);\n\n // Switching modes re-paginates, so the pixel offset is meaningless but the\n // page number is not: come back to the page you left from.\n const lastMode = useRef(mode);\n useLayoutEffect(() => {\n if (lastMode.current === mode) return;\n lastMode.current = mode;\n pendingPage.current = currentPage;\n }, [mode, currentPage]);\n useEffect(() => {\n if (pendingPage.current === null || !layout) return;\n const target = pendingPage.current;\n pendingPage.current = null;\n goToPage(target);\n }, [layout, goToPage]);\n\n /** Which page a node landed on, from the layout rather than the DOM. */\n const pageOfNode = useCallback(\n (id: string): number | null => {\n if (!layout) return null;\n const covers = (sectionKey: string, top: number) => {\n for (const page of layout.paged.pages) {\n for (const f of page.fragments) {\n if (f.sectionKey === sectionKey && top >= f.from - 1 && top < f.to + 1) return page.index;\n }\n }\n return null;\n };\n for (const [sectionKey, geom] of Object.entries(layout.geometry)) {\n if (layout.nodesByKey.get(sectionKey)?.nodeId === id) {\n const p = covers(sectionKey, 0);\n if (p !== null) return p;\n }\n for (const [key, g] of Object.entries(geom.nodes)) {\n if (layout.nodesByKey.get(key)?.nodeId !== id) continue;\n const p = covers(sectionKey, g.top);\n if (p !== null) return p;\n }\n }\n return null;\n },\n [layout]\n );\n\n // Scroll a node into view when requested (from layers, issues, insertion).\n //\n // Each request is honoured exactly once. The effect has to watch the visible\n // range, because a node on an unrendered page has no element to scroll to\n // until that range widens — but re-acting on every scroll would drag the\n // canvas back to the last revealed block the moment you tried to leave it.\n const reveal_ = useRef<{ seq: number; done: boolean; tries: number }>({ seq: -1, done: true, tries: 0 });\n useEffect(() => {\n const scroller = scrollRef.current;\n const pages = pagesRef.current;\n if (!reveal || !pages || !scroller || !layout) return;\n if (reveal_.current.seq !== reveal.seq) reveal_.current = { seq: reveal.seq, done: false, tries: 0 };\n if (reveal_.current.done) return;\n\n const el = pages.querySelector<HTMLElement>(`[data-node=\"${CSS.escape(reveal.id)}\"]:not([data-culled])`);\n if (el) {\n reveal_.current.done = true;\n const r = el.getBoundingClientRect();\n const sr = scroller.getBoundingClientRect();\n // Instant, not smooth: a smooth scroll keeps animating after the user\n // starts scrolling themselves, and lands wherever it was going — which\n // reads as the canvas dragging itself back.\n if (r.top < sr.top + 40 || r.bottom > sr.bottom - 40) el.scrollIntoView({ block: \"center\", behavior: \"instant\" as ScrollBehavior });\n return;\n }\n\n // The node's page is not rendered — or, just after an insertion, the layout\n // has not caught up with it at all. Either way this effect runs again when\n // the layout or the visible range changes, so keep trying for a few passes\n // rather than giving up on the first stale layout; a request for a node\n // that really is gone stops after that instead of pinning the canvas.\n const index = pageOfNode(reveal.id);\n if (index === null) {\n if (++reveal_.current.tries > 8) reveal_.current.done = true;\n return;\n }\n scroller.scrollTop = scrollTopForPage(index, layout.page.height, zoom, scroller.clientHeight);\n setVisibleRange(([first, last]) => (index >= first && index <= last ? [first, last] : [Math.max(0, index - 1), Math.min(layout.paged.totalPages - 1, index + 1)]));\n }, [reveal, version, visibleRange, layout, zoom, pageOfNode]);\n\n // Says where it went. A block inserted from the palette or the library can\n // land on a page you were not looking at, and a selection outline on its own\n // is easy to miss when the canvas has just scrolled to it; the flash is what\n // connects \"I clicked Insert\" to \"there it is\". It is re-applied whenever the\n // page rebuilds, because the page DOM is replaced wholesale on every layout.\n const [flash, setFlash] = useState<{ id: string; seq: number; shown: boolean } | null>(null);\n useEffect(() => {\n if (reveal) setFlash({ id: reveal.id, seq: reveal.seq, shown: false });\n }, [reveal]);\n // The countdown starts when the block is first on screen, not when it was\n // asked for: an insertion has to be re-measured and re-laid-out before it\n // exists in the DOM at all, and on a long document that can take longer than\n // the flash itself — so timing from the request meant the one case that most\n // needed the highlight was the one case that never showed it.\n useEffect(() => {\n if (!flash) return;\n const t = setTimeout(() => setFlash((f) => (f?.seq === flash.seq ? null : f)), flash.shown ? 1400 : 8000);\n return () => clearTimeout(t);\n }, [flash]);\n useLayoutEffect(() => {\n const pages = pagesRef.current;\n if (!pages) return;\n for (const el of pages.querySelectorAll(\".bpe-flash\")) el.classList.remove(\"bpe-flash\");\n if (!flash) return;\n const els = pages.querySelectorAll(`[data-node=\"${CSS.escape(flash.id)}\"]`);\n for (const el of els) el.classList.add(\"bpe-flash\");\n if (els.length && !flash.shown) setFlash({ ...flash, shown: true });\n }, [flash, version, visibleRange, zoom]);\n\n /* ----------------------------- pointer ----------------------------- */\n\n const pageFirst = useCallback((el: Element) => el.closest(\".bp-page\")?.classList.contains(\"bp-page--first\") ?? false, []);\n\n /** Places the insertion caret where the pointer is, if that is a real place. */\n const placeCaret = useCallback(\n (x: number, y: number) => {\n const canvas = pagesRef.current;\n const origin = innerRef.current;\n if (!canvas || !origin) return;\n const target = computeInsertion(x, y, { template: session.store.template, registry: session.registry, canvas, overlayOrigin: origin }, pageFirst);\n session.ui.patch({ insertion: target?.line ? { parentId: target.parentId, region: target.region, index: target.index, line: target.line } : null });\n },\n [session, pageFirst]\n );\n\n const onPointerDown = (e: React.PointerEvent) => {\n if (mode !== \"design\") return;\n if ((e.target as HTMLElement).closest(\".bpe-overlay, .bpe-inline-editor, .bpe-bubble, .bpe-block-toolbar\")) return;\n const hit = nodeIdAt(e.target);\n if (editingId && hit?.id !== editingId) session.store.setEditing(null);\n // Every click in the canvas answers \"where would the next block go\", so a\n // block from the palette lands where you were looking rather than at the\n // end of the document.\n placeCaret(e.clientX, e.clientY);\n if (!hit) {\n if (!e.shiftKey) session.store.select([]);\n scrollRef.current?.focus({ preventScroll: true });\n return;\n }\n // Repeater iterations and structural columns select their logical node.\n const id = hit.id;\n if (e.shiftKey || e.metaKey || e.ctrlKey) session.store.toggleSelect(id);\n else if (!selection.includes(id)) session.store.select([id]);\n // Drag to move (after threshold) when pressing on an already-selected block.\n const node = session.store.getNode(id);\n if (node && !node.locked && node.type !== \"column\" && !editingId) {\n beginDrag(session, e, { kind: \"move\", payload: id, label: nodeLabel(session, node), icon: session.registry.get(node.type)?.icon }, { threshold: 6 });\n }\n scrollRef.current?.focus({ preventScroll: true });\n };\n\n const onDoubleClick = (e: React.MouseEvent) => {\n if (mode !== \"design\") return;\n const hit = nodeIdAt(e.target);\n if (!hit) return;\n const def = session.registry.get(hit.type);\n if (def?.canvas?.inlineEdit) {\n const node = session.store.getNode(hit.id);\n if (node?.locked) return;\n session.store.setEditing(hit.id);\n }\n };\n\n const onPointerMove = (e: React.PointerEvent) => {\n if (mode !== \"design\" || drag) return;\n const hit = nodeIdAt(e.target);\n const id = hit && !(e.target as HTMLElement).closest(\".bpe-overlay\") ? hit.id : null;\n if (id !== hoverId) session.store.hover(id);\n };\n\n /* ------------------------------ keyboard --------------------------- */\n\n const onKeyDown = (e: React.KeyboardEvent) => {\n if (mode !== \"design\" || editingId) return;\n const target = e.target as HTMLElement;\n if (target.closest(\"input, textarea, select, [contenteditable=true]\")) return;\n const mod = e.metaKey || e.ctrlKey;\n const key = e.key.toLowerCase();\n if (mod && key === \"z\" && !e.shiftKey) return void (e.preventDefault(), actions.undo());\n if ((mod && key === \"z\" && e.shiftKey) || (mod && key === \"y\")) return void (e.preventDefault(), actions.redo());\n if (mod && key === \"c\") return void (e.preventDefault(), actions.copySelection());\n if (mod && key === \"x\") return void (e.preventDefault(), actions.cutSelection());\n if (mod && key === \"v\") return void (e.preventDefault(), actions.pasteFromClipboard());\n if (mod && key === \"d\") return void (e.preventDefault(), actions.duplicateSelection());\n if (mod && key === \"s\") return void (e.preventDefault(), actions.save());\n if (mod && key === \"a\") return void (e.preventDefault(), session.store.select(session.store.template.body.map((s) => s.id)));\n if (e.key === \"Delete\" || e.key === \"Backspace\") return void (e.preventDefault(), actions.deleteSelection());\n if (e.key === \"Escape\") return void session.store.select([]);\n if (e.key === \"Enter\") {\n const id = selection[0];\n const node = id ? session.store.getNode(id) : undefined;\n if (node && session.registry.get(node.type)?.canvas?.inlineEdit) {\n e.preventDefault();\n session.store.setEditing(id!);\n }\n return;\n }\n if (e.key === \"ArrowUp\" || e.key === \"ArrowDown\") {\n e.preventDefault();\n if (e.altKey) actions.moveSelection(e.key === \"ArrowUp\" ? -1 : 1);\n else actions.selectSibling(e.key === \"ArrowUp\" ? -1 : 1);\n return;\n }\n if (e.key === \"ArrowLeft\") return void (e.preventDefault(), actions.selectParent());\n if (e.key === \"ArrowRight\") return void (e.preventDefault(), actions.selectFirstChild());\n if (mod && (e.key === \"=\" || e.key === \"+\")) return void (e.preventDefault(), session.store.setZoom(zoom + 0.1));\n if (mod && e.key === \"-\") return void (e.preventDefault(), session.store.setZoom(zoom - 0.1));\n if (mod && e.key === \"0\") return void (e.preventDefault(), session.store.setZoom(1));\n };\n\n /* ---------------------------- drag & drop -------------------------- */\n\n\n useEffect(() => {\n registerDragHandlers(session, {\n resolve: (x, y, d) => {\n const canvas = pagesRef.current;\n const origin = innerRef.current;\n if (!canvas || !origin) return null;\n const sr = scrollRef.current!.getBoundingClientRect();\n if (x < sr.left || x > sr.right || y < sr.top || y > sr.bottom) return null;\n return computeDropTarget(x, y, d, { template: session.store.template, registry: session.registry, canvas, overlayOrigin: origin }, pageFirst);\n },\n drop: (target, d) => {\n if (target.textTargetId && d.kind === \"field\") {\n const p = d.payload as { expr: string; label: string };\n const node = session.store.getNode(target.textTargetId);\n if (!node) return;\n if (node.type === \"heading\") {\n const text = String(node.props.text ?? \"\");\n session.store.dispatch({ type: \"setProp\", id: node.id, path: \"text\", value: `${text}${text && !text.endsWith(\" \") ? \" \" : \"\"}{{ ${p.expr} }}` }, { label: \"Insert field\" });\n } else {\n const doc: RichTextDoc = isRichTextDoc(node.props.content) ? structuredClone(node.props.content) : richTextFromTemplate(\"\");\n const last = doc.content[doc.content.length - 1];\n if (last && last.type === \"paragraph\") {\n if (last.content.length) last.content.push({ type: \"text\", text: \" \" });\n last.content.push({ type: \"token\", expr: p.expr });\n } else doc.content.push({ type: \"paragraph\", content: [{ type: \"token\", expr: p.expr }] });\n session.store.dispatch({ type: \"setProp\", id: node.id, path: \"content\", value: doc }, { label: \"Insert field\" });\n }\n session.store.select([node.id]);\n return;\n }\n const path = target.parentId ? [...(session.store.locationOf(target.parentId)?.path ?? []), target.index] : [target.index];\n const at = { region: target.region, path };\n if (d.kind === \"move\") {\n actions.moveNode(String(d.payload), at);\n return;\n }\n const node: Node | undefined = nodeForDrop(d, {\n registry: session.registry,\n template: session.store.template,\n createNode: (type, props) => createNode(session.registry, type, { props }),\n createRow: (layout) => createRow(layout),\n cloneLibrary: (id) => {\n const item = session.store.template.library?.find((l) => l.id === id) ?? session.options.get().library?.find((l) => l.id === id);\n return item ? cloneWithNewIds(item.node) : undefined;\n }\n });\n if (node) {\n actions.insertNodeAt(node, at, `Add ${session.registry.get(node.type)?.name ?? node.type}`);\n }\n },\n autoScroll: (x, y) => {\n const sc = scrollRef.current;\n if (!sc) return;\n const r = sc.getBoundingClientRect();\n const edge = 48;\n if (y < r.top + edge && y > r.top - 20) sc.scrollTop -= 14;\n else if (y > r.bottom - edge && y < r.bottom + 20) sc.scrollTop += 14;\n }\n });\n return () => registerDragHandlers(session, null);\n }, [session, actions, pageFirst]);\n\n /* ------------------------------ render ----------------------------- */\n\n const pages = useMemo(() => {\n if (!layout) return null;\n return Array.from({ length: layout.paged.totalPages }, (_, i) => (\n <PageView key={i} layout={layout} index={i} version={version} zoom={zoom} visible={i >= visibleRange[0] && i <= visibleRange[1]} interactive={interactiveCharts} />\n ));\n }, [layout, version, zoom, visibleRange, interactiveCharts]);\n\n const cls = [\"bpe-canvas\", mode === \"design\" && \"bpe-canvas--design\", guides && \"bpe-canvas--guides\", drag && \"bpe-canvas--dragging\"].filter(Boolean).join(\" \");\n\n return (\n <div className={cls}>\n {mode === \"preview\" ? (\n <div className=\"bpe-preview-bar\">\n <Icon name=\"eye\" size={14} />\n <span>Exactly what the PDF will contain, with the selected sample data. Editing panels are hidden until you go back.</span>\n <span style={{ marginLeft: \"auto\" }} />\n <Button size=\"sm\" variant=\"ghost\" icon=\"pencil\" onClick={() => session.setMode(\"design\")}>Back to design</Button>\n </div>\n ) : null}\n <div ref={scrollRef} className=\"bpe-canvas__scroll\" tabIndex={0} role=\"region\" aria-label=\"Document canvas\" onKeyDown={onKeyDown} onPointerDown={onPointerDown} onDoubleClick={onDoubleClick} onPointerMove={onPointerMove} onPointerLeave={() => session.store.hover(null)}>\n <div ref={innerRef} className=\"bpe-canvas__inner\">\n <div ref={pagesRef} className={`bpe-pages bp-doc ${mode === \"design\" ? \"bp-doc--design\" : \"\"}`}>{pages}</div>\n {layout && innerRef.current && pagesRef.current ? <Overlays container={pagesRef.current} origin={innerRef.current} actions={actions} zoom={zoom} /> : null}\n {editingId && pagesRef.current && innerRef.current && mode === \"design\" ? <InlineEditor key={editingId} nodeId={editingId} container={pagesRef.current} origin={innerRef.current} zoom={zoom} onClose={() => session.store.setEditing(null)} /> : null}\n {!layout ? <div className=\"bpe-empty\" style={{ height: 400 }}>Laying out…</div> : null}\n </div>\n </div>\n <div ref={measureHostRef} style={{ position: \"absolute\", left: 0, top: 0, width: 0, height: 0, overflow: \"hidden\" }} aria-hidden=\"true\" />\n <div className=\"bpe-canvas__bar\">\n {/* The breadcrumb and the \"select a block\" prompt are instructions for\n editing. In preview there is nothing to select, so they would be\n telling you to do something the mode does not allow. */}\n {mode === \"design\" ? <Breadcrumb /> : <span className=\"bpe-breadcrumb bpe-muted\">Previewing “{sampleLabel}”</span>}\n <div className=\"bpe-canvas__bar-end\">\n {layout && layout.paged.totalPages > 1 ? (\n <nav className=\"bpe-pager\" aria-label=\"Page navigation\">\n <Button size=\"sm\" variant=\"ghost\" icon=\"chevron-left\" tooltip=\"Previous page\" disabled={currentPage === 0} onClick={() => goToPage(currentPage - 1)} />\n <span className=\"bpe-pager__label\">Page {currentPage + 1} of {layout.paged.totalPages}</span>\n <Button size=\"sm\" variant=\"ghost\" icon=\"chevron-right\" tooltip=\"Next page\" disabled={currentPage >= layout.paged.totalPages - 1} onClick={() => goToPage(currentPage + 1)} />\n </nav>\n ) : layout ? (\n <span>1 page</span>\n ) : null}\n {layout?.warnings.length ? (\n <span className=\"bpe-badge bpe-badge--warning\" title={layout.warnings.map((w) => w.message).join(\"\\n\")}>\n <Icon name=\"alert-triangle\" size={11} /> {layout.warnings.length}\n </span>\n ) : null}\n {mode === \"design\" ? <Button size=\"sm\" variant=\"ghost\" icon=\"ruler\" active={guides} tooltip=\"Show page margins\" onClick={() => session.ui.patch({ guides: !guides })} /> : null}\n {mode === \"design\" ? <DesignLegend sampleLabel={sampleLabel} /> : null}\n </div>\n </div>\n {toast ? (\n <div className=\"bpe-toast\" role=\"status\">\n <Icon name={toast.tone === \"error\" ? \"alert-circle\" : toast.tone === \"success\" ? \"check-circle\" : \"info\"} />\n {toast.message}\n </div>\n ) : null}\n {drag ? (\n <div className=\"bpe-drag-ghost\" style={{ left: drag.x, top: drag.y }}>\n <Icon name={drag.icon ?? \"box\"} /> {drag.label}\n </div>\n ) : null}\n </div>\n );\n}\n","import { memo, useEffect, useLayoutEffect, useRef } from \"react\";\nimport { enableChartInteractions, vnodeToDom } from \"@broadpaper/renderer\";\nimport type { LayoutResult } from \"@broadpaper/renderer\";\n\ninterface PageViewProps {\n layout: LayoutResult;\n index: number;\n version: number;\n visible: boolean;\n zoom: number;\n /** Charts respond to a pointer and to the keyboard. */\n interactive?: boolean;\n}\n\n/**\n * Mounts one rendered page (a VNode from the shared pipeline) into the DOM.\n * The page content is not React-managed; React only owns the slot.\n */\nexport const PageView = memo(function PageView({ layout, index, version, visible, zoom, interactive }: PageViewProps) {\n const ref = useRef<HTMLDivElement>(null);\n const { width, height } = layout.page;\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n if (!visible) {\n el.replaceChildren();\n return;\n }\n const v = layout.renderPage(index);\n el.replaceChildren(vnodeToDom(v, el.ownerDocument));\n }, [layout, index, version, visible]);\n\n // After the page is in the DOM, not during: the interaction layer reads the\n // marks' real boxes, and it has to be torn down and rebuilt whenever the page\n // content is replaced, which is every layout.\n useEffect(() => {\n const el = ref.current;\n if (!el || !visible || !interactive) return;\n return enableChartInteractions(el);\n }, [layout, index, version, visible, interactive]);\n return (\n <div className={`bpe-page-slot ${visible ? \"\" : \"bpe-page-slot--placeholder\"}`} style={{ width: width * zoom, height: height * zoom, marginBottom: 28 }} data-page-slot={index}>\n <span className=\"bpe-page-number\" aria-hidden=\"true\">\n Page {index + 1} of {layout.paged.totalPages}\n </span>\n <div ref={ref} className=\"bpe-page__zoom\" style={{ zoom, width, height }} />\n </div>\n );\n});\n","import { useLayoutEffect, useState } from \"react\";\nimport { useSession, useEditorState, useLayoutVersion, useUi, nodeLabel } from \"../state/context.js\";\nimport type { EditorActions } from \"../state/actions.js\";\nimport { visibleNodeRects, type Rect } from \"./geometry.js\";\nimport { Button } from \"../ui/primitives.js\";\nimport { Icon } from \"../ui/icons.js\";\nimport { Menu } from \"../ui/floating.js\";\nimport { beginDrag } from \"../dnd/drag-manager.js\";\n\ninterface OverlayProps {\n container: HTMLElement;\n origin: HTMLElement;\n actions: EditorActions;\n zoom: number;\n}\n\nexport function Overlays({ container, origin, actions, zoom }: OverlayProps) {\n const session = useSession();\n const selection = useEditorState((s) => s.selection);\n const hoverId = useEditorState((s) => s.hoverId);\n const editingId = useEditorState((s) => s.editingId);\n const mode = useEditorState((s) => s.mode);\n const version = useLayoutVersion();\n const drag = useUi((u) => u.drag);\n const dropTarget = useUi((u) => u.dropTarget);\n const insertion = useUi((u) => u.insertion);\n const [rects, setRects] = useState<{ selected: Array<{ id: string; rects: Rect[] }>; hover: Rect[] }>({ selected: [], hover: [] });\n\n useLayoutEffect(() => {\n if (mode !== \"design\") return setRects({ selected: [], hover: [] });\n const selected = selection.map((id) => ({ id, rects: visibleNodeRects(container, origin, id) }));\n const hover = hoverId && !selection.includes(hoverId) ? visibleNodeRects(container, origin, hoverId) : [];\n setRects({ selected, hover });\n }, [container, origin, selection, hoverId, version, zoom, mode, drag]);\n\n if (mode !== \"design\") return null;\n const primaryId = selection[0];\n const primary = rects.selected[0];\n const primaryRect = primary?.rects[0];\n const node = primaryId ? session.store.getNode(primaryId) : undefined;\n const def = node ? session.registry.get(node.type) : undefined;\n const hoverNode = hoverId ? session.store.getNode(hoverId) : undefined;\n const showToolbar = !!node && !!primaryRect && !editingId && !drag;\n\n return (\n <div className=\"bpe-overlay\">\n {rects.hover.map((r, i) => (\n <div key={`h${i}`} className={`bpe-outline bpe-outline--hover ${hoverNode?.type === \"section\" ? \"bpe-outline--section\" : \"\"}`} style={{ left: r.x, top: r.y, width: r.width, height: r.height }}>\n {i === 0 && hoverNode ? (\n <span className=\"bpe-outline__label\">\n <Icon name={session.registry.get(hoverNode.type)?.icon ?? \"box\"} size={10} /> {nodeLabel(session, hoverNode)}\n </span>\n ) : null}\n </div>\n ))}\n {rects.selected.map((s) =>\n s.rects.map((r, i) => (\n <div key={`${s.id}${i}`} className={`bpe-outline bpe-outline--selected ${session.store.getNode(s.id)?.type === \"section\" ? \"bpe-outline--section\" : \"\"}`} style={{ left: r.x, top: r.y, width: r.width, height: r.height }} />\n ))\n )}\n {showToolbar && node && primaryRect ? (\n <BlockToolbar node={node} rect={primaryRect} actions={actions} label={nodeLabel(session, node)} typeName={(def?.name ?? node.type).toLowerCase()} icon={def?.icon} canEdit={!!def?.canvas?.inlineEdit} />\n ) : null}\n {insertion && !drag && !editingId ? (\n <div className=\"bpe-caret\" style={{ left: insertion.line.x, top: insertion.line.y, width: insertion.line.width }} aria-hidden=\"true\" />\n ) : null}\n {dropTarget?.line ? <div className=\"bpe-drop-line\" style={{ left: dropTarget.line.x, top: dropTarget.line.y, width: dropTarget.line.width }} /> : null}\n {dropTarget?.zone ? <div className={`bpe-drop-zone ${dropTarget.valid ? \"\" : \"bpe-drop-zone--invalid\"}`} style={{ left: dropTarget.zone.x, top: dropTarget.zone.y, width: dropTarget.zone.width, height: dropTarget.zone.height }} /> : null}\n </div>\n );\n}\n\nfunction BlockToolbar({ node, rect, actions, label, typeName, icon, canEdit }: { node: { id: string; type: string; locked?: boolean }; rect: Rect; actions: EditorActions; label: string; typeName: string; icon?: string; canEdit: boolean }) {\n const session = useSession();\n const top = rect.y - 34 < 0 ? rect.y + rect.height + 6 : rect.y - 34;\n const isSection = node.type === \"section\";\n const isColumn = node.type === \"column\";\n return (\n <div className=\"bpe-block-toolbar\" style={{ left: Math.max(0, rect.x), top }} role=\"toolbar\" aria-label={`${label} actions`} onPointerDown={(e) => e.stopPropagation()}>\n {!isColumn && (\n <button\n type=\"button\"\n className=\"bpe-btn bpe-btn--ghost bpe-btn--icon bpe-block-toolbar__handle\"\n aria-label=\"Drag to move\"\n title=\"Drag to move\"\n disabled={!!node.locked}\n onPointerDown={(e) => {\n e.stopPropagation();\n beginDrag(session, e, { kind: \"move\", payload: node.id, label, icon }, { threshold: 2 });\n }}\n >\n <Icon name=\"grip\" />\n </button>\n )}\n <span className=\"bpe-block-toolbar__type\">\n {label}\n </span>\n {/* Spelled out, not an icon: double-clicking to edit text is not a thing\n anyone discovers, and the pencil alone did not say what it did. */}\n {canEdit ? <Button size=\"sm\" variant=\"ghost\" icon=\"pencil\" tooltip=\"Edit this text on the canvas\" shortcut=\"Enter\" aria-label={typeName === \"text\" ? \"Edit this text\" : `Edit this ${typeName}'s text`} className=\"bpe-block-toolbar__edit\" onClick={() => session.store.setEditing(node.id)}>Edit text</Button> : null}\n <Button size=\"sm\" variant=\"ghost\" icon=\"arrow-up\" tooltip={`Move ${typeName} up`} shortcut=\"Alt+↑\" disabled={!!node.locked} onClick={() => actions.moveSelection(-1)} />\n <Button size=\"sm\" variant=\"ghost\" icon=\"arrow-down\" tooltip={`Move ${typeName} down`} shortcut=\"Alt+↓\" disabled={!!node.locked} onClick={() => actions.moveSelection(1)} />\n {!isColumn && <Button size=\"sm\" variant=\"ghost\" icon=\"copy\" tooltip={`Duplicate ${typeName}`} shortcut=\"⌘D\" onClick={() => actions.duplicateSelection()} />}\n <Menu\n placement=\"bottom-start\"\n trigger={<Button size=\"sm\" variant=\"ghost\" icon=\"more\" tooltip={`More ${typeName} actions`} />}\n items={[\n { id: \"parent\", label: \"Select parent\", icon: \"corner-down-right\", hint: \"←\", onSelect: () => actions.selectParent() },\n { id: \"copy\", label: \"Copy\", icon: \"copy\", hint: \"⌘C\", onSelect: () => actions.copySelection() },\n ...(isSection || isColumn ? [] : [\n { id: \"wrap-card\", label: \"Wrap in card\", icon: \"panel-top\", separatorBefore: true, onSelect: () => actions.wrapSelectionIn(\"card\") },\n { id: \"wrap-keep\", label: \"Keep together\", icon: \"link\", onSelect: () => actions.wrapSelectionIn(\"keepTogether\") },\n { id: \"wrap-cond\", label: \"Make conditional\", icon: \"git-branch\", onSelect: () => actions.wrapSelectionIn(\"conditional\") }\n ]),\n { id: \"library\", label: \"Save to library…\", icon: \"book-marked\", separatorBefore: true, onSelect: () => {\n const name = window.prompt(\"Name this reusable block\", label);\n if (name) actions.saveSelectionToLibrary(name);\n } },\n { id: \"lock\", label: node.locked ? \"Unlock\" : \"Lock\", icon: node.locked ? \"unlock\" : \"lock\", onSelect: () => actions.toggleLock() },\n ...(isColumn ? [] : [{ id: \"delete\", label: \"Delete\", icon: \"trash\", hint: \"⌫\", danger: true, separatorBefore: true, disabled: !!node.locked, onSelect: () => actions.deleteSelection() }])\n ]}\n />\n {!isColumn && <Button size=\"sm\" variant=\"ghost\" icon=\"trash\" tooltip={`Delete ${typeName}`} shortcut=\"⌫\" disabled={!!node.locked} onClick={() => actions.deleteSelection()} className=\"bpe-btn--danger\" />}\n </div>\n );\n}\n","export interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nfunction intersect(a: DOMRect, b: DOMRect): DOMRect | null {\n const left = Math.max(a.left, b.left);\n const top = Math.max(a.top, b.top);\n const right = Math.min(a.right, b.right);\n const bottom = Math.min(a.bottom, b.bottom);\n if (right - left < 1 || bottom - top < 1) return null;\n return new DOMRect(left, top, right - left, bottom - top);\n}\n\n/**\n * Visible rectangles (relative to `origin`) of every rendered copy of a node.\n * A node can appear on several pages (clip windows) and inside repeated\n * headers; each copy is clipped to its fragment and page body.\n */\nexport function visibleNodeRects(container: HTMLElement, origin: HTMLElement, nodeId: string): Rect[] {\n const originRect = origin.getBoundingClientRect();\n const out: Rect[] = [];\n const els = container.querySelectorAll<HTMLElement>(`[data-node=\"${CSS.escape(nodeId)}\"]`);\n for (const el of els) {\n if (el.hasAttribute(\"data-culled\")) continue;\n if (el.closest(\".bp-repeat-header\")) continue;\n let r: DOMRect | null = el.getBoundingClientRect();\n const clip = el.closest<HTMLElement>(\".bp-fragment__clip, .bp-page__region\");\n if (clip) r = intersect(r, clip.getBoundingClientRect());\n if (!r) continue;\n const body = el.closest<HTMLElement>(\".bp-page__body, .bp-page__region\");\n if (body) r = intersect(r, body.getBoundingClientRect());\n if (!r) continue;\n out.push({ x: r.left - originRect.left, y: r.top - originRect.top, width: r.width, height: r.height });\n }\n return out;\n}\n\n/** The first visible element for a node (used for the block toolbar and inline editing). */\nexport function firstVisibleElement(container: HTMLElement, nodeId: string): HTMLElement | null {\n const els = container.querySelectorAll<HTMLElement>(`[data-node=\"${CSS.escape(nodeId)}\"]`);\n for (const el of els) {\n if (el.hasAttribute(\"data-culled\") || el.closest(\".bp-repeat-header\")) continue;\n const r = el.getBoundingClientRect();\n const clip = el.closest<HTMLElement>(\".bp-fragment__clip, .bp-page__region\");\n if (clip && !intersect(r, clip.getBoundingClientRect())) continue;\n return el;\n }\n return null;\n}\n\n/** Finds the node id under a pointer event within the canvas. */\nexport function nodeIdAt(target: EventTarget | null): { id: string; type: string; el: HTMLElement } | null {\n // Wrappers carry data-key; inner parts carry only data-node, so anchor on the wrapper.\n const el = (target as HTMLElement | null)?.closest?.<HTMLElement>(\"[data-key]\") ?? null;\n if (!el) return null;\n return { id: el.getAttribute(\"data-node\")!, type: el.getAttribute(\"data-type\") ?? \"\", el };\n}\n","import { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { createSchemaScope, isRichTextDoc, richTextFromTemplate, richTextToPlain, parseExpression, labelForPath, type RichTextDoc } from \"@broadpaper/core\";\nimport type { EditorView } from \"prosemirror-view\";\nimport { useSession, useNode, useLayoutVersion } from \"../state/context.js\";\nimport { createRichTextView, activeFormats, rteCommands, type ActiveFormats } from \"../richtext/editor.js\";\nimport { TokenSuggestions } from \"../richtext/TokenSuggestions.js\";\nimport type { AutocompleteHandlers, TokenTrigger } from \"../richtext/autocomplete.js\";\nimport { firstVisibleElement } from \"./geometry.js\";\nimport { Button } from \"../ui/primitives.js\";\nimport { Popover } from \"../ui/floating.js\";\nimport { DataPicker } from \"../inspector/DataPicker.js\";\nimport { ColorPicker } from \"../inspector/fields/ColorField.js\";\nimport { TextInput } from \"../ui/primitives.js\";\n\ninterface Props {\n nodeId: string;\n container: HTMLElement;\n origin: HTMLElement;\n zoom: number;\n onClose: () => void;\n}\n\n/**\n * ProseMirror overlay placed exactly over a text or heading block. Edits are\n * written to the store as one merged undo step per typing burst.\n */\nexport function InlineEditor({ nodeId, container, origin, zoom, onClose }: Props) {\n const session = useSession();\n const entry = useNode(nodeId);\n const version = useLayoutVersion();\n const hostRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<ReturnType<typeof createRichTextView> | null>(null);\n const [formats, setFormats] = useState<ActiveFormats | null>(null);\n const [box, setBox] = useState<{ left: number; top: number; width: number; minHeight: number; style: string } | null>(null);\n // A \"{{\" the user is part way through typing, and where to anchor its list.\n const [suggest, setSuggest] = useState<{ trigger: TokenTrigger; view: EditorView; at: { left: number; top: number } } | null>(null);\n const handlersRef = useRef<AutocompleteHandlers | null>(null);\n const def = entry ? session.registry.get(entry.node.type) : undefined;\n const inline = def?.canvas?.inlineEdit;\n const prop = inline?.prop ?? \"content\";\n const singleLine = inline?.kind === \"text\";\n\n const labelFor = (expr: string) => {\n try {\n const ast = parseExpression(expr);\n const scope = createSchemaScope(session.dataSources);\n if (ast.kind === \"path\") return labelForPath(ast.segments, scope);\n if (ast.kind === \"pipe\" && ast.input.kind === \"path\") return `${labelForPath(ast.input.segments, scope)} · ${ast.name}`;\n } catch {\n /* fall through */\n }\n return expr;\n };\n\n // Position over the first visible copy of the node; copy its computed text styles.\n useLayoutEffect(() => {\n const el = firstVisibleElement(container, nodeId);\n if (!el) return;\n const textEl = (el.querySelector<HTMLElement>(\"[data-part='text']\") ?? el.firstElementChild ?? el) as HTMLElement;\n const r = textEl.getBoundingClientRect();\n const o = origin.getBoundingClientRect();\n const cs = getComputedStyle(textEl);\n const style = [\"font-family\", \"font-size\", \"font-weight\", \"font-style\", \"line-height\", \"letter-spacing\", \"text-transform\", \"text-align\", \"color\", \"padding\", \"background\", \"border\", \"border-radius\"].map((p) => `${p}:${cs.getPropertyValue(p)}`).join(\";\");\n setBox({ left: (r.left - o.left) / zoom, top: (r.top - o.top) / zoom, width: r.width / zoom, minHeight: r.height / zoom, style });\n el.setAttribute(\"data-editing\", \"\");\n return () => el.removeAttribute(\"data-editing\");\n }, [container, origin, nodeId, zoom, version]);\n\n // Create the ProseMirror view once.\n useEffect(() => {\n const host = hostRef.current;\n if (!host || !entry) return;\n const raw = entry.node.props[prop];\n const initial: RichTextDoc = isRichTextDoc(raw) ? raw : richTextFromTemplate(typeof raw === \"string\" ? raw : \"\");\n const handle = createRichTextView({\n element: host,\n doc: initial,\n labelFor,\n singleLine,\n onEnter: onClose,\n onEscape: onClose,\n onChange: (doc) => {\n const value = singleLine ? richTextToPlain(doc) : doc;\n session.store.dispatch({ type: \"setProp\", id: nodeId, path: prop, value }, { label: \"Edit text\", mergeKey: `text:${nodeId}` });\n },\n onSelectionChange: (v) => setFormats(activeFormats(v)),\n autocompleteHandlers: () => handlersRef.current,\n onTokenTrigger: (trigger, v) => {\n if (!trigger) return setSuggest(null);\n // Anchor below the braces themselves, in the overlay's coordinates.\n const c = v.coordsAtPos(trigger.from);\n const o = origin.getBoundingClientRect();\n setSuggest({ trigger, view: v, at: { left: c.left - o.left, top: c.bottom - o.top + 4 } });\n }\n });\n viewRef.current = handle;\n handle.view.focus();\n rteCommands.selectAll(handle.view);\n setFormats(activeFormats(handle.view));\n return () => {\n handle.destroy();\n viewRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [nodeId, box !== null]);\n\n if (!entry || !box) return null;\n const view: EditorView | undefined = viewRef.current?.view;\n const f = formats;\n\n return (\n <>\n <div className=\"bpe-inline-editor\" style={{ left: box.left, top: box.top, width: box.width, minHeight: box.minHeight, zoom }} onPointerDown={(e) => e.stopPropagation()} onMouseDown={(e) => e.stopPropagation()}>\n <div className=\"bpe-inline-editor__frame\" />\n <div ref={hostRef} style={cssStringToObject(box.style)} />\n </div>\n {suggest ? (\n <TokenSuggestions\n ref={handlersRef}\n trigger={suggest.trigger}\n view={suggest.view}\n dataSources={session.dataSources}\n at={suggest.at}\n onClose={() => setSuggest(null)}\n />\n ) : null}\n <div className=\"bpe-bubble\" style={{ left: box.left * zoom, top: Math.max(0, box.top * zoom - 40) }} onPointerDown={(e) => e.stopPropagation()} onMouseDown={(e) => e.preventDefault()}>\n {!singleLine && (\n <>\n <Button size=\"sm\" icon=\"bold\" tooltip=\"Bold\" shortcut=\"⌘B\" active={!!f?.bold} onClick={() => view && rteCommands.toggle(view, \"bold\")} />\n <Button size=\"sm\" icon=\"italic\" tooltip=\"Italic\" shortcut=\"⌘I\" active={!!f?.italic} onClick={() => view && rteCommands.toggle(view, \"italic\")} />\n <Button size=\"sm\" icon=\"underline\" tooltip=\"Underline\" shortcut=\"⌘U\" active={!!f?.underline} onClick={() => view && rteCommands.toggle(view, \"underline\")} />\n <Button size=\"sm\" icon=\"strikethrough\" tooltip=\"Strikethrough\" active={!!f?.strike} onClick={() => view && rteCommands.toggle(view, \"strike\")} />\n <span className=\"bpe-bubble__sep\" />\n <Button size=\"sm\" icon=\"list\" tooltip=\"Bullet list\" active={!!f?.bulletList} onClick={() => view && rteCommands.toggleList(view, \"bullet\")} />\n <Button size=\"sm\" icon=\"list-ordered\" tooltip=\"Numbered list\" active={!!f?.orderedList} onClick={() => view && rteCommands.toggleList(view, \"ordered\")} />\n <span className=\"bpe-bubble__sep\" />\n <Button size=\"sm\" icon=\"align-left\" tooltip=\"Align left\" active={!f?.align || f.align === \"left\"} onClick={() => view && rteCommands.setAlign(view, null)} />\n <Button size=\"sm\" icon=\"align-center\" tooltip=\"Align centre\" active={f?.align === \"center\"} onClick={() => view && rteCommands.setAlign(view, \"center\")} />\n <Button size=\"sm\" icon=\"align-right\" tooltip=\"Align right\" active={f?.align === \"right\"} onClick={() => view && rteCommands.setAlign(view, \"right\")} />\n <Button size=\"sm\" icon=\"align-justify\" tooltip=\"Justify\" active={f?.align === \"justify\"} onClick={() => view && rteCommands.setAlign(view, \"justify\")} />\n <span className=\"bpe-bubble__sep\" />\n <Popover placement=\"bottom-start\" trigger={<Button size=\"sm\" icon=\"link\" tooltip=\"Link\" active={!!f?.link} />}>\n {(close) => <LinkEditor value={f?.link ?? \"\"} onSubmit={(href) => { view && rteCommands.setLink(view, href || null); close(); }} />}\n </Popover>\n <Popover placement=\"bottom-start\" className=\"bpe-color-popover\" trigger={<Button size=\"sm\" icon=\"palette\" tooltip=\"Text colour\" active={!!f?.color} />}>\n {(close) => <ColorPicker value={f?.color ?? \"\"} theme={session.activeTheme} allowTransparent={false} onChange={(c) => { view && rteCommands.setColor(view, c || null); close(); }} />}\n </Popover>\n <span className=\"bpe-bubble__sep\" />\n </>\n )}\n <Popover placement=\"bottom-start\" className=\"bpe-picker\" trigger={<Button size=\"sm\" icon=\"braces\" tooltip=\"Insert data field\">Field</Button>}>\n {(close) => (\n <DataPicker\n dataSources={session.dataSources}\n onPick={(expr, label) => {\n if (view) rteCommands.insertToken(view, expr, label);\n close();\n }}\n />\n )}\n </Popover>\n <Button size=\"sm\" variant=\"primary\" icon=\"check\" tooltip=\"Done\" shortcut=\"Esc\" onClick={onClose} />\n </div>\n </>\n );\n}\n\nfunction LinkEditor({ value, onSubmit }: { value: string; onSubmit: (href: string) => void }) {\n const [v, setV] = useState(value);\n return (\n <div style={{ display: \"flex\", gap: 6, padding: 4, width: 280 }}>\n <TextInput value={v} onChange={setV} placeholder=\"https://… or mailto:\" autoFocus onKeyDown={(e) => e.key === \"Enter\" && onSubmit(v)} />\n <Button variant=\"primary\" size=\"sm\" onClick={() => onSubmit(v)}>Apply</Button>\n {value ? <Button size=\"sm\" icon=\"x\" tooltip=\"Remove link\" onClick={() => onSubmit(\"\")} /> : null}\n </div>\n );\n}\n\nfunction cssStringToObject(css: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (const decl of css.split(\";\")) {\n const i = decl.indexOf(\":\");\n if (i < 0) continue;\n const k = decl.slice(0, i).trim();\n const v = decl.slice(i + 1).trim();\n if (!k || !v) continue;\n out[k.replace(/-([a-z])/g, (_, c) => c.toUpperCase())] = v;\n }\n return out;\n}\n","import { EditorState, Plugin, TextSelection, type Transaction } from \"prosemirror-state\";\nimport { EditorView } from \"prosemirror-view\";\nimport { keymap } from \"prosemirror-keymap\";\nimport { baseKeymap, toggleMark, setBlockType, chainCommands, exitCode } from \"prosemirror-commands\";\nimport { wrapInList, splitListItem, liftListItem, sinkListItem } from \"prosemirror-schema-list\";\nimport type { MarkType, Node as PmNode } from \"prosemirror-model\";\nimport type { RichTextDoc } from \"@broadpaper/core\";\nimport { richTextSchema, modelToPm, pmToModel } from \"./schema.js\";\nimport { autocompleteKeymap, tokenAutocomplete, type AutocompleteHandlers, type TokenTrigger } from \"./autocomplete.js\";\n\nexport interface RichTextViewOptions {\n element: HTMLElement;\n doc: RichTextDoc | undefined;\n labelFor: (expr: string) => string;\n onChange: (doc: RichTextDoc) => void;\n onSelectionChange?: (view: EditorView) => void;\n onEscape?: () => void;\n onBlur?: () => void;\n /** Single paragraph only (headings). */\n singleLine?: boolean;\n /** Fires when the user presses Enter in single-line mode. */\n onEnter?: () => void;\n /** Fires as a \"{{\" field trigger opens, moves or closes. */\n onTokenTrigger?: (trigger: TokenTrigger | null, view: EditorView) => void;\n /** Consulted before Enter/Tab/arrows, so an open suggestion list wins. */\n autocompleteHandlers?: () => AutocompleteHandlers | null;\n}\n\nexport interface ActiveFormats {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strike: boolean;\n code: boolean;\n link: string | null;\n color: string | null;\n bulletList: boolean;\n orderedList: boolean;\n align: string | null;\n}\n\nexport function createRichTextView(opts: RichTextViewOptions): { view: EditorView; destroy(): void; setDoc(doc: RichTextDoc | undefined): void } {\n const s = richTextSchema;\n const bindings: Record<string, (state: EditorState, dispatch?: (tr: Transaction) => void, view?: EditorView) => boolean> = {\n \"Mod-b\": toggleMark(s.marks.bold!),\n \"Mod-i\": toggleMark(s.marks.italic!),\n \"Mod-u\": toggleMark(s.marks.underline!),\n \"Mod-Shift-x\": toggleMark(s.marks.strike!),\n \"Mod-e\": toggleMark(s.marks.code!),\n \"Shift-Enter\": chainCommands(exitCode, (state, dispatch) => {\n dispatch?.(state.tr.replaceSelectionWith(s.nodes.hard_break!.create()).scrollIntoView());\n return true;\n }),\n Escape: () => {\n opts.onEscape?.();\n return true;\n }\n };\n if (opts.singleLine) {\n bindings[\"Enter\"] = () => {\n opts.onEnter?.();\n return true;\n };\n } else {\n bindings[\"Enter\"] = chainCommands(splitListItem(s.nodes.list_item!), baseKeymap[\"Enter\"]!);\n bindings[\"Tab\"] = sinkListItem(s.nodes.list_item!);\n bindings[\"Shift-Tab\"] = liftListItem(s.nodes.list_item!);\n bindings[\"Mod-Shift-8\"] = wrapInList(s.nodes.bullet_list!);\n bindings[\"Mod-Shift-7\"] = wrapInList(s.nodes.ordered_list!);\n }\n\n const plugins = [\n ...(opts.autocompleteHandlers ? [keymap(autocompleteKeymap(opts.autocompleteHandlers))] : []),\n keymap(bindings),\n keymap(baseKeymap),\n ...(opts.onTokenTrigger ? [tokenAutocomplete({ onTrigger: opts.onTokenTrigger })] : []),\n new Plugin({\n props: {\n handleDOMEvents: {\n blur: () => {\n opts.onBlur?.();\n return false;\n }\n },\n // Never accept pasted HTML structure beyond what the schema allows; plain text is safest.\n clipboardTextParser: (text, $context) => {\n const paragraphs = text.split(/\\r?\\n/).map((line) => s.nodes.paragraph!.create(null, line ? [s.text(line)] : []));\n return s.nodes.doc!.create(null, paragraphs).slice(0, paragraphs.length ? undefined : 0) as never;\n void $context;\n }\n }\n })\n ];\n\n let suppress = false;\n const state = EditorState.create({ doc: modelToPm(opts.doc, opts.labelFor), plugins });\n const view = new EditorView(opts.element, {\n state,\n attributes: { class: \"bpe-rte\", spellcheck: \"true\" },\n dispatchTransaction(tr) {\n const next = view.state.apply(tr);\n view.updateState(next);\n if (tr.docChanged && !suppress) opts.onChange(pmToModel(next.doc));\n if (tr.selectionSet || tr.docChanged) opts.onSelectionChange?.(view);\n }\n });\n\n return {\n view,\n destroy: () => view.destroy(),\n setDoc(doc) {\n const pm = modelToPm(doc, opts.labelFor);\n if (pm.eq(view.state.doc)) return;\n suppress = true;\n const tr = view.state.tr.replaceWith(0, view.state.doc.content.size, pm.content);\n view.dispatch(tr);\n suppress = false;\n }\n };\n}\n\nexport function activeFormats(view: EditorView): ActiveFormats {\n const { state } = view;\n const { from, $from, to, empty } = state.selection;\n const has = (type: MarkType): boolean => {\n if (empty) return !!type.isInSet(state.storedMarks ?? $from.marks());\n return state.doc.rangeHasMark(from, to, type);\n };\n const markAttr = (type: MarkType, attr: string): string | null => {\n const marks = empty ? state.storedMarks ?? $from.marks() : $from.marks();\n const m = marks.find((x) => x.type === type);\n return m ? String(m.attrs[attr]) : null;\n };\n let bulletList = false;\n let orderedList = false;\n for (let d = $from.depth; d > 0; d--) {\n const n = $from.node(d);\n if (n.type.name === \"bullet_list\") bulletList = true;\n if (n.type.name === \"ordered_list\") orderedList = true;\n }\n const para = $from.parent.type.name === \"paragraph\" ? $from.parent : null;\n return {\n bold: has(richTextSchema.marks.bold!),\n italic: has(richTextSchema.marks.italic!),\n underline: has(richTextSchema.marks.underline!),\n strike: has(richTextSchema.marks.strike!),\n code: has(richTextSchema.marks.code!),\n link: markAttr(richTextSchema.marks.link!, \"href\"),\n color: markAttr(richTextSchema.marks.color!, \"color\"),\n bulletList,\n orderedList,\n align: para ? (para.attrs.align as string | null) : null\n };\n}\n\nexport const rteCommands = {\n toggle(view: EditorView, mark: \"bold\" | \"italic\" | \"underline\" | \"strike\" | \"code\") {\n toggleMark(richTextSchema.marks[mark]!)(view.state, view.dispatch);\n view.focus();\n },\n setLink(view: EditorView, href: string | null) {\n const type = richTextSchema.marks.link!;\n const { from, to, empty } = view.state.selection;\n let tr = view.state.tr;\n if (empty) {\n if (href) tr = tr.addStoredMark(type.create({ href }));\n else tr = tr.removeStoredMark(type);\n } else {\n tr = tr.removeMark(from, to, type);\n if (href) tr = tr.addMark(from, to, type.create({ href }));\n }\n view.dispatch(tr);\n view.focus();\n },\n setColor(view: EditorView, color: string | null) {\n const type = richTextSchema.marks.color!;\n const { from, to, empty } = view.state.selection;\n let tr = view.state.tr;\n if (empty) tr = color ? tr.addStoredMark(type.create({ color })) : tr.removeStoredMark(type);\n else {\n tr = tr.removeMark(from, to, type);\n if (color) tr = tr.addMark(from, to, type.create({ color }));\n }\n view.dispatch(tr);\n view.focus();\n },\n setAlign(view: EditorView, align: string | null) {\n const { from, to } = view.state.selection;\n let tr = view.state.tr;\n view.state.doc.nodesBetween(from, to, (node, pos) => {\n if (node.type.name === \"paragraph\") tr = tr.setNodeMarkup(pos, undefined, { ...node.attrs, align });\n });\n view.dispatch(tr);\n view.focus();\n },\n toggleList(view: EditorView, kind: \"bullet\" | \"ordered\") {\n const formats = activeFormats(view);\n const active = kind === \"bullet\" ? formats.bulletList : formats.orderedList;\n if (active) liftListItem(richTextSchema.nodes.list_item!)(view.state, view.dispatch);\n else {\n const ok = wrapInList(richTextSchema.nodes[kind === \"bullet\" ? \"bullet_list\" : \"ordered_list\"]!)(view.state, view.dispatch);\n if (!ok) {\n // Switch list type\n liftListItem(richTextSchema.nodes.list_item!)(view.state, view.dispatch);\n wrapInList(richTextSchema.nodes[kind === \"bullet\" ? \"bullet_list\" : \"ordered_list\"]!)(view.state, view.dispatch);\n }\n }\n view.focus();\n },\n insertToken(view: EditorView, expr: string, label: string) {\n const node = richTextSchema.nodes.token!.create({ expr, label });\n const tr = view.state.tr.replaceSelectionWith(node).scrollIntoView();\n view.dispatch(tr);\n view.focus();\n },\n insertText(view: EditorView, text: string) {\n view.dispatch(view.state.tr.insertText(text).scrollIntoView());\n view.focus();\n },\n paragraph(view: EditorView) {\n setBlockType(richTextSchema.nodes.paragraph!)(view.state, view.dispatch);\n },\n selectAll(view: EditorView) {\n view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, 0, view.state.doc.content.size)));\n }\n};\n\nexport type { PmNode, EditorView };\n","import { Schema, type Node as PmNode, type Mark } from \"prosemirror-model\";\nimport type { RichTextDoc, InlineNode, Paragraph, BlockNode, TextMarks } from \"@broadpaper/core\";\n\n/** ProseMirror schema mirroring the BroadPaper rich text model exactly. */\nexport const richTextSchema = new Schema({\n nodes: {\n doc: { content: \"block+\" },\n paragraph: {\n group: \"block\",\n content: \"inline*\",\n attrs: { align: { default: null } },\n parseDOM: [{ tag: \"p\", getAttrs: (dom) => ({ align: (dom as HTMLElement).style.textAlign || null }) }],\n toDOM: (n) => [\"p\", { class: \"bp-p\", style: n.attrs.align ? `text-align:${n.attrs.align}` : undefined }, 0]\n },\n bullet_list: { group: \"block\", content: \"list_item+\", parseDOM: [{ tag: \"ul\" }], toDOM: () => [\"ul\", { class: \"bp-list\" }, 0] },\n ordered_list: { group: \"block\", content: \"list_item+\", parseDOM: [{ tag: \"ol\" }], toDOM: () => [\"ol\", { class: \"bp-list\" }, 0] },\n list_item: { content: \"paragraph+\", parseDOM: [{ tag: \"li\" }], toDOM: () => [\"li\", 0], defining: true },\n text: { group: \"inline\" },\n hard_break: { group: \"inline\", inline: true, selectable: false, parseDOM: [{ tag: \"br\" }], toDOM: () => [\"br\"] },\n token: {\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: true,\n draggable: true,\n attrs: { expr: {}, label: { default: null } },\n parseDOM: [{ tag: \"span[data-expr]\", getAttrs: (dom) => ({ expr: (dom as HTMLElement).getAttribute(\"data-expr\"), label: (dom as HTMLElement).textContent }) }],\n toDOM: (n) => [\"span\", { class: \"bp-token\", \"data-expr\": n.attrs.expr, title: n.attrs.expr, contenteditable: \"false\" }, n.attrs.label ?? n.attrs.expr]\n }\n },\n marks: {\n bold: { parseDOM: [{ tag: \"strong\" }, { tag: \"b\" }, { style: \"font-weight=bold\" }], toDOM: () => [\"strong\", 0] },\n italic: { parseDOM: [{ tag: \"em\" }, { tag: \"i\" }, { style: \"font-style=italic\" }], toDOM: () => [\"em\", 0] },\n underline: { parseDOM: [{ tag: \"u\" }, { style: \"text-decoration=underline\" }], toDOM: () => [\"u\", 0] },\n strike: { parseDOM: [{ tag: \"s\" }, { tag: \"del\" }, { style: \"text-decoration=line-through\" }], toDOM: () => [\"s\", 0] },\n code: { parseDOM: [{ tag: \"code\" }], toDOM: () => [\"code\", { class: \"bp-code\" }, 0] },\n link: { attrs: { href: {} }, inclusive: false, parseDOM: [{ tag: \"a[href]\", getAttrs: (dom) => ({ href: (dom as HTMLElement).getAttribute(\"href\") }) }], toDOM: (m) => [\"a\", { href: m.attrs.href, class: \"bp-link\" }, 0] },\n color: { attrs: { color: {} }, parseDOM: [{ style: \"color\", getAttrs: (v) => ({ color: v }) }], toDOM: (m) => [\"span\", { style: `color:${m.attrs.color}` }, 0] }\n }\n});\n\n/* ---------------------------- model → PM ---------------------------- */\n\nfunction marksToPm(marks: TextMarks | undefined): Mark[] {\n if (!marks) return [];\n const out: Mark[] = [];\n const s = richTextSchema.marks;\n if (marks.bold) out.push(s.bold!.create());\n if (marks.italic) out.push(s.italic!.create());\n if (marks.underline) out.push(s.underline!.create());\n if (marks.strike) out.push(s.strike!.create());\n if (marks.code) out.push(s.code!.create());\n if (marks.link) out.push(s.link!.create({ href: marks.link }));\n if (marks.color) out.push(s.color!.create({ color: marks.color }));\n return out;\n}\n\nfunction inlineToPm(content: InlineNode[], labelFor: (expr: string) => string): PmNode[] {\n const out: PmNode[] = [];\n for (const n of content) {\n if (n.type === \"text\") {\n if (n.text) out.push(richTextSchema.text(n.text, marksToPm(n.marks)));\n } else if (n.type === \"token\") out.push(richTextSchema.nodes.token!.create({ expr: n.expr, label: labelFor(n.expr) }, undefined, marksToPm(n.marks)));\n else out.push(richTextSchema.nodes.hard_break!.create());\n }\n return out;\n}\n\nfunction paragraphToPm(p: Paragraph, labelFor: (expr: string) => string): PmNode {\n return richTextSchema.nodes.paragraph!.create({ align: p.align ?? null }, inlineToPm(p.content, labelFor));\n}\n\nexport function modelToPm(doc: RichTextDoc | undefined, labelFor: (expr: string) => string): PmNode {\n const blocks: PmNode[] = [];\n for (const b of doc?.content ?? []) {\n if (b.type === \"paragraph\") blocks.push(paragraphToPm(b, labelFor));\n else {\n const items = b.content.map((li) => richTextSchema.nodes.list_item!.create(null, li.content.map((p) => paragraphToPm(p, labelFor))));\n blocks.push(richTextSchema.nodes[b.type === \"bulletList\" ? \"bullet_list\" : \"ordered_list\"]!.create(null, items.length ? items : [richTextSchema.nodes.list_item!.create(null, [richTextSchema.nodes.paragraph!.create()])]));\n }\n }\n if (blocks.length === 0) blocks.push(richTextSchema.nodes.paragraph!.create());\n return richTextSchema.nodes.doc!.create(null, blocks);\n}\n\n/* ---------------------------- PM → model ---------------------------- */\n\nfunction pmMarks(marks: readonly Mark[]): TextMarks | undefined {\n if (!marks.length) return undefined;\n const out: TextMarks = {};\n for (const m of marks) {\n switch (m.type.name) {\n case \"bold\":\n out.bold = true;\n break;\n case \"italic\":\n out.italic = true;\n break;\n case \"underline\":\n out.underline = true;\n break;\n case \"strike\":\n out.strike = true;\n break;\n case \"code\":\n out.code = true;\n break;\n case \"link\":\n out.link = String(m.attrs.href ?? \"\");\n break;\n case \"color\":\n out.color = String(m.attrs.color ?? \"\");\n break;\n }\n }\n return Object.keys(out).length ? out : undefined;\n}\n\nfunction pmInline(p: PmNode): InlineNode[] {\n const out: InlineNode[] = [];\n p.forEach((child) => {\n const marks = pmMarks(child.marks);\n if (child.type.name === \"text\") out.push({ type: \"text\", text: child.text ?? \"\", ...(marks ? { marks } : {}) });\n else if (child.type.name === \"token\") out.push({ type: \"token\", expr: String(child.attrs.expr), ...(marks ? { marks } : {}) });\n else if (child.type.name === \"hard_break\") out.push({ type: \"break\" });\n });\n return out;\n}\n\nfunction pmParagraph(p: PmNode): Paragraph {\n const para: Paragraph = { type: \"paragraph\", content: pmInline(p) };\n if (p.attrs.align) para.align = p.attrs.align;\n return para;\n}\n\nexport function pmToModel(doc: PmNode): RichTextDoc {\n const content: BlockNode[] = [];\n doc.forEach((b) => {\n if (b.type.name === \"paragraph\") content.push(pmParagraph(b));\n else if (b.type.name === \"bullet_list\" || b.type.name === \"ordered_list\") {\n const items: Array<{ type: \"listItem\"; content: Paragraph[] }> = [];\n b.forEach((li) => {\n const ps: Paragraph[] = [];\n li.forEach((p) => {\n if (p.type.name === \"paragraph\") ps.push(pmParagraph(p));\n });\n items.push({ type: \"listItem\", content: ps });\n });\n content.push({ type: b.type.name === \"bullet_list\" ? \"bulletList\" : \"orderedList\", content: items });\n }\n });\n return { type: \"doc\", content: content.length ? content : [{ type: \"paragraph\", content: [] }] };\n}\n","/**\n * Typing `{{` offers the fields the report can actually bind to.\n *\n * The data picker in the bubble menu is the deliberate route; this is the fast\n * one, for people who are already typing a sentence and want a value in the\n * middle of it. Both end in the same token node, so a field inserted either way\n * is the same thing afterwards.\n *\n * The plugin owns only what ProseMirror can know — where the trigger starts and\n * what has been typed since. Which item is highlighted belongs to the popup,\n * which is why the keyboard bindings delegate rather than decide.\n */\nimport { Plugin, PluginKey, type EditorState } from \"prosemirror-state\";\nimport type { EditorView } from \"prosemirror-view\";\nimport { richTextSchema } from \"./schema.js\";\n\n/** An open trigger: `{{` plus whatever has been typed after it. */\nexport interface TokenTrigger {\n /** Document position of the first brace. */\n from: number;\n /** Document position of the cursor. */\n to: number;\n query: string;\n}\n\n/** What the popup must be able to do when a key arrives at the editor first. */\nexport interface AutocompleteHandlers {\n isOpen(): boolean;\n move(delta: number): void;\n /** Returns false to let the key fall through, e.g. nothing is highlighted. */\n accept(): boolean;\n close(): void;\n}\n\nexport const autocompleteKey = new PluginKey<TokenTrigger | null>(\"bp-token-autocomplete\");\n\n/**\n * A trigger is open when the text between the cursor and the nearest preceding\n * `{{` in the same block contains no brace of its own. Closing the braces by\n * hand, or moving away, ends it.\n */\nfunction triggerAt(state: EditorState): TokenTrigger | null {\n const sel = state.selection;\n if (!sel.empty) return null;\n const $from = sel.$from;\n if (!$from.parent.isTextblock) return null;\n // A replacement character stands in for tokens and other leaf nodes so the\n // offsets stay aligned with the document.\n const before = $from.parent.textBetween(0, $from.parentOffset, undefined, \"\");\n const match = /\\{\\{([^{}]*)$/.exec(before);\n if (!match) return null;\n return {\n from: $from.start() + $from.parentOffset - match[0].length,\n to: sel.from,\n query: match[1]!.trim()\n };\n}\n\nexport function tokenAutocomplete(opts: { onTrigger(trigger: TokenTrigger | null, view: EditorView): void }): Plugin<TokenTrigger | null> {\n return new Plugin<TokenTrigger | null>({\n key: autocompleteKey,\n state: {\n init: (_config, state) => triggerAt(state),\n apply: (tr, _prev, _old, next) => (tr.getMeta(autocompleteKey) === \"close\" ? null : triggerAt(next))\n },\n view: (view) => {\n let last: string | null = null;\n const publish = () => {\n const trigger = autocompleteKey.getState(view.state) ?? null;\n // Only tell the popup when something it cares about actually moved.\n const signature = trigger ? `${trigger.from}:${trigger.to}:${trigger.query}` : null;\n if (signature === last) return;\n last = signature;\n opts.onTrigger(trigger, view);\n };\n publish();\n return { update: publish };\n }\n });\n}\n\n/** Replaces an open `{{query` with a token node, and a following space. */\nexport function acceptToken(view: EditorView, trigger: TokenTrigger, expr: string, label: string): void {\n const token = richTextSchema.nodes.token!.create({ expr, label });\n const tr = view.state.tr.replaceWith(trigger.from, trigger.to, token);\n tr.setMeta(autocompleteKey, \"close\");\n view.dispatch(tr.scrollIntoView());\n view.focus();\n}\n\n/** Abandons the trigger, leaving the typed text exactly as it is. */\nexport function dismissAutocomplete(view: EditorView): void {\n view.dispatch(view.state.tr.setMeta(autocompleteKey, \"close\"));\n}\n\n/**\n * Key bindings that apply only while the popup is open, so ordinary typing,\n * Enter and Escape behave normally the rest of the time.\n */\nexport function autocompleteKeymap(handlers: () => AutocompleteHandlers | null): Record<string, () => boolean> {\n const when = (fn: (h: AutocompleteHandlers) => boolean) => (): boolean => {\n const h = handlers();\n return h && h.isOpen() ? fn(h) : false;\n };\n return {\n ArrowDown: when((h) => (h.move(1), true)),\n ArrowUp: when((h) => (h.move(-1), true)),\n Enter: when((h) => h.accept()),\n Tab: when((h) => h.accept()),\n Escape: when((h) => (h.close(), true))\n };\n}\n","import { useEffect, useImperativeHandle, useMemo, useRef, useState, forwardRef } from \"react\";\nimport type { DataSource, FieldSchema } from \"@broadpaper/core\";\nimport type { EditorView } from \"prosemirror-view\";\nimport { flattenSchemas, type PickerEntry } from \"../inspector/DataPicker.js\";\nimport { acceptToken, dismissAutocomplete, type AutocompleteHandlers, type TokenTrigger } from \"./autocomplete.js\";\nimport { Icon, FIELD_TYPE_ICONS } from \"../ui/icons.js\";\n\nconst MAX_ITEMS = 8;\n\n/** Ranks a field against what has been typed after the braces. */\nfunction score(entry: PickerEntry, query: string): number {\n if (!query) return 1;\n const expr = entry.expr.toLowerCase();\n const label = entry.label.toLowerCase();\n const leaf = entry.expr.slice(entry.expr.lastIndexOf(\".\") + 1).toLowerCase();\n // A prefix match on the name people would type beats a match buried in the\n // middle of a long path.\n if (leaf.startsWith(query)) return 100 - leaf.length;\n if (expr.startsWith(query)) return 90 - expr.length;\n if (leaf.includes(query)) return 60;\n if (expr.includes(query)) return 40;\n if (label.includes(query)) return 20;\n return 0;\n}\n\nexport interface TokenSuggestionsProps {\n trigger: TokenTrigger;\n view: EditorView;\n dataSources: DataSource[];\n scopeVars?: Record<string, FieldSchema>;\n /** Position of the trigger, in the overlay's coordinate space. */\n at: { left: number; top: number };\n onClose: () => void;\n}\n\n/**\n * The list offered while a `{{` is open.\n *\n * It owns the highlighted row, and hands the editor a set of handlers so the\n * arrow keys and Enter reach the list before ProseMirror's own bindings.\n */\nexport const TokenSuggestions = forwardRef<AutocompleteHandlers, TokenSuggestionsProps>(function TokenSuggestions(\n { trigger, view, dataSources, scopeVars, at, onClose },\n ref\n) {\n const [index, setIndex] = useState(0);\n const listRef = useRef<HTMLDivElement>(null);\n\n const entries = useMemo(() => flattenSchemas(dataSources, scopeVars ?? {}), [dataSources, scopeVars]);\n const items = useMemo(() => {\n const q = trigger.query.toLowerCase();\n return entries\n .map((e) => ({ e, s: score(e, q) }))\n .filter((x) => x.s > 0)\n .sort((a, b) => b.s - a.s)\n .slice(0, MAX_ITEMS)\n .map((x) => x.e);\n }, [entries, trigger.query]);\n\n // A new query starts from the top; keeping the old row would highlight\n // something the user never looked at.\n useEffect(() => setIndex(0), [trigger.query]);\n\n const accept = (i = index): boolean => {\n const item = items[i];\n if (!item) return false;\n acceptToken(view, trigger, item.expr, item.label);\n return true;\n };\n\n useImperativeHandle(\n ref,\n (): AutocompleteHandlers => ({\n isOpen: () => items.length > 0,\n move: (delta) => setIndex((i) => (items.length ? (i + delta + items.length) % items.length : 0)),\n accept: () => accept(),\n close: () => {\n dismissAutocomplete(view);\n onClose();\n }\n }),\n [items, index, view, trigger, onClose]\n );\n\n useEffect(() => {\n listRef.current?.querySelector<HTMLElement>('[aria-selected=\"true\"]')?.scrollIntoView({ block: \"nearest\" });\n }, [index]);\n\n if (!items.length) return null;\n\n return (\n <div className=\"bpe-suggest\" style={{ left: at.left, top: at.top }} role=\"listbox\" aria-label=\"Insert a data field\" ref={listRef} onPointerDown={(e) => e.preventDefault()}>\n {items.map((item, i) => (\n <div\n key={item.expr}\n role=\"option\"\n aria-selected={i === index}\n className={`bpe-suggest__item ${i === index ? \"bpe-suggest__item--active\" : \"\"}`}\n onMouseEnter={() => setIndex(i)}\n onClick={() => accept(i)}\n >\n <Icon name={FIELD_TYPE_ICONS[item.type] ?? \"circle\"} size={13} className=\"bpe-suggest__icon\" />\n <span className=\"bpe-suggest__label bpe-truncate\">{item.label}</span>\n <span className=\"bpe-suggest__expr bpe-truncate\">{item.expr}</span>\n </div>\n ))}\n <div className=\"bpe-suggest__hint\">\n <kbd>↑</kbd>\n <kbd>↓</kbd> to choose · <kbd>Enter</kbd> to insert · <kbd>Esc</kbd> to dismiss\n </div>\n </div>\n );\n});\n","import { useMemo, useState } from \"react\";\nimport { GLOBAL_SCHEMAS, PIPES, checkExpressionSyntax, type DataSource, type FieldSchema, type FieldType } from \"@broadpaper/core\";\nimport { Icon, FIELD_TYPE_ICONS } from \"../ui/icons.js\";\nimport { Button, TextInput } from \"../ui/primitives.js\";\n\nexport interface PickerEntry {\n expr: string;\n label: string;\n path: string[];\n type: FieldType;\n schema: FieldSchema;\n depth: number;\n group: string;\n}\n\n/** Flattens data sources (and scope variables) into pickable entries. */\nexport function flattenSchemas(dataSources: DataSource[], extra: Record<string, FieldSchema> = {}, opts: { includeGlobals?: boolean; arraysOnly?: boolean; types?: FieldType[] } = {}): PickerEntry[] {\n const out: PickerEntry[] = [];\n const visit = (expr: string, schema: FieldSchema, labels: string[], depth: number, group: string) => {\n const label = labels.join(\" › \");\n const isObject = schema.type === \"object\";\n const wanted = opts.arraysOnly ? schema.type === \"array\" : !opts.types || opts.types.includes(schema.type) || schema.type === \"object\" || schema.type === \"array\";\n if (!isObject && wanted) out.push({ expr, label, path: labels, type: schema.type, schema, depth, group });\n if (isObject && schema.fields) for (const [k, f] of Object.entries(schema.fields)) visit(`${expr}.${k}`, f, [...labels, f.label ?? k], depth + 1, group);\n if (schema.type === \"array\" && schema.itemSchema?.type === \"object\" && schema.itemSchema.fields && !opts.arraysOnly) {\n // Expose projections (e.g. holdings.value) for aggregates.\n for (const [k, f] of Object.entries(schema.itemSchema.fields)) if (f.type !== \"object\" && f.type !== \"array\") out.push({ expr: `${expr}.${k}`, label: [...labels, `each ${f.label ?? k}`].join(\" › \"), path: [...labels, f.label ?? k], type: \"array\", schema: { type: \"array\", itemSchema: f }, depth: depth + 1, group });\n }\n };\n for (const [name, schema] of Object.entries(extra)) visit(name, schema, [schema.label ?? name], 0, \"Current item\");\n for (const s of dataSources) {\n if (s.schema && Object.keys(s.schema).length) for (const [k, f] of Object.entries(s.schema)) visit(`${s.id}.${k}`, f, [s.label, f.label ?? k], 1, s.label);\n }\n if (opts.includeGlobals !== false && !opts.arraysOnly) {\n for (const [name, schema] of Object.entries(GLOBAL_SCHEMAS)) {\n if (name === \"theme\") continue;\n visit(name, schema, [schema.label ?? name], 0, \"Document\");\n }\n }\n return out;\n}\n\nexport interface DataPickerProps {\n dataSources: DataSource[];\n /** Scope variables (repeater item etc.). */\n scopeVars?: Record<string, FieldSchema>;\n arraysOnly?: boolean;\n types?: FieldType[];\n /** Currently bound expression, shown in the manual box. */\n value?: string;\n onPick: (expr: string, label: string, entry?: PickerEntry) => void;\n onClear?: () => void;\n allowExpression?: boolean;\n}\n\nconst FORMAT_SUGGESTIONS: Record<string, Array<{ label: string; pipe: string }>> = {\n currency: [{ label: \"£ 12,345.67\", pipe: \"currency\" }, { label: \"£ 12,346\", pipe: \"currency:\\\"GBP\\\":0\" }],\n number: [{ label: \"12,345.67\", pipe: \"number\" }, { label: \"12,346\", pipe: \"number:0\" }],\n percent: [{ label: \"12.3%\", pipe: \"percent\" }, { label: \"12%\", pipe: \"percent:0\" }],\n date: [{ label: \"20 May 2026\", pipe: 'date:\"d MMMM yyyy\"' }, { label: \"20/05/2026\", pipe: 'date:\"dd/MM/yyyy\"' }, { label: \"May 2026\", pipe: 'date:\"MMMM yyyy\"' }],\n datetime: [{ label: \"20 May 2026, 14:30\", pipe: 'datetime:\"d MMM yyyy, HH:mm\"' }, { label: \"Date only\", pipe: 'date:\"d MMMM yyyy\"' }],\n boolean: [{ label: \"Yes / No\", pipe: \"boolean\" }, { label: \"Custom words\", pipe: 'boolean:\"Yes\":\"No\"' }],\n string: [{ label: \"UPPERCASE\", pipe: \"upper\" }, { label: \"Title Case\", pipe: \"title\" }],\n array: [{ label: \"Count\", pipe: \"length\" }, { label: \"Join with commas\", pipe: 'join:\", \"' }]\n};\n\nexport function DataPicker({ dataSources, scopeVars, arraysOnly, types, value, onPick, onClear, allowExpression = true }: DataPickerProps) {\n const [q, setQ] = useState(\"\");\n const [expr, setExpr] = useState(value ?? \"\");\n const [pending, setPending] = useState<PickerEntry | null>(null);\n const entries = useMemo(() => flattenSchemas(dataSources, scopeVars, { arraysOnly, types }), [dataSources, scopeVars, arraysOnly, types]);\n const filtered = useMemo(() => {\n const needle = q.trim().toLowerCase();\n if (!needle) return entries;\n return entries.filter((e) => e.label.toLowerCase().includes(needle) || e.expr.toLowerCase().includes(needle));\n }, [entries, q]);\n const groups = useMemo(() => {\n const m = new Map<string, PickerEntry[]>();\n for (const e of filtered) m.set(e.group, [...(m.get(e.group) ?? []), e]);\n return [...m.entries()];\n }, [filtered]);\n const syntaxError = expr.trim() ? checkExpressionSyntax(expr) : null;\n\n if (pending) {\n const suggestions = FORMAT_SUGGESTIONS[pending.type] ?? [];\n return (\n <div>\n <div className=\"bpe-picker__search\" style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n <Button size=\"sm\" icon=\"chevron-right\" style={{ transform: \"rotate(180deg)\" }} tooltip=\"Back\" onClick={() => setPending(null)} />\n <span className=\"bpe-truncate\" style={{ fontWeight: 600 }}>{pending.label}</span>\n </div>\n <div className=\"bpe-picker__list\">\n <div className=\"bpe-picker__group\">Format</div>\n <button type=\"button\" className=\"bpe-data-field\" onClick={() => onPick(pending.expr, pending.label, pending)}>\n <Icon name=\"check\" className=\"bpe-data-field__icon\" /> As is\n </button>\n {suggestions.map((s) => (\n <button key={s.pipe} type=\"button\" className=\"bpe-data-field\" onClick={() => onPick(`${pending.expr} | ${s.pipe}`, pending.label, pending)}>\n <Icon name=\"wand\" className=\"bpe-data-field__icon\" /> {s.label}\n <span className=\"bpe-data-field__type bpe-mono\" style={{ textTransform: \"none\" }}>| {s.pipe}</span>\n </button>\n ))}\n {pending.type !== \"array\" && (\n <button type=\"button\" className=\"bpe-data-field\" onClick={() => onPick(`${pending.expr} | default:\"—\"`, pending.label, pending)}>\n <Icon name=\"eraser\" className=\"bpe-data-field__icon\" /> With fallback “—” when empty\n </button>\n )}\n </div>\n </div>\n );\n }\n\n return (\n <div>\n <div className=\"bpe-picker__search\">\n <TextInput value={q} onChange={setQ} placeholder={arraysOnly ? \"Search lists…\" : \"Search fields…\"} autoFocus aria-label=\"Search fields\" />\n </div>\n <div className=\"bpe-picker__list\" role=\"listbox\">\n {groups.length === 0 ? <div className=\"bpe-empty\">No matching fields</div> : null}\n {groups.map(([group, items]) => (\n <div key={group}>\n <div className=\"bpe-picker__group\">{group}</div>\n {items.map((e) => (\n <button key={e.expr} type=\"button\" role=\"option\" aria-selected={value === e.expr} className=\"bpe-data-field\" style={{ paddingLeft: 6 + Math.max(0, e.depth - 1) * 10 }} title={e.expr} onClick={() => (arraysOnly || e.type === \"array\" || e.type === \"object\" ? onPick(e.expr, e.label, e) : setPending(e))}>\n <Icon name={FIELD_TYPE_ICONS[e.type] ?? \"box\"} className=\"bpe-data-field__icon\" />\n <span className=\"bpe-truncate\">{e.path[e.path.length - 1]}</span>\n <span className=\"bpe-data-field__type\">{e.type}</span>\n </button>\n ))}\n </div>\n ))}\n </div>\n {allowExpression ? (\n <div className=\"bpe-picker__foot\">\n <TextInput value={expr} onChange={setExpr} mono placeholder=\"or type an expression\" invalid={!!syntaxError} aria-label=\"Expression\" onKeyDown={(e) => e.key === \"Enter\" && !syntaxError && expr.trim() && onPick(expr.trim(), expr.trim())} />\n <Button size=\"sm\" variant=\"primary\" disabled={!!syntaxError || !expr.trim()} onClick={() => onPick(expr.trim(), expr.trim())}>Use</Button>\n {onClear && value ? <Button size=\"sm\" icon=\"x\" tooltip=\"Clear binding\" onClick={onClear} /> : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport const PIPE_NAMES = Object.keys(PIPES);\n","import { useState } from \"react\";\nimport { listThemeTokens, resolveValue, isTokenRef, type Theme } from \"@broadpaper/core\";\nimport { Popover } from \"../../ui/floating.js\";\nimport { TextInput, Button } from \"../../ui/primitives.js\";\n\nconst PRESETS = [\"#111827\", \"#374151\", \"#6B7280\", \"#9CA3AF\", \"#D1D5DB\", \"#F3F4F6\", \"#FFFFFF\", \"#B91C1C\", \"#DC2626\", \"#EA580C\", \"#D97706\", \"#CA8A04\", \"#65A30D\", \"#16A34A\", \"#059669\", \"#0D9488\", \"#0891B2\", \"#0284C7\", \"#2563EB\", \"#4F46E5\", \"#7C3AED\", \"#9333EA\", \"#C026D3\", \"#DB2777\"];\n\nexport function ColorPicker({ value, onChange, theme, allowTransparent = true }: { value: string; onChange: (v: string) => void; theme: Theme; allowTransparent?: boolean }) {\n const tokens = listThemeTokens(theme).filter((t) => t.group === \"colors\" || t.group === \"table\");\n const [hex, setHex] = useState(isTokenRef(value) ? \"\" : value);\n return (\n <div>\n <div className=\"bpe-menu__label\">Theme colours</div>\n {tokens.map((t) => (\n <button key={t.token} type=\"button\" className=\"bpe-color-token\" aria-pressed={value === t.token} style={{ [\"--c\" as string]: t.value }} onClick={() => onChange(t.token)}>\n <span className=\"bpe-color-token__sw\" />\n <span className=\"bpe-truncate\">{t.label}</span>\n <span className=\"bpe-color-token__val\">{t.value.toUpperCase()}</span>\n </button>\n ))}\n <div className=\"bpe-menu__label\">Custom</div>\n <div className=\"bpe-color-grid\">\n {PRESETS.map((c) => (\n <button key={c} type=\"button\" className=\"bpe-color-grid__item\" aria-pressed={value.toUpperCase() === c} aria-label={c} style={{ [\"--c\" as string]: c }} onClick={() => onChange(c)} />\n ))}\n </div>\n <div style={{ display: \"flex\", gap: 6, padding: 4, alignItems: \"center\" }}>\n <input type=\"color\" aria-label=\"Pick colour\" value={/^#[0-9a-f]{6}$/i.test(hex) ? hex : resolveValue(value, theme, \"#000000\")} onChange={(e) => { setHex(e.target.value); onChange(e.target.value); }} style={{ width: 28, height: 28, padding: 0, border: \"1px solid var(--bpe-border)\", borderRadius: 6, background: \"none\" }} />\n <TextInput value={hex} onChange={setHex} placeholder=\"#RRGGBB\" mono lazy onBlur={() => /^#[0-9a-f]{6}$/i.test(hex) && onChange(hex)} onKeyDown={(e) => e.key === \"Enter\" && /^#[0-9a-f]{6}$/i.test(hex) && onChange(hex)} />\n {allowTransparent ? <Button size=\"sm\" onClick={() => onChange(\"\")}>None</Button> : null}\n </div>\n </div>\n );\n}\n\nexport function ColorField({ value, onChange, theme, allowTransparent, placeholder = \"Default\" }: { value: string | undefined; onChange: (v: string | undefined) => void; theme: Theme; allowTransparent?: boolean; placeholder?: string }) {\n const v = value ?? \"\";\n const resolved = v ? resolveValue(v, theme, \"transparent\") : \"transparent\";\n const label = !v ? placeholder : isTokenRef(v) ? listThemeTokens(theme).find((t) => t.token === v)?.label ?? v : v.toUpperCase();\n return (\n <Popover className=\"bpe-color-popover\" trigger={<button type=\"button\" className=\"bpe-color-btn\" aria-label={`Colour: ${label}`}><span className=\"bpe-color-btn__swatch\" style={{ [\"--c\" as string]: resolved }} /><span className=\"bpe-color-btn__label\">{label}</span></button>}>\n {(close) => (\n <ColorPicker\n value={v}\n theme={theme}\n allowTransparent={allowTransparent}\n onChange={(c) => {\n onChange(c || undefined);\n if (!c || isTokenRef(c) || /^#[0-9a-f]{6}$/i.test(c)) close();\n }}\n />\n )}\n </Popover>\n );\n}\n","import type { BlockRegistry, Node, ReportTemplate } from \"@broadpaper/core\";\nimport { indexTemplate, type RegionId } from \"@broadpaper/core\";\nimport type { DragState, DropTarget } from \"../state/session.js\";\n\nexport interface DropContext {\n template: ReportTemplate;\n registry: BlockRegistry;\n /** The scrolling canvas element. */\n canvas: HTMLElement;\n /** The element overlays are positioned relative to. */\n overlayOrigin: HTMLElement;\n}\n\ninterface ZoneInfo {\n el: HTMLElement;\n parentId: string | null;\n region: RegionId;\n parentType: string;\n}\n\nfunction regionOfElement(el: Element, first: boolean): RegionId {\n const region = el.closest<HTMLElement>(\"[data-region]\")?.getAttribute(\"data-region\") ?? \"body\";\n if (region === \"header\") return first ? \"header:first\" : \"header\";\n if (region === \"footer\") return first ? \"footer:first\" : \"footer\";\n return \"body\";\n}\n\nfunction dragType(drag: DragState): string {\n switch (drag.kind) {\n case \"new\":\n return String(drag.payload);\n case \"row\":\n return \"row\";\n case \"library\":\n return \"section\";\n case \"field\":\n return \"field\";\n case \"move\":\n return \"\";\n }\n}\n\n/**\n * Computes the drop target for the current pointer position. Pure with respect\n * to the editor state; reads the DOM for geometry only.\n */\nexport function computeDropTarget(x: number, y: number, drag: DragState, ctx: DropContext, pageFirst: (el: Element) => boolean): DropTarget | null {\n const doc = ctx.canvas.ownerDocument;\n const index = indexTemplate(ctx.template);\n const movingNode = drag.kind === \"move\" ? index.get(String(drag.payload))?.node : undefined;\n const type = movingNode ? movingNode.type : dragType(drag);\n if (drag.kind === \"library\") {\n const item = ctx.template.library?.find((l) => l.id === drag.payload);\n if (item) return sectionDrop(x, y, ctx, item.node.type === \"section\" ? \"section\" : item.node.type, pageFirst, index);\n }\n if (type === \"section\" || movingNode?.type === \"section\") return sectionDrop(x, y, ctx, \"section\", pageFirst, index, movingNode?.id);\n\n const stack = doc.elementsFromPoint(x, y);\n const originRect = ctx.overlayOrigin.getBoundingClientRect();\n const rel = (r: DOMRect) => ({ x: r.left - originRect.left, y: r.top - originRect.top, width: r.width, height: r.height });\n\n // Field drops onto text-like blocks insert a token.\n if (drag.kind === \"field\") {\n for (const el of stack) {\n const nodeEl = (el as HTMLElement).closest?.<HTMLElement>(\"[data-key][data-type='text'],[data-key][data-type='heading']\");\n if (nodeEl && ctx.canvas.contains(nodeEl)) {\n const r = rel(nodeEl.getBoundingClientRect());\n return { parentId: null, region: \"body\", index: 0, line: null, zone: r, valid: true, textTargetId: nodeEl.getAttribute(\"data-node\")! };\n }\n break;\n }\n }\n\n // Deepest dropzone under the pointer that accepts the dragged type.\n let zone: ZoneInfo | null = null;\n for (const el of stack) {\n const z = (el as HTMLElement).closest?.<HTMLElement>(\"[data-dropzone]\");\n if (!z || !ctx.canvas.contains(z)) continue;\n let cur: HTMLElement | null = z;\n while (cur) {\n const parentId = cur.getAttribute(\"data-dropzone\")!;\n const parentNode = index.get(parentId)?.node;\n const parentType = parentNode?.type ?? \"section\";\n const accepts = drag.kind === \"field\" ? ctx.registry.accepts(parentType, \"field\") : ctx.registry.accepts(parentType, type);\n const insideSelf = movingNode ? parentId === movingNode.id || isInside(index, movingNode.id, parentId) : false;\n if (accepts && !insideSelf && !parentNode?.locked) {\n zone = { el: cur, parentId, region: regionOfElement(cur, pageFirst(cur)), parentType };\n break;\n }\n cur = cur.parentElement?.closest<HTMLElement>(\"[data-dropzone]\") ?? null;\n }\n if (zone) break;\n }\n\n if (!zone) {\n // Over a page body but not over any dropzone — the margin beside a section,\n // or the gap between two. Falling back to the last section on the page put\n // blocks a long way from where they were dropped, so pick the section the\n // pointer is actually nearest to instead.\n const pageBody = stack.find((el) => (el as HTMLElement).classList?.contains(\"bp-page__body\")) as HTMLElement | undefined;\n if (!pageBody) return null;\n const region = regionOfElement(pageBody, pageFirst(pageBody));\n const sections = [...pageBody.querySelectorAll<HTMLElement>(\".bp-section [data-dropzone]\")].filter((el) => el.closest(\".bp-section\")?.parentElement?.closest(\".bp-section\") === null);\n let best: HTMLElement | undefined;\n let bestDistance = Infinity;\n for (const el of sections) {\n const r = el.getBoundingClientRect();\n const distance = y < r.top ? r.top - y : y > r.bottom ? y - r.bottom : 0;\n if (distance < bestDistance) {\n best = el;\n bestDistance = distance;\n if (distance === 0) break;\n }\n }\n if (!best) return null;\n zone = { el: best, parentId: best.getAttribute(\"data-dropzone\"), region, parentType: \"section\" };\n }\n\n const children = [...zone.el.children].filter((c) => c.matches(\"[data-node]\")) as HTMLElement[];\n const rects = children.map((c) => c.getBoundingClientRect());\n let insertIndex = children.length;\n for (let i = 0; i < rects.length; i++) {\n const r = rects[i]!;\n if (y < r.top + r.height / 2) {\n insertIndex = i;\n break;\n }\n }\n // Map DOM index to model index (design mode renders the same children in order).\n const parentNode = zone.parentId ? index.get(zone.parentId)?.node : undefined;\n const modelChildren = parentNode?.children ?? [];\n const domIds = children.map((c) => c.getAttribute(\"data-node\"));\n let modelIndex = modelChildren.length;\n if (insertIndex < children.length) {\n const targetId = domIds[insertIndex];\n const mi = modelChildren.findIndex((n) => n.id === targetId);\n modelIndex = mi >= 0 ? mi : modelChildren.length;\n }\n const zr = rel(zone.el.getBoundingClientRect());\n let lineY: number;\n if (rects.length === 0) lineY = zr.y + zr.height / 2;\n else if (insertIndex < rects.length) lineY = rel(rects[insertIndex]!).y - 3;\n else lineY = rel(rects[rects.length - 1]!).y + rects[rects.length - 1]!.height + 3;\n\n if (movingNode) {\n const entry = index.get(movingNode.id)!;\n const sameParent = (entry.parent?.id ?? null) === zone.parentId;\n if (sameParent && (modelIndex === entry.index || modelIndex === entry.index + 1)) {\n return { parentId: zone.parentId, region: zone.region, index: modelIndex, line: null, zone: null, valid: false };\n }\n }\n return { parentId: zone.parentId, region: zone.region, index: modelIndex, line: { x: zr.x + 2, y: lineY, width: Math.max(0, zr.width - 4) }, zone: rects.length === 0 ? zr : null, valid: true };\n}\n\nfunction isInside(index: ReturnType<typeof indexTemplate>, ancestorId: string, id: string): boolean {\n let cur = index.get(id);\n while (cur?.parent) {\n if (cur.parent.id === ancestorId) return true;\n cur = index.get(cur.parent.id);\n }\n return false;\n}\n\n/** Sections drop between other sections in the region under the pointer. */\nfunction sectionDrop(x: number, y: number, ctx: DropContext, _type: string, pageFirst: (el: Element) => boolean, index: ReturnType<typeof indexTemplate>, movingId?: string): DropTarget | null {\n const doc = ctx.canvas.ownerDocument;\n const stack = doc.elementsFromPoint(x, y);\n const pageBody = stack.find((el) => (el as HTMLElement).classList?.contains(\"bp-page__body\") || (el as HTMLElement).classList?.contains(\"bp-page__region\")) as HTMLElement | undefined;\n if (!pageBody) return null;\n const region = regionOfElement(pageBody, pageFirst(pageBody));\n const originRect = ctx.overlayOrigin.getBoundingClientRect();\n // Top-level section elements visible on this page (one per fragment).\n const sectionEls = [...pageBody.querySelectorAll<HTMLElement>(\".bp-section\")].filter((el) => !el.parentElement?.closest(\".bp-section\"));\n const list = region === \"body\" ? ctx.template.body : region.startsWith(\"header\") ? (region === \"header\" ? ctx.template.header.default : ctx.template.header.firstPage ?? []) : region === \"footer\" ? ctx.template.footer.default : ctx.template.footer.firstPage ?? [];\n let modelIndex = list.length;\n let lineY = 0;\n const bodyRect = pageBody.getBoundingClientRect();\n if (sectionEls.length === 0) {\n lineY = bodyRect.top - originRect.top + 8;\n modelIndex = 0;\n } else {\n let placed = false;\n for (const el of sectionEls) {\n const r = el.getBoundingClientRect();\n const frag = el.closest<HTMLElement>(\".bp-fragment\");\n const clipTop = frag ? frag.getBoundingClientRect().top : r.top;\n const visibleTop = Math.max(r.top, clipTop);\n const visibleBottom = frag ? Math.min(r.bottom, frag.getBoundingClientRect().bottom) : r.bottom;\n if (y < (visibleTop + visibleBottom) / 2) {\n const id = el.getAttribute(\"data-node\")!;\n modelIndex = Math.max(0, list.findIndex((n) => n.id === id));\n lineY = visibleTop - originRect.top - 2;\n placed = true;\n break;\n }\n }\n if (!placed) {\n const lastEl = sectionEls[sectionEls.length - 1]!;\n const frag = lastEl.closest<HTMLElement>(\".bp-fragment\");\n const bottom = frag ? Math.min(lastEl.getBoundingClientRect().bottom, frag.getBoundingClientRect().bottom) : lastEl.getBoundingClientRect().bottom;\n const id = lastEl.getAttribute(\"data-node\")!;\n const li = list.findIndex((n) => n.id === id);\n modelIndex = li >= 0 ? li + 1 : list.length;\n lineY = bottom - originRect.top + 2;\n }\n }\n if (movingId) {\n const entry = index.get(movingId);\n if (entry && entry.region === region && (modelIndex === entry.index || modelIndex === entry.index + 1)) return { parentId: null, region, index: modelIndex, line: null, zone: null, valid: false };\n }\n return { parentId: null, region, index: modelIndex, line: { x: bodyRect.left - originRect.left, y: lineY, width: bodyRect.width }, zone: null, valid: true };\n}\n\nexport function nodeForDrop(drag: DragState, ctx: { registry: BlockRegistry; template: ReportTemplate; createNode: (type: string, props?: Record<string, unknown>) => Node; createRow: (layout: number[]) => Node; cloneLibrary: (id: string) => Node | undefined }): Node | undefined {\n switch (drag.kind) {\n case \"new\":\n return ctx.createNode(String(drag.payload));\n case \"row\":\n return ctx.createRow(drag.payload as number[]);\n case \"library\":\n return ctx.cloneLibrary(String(drag.payload));\n case \"field\": {\n const p = drag.payload as { expr: string; label: string; type?: string };\n const isList = p.type === \"array\";\n if (isList) return ctx.createNode(\"table\", { source: p.expr });\n return ctx.createNode(\"field\", { label: p.label.split(\" › \").pop() ?? p.label, value: p.expr });\n }\n default:\n return undefined;\n }\n}\n\n/**\n * Where a click in the canvas would put a new block.\n *\n * This is the drop machinery asked a hypothetical question, so click-to-place\n * and drag-to-place can never disagree about what a position means. The type\n * used for the enquiry is a plain text block: it is accepted anywhere an\n * ordinary block is, which is what makes the answer a fair general one.\n */\nexport function computeInsertion(x: number, y: number, ctx: DropContext, pageFirst: (el: Element) => boolean): DropTarget | null {\n const target = computeDropTarget(x, y, { kind: \"new\", payload: \"text\", label: \"Text\", x, y }, ctx, pageFirst);\n return target && target.valid && target.line && !target.textTargetId ? target : null;\n}\n","import { ancestors } from \"@broadpaper/core\";\nimport { useSession, useEditorState, nodeLabel } from \"../state/context.js\";\nimport { Icon } from \"../ui/icons.js\";\n\nexport function Breadcrumb() {\n const session = useSession();\n const selection = useEditorState((s) => s.selection);\n const version = useEditorState((s) => s.version);\n void version;\n const id = selection[0];\n if (!id) return <div className=\"bpe-breadcrumb bpe-muted\">Select a block to edit it, or drag one in from the left.</div>;\n const chain = ancestors(session.store.index(), id);\n const regionEntry = chain[0];\n const regionLabel = regionEntry?.region === \"body\" ? \"Body\" : regionEntry?.region.startsWith(\"header\") ? \"Header\" : \"Footer\";\n return (\n <nav className=\"bpe-breadcrumb\" aria-label=\"Selection path\">\n <span className=\"bpe-breadcrumb__item bpe-muted\">{regionLabel}</span>\n {chain.map((e, i) => (\n <span key={e.node.id} style={{ display: \"contents\" }}>\n <Icon name=\"chevron-right\" size={11} className=\"bpe-breadcrumb__sep\" />\n <button type=\"button\" className={`bpe-breadcrumb__item ${i === chain.length - 1 ? \"bpe-breadcrumb__item--current\" : \"\"}`} onClick={() => session.store.select([e.node.id])}>\n <Icon name={session.registry.get(e.node.type)?.icon ?? \"box\"} size={11} />\n {nodeLabel(session, e.node)}\n </button>\n </span>\n ))}\n {selection.length > 1 ? <span className=\"bpe-badge bpe-badge--accent\">+{selection.length - 1} more</span> : null}\n </nav>\n );\n}\n","import { Popover } from \"../ui/floating.js\";\nimport { Icon } from \"../ui/icons.js\";\nimport { Button } from \"../ui/primitives.js\";\n\n/**\n * What the design canvas is actually showing.\n *\n * The canvas mixes four different things at once — data tokens that have not\n * been substituted, values that have, content a rule is currently hiding, and\n * tables cut down to a few rows for speed — and never says which is which. Put\n * on the canvas that would be four permanent captions competing with the report;\n * behind one button it is a page you read once and then stop needing.\n *\n * None of it is part of the document: every badge and outline is styled by the\n * editor and drawn only in design mode, so preview and the exported PDF never\n * see any of it.\n */\nexport function DesignLegend({ sampleLabel }: { sampleLabel: string }) {\n return (\n <Popover\n placement=\"top-end\"\n className=\"bpe-legend\"\n trigger={<Button size=\"sm\" variant=\"ghost\" icon=\"info\" tooltip=\"What am I looking at?\" aria-label=\"What am I looking at?\" />}\n >\n <div className=\"bpe-legend__body\">\n <h3 className=\"bpe-legend__title\">Reading the design view</h3>\n <p className=\"bpe-legend__intro\">\n This is the template, filled in from <strong>{sampleLabel}</strong> so you can see the shape of a real report. Switch to Preview for exactly what the PDF will contain.\n </p>\n <dl className=\"bpe-legend__list\">\n <Entry swatch={<span className=\"bp-token bpe-legend__token\">Client › Full name</span>} term=\"A blue chip is a data field\">\n It shows which field is bound there, not the value. In Preview it becomes the value.\n </Entry>\n <Entry swatch={<Icon name=\"git-branch\" size={14} />} term=\"A dashed outline is conditional\">\n Content shown or hidden by a rule. The badge says which way the rule falls for this sample; hidden content still prints for a client the rule matches.\n </Entry>\n <Entry swatch={<Icon name=\"table\" size={14} />} term=\"Tables and repeaters are shortened\">\n The badge says how many of the sample's rows are drawn. Totals are always calculated over the whole list, not the visible rows.\n </Entry>\n <Entry swatch={<Icon name=\"pencil\" size={14} />} term=\"Text is edited in place\">\n Select a block and use <strong>Edit text</strong>, or double-click it. Drag a field from the Data panel to drop a token into a sentence.\n </Entry>\n </dl>\n <p className=\"bpe-legend__foot\">None of these markings exist in the exported document.</p>\n </div>\n </Popover>\n );\n}\n\nfunction Entry({ swatch, term, children }: { swatch: React.ReactNode; term: string; children: React.ReactNode }) {\n return (\n <div className=\"bpe-legend__entry\">\n <div className=\"bpe-legend__swatch\">{swatch}</div>\n <div>\n <dt>{term}</dt>\n <dd>{children}</dd>\n </div>\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { ROW_LAYOUTS, itemSchemaOf, createSchemaScope, ancestors, type FieldSchema, type Node, type NodeEntry } from \"@broadpaper/core\";\nimport { useSession, useFeatures, nodeLabel } from \"../state/context.js\";\nimport type { EditorActions } from \"../state/actions.js\";\nimport { FieldRenderer, getPath, type FieldContext } from \"./fields/FieldRenderer.js\";\nimport { StyleGroups } from \"./StyleGroups.js\";\nimport { ConditionBuilder } from \"./fields/ConditionBuilder.js\";\nimport { Section, Field, TextInput, Switch, Button, Badge, Segmented } from \"../ui/primitives.js\";\nimport { Icon } from \"../ui/icons.js\";\n\n/** Scope variables visible to a node: repeater/table aliases from its ancestors. */\nexport function scopeVarsFor(entry: NodeEntry, session: ReturnType<typeof useSession>): Record<string, FieldSchema> | undefined {\n const chain = ancestors(session.store.index(), entry.node.id);\n const root = createSchemaScope(session.dataSources);\n let vars: Record<string, FieldSchema> = {};\n let scope = root;\n for (const e of chain) {\n const def = session.registry.get(e.node.type);\n const repeat = def?.container?.repeat;\n const isSelf = e.node.id === entry.node.id;\n // Table/chart aliases apply to the node itself; repeater aliases apply to descendants.\n const bindingsWithAlias = session.registry.bindingsOf(e.node.type).filter((b) => b.kind === \"collection\");\n for (const b of bindingsWithAlias) {\n const appliesHere = repeat ? !isSelf : isSelf;\n if (!appliesHere) continue;\n const props = { ...(typeof def!.defaultProps === \"function\" ? def!.defaultProps() : def!.defaultProps), ...e.node.props } as Record<string, unknown>;\n const expr = props[b.prop];\n const alias = (b.alias && (props[b.alias] as string)) || \"item\";\n const item = typeof expr === \"string\" && expr.trim() ? itemSchemaOf(expr, scope) : undefined;\n const itemSchema = item ?? { type: \"object\" as const, label: alias, fields: {} };\n vars = { ...vars, [alias]: { ...itemSchema, label: alias }, index: { type: \"number\", label: \"Index\" }, first: { type: \"boolean\", label: \"Is first\" }, last: { type: \"boolean\", label: \"Is last\" }, count: { type: \"number\", label: \"Count\" } };\n if (!repeat) vars = { ...vars, row: { ...itemSchema, label: \"row\" } };\n scope = scope.child(vars);\n }\n }\n return Object.keys(vars).length ? vars : undefined;\n}\n\nexport function NodeInspector({ entry, actions }: { entry: NodeEntry; actions: EditorActions }) {\n const session = useSession();\n const features = useFeatures();\n const node = entry.node;\n const def = session.registry.get(node.type);\n const theme = session.activeTheme;\n const textStyles = Object.keys(session.store.template.styles.text);\n const scopeVars = useMemo(() => scopeVarsFor(entry, session), [entry, session]);\n const props = useMemo(() => ({ ...(def ? (typeof def.defaultProps === \"function\" ? def.defaultProps() : def.defaultProps) : {}), ...node.props }) as Record<string, unknown>, [def, node.props]);\n\n const setProp = (path: string, value: unknown, label = \"Edit properties\") => session.store.dispatch({ type: \"setProp\", id: node.id, path, value }, { label, mergeKey: `prop:${node.id}:${path}` });\n const ctx: FieldContext = {\n dataSources: session.dataSources,\n scopeVars,\n theme,\n textStyles,\n node,\n props,\n setProps: (patch) => session.store.dispatch({ type: \"setProps\", id: node.id, patch }),\n allowExpressions: features.expressions\n };\n\n const label = nodeLabel(session, node);\n const issues = session.ui.get().issues.filter((i) => i.nodeId === node.id);\n\n return (\n <>\n <div className=\"bpe-inspector__header\">\n <span className=\"bpe-inspector__icon\"><Icon name={def?.icon ?? \"box\"} /></span>\n <div style={{ minWidth: 0 }}>\n <div className=\"bpe-inspector__title\" title={label}>{label}</div>\n <div className=\"bpe-inspector__subtitle\">{def?.name ?? node.type}{def?.license && def.license !== \"community\" ? ` · ${def.license}` : \"\"}</div>\n </div>\n <div className=\"bpe-inspector__actions\">\n <Button size=\"sm\" variant=\"ghost\" icon={node.locked ? \"lock\" : \"unlock\"} tooltip={node.locked ? \"Unlock\" : \"Lock\"} onClick={() => actions.toggleLock()} />\n {node.type !== \"column\" ? <Button size=\"sm\" variant=\"ghost\" icon=\"trash\" tooltip=\"Delete\" onClick={() => actions.deleteSelection()} disabled={!!node.locked} /> : null}\n </div>\n </div>\n <div className=\"bpe-inspector__body\">\n {issues.length ? (\n <div style={{ padding: \"8px 12px 0\" }}>\n {issues.map((i, k) => (\n <div key={k} className={`bpe-issue bpe-issue--${i.severity}`} style={{ padding: \"4px 0\" }}>\n <Icon name={i.severity === \"error\" ? \"alert-circle\" : i.severity === \"warning\" ? \"alert-triangle\" : \"info\"} />\n <span>{i.message}</span>\n </div>\n ))}\n </div>\n ) : null}\n {!def ? <div className=\"bpe-empty\"><Icon name=\"alert-triangle\" /><div className=\"bpe-empty__title\">Unknown block “{node.type}”</div>This block is not registered in this editor. Its settings are preserved.</div> : null}\n\n {node.type === \"row\" ? (\n <Section title=\"Layout\">\n <div className=\"bpe-prop-grid\">\n <Field label=\"Columns\" stacked>\n <div className=\"bpe-layouts__grid\" style={{ width: \"100%\" }}>\n {ROW_LAYOUTS.map((l) => (\n <button key={l.id} type=\"button\" className=\"bpe-layout-item\" aria-pressed={JSON.stringify(l.layout) === JSON.stringify(node.props.layout)} style={JSON.stringify(l.layout) === JSON.stringify(node.props.layout) ? { borderColor: \"var(--bpe-accent)\", background: \"var(--bpe-accent-soft)\" } : undefined} onClick={() => session.store.dispatch({ type: \"setRowLayout\", id: node.id, layout: l.layout })}>\n <div className=\"bpe-layout-item__cols\" style={{ gridTemplateColumns: l.layout.map((c) => `${c}fr`).join(\" \") }}>\n {l.layout.map((_, i) => <div key={i} className=\"bpe-layout-item__col\" />)}\n </div>\n <span className=\"bpe-layout-item__name\">{l.label}</span>\n </button>\n ))}\n </div>\n </Field>\n </div>\n </Section>\n ) : null}\n\n {node.type === \"column\" ? (\n <Section title=\"Column\">\n <div className=\"bpe-prop-grid\">\n <Field label=\"Width\" hint=\"Twelfths of the row. Change the row layout to resize columns.\">\n <Badge>{String(node.props.span)} / 12</Badge>\n </Field>\n <Field label=\"Row\"><Button size=\"sm\" onClick={() => actions.selectParent()}>Select row</Button></Field>\n </div>\n </Section>\n ) : null}\n\n {(def?.inspector ?? []).map((section, si) => {\n if (section.when && !section.when(props)) return null;\n const fields = section.fields.filter((f) => !f.when || f.when(props));\n if (!fields.length) return null;\n return (\n <Section key={si} title={section.title} defaultOpen={!section.collapsed}>\n <div className=\"bpe-prop-grid\">\n {fields.map((f) => (\n <FieldRenderer key={f.prop} field={f} value={getPath(props, f.prop)} onChange={(v) => setProp(f.prop, v)} ctx={ctx} />\n ))}\n </div>\n </Section>\n );\n })}\n\n {def ? (\n <StyleGroups\n node={node}\n groups={def.styleGroups ?? [\"spacing\", \"flow\"]}\n theme={theme}\n textStyles={textStyles}\n allowOverrides={features.styleOverrides}\n setStyle={(patch) => session.store.dispatch({ type: \"setStyle\", id: node.id, patch }, { label: \"Edit style\", mergeKey: `style:${node.id}` })}\n setFlow={(patch) => session.store.dispatch({ type: \"setFlow\", id: node.id, patch }, { label: \"Edit page flow\" })}\n />\n ) : null}\n\n {node.type !== \"column\" ? (\n <Section title=\"Visibility\" defaultOpen={!!node.visibleWhen} icon=\"eye\">\n <div className=\"bpe-prop-grid\">\n <Field label=\"Show when\" stacked hint=\"Leave empty to always show this block.\">\n <ConditionBuilder value={node.visibleWhen} onChange={(v) => session.store.dispatch({ type: \"setVisibleWhen\", id: node.id, condition: v }, { label: \"Edit visibility\" })} dataSources={session.dataSources} scopeVars={scopeVars} allowExpression={features.expressions} />\n </Field>\n </div>\n </Section>\n ) : null}\n\n <Section title=\"Advanced\" defaultOpen={false} icon=\"settings\">\n <div className=\"bpe-prop-grid\">\n <Field label=\"Name\" hint=\"Shown in the layers panel and breadcrumb.\">\n <TextInput value={node.name ?? \"\"} onChange={(v) => session.store.dispatch({ type: \"setName\", id: node.id, name: v || undefined })} lazy placeholder={def?.name} />\n </Field>\n <Field label=\"Locked\"><Switch checked={!!node.locked} onChange={(v) => session.store.dispatch({ type: \"setLocked\", id: node.id, locked: v })} /></Field>\n <Field label=\"ID\"><code className=\"bpe-mono bpe-muted\" style={{ fontSize: 10 }}>{node.id}</code></Field>\n <Field label=\"Type\"><code className=\"bpe-mono bpe-muted\" style={{ fontSize: 10 }}>{node.type}</code></Field>\n {node.type !== \"section\" && node.type !== \"column\" ? (\n <Field label=\"Wrap in\">\n <Segmented value=\"\" onChange={(v) => actions.wrapSelectionIn(v as never)} options={[{ value: \"card\", label: \"Card\" }, { value: \"keepTogether\", label: \"Keep\" }, { value: \"conditional\", label: \"If\" }]} />\n </Field>\n ) : null}\n </div>\n </Section>\n </div>\n </>\n );\n}\n\nexport type { Node };\n","import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { checkExpressionSyntax, createSchemaScope, textStyleLabel, type DataSource, type FieldSchema, type InspectorField, type InspectorApi, type Node, type Theme, type RichTextDoc, richTextToPlain, richTextFromTemplate, isRichTextDoc } from \"@broadpaper/core\";\nimport { Field, NumberInput, Segmented, Select, Switch, TextArea, TextInput, Button } from \"../../ui/primitives.js\";\nimport { Popover } from \"../../ui/floating.js\";\nimport { ColorField } from \"./ColorField.js\";\nimport { BindingField } from \"./BindingField.js\";\nimport { ImageField } from \"./ImageField.js\";\nimport { ConditionBuilder } from \"./ConditionBuilder.js\";\nimport { ColumnsEditor, SeriesEditor, KeyValuesEditor, SubFormList, type ColumnItem, type SeriesItem, type KeyValueItem } from \"./ListEditors.js\";\nimport { DataPicker } from \"../DataPicker.js\";\nimport { useSession } from \"../../state/context.js\";\n\nexport interface FieldContext {\n dataSources: DataSource[];\n scopeVars?: Record<string, FieldSchema>;\n theme: Theme;\n textStyles: string[];\n node: Node;\n props: Record<string, unknown>;\n setProps: (patch: Record<string, unknown>) => void;\n allowExpressions: boolean;\n}\n\nfunction getPath(obj: Record<string, unknown>, path: string): unknown {\n let cur: unknown = obj;\n for (const p of path.split(\".\")) {\n if (cur === null || cur === undefined || typeof cur !== \"object\") return undefined;\n cur = (cur as Record<string, unknown>)[p];\n }\n return cur;\n}\n\nconst COMMON_FONTS = [\"Inter\", \"Roboto\", \"Open Sans\", \"Lato\", \"Source Sans 3\", \"Helvetica Neue\", \"Arial\", \"Georgia\", \"Times New Roman\", \"Merriweather\", \"Playfair Display\", \"Courier New\", \"JetBrains Mono\"];\n\n/** Renders one inspector field. Values flow through `setValue`; every change is one store command. */\nexport function FieldRenderer({ field, value, onChange, ctx }: { field: InspectorField; value: unknown; onChange: (v: unknown) => void; ctx: FieldContext }) {\n const description = typeof field.description === \"function\" ? field.description(ctx.props) : field.description;\n const wrap = (control: ReactNode, opts: { stacked?: boolean; hint?: ReactNode; error?: ReactNode } = {}) => (\n <Field label={field.label} stacked={opts.stacked ?? field.fullWidth} hint={opts.hint ?? description} error={opts.error}>\n {control}\n </Field>\n );\n const str = typeof value === \"string\" ? value : value === undefined || value === null ? \"\" : String(value);\n\n switch (field.kind) {\n case \"text\": {\n const tokens = field.allowTokens !== false && ctx.allowExpressions;\n return wrap(\n <div className=\"bpe-binding\">\n <TextInput value={str} onChange={(v) => onChange(v)} lazy placeholder={field.placeholder} />\n {tokens ? (\n <Popover className=\"bpe-picker\" trigger={<Button size=\"sm\" variant=\"ghost\" icon=\"braces\" tooltip=\"Insert field\" />}>\n {(close) => (\n <DataPicker dataSources={ctx.dataSources} scopeVars={ctx.scopeVars} onPick={(expr) => { onChange(`${str}${str && !str.endsWith(\" \") ? \" \" : \"\"}{{ ${expr} }}`); close(); }} />\n )}\n </Popover>\n ) : null}\n </div>\n );\n }\n case \"textarea\":\n return wrap(<TextArea value={str} rows={field.rows ?? 3} placeholder={field.placeholder} onChange={(e) => onChange(e.target.value)} />, { stacked: true });\n case \"richtext\": {\n const doc: RichTextDoc = isRichTextDoc(value) ? value : richTextFromTemplate(str);\n const plain = richTextToPlain(doc);\n return wrap(\n <TextArea value={plain} rows={4} onChange={(e) => onChange(richTextFromTemplate(e.target.value))} placeholder=\"Type text, use {{ field }} for data. Double-click the block on the canvas for rich formatting.\" />,\n { stacked: true, hint: \"Double-click the block on the canvas for formatting, lists and links.\" }\n );\n }\n case \"number\":\n return wrap(<NumberInput value={typeof value === \"number\" ? value : null} onChange={(v) => onChange(v)} min={field.min} max={field.max} step={field.step} unit={field.unit} placeholder=\"auto\" />);\n case \"toggle\":\n return wrap(<Switch checked={!!value} onChange={(v) => onChange(v)} label={field.label} />);\n case \"select\": {\n const options = field.optionsFrom ? field.optionsFrom(ctx.props) : field.options ?? [];\n return wrap(<Select value={str} onChange={(v) => onChange(coerce(v, options))} options={options.map((o) => ({ value: String(o.value), label: o.label }))} />);\n }\n case \"segmented\":\n return wrap(<Segmented value={str} onChange={(v) => onChange(coerce(v, field.options))} options={field.options.map((o) => ({ value: String(o.value), label: o.label, icon: o.icon }))} iconOnly={field.options.every((o) => !!o.icon) && field.options.length > 3} ariaLabel={field.label} />);\n case \"color\":\n return wrap(<ColorField value={str || undefined} onChange={(v) => onChange(v ?? \"\")} theme={ctx.theme} allowTransparent={field.allowTransparent} />);\n case \"font\":\n return wrap(<FontSelect value={str} onChange={onChange} theme={ctx.theme} />);\n case \"textStyle\":\n return wrap(<Select value={str} onChange={(v) => onChange(v || undefined)} placeholder=\"Default\" options={ctx.textStyles.map((s) => ({ value: s, label: textStyleLabel(s) }))} />);\n case \"binding\":\n return wrap(<BindingField value={str} onChange={(v) => onChange(v)} dataSources={ctx.dataSources} scopeVars={ctx.scopeVars} types={field.valueType ? (Array.isArray(field.valueType) ? field.valueType : [field.valueType]) : undefined} placeholder={field.placeholder} allowExpression={ctx.allowExpressions} />);\n case \"collection\":\n return wrap(<BindingField value={str} onChange={(v) => onChange(v)} dataSources={ctx.dataSources} scopeVars={ctx.scopeVars} arraysOnly placeholder={field.placeholder} allowExpression={ctx.allowExpressions} />);\n case \"expression\": {\n const err = str.trim() ? checkExpressionSyntax(str) : null;\n return wrap(\n <div className=\"bpe-binding\">\n <TextInput value={str} onChange={(v) => onChange(v)} lazy mono placeholder={field.placeholder} invalid={!!err} />\n <Popover className=\"bpe-picker\" trigger={<Button size=\"sm\" variant=\"ghost\" icon=\"braces\" tooltip=\"Pick field\" />}>\n {(close) => <DataPicker dataSources={ctx.dataSources} scopeVars={ctx.scopeVars} value={str} onPick={(expr) => { onChange(expr); close(); }} />}\n </Popover>\n </div>,\n { error: err?.message }\n );\n }\n case \"image\":\n return (\n <ImageFieldRow\n field={field}\n value={str}\n onChange={onChange}\n ctx={ctx}\n render={(control, error) => wrap(control, { error })}\n />\n );\n case \"condition\":\n return wrap(<ConditionBuilder value={value as never} onChange={(v) => onChange(v ?? \"\")} dataSources={ctx.dataSources} scopeVars={ctx.scopeVars} allowExpression={ctx.allowExpressions} />, { stacked: true });\n case \"columns\":\n return wrap(<ColumnsEditor value={(Array.isArray(value) ? value : []) as ColumnItem[]} onChange={onChange} dataSources={ctx.dataSources} scopeVars={ctx.scopeVars} />, { stacked: true });\n case \"series\":\n return wrap(<SeriesEditor value={(Array.isArray(value) ? value : []) as SeriesItem[]} onChange={onChange} dataSources={ctx.dataSources} scopeVars={ctx.scopeVars} renderColor={(v, set) => <ColorField value={v} onChange={set} theme={ctx.theme} placeholder=\"Palette\" />} />, { stacked: true });\n case \"keyValues\":\n return wrap(<KeyValuesEditor value={(Array.isArray(value) ? value : []) as KeyValueItem[]} onChange={onChange} dataSources={ctx.dataSources} scopeVars={ctx.scopeVars} />, { stacked: true });\n case \"list\":\n return wrap(\n <SubFormList\n value={(Array.isArray(value) ? value : []) as Array<Record<string, unknown>>}\n onChange={onChange}\n fields={field.fields}\n itemLabel={field.itemLabel}\n summary={field.itemSummary ? (item, i) => field.itemSummary!(item, i, ctx.props) : undefined}\n renderField={(f, v, set) => <FieldRenderer field={f} value={v} onChange={set} ctx={ctx} />}\n />,\n { stacked: true }\n );\n case \"custom\":\n return wrap(<CustomFieldHost field={field} value={value} onChange={onChange} ctx={ctx} />, { stacked: true });\n }\n}\n\nfunction coerce(v: string, options: Array<{ value: string | number | boolean }>): unknown {\n const match = options.find((o) => String(o.value) === v);\n return match ? match.value : v;\n}\n\nfunction FontSelect({ value, onChange, theme }: { value: string; onChange: (v: string) => void; theme: Theme }) {\n const themeFonts = [\n { value: \"$typography.headingFont\", label: `Heading font (${theme.typography.headingFont.split(\",\")[0]})` },\n { value: \"$typography.bodyFont\", label: `Body font (${theme.typography.bodyFont.split(\",\")[0]})` },\n ...(theme.typography.monoFont ? [{ value: \"$typography.monoFont\", label: \"Mono font\" }] : [])\n ];\n const fonts = [...(theme.fonts ?? []).map((f) => f.family), ...COMMON_FONTS].filter((f, i, a) => a.indexOf(f) === i);\n return <Select value={value} onChange={onChange} placeholder=\"Default\" options={[...themeFonts, ...fonts.map((f) => ({ value: f, label: f }))]} />;\n}\n\nfunction CustomFieldHost({ field, value, onChange, ctx }: { field: Extract<InspectorField, { kind: \"custom\" }>; value: unknown; onChange: (v: unknown) => void; ctx: FieldContext }) {\n const session = useSession();\n const ref = useRef<HTMLDivElement>(null);\n const mounted = useRef(false);\n const api = (): InspectorApi => ({\n value,\n props: ctx.props,\n node: ctx.node,\n setValue: onChange,\n setProps: ctx.setProps,\n dataSources: ctx.dataSources,\n schemaScope: createSchemaScope(ctx.dataSources).child(ctx.scopeVars ?? {}),\n theme: ctx.theme\n });\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n if (!mounted.current) {\n field.component.mount(el, api());\n mounted.current = true;\n } else field.component.update?.(api());\n });\n useEffect(() => {\n const el = ref.current;\n return () => {\n if (el && mounted.current) field.component.unmount?.(el);\n mounted.current = false;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [field.component, session]);\n return <div ref={ref} style={{ width: \"100%\" }} />;\n}\n\n/**\n * The image field needs somewhere to keep the last upload failure, and a hook\n * cannot live inside the switch above. It exists only to own that one piece of\n * state and hand it back to the same `wrap` every other field is rendered by,\n * so a rejected file reads like any other invalid value rather than an alert.\n */\nfunction ImageFieldRow({\n field,\n value,\n onChange,\n ctx,\n render\n}: {\n field: Extract<InspectorField, { kind: \"image\" }>;\n value: string;\n onChange: (v: unknown) => void;\n ctx: FieldContext;\n render: (control: ReactNode, error: ReactNode) => ReactNode;\n}) {\n const [error, setError] = useState<string | null>(null);\n return render(\n <ImageField\n value={value}\n onChange={(v) => {\n setError(null);\n onChange(v);\n }}\n allowBinding={field.allowBinding !== false}\n dataSources={ctx.dataSources}\n scopeVars={ctx.scopeVars}\n onError={setError}\n />,\n error\n );\n}\n\nexport { getPath };\n","import { useMemo } from \"react\";\nimport { createSchemaScope, typeCheck, parseExpression, labelForPath, type DataSource, type FieldSchema, type FieldType } from \"@broadpaper/core\";\nimport { Popover } from \"../../ui/floating.js\";\nimport { Button } from \"../../ui/primitives.js\";\nimport { Icon } from \"../../ui/icons.js\";\nimport { DataPicker } from \"../DataPicker.js\";\n\nexport function useExpressionLabel(dataSources: DataSource[], scopeVars: Record<string, FieldSchema> | undefined) {\n return useMemo(() => {\n const scope = createSchemaScope(dataSources).child(scopeVars ?? {});\n return (expr: string): { label: string; error: string | null } => {\n if (!expr.trim()) return { label: \"\", error: null };\n const r = typeCheck(expr, scope);\n const error = r.issues[0]?.message ?? null;\n try {\n const ast = parseExpression(expr);\n if (ast.kind === \"path\") return { label: labelForPath(ast.segments, scope), error };\n if (ast.kind === \"pipe\" && ast.input.kind === \"path\") return { label: `${labelForPath(ast.input.segments, scope)} · ${ast.name}`, error };\n } catch {\n /* fall through */\n }\n return { label: expr, error };\n };\n }, [dataSources, scopeVars]);\n}\n\nexport interface BindingFieldProps {\n value: string;\n onChange: (expr: string) => void;\n dataSources: DataSource[];\n scopeVars?: Record<string, FieldSchema>;\n arraysOnly?: boolean;\n types?: FieldType[];\n placeholder?: string;\n allowExpression?: boolean;\n}\n\n/** A button that opens the data picker; shows the human label of the current binding. */\nexport function BindingField({ value, onChange, dataSources, scopeVars, arraysOnly, types, placeholder, allowExpression = true }: BindingFieldProps) {\n const describe = useExpressionLabel(dataSources, scopeVars);\n const { label, error } = describe(value);\n return (\n <div className=\"bpe-binding\">\n <Popover\n className=\"bpe-picker\"\n trigger={\n <button type=\"button\" className={`bpe-binding__btn ${value ? \"\" : \"bpe-binding__btn--empty\"} ${error ? \"bpe-input--invalid\" : \"\"}`} title={error ?? value}>\n <Icon name={error ? \"alert-triangle\" : arraysOnly ? \"list-tree\" : \"braces\"} style={error ? { color: \"var(--bpe-danger)\" } : undefined} />\n <span className=\"bpe-truncate\">{value ? label : placeholder ?? (arraysOnly ? \"Choose a list\" : \"Choose a field\")}</span>\n </button>\n }\n >\n {(close) => (\n <DataPicker\n dataSources={dataSources}\n scopeVars={scopeVars}\n arraysOnly={arraysOnly}\n types={types}\n value={value}\n allowExpression={allowExpression}\n onPick={(expr) => {\n onChange(expr);\n close();\n }}\n onClear={() => {\n onChange(\"\");\n close();\n }}\n />\n )}\n </Popover>\n {value ? <Button size=\"sm\" variant=\"ghost\" icon=\"x\" tooltip=\"Clear\" onClick={() => onChange(\"\")} /> : null}\n </div>\n );\n}\n","import { useRef, useState } from \"react\";\nimport { isSafeUrl, type DataSource, type FieldSchema, type FieldType } from \"@broadpaper/core\";\nimport { Button, TextInput } from \"../../ui/primitives.js\";\nimport { Popover } from \"../../ui/floating.js\";\nimport { DataPicker } from \"../DataPicker.js\";\nimport { BindingField } from \"./BindingField.js\";\nimport { useOptions } from \"../../state/context.js\";\n\n/**\n * How large a file may be before the built-in reader refuses it.\n *\n * A `data:` URL is not stored somewhere and referenced — it *is* the value, so\n * it is copied into every save, every export and every render request for the\n * life of the template, and base64 adds a third again on top. A megabyte is\n * generous for the things this path is for (a logo, a signature, a letterhead\n * rule) and small enough that a template full of them is still a document\n * rather than an archive. Hosts that need more supply `onUploadImage` and put\n * the file somewhere of their own.\n */\nexport const MAX_INLINE_IMAGE_BYTES = 1_000_000;\n\n/** The formats `isSafeUrl` will accept back as a data URL, so nothing else is worth offering. */\nconst ACCEPT = \"image/png,image/jpeg,image/gif,image/webp,image/svg+xml\";\n\nconst BINDABLE: FieldType[] = [\"image\", \"url\", \"string\"];\n\nfunction readAsDataUrl(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onerror = () => reject(new Error(\"The file could not be read.\"));\n reader.onload = () => resolve(String(reader.result ?? \"\"));\n reader.readAsDataURL(file);\n });\n}\n\nfunction describeSize(bytes: number): string {\n return bytes >= 1_000_000 ? `${(bytes / 1_000_000).toFixed(1)} MB` : `${Math.max(1, Math.round(bytes / 1000))} KB`;\n}\n\n/**\n * The `image` inspector field: an address, a picker to bind it to data, and a\n * way to put a file there.\n *\n * The upload is deliberately not a separate mode. Whatever route the value\n * arrived by it is still just a URL in the template, which is what keeps the\n * renderers, the validator and the PDF backends from needing to know that\n * uploading exists at all.\n */\nexport function ImageField({\n value,\n onChange,\n allowBinding,\n dataSources,\n scopeVars,\n onError\n}: {\n value: string;\n onChange: (v: string) => void;\n allowBinding: boolean;\n dataSources: DataSource[];\n scopeVars?: Record<string, FieldSchema>;\n onError: (message: string | null) => void;\n}) {\n const options = useOptions();\n const fileRef = useRef<HTMLInputElement>(null);\n const [busy, setBusy] = useState(false);\n const bound = /^\\{\\{[\\s\\S]*\\}\\}$/.test(value.trim());\n\n async function accept(file: File) {\n onError(null);\n setBusy(true);\n try {\n const upload = options.onUploadImage;\n if (upload) {\n const url = await upload(file);\n if (url) onChange(url);\n return;\n }\n if (file.size > MAX_INLINE_IMAGE_BYTES) {\n onError(\n `${describeSize(file.size)} is too large to store in the template. Use an image under ${describeSize(MAX_INLINE_IMAGE_BYTES)}, or link to one by address.`\n );\n return;\n }\n const url = await readAsDataUrl(file);\n // The same check the renderers and the validator apply, run here so the\n // refusal arrives while the file picker is still in mind rather than as\n // a blank space in the PDF. It is what rejects an SVG carrying a script.\n if (!isSafeUrl(url, { allowData: true })) {\n onError(\"That file cannot be used: it is not an image this designer accepts, or it contains scripting.\");\n return;\n }\n onChange(url);\n } catch (err) {\n onError(err instanceof Error && err.message ? err.message : \"The image could not be uploaded.\");\n } finally {\n setBusy(false);\n // Cleared so choosing the same file twice in a row still fires a change.\n if (fileRef.current) fileRef.current.value = \"\";\n }\n }\n\n return (\n <div className=\"bpe-binding bpe-image\">\n {bound ? (\n <BindingField\n value={value.replace(/^\\{\\{\\s*|\\s*\\}\\}$/g, \"\")}\n onChange={(v) => onChange(v ? `{{ ${v} }}` : \"\")}\n dataSources={dataSources}\n scopeVars={scopeVars}\n types={BINDABLE}\n />\n ) : (\n <TextInput value={value} onChange={onChange} lazy placeholder=\"https://… or upload\" />\n )}\n\n {/* Not rendered by the Button: a file input is the only way to open the\n picker, and a visually hidden one keeps the keyboard path intact. */}\n <input\n ref={fileRef}\n type=\"file\"\n accept={ACCEPT}\n className=\"bpe-image__file\"\n tabIndex={-1}\n aria-hidden=\"true\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n if (file) void accept(file);\n }}\n />\n {!bound ? (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n icon=\"upload\"\n disabled={busy}\n tooltip={options.onUploadImage ? \"Upload an image\" : \"Upload an image (stored in the template)\"}\n onClick={() => fileRef.current?.click()}\n />\n ) : null}\n\n {allowBinding ? (\n <Popover className=\"bpe-picker\" trigger={<Button size=\"sm\" variant=\"ghost\" icon=\"braces\" tooltip=\"Bind to a field\" />}>\n {(close) => (\n <DataPicker\n dataSources={dataSources}\n scopeVars={scopeVars}\n types={BINDABLE}\n onPick={(expr) => {\n onChange(`{{ ${expr} }}`);\n close();\n }}\n />\n )}\n </Popover>\n ) : null}\n </div>\n );\n}\n","import { CONDITION_OPERATORS, compileCondition, checkExpressionSyntax, type Condition, type ConditionGroup, type ConditionRule, type DataSource, type FieldSchema } from \"@broadpaper/core\";\nimport { Button, Segmented, Select, TextInput } from \"../../ui/primitives.js\";\nimport { BindingField } from \"./BindingField.js\";\nimport { useState } from \"react\";\n\ninterface Props {\n value: Condition | undefined;\n onChange: (value: Condition | undefined) => void;\n dataSources: DataSource[];\n scopeVars?: Record<string, FieldSchema>;\n allowExpression?: boolean;\n}\n\nfunction isGroup(v: Condition | undefined): v is ConditionGroup {\n return !!v && typeof v === \"object\" && \"op\" in v;\n}\n\n/** Visual AND/OR rule builder that compiles to the expression language. */\nexport function ConditionBuilder({ value, onChange, dataSources, scopeVars, allowExpression = true }: Props) {\n const [advanced, setAdvanced] = useState(typeof value === \"string\" && value.trim() !== \"\");\n const group: ConditionGroup = isGroup(value) ? value : { op: \"and\", rules: [] };\n const compiled = compileCondition(value);\n\n if (advanced) {\n const src = typeof value === \"string\" ? value : compiled ?? \"\";\n const err = src.trim() ? checkExpressionSyntax(src) : null;\n return (\n <div className=\"bpe-cond\">\n <TextInput value={src} onChange={(v) => onChange(v.trim() ? v : undefined)} mono lazy placeholder=\"e.g. client.riskScore > 7 and client.isRetired\" invalid={!!err} />\n {err ? <div className=\"bpe-field__error\">{err.message}</div> : null}\n <div style={{ display: \"flex\", gap: 6 }}>\n <Button size=\"sm\" onClick={() => { setAdvanced(false); onChange({ op: \"and\", rules: [] }); }}>Use rule builder</Button>\n {value ? <Button size=\"sm\" variant=\"ghost\" icon=\"x\" onClick={() => onChange(undefined)}>Clear</Button> : null}\n </div>\n </div>\n );\n }\n\n const update = (g: ConditionGroup) => onChange(g.rules.length ? g : undefined);\n return (\n <div className=\"bpe-cond\">\n <GroupEditor group={group} onChange={update} dataSources={dataSources} scopeVars={scopeVars} depth={0} />\n <div style={{ display: \"flex\", gap: 6, alignItems: \"center\", flexWrap: \"wrap\" }}>\n <Button size=\"sm\" icon=\"plus\" onClick={() => update({ ...group, rules: [...group.rules, { left: \"\", operator: \"eq\", right: \"\" }] })}>Rule</Button>\n <Button size=\"sm\" icon=\"plus\" onClick={() => update({ ...group, rules: [...group.rules, { op: \"or\", rules: [{ left: \"\", operator: \"eq\", right: \"\" }] }] })}>Group</Button>\n {allowExpression ? <Button size=\"sm\" variant=\"ghost\" icon=\"braces\" onClick={() => setAdvanced(true)}>Expression</Button> : null}\n </div>\n {compiled ? <div className=\"bpe-field__hint bpe-mono\" title={compiled}>{compiled}</div> : <div className=\"bpe-field__hint\">Always shown</div>}\n </div>\n );\n}\n\nfunction GroupEditor({ group, onChange, dataSources, scopeVars, depth }: { group: ConditionGroup; onChange: (g: ConditionGroup) => void; dataSources: DataSource[]; scopeVars?: Record<string, FieldSchema>; depth: number }) {\n const setRule = (i: number, r: ConditionRule | ConditionGroup) => onChange({ ...group, rules: group.rules.map((x, j) => (j === i ? r : x)) });\n const remove = (i: number) => onChange({ ...group, rules: group.rules.filter((_, j) => j !== i) });\n return (\n <div className={depth > 0 ? \"bpe-cond__group\" : undefined}>\n {group.rules.length > 1 ? (\n <div className=\"bpe-cond__op\" style={{ marginBottom: 6 }}>\n <span className=\"bpe-muted\" style={{ fontSize: \"var(--bpe-text-xs)\" }}>Match</span>\n <Segmented value={group.op} onChange={(op) => onChange({ ...group, op: op as \"and\" | \"or\" })} options={[{ value: \"and\", label: \"All (AND)\" }, { value: \"or\", label: \"Any (OR)\" }]} className=\"bpe-mode\" />\n </div>\n ) : null}\n {group.rules.map((r, i) => (\n <div key={i} className=\"bpe-cond__rule\" style={{ marginBottom: 6 }}>\n {\"op\" in r ? (\n <GroupEditor group={r} onChange={(g) => setRule(i, g)} dataSources={dataSources} scopeVars={scopeVars} depth={depth + 1} />\n ) : (\n <RuleEditor rule={r} onChange={(x) => setRule(i, x)} dataSources={dataSources} scopeVars={scopeVars} />\n )}\n <Button size=\"sm\" variant=\"ghost\" icon=\"x\" tooltip=\"Remove\" onClick={() => remove(i)} />\n </div>\n ))}\n {depth > 0 ? (\n <Button size=\"sm\" icon=\"plus\" onClick={() => onChange({ ...group, rules: [...group.rules, { left: \"\", operator: \"eq\", right: \"\" }] })}>Rule</Button>\n ) : null}\n </div>\n );\n}\n\nfunction RuleEditor({ rule, onChange, dataSources, scopeVars }: { rule: ConditionRule; onChange: (r: ConditionRule) => void; dataSources: DataSource[]; scopeVars?: Record<string, FieldSchema> }) {\n const op = CONDITION_OPERATORS.find((o) => o.value === rule.operator) ?? CONDITION_OPERATORS[0]!;\n const rightStr = rule.right === undefined || rule.right === null ? \"\" : String(rule.right);\n return (\n <div className=\"bpe-cond__row\">\n <BindingField value={rule.left} onChange={(left) => onChange({ ...rule, left })} dataSources={dataSources} scopeVars={scopeVars} placeholder=\"Choose a field\" />\n <Select value={rule.operator} onChange={(v) => onChange({ ...rule, operator: v as ConditionRule[\"operator\"] })} options={CONDITION_OPERATORS.map((o) => ({ value: o.value, label: o.label }))} />\n {op.needsValue ? (\n <TextInput\n value={rightStr}\n lazy\n placeholder=\"Value, or {{ field }}\"\n onChange={(v) => {\n const trimmed = v.trim();\n let right: ConditionRule[\"right\"] = v;\n if (trimmed === \"true\") right = true;\n else if (trimmed === \"false\") right = false;\n else if (trimmed !== \"\" && !Number.isNaN(Number(trimmed))) right = Number(trimmed);\n onChange({ ...rule, right });\n }}\n />\n ) : null}\n </div>\n );\n}\n","import { useState, type ReactNode } from \"react\";\nimport { createId, type DataSource, type FieldSchema, type InspectorField } from \"@broadpaper/core\";\nimport { Button, Field, Select, Switch, TextInput, NumberInput } from \"../../ui/primitives.js\";\nimport { Icon } from \"../../ui/icons.js\";\nimport { BindingField } from \"./BindingField.js\";\n\n/* ------------------------------- generic list ------------------------------ */\n\nexport function ListEditor<T extends { id?: string }>({ items, onChange, renderItem, label, itemLabel = \"Item\", create, summary }: { items: T[]; onChange: (items: T[]) => void; renderItem: (item: T, update: (patch: Partial<T>) => void, index: number) => ReactNode; label?: string; itemLabel?: string; create: () => T; summary?: (item: T, index: number) => string }) {\n const [open, setOpen] = useState<number | null>(null);\n const update = (i: number, patch: Partial<T>) => onChange(items.map((it, j) => (j === i ? { ...it, ...patch } : it)));\n const noun = itemLabel.toLowerCase();\n const name = (item: T, i: number) => summary?.(item, i) || `${itemLabel} ${i + 1}`;\n const move = (i: number, dir: -1 | 1) => {\n const j = i + dir;\n if (j < 0 || j >= items.length) return;\n const next = [...items];\n [next[i], next[j]] = [next[j]!, next[i]!];\n onChange(next);\n setOpen(j);\n };\n return (\n <div className=\"bpe-list-editor\">\n {items.map((it, i) => (\n <div key={it.id ?? i} className=\"bpe-list-editor__item\">\n <div className=\"bpe-list-editor__head\">\n {/* Named after the item, because \"Move up\" appears in the block\n toolbar, the layer tree and every list editor on the page. */}\n <button type=\"button\" className=\"bpe-layer__toggle\" aria-expanded={open === i} aria-label={`${open === i ? \"Collapse\" : \"Expand\"} ${name(it, i)}`} onClick={() => setOpen(open === i ? null : i)}>\n <Icon name=\"chevron-down\" />\n </button>\n <span className=\"bpe-truncate\" title={summary?.(it, i)}>{name(it, i)}</span>\n <Button size=\"sm\" variant=\"ghost\" icon=\"arrow-up\" tooltip={`Move ${noun} up`} disabled={i === 0} onClick={() => move(i, -1)} />\n <Button size=\"sm\" variant=\"ghost\" icon=\"arrow-down\" tooltip={`Move ${noun} down`} disabled={i === items.length - 1} onClick={() => move(i, 1)} />\n <Button size=\"sm\" variant=\"ghost\" icon=\"trash\" tooltip={`Remove ${noun}`} onClick={() => onChange(items.filter((_, j) => j !== i))} />\n </div>\n {open === i ? <div className=\"bpe-list-editor__body\">{renderItem(it, (patch) => update(i, patch), i)}</div> : null}\n </div>\n ))}\n <Button size=\"sm\" icon=\"plus\" onClick={() => { onChange([...items, create()]); setOpen(items.length); }}>\n Add {label ?? itemLabel.toLowerCase()}\n </Button>\n </div>\n );\n}\n\n/* --------------------------------- columns --------------------------------- */\n\nexport interface ColumnItem {\n id: string;\n header: string;\n value: string;\n align?: \"left\" | \"center\" | \"right\";\n width?: number | null;\n bold?: boolean;\n total?: \"none\" | \"sum\" | \"avg\" | \"count\" | \"min\" | \"max\";\n totalFormat?: string;\n wrap?: boolean;\n}\n\nexport function ColumnsEditor({ value, onChange, dataSources, scopeVars }: { value: ColumnItem[]; onChange: (v: ColumnItem[]) => void; dataSources: DataSource[]; scopeVars?: Record<string, FieldSchema> }) {\n return (\n <ListEditor<ColumnItem>\n items={value}\n onChange={onChange}\n itemLabel=\"Column\"\n summary={(c) => c.header || c.value || \"Column\"}\n create={() => ({ id: createId(\"c\"), header: \"New column\", value: \"\", align: \"left\", width: null })}\n renderItem={(c, update) => (\n <>\n <Field label=\"Heading\" stacked><TextInput value={c.header} onChange={(header) => update({ header })} lazy /></Field>\n <Field label=\"Value\" stacked><BindingField value={c.value} onChange={(v) => update({ value: v })} dataSources={dataSources} scopeVars={scopeVars} placeholder=\"Field per row\" /></Field>\n <Field label=\"Align\"><Select value={c.align ?? \"left\"} onChange={(v) => update({ align: v as ColumnItem[\"align\"] })} options={[{ value: \"left\", label: \"Left\" }, { value: \"center\", label: \"Centre\" }, { value: \"right\", label: \"Right\" }]} /></Field>\n <Field label=\"Width\"><NumberInput value={c.width ?? null} onChange={(w) => update({ width: w })} min={3} max={100} unit=\"%\" placeholder=\"auto\" /></Field>\n <Field label=\"Total\"><Select value={c.total ?? \"none\"} onChange={(v) => update({ total: v as ColumnItem[\"total\"] })} options={[{ value: \"none\", label: \"None\" }, { value: \"sum\", label: \"Sum\" }, { value: \"avg\", label: \"Average\" }, { value: \"count\", label: \"Count\" }, { value: \"min\", label: \"Minimum\" }, { value: \"max\", label: \"Maximum\" }]} /></Field>\n {c.total && c.total !== \"none\" ? <Field label=\"Total format\"><TextInput value={c.totalFormat ?? \"\"} onChange={(totalFormat) => update({ totalFormat })} mono lazy placeholder='e.g. currency:\"GBP\":0' /></Field> : null}\n <Field label=\"Bold\"><Switch checked={!!c.bold} onChange={(bold) => update({ bold })} /></Field>\n <Field label=\"Wrap text\"><Switch checked={c.wrap !== false} onChange={(wrap) => update({ wrap })} /></Field>\n </>\n )}\n />\n );\n}\n\n/* ---------------------------------- series --------------------------------- */\n\nexport interface SeriesItem {\n id: string;\n label: string;\n value: string;\n color?: string;\n}\n\nexport function SeriesEditor({ value, onChange, dataSources, scopeVars, renderColor }: { value: SeriesItem[]; onChange: (v: SeriesItem[]) => void; dataSources: DataSource[]; scopeVars?: Record<string, FieldSchema>; renderColor: (value: string | undefined, onChange: (v: string | undefined) => void) => ReactNode }) {\n return (\n <ListEditor<SeriesItem>\n items={value}\n onChange={onChange}\n itemLabel=\"Series\"\n summary={(s) => s.label || s.value || \"Series\"}\n create={() => ({ id: createId(\"s\"), label: `Series ${value.length + 1}`, value: \"\" })}\n renderItem={(s, update) => (\n <>\n <Field label=\"Label\"><TextInput value={s.label} onChange={(label) => update({ label })} lazy /></Field>\n <Field label=\"Value\" stacked><BindingField value={s.value} onChange={(v) => update({ value: v })} dataSources={dataSources} scopeVars={scopeVars} placeholder=\"Numeric field per item\" /></Field>\n <Field label=\"Colour\">{renderColor(s.color, (color) => update({ color }))}</Field>\n </>\n )}\n />\n );\n}\n\n/* -------------------------------- key/values ------------------------------- */\n\nexport interface KeyValueItem {\n id: string;\n label: string;\n value: string;\n}\n\nexport function KeyValuesEditor({ value, onChange, dataSources, scopeVars }: { value: KeyValueItem[]; onChange: (v: KeyValueItem[]) => void; dataSources: DataSource[]; scopeVars?: Record<string, FieldSchema> }) {\n return (\n <ListEditor<KeyValueItem>\n items={value}\n onChange={onChange}\n itemLabel=\"Item\"\n summary={(k) => k.label || \"Item\"}\n create={() => ({ id: createId(\"k\"), label: \"Label\", value: \"\" })}\n renderItem={(k, update) => (\n <>\n <Field label=\"Label\"><TextInput value={k.label} onChange={(label) => update({ label })} lazy /></Field>\n <Field label=\"Value\" stacked>\n <BindingField value={k.value.replace(/^\\{\\{\\s*|\\s*\\}\\}$/g, \"\")} onChange={(v) => update({ value: v ? `{{ ${v} }}` : \"\" })} dataSources={dataSources} scopeVars={scopeVars} placeholder=\"Field or text\" />\n </Field>\n <Field label=\"Text\" stacked><TextInput value={k.value} onChange={(value) => update({ value })} lazy placeholder=\"Static text or {{ field }}\" /></Field>\n </>\n )}\n />\n );\n}\n\n/* ------------------------------ generic sub-form ---------------------------- */\n\nexport function SubFormList({ value, onChange, fields, itemLabel, summary, renderField }: { value: Array<Record<string, unknown>>; onChange: (v: Array<Record<string, unknown>>) => void; fields: InspectorField[]; itemLabel?: string; summary?: (item: Record<string, unknown>, index: number) => string; renderField: (field: InspectorField, value: unknown, onChange: (v: unknown) => void) => ReactNode }) {\n return (\n <ListEditor<Record<string, unknown> & { id?: string }>\n items={value}\n onChange={onChange}\n itemLabel={itemLabel ?? \"Item\"}\n // The generic fallback reaches for whatever field looks like a name. That\n // is fine for a series and useless for a rule keyed by column id, which\n // is why a block can describe its own items.\n summary={(it, i) => summary?.(it, i) || String(it.label ?? it.header ?? `${itemLabel ?? \"Item\"} ${i + 1}`)}\n create={() => ({ id: createId(\"i\") })}\n renderItem={(it, update) => <>{fields.map((f) => <div key={f.prop}>{renderField(f, it[f.prop], (v) => update({ [f.prop]: v }))}</div>)}</>}\n />\n );\n}\n","import { textStyleLabel, type BlockStyle, type FlowOptions, type Node, type StyleGroup, type Theme, type Spacing } from \"@broadpaper/core\";\nimport { Field, NumberInput, Segmented, Select, Switch, Section, Button } from \"../ui/primitives.js\";\nimport { ColorField } from \"./fields/ColorField.js\";\n\ninterface Props {\n node: Node;\n groups: StyleGroup[];\n theme: Theme;\n textStyles: string[];\n setStyle: (patch: BlockStyle | null) => void;\n setFlow: (patch: FlowOptions) => void;\n allowOverrides: boolean;\n}\n\nconst SIDES = [\"top\", \"right\", \"bottom\", \"left\"] as const;\n\nfunction SpacingGrid({ value, onChange }: { value: Spacing | undefined; onChange: (v: Spacing | undefined) => void }) {\n const v = value ?? {};\n return (\n <div>\n <div className=\"bpe-spacing-grid\">\n {SIDES.map((s) => (\n <NumberInput key={s} value={v[s] ?? null} onChange={(n) => onChange({ ...v, [s]: n ?? undefined })} min={-200} max={400} placeholder=\"0\" aria-label={s} />\n ))}\n </div>\n <div className=\"bpe-spacing-grid\">\n {SIDES.map((s) => (\n <div key={s} className=\"bpe-spacing-grid__lbl\">{s}</div>\n ))}\n </div>\n </div>\n );\n}\n\n/** The built-in style groups shown for every block (per its `styleGroups`). */\nexport function StyleGroups({ node, groups, theme, textStyles, setStyle, setFlow, allowOverrides }: Props) {\n const s = node.style ?? {};\n const f = node.flow ?? {};\n const has = (g: StyleGroup) => groups.includes(g);\n const hasOverrides = Object.keys(s).length > 0;\n\n return (\n <>\n {allowOverrides && (has(\"textStyle\") || has(\"typography\") || has(\"alignment\")) ? (\n <Section title=\"Typography\" actions={hasOverrides ? <Button size=\"sm\" variant=\"ghost\" icon=\"rotate-ccw\" tooltip=\"Reset style overrides\" onClick={() => setStyle(null)} /> : null}>\n <div className=\"bpe-prop-grid\">\n {has(\"textStyle\") ? (\n <Field label=\"Text style\">\n <Select value={s.textStyle ?? \"\"} onChange={(v) => setStyle({ textStyle: v || undefined })} placeholder=\"Block default\" options={textStyles.map((t) => ({ value: t, label: textStyleLabel(t) }))} />\n </Field>\n ) : null}\n {has(\"typography\") ? (\n <>\n <Field label=\"Font\">\n <Select value={s.fontFamily ?? \"\"} onChange={(v) => setStyle({ fontFamily: v || undefined })} placeholder=\"Inherit\" options={[{ value: \"$typography.headingFont\", label: \"Heading font\" }, { value: \"$typography.bodyFont\", label: \"Body font\" }, ...(theme.fonts ?? []).map((x) => ({ value: x.family, label: x.family })), ...[\"Inter\", \"Roboto\", \"Georgia\", \"Arial\", \"Times New Roman\"].map((x) => ({ value: x, label: x }))]} />\n </Field>\n <Field label=\"Size\"><NumberInput value={s.fontSize ?? null} onChange={(v) => setStyle({ fontSize: v ?? undefined })} min={4} max={200} unit=\"px\" placeholder=\"inherit\" /></Field>\n <Field label=\"Weight\">\n <Select value={s.fontWeight === undefined ? \"\" : String(s.fontWeight)} onChange={(v) => setStyle({ fontWeight: v ? Number(v) : undefined })} placeholder=\"Inherit\" options={[300, 400, 500, 600, 700, 800].map((w) => ({ value: String(w), label: w === 400 ? \"Regular\" : w === 700 ? \"Bold\" : String(w) }))} />\n </Field>\n <Field label=\"Line height\"><NumberInput value={s.lineHeight ?? null} onChange={(v) => setStyle({ lineHeight: v ?? undefined })} min={0.6} max={4} step={0.05} placeholder=\"inherit\" /></Field>\n <Field label=\"Spacing\"><NumberInput value={s.letterSpacing ?? null} onChange={(v) => setStyle({ letterSpacing: v ?? undefined })} min={-0.2} max={1} step={0.01} unit=\"em\" placeholder=\"0\" /></Field>\n <Field label=\"Case\">\n <Segmented value={s.textTransform ?? \"none\"} onChange={(v) => setStyle({ textTransform: v === \"none\" ? undefined : (v as BlockStyle[\"textTransform\"]) })} options={[{ value: \"none\", label: \"Aa\" }, { value: \"uppercase\", label: \"AA\" }, { value: \"lowercase\", label: \"aa\" }, { value: \"capitalize\", label: \"Aa Bb\" }]} />\n </Field>\n <Field label=\"Style\">\n <Segmented value={s.fontStyle ?? \"normal\"} onChange={(v) => setStyle({ fontStyle: v === \"normal\" ? undefined : \"italic\" })} options={[{ value: \"normal\", label: \"Normal\" }, { value: \"italic\", label: \"Italic\" }]} />\n </Field>\n <Field label=\"Colour\"><ColorField value={s.color} onChange={(v) => setStyle({ color: v })} theme={theme} allowTransparent={false} placeholder=\"Inherit\" /></Field>\n </>\n ) : null}\n {has(\"alignment\") ? (\n <Field label=\"Align\">\n <Segmented value={s.textAlign ?? \"left\"} onChange={(v) => setStyle({ textAlign: v === \"left\" ? undefined : (v as BlockStyle[\"textAlign\"]) })} iconOnly ariaLabel=\"Text alignment\" options={[{ value: \"left\", label: \"Left\", icon: \"align-left\" }, { value: \"center\", label: \"Centre\", icon: \"align-center\" }, { value: \"right\", label: \"Right\", icon: \"align-right\" }, { value: \"justify\", label: \"Justify\", icon: \"align-justify\" }]} />\n </Field>\n ) : null}\n </div>\n </Section>\n ) : null}\n\n {allowOverrides && (has(\"spacing\") || has(\"size\")) ? (\n <Section title=\"Spacing & size\" defaultOpen={false}>\n <div className=\"bpe-prop-grid\">\n {has(\"spacing\") ? (\n <>\n <Field label=\"Margin\" stacked><SpacingGrid value={s.margin} onChange={(v) => setStyle({ margin: v })} /></Field>\n <Field label=\"Padding\" stacked><SpacingGrid value={s.padding} onChange={(v) => setStyle({ padding: v })} /></Field>\n </>\n ) : null}\n {has(\"size\") ? (\n <>\n <Field label=\"Width\"><NumberInput value={typeof s.width === \"number\" ? s.width : null} onChange={(v) => setStyle({ width: v ?? undefined })} min={8} max={2000} unit=\"px\" placeholder=\"auto\" /></Field>\n <Field label=\"Placement\">\n <Segmented value={s.align ?? \"left\"} onChange={(v) => setStyle({ align: v === \"left\" ? undefined : (v as BlockStyle[\"align\"]) })} options={[{ value: \"left\", label: \"Left\" }, { value: \"center\", label: \"Centre\" }, { value: \"right\", label: \"Right\" }]} />\n </Field>\n </>\n ) : null}\n </div>\n </Section>\n ) : null}\n\n {allowOverrides && (has(\"background\") || has(\"border\")) ? (\n <Section title=\"Background & border\" defaultOpen={false}>\n <div className=\"bpe-prop-grid\">\n {has(\"background\") ? <Field label=\"Background\"><ColorField value={s.background} onChange={(v) => setStyle({ background: v })} theme={theme} placeholder=\"None\" /></Field> : null}\n {has(\"border\") ? (\n <>\n <Field label=\"Border\"><NumberInput value={s.border?.width ?? null} onChange={(v) => setStyle({ border: { ...(s.border ?? {}), width: v ?? undefined } })} min={0} max={20} unit=\"px\" placeholder=\"0\" /></Field>\n <Field label=\"Border colour\"><ColorField value={s.border?.color} onChange={(v) => setStyle({ border: { ...(s.border ?? {}), color: v } })} theme={theme} placeholder=\"Theme border\" /></Field>\n <Field label=\"Line\"><Segmented value={s.border?.style ?? \"solid\"} onChange={(v) => setStyle({ border: { ...(s.border ?? {}), style: v as \"solid\" | \"dashed\" | \"dotted\" } })} options={[{ value: \"solid\", label: \"Solid\" }, { value: \"dashed\", label: \"Dashed\" }, { value: \"dotted\", label: \"Dotted\" }]} /></Field>\n <Field label=\"Radius\"><NumberInput value={s.border?.radius ?? null} onChange={(v) => setStyle({ border: { ...(s.border ?? {}), radius: v ?? undefined } })} min={0} max={100} unit=\"px\" placeholder=\"0\" /></Field>\n <Field label=\"Sides\">\n <div style={{ display: \"flex\", gap: 4 }}>\n {SIDES.map((side) => {\n const sides = s.border?.sides ?? [...SIDES];\n const on = sides.includes(side);\n return (\n <Button key={side} size=\"sm\" active={on} onClick={() => setStyle({ border: { ...(s.border ?? {}), sides: on ? sides.filter((x) => x !== side) : [...sides, side] } })} style={{ flex: 1, textTransform: \"capitalize\" }}>\n {side[0]!.toUpperCase()}\n </Button>\n );\n })}\n </div>\n </Field>\n </>\n ) : null}\n <Field label=\"Opacity\"><NumberInput value={s.opacity ?? null} onChange={(v) => setStyle({ opacity: v ?? undefined })} min={0} max={1} step={0.05} placeholder=\"1\" /></Field>\n </div>\n </Section>\n ) : null}\n\n {has(\"flow\") ? (\n <Section title=\"Page flow\" defaultOpen={false} icon=\"file-output\">\n <div className=\"bpe-prop-grid\">\n <Field label=\"Keep together\" hint=\"Never split this block across pages (unless it is taller than a page).\">\n <Switch checked={!!f.keepTogether} onChange={(v) => setFlow({ keepTogether: v || undefined })} />\n </Field>\n <Field label=\"Keep with next\" hint=\"Stay on the same page as the start of the next block.\">\n <Switch checked={!!f.keepWithNext} onChange={(v) => setFlow({ keepWithNext: v || undefined })} />\n </Field>\n <Field label=\"Break before\">\n <Segmented value={f.breakBefore ?? \"auto\"} onChange={(v) => setFlow({ breakBefore: v === \"auto\" ? undefined : \"page\" })} options={[{ value: \"auto\", label: \"Auto\" }, { value: \"page\", label: \"New page\" }]} />\n </Field>\n <Field label=\"Break after\">\n <Segmented value={f.breakAfter ?? \"auto\"} onChange={(v) => setFlow({ breakAfter: v === \"auto\" ? undefined : \"page\" })} options={[{ value: \"auto\", label: \"Auto\" }, { value: \"page\", label: \"New page\" }]} />\n </Field>\n <Field label=\"Min. lines before\"><NumberInput value={f.minOrphans ?? null} onChange={(v) => setFlow({ minOrphans: v ?? undefined })} min={1} max={10} placeholder=\"2\" /></Field>\n <Field label=\"Min. lines after\"><NumberInput value={f.minWidows ?? null} onChange={(v) => setFlow({ minWidows: v ?? undefined })} min={1} max={10} placeholder=\"2\" /></Field>\n </div>\n </Section>\n ) : null}\n </>\n );\n}\n","import { useState } from \"react\";\nimport { PAGE_SIZES_MM, textStyleLabel, type PageSettings, type TextStyle, type ReportTemplate } from \"@broadpaper/core\";\nimport { useSession, useFeatures, useTemplate } from \"../state/context.js\";\nimport { Section, Field, NumberInput, Segmented, Select, Switch, TextInput, Button } from \"../ui/primitives.js\";\nimport { ColorField } from \"./fields/ColorField.js\";\nimport { Icon } from \"../ui/icons.js\";\n\nconst SIZE_OPTIONS = [...Object.keys(PAGE_SIZES_MM).map((k) => ({ value: k, label: `${k} (${PAGE_SIZES_MM[k as keyof typeof PAGE_SIZES_MM].width} × ${PAGE_SIZES_MM[k as keyof typeof PAGE_SIZES_MM].height} mm)` })), { value: \"custom\", label: \"Custom\" }];\n\nexport function DocumentInspector() {\n const session = useSession();\n const features = useFeatures();\n const template = useTemplate();\n const theme = session.activeTheme;\n const page = template.page;\n const setPage = (patch: Partial<PageSettings>, label = \"Page settings\") => session.store.dispatch({ type: \"setPage\", patch }, { label, mergeKey: \"page\" });\n const sizeName = typeof page.size === \"string\" ? page.size : \"custom\";\n const [editingStyle, setEditingStyle] = useState<string | null>(null);\n\n return (\n <>\n <div className=\"bpe-inspector__header\">\n <span className=\"bpe-inspector__icon\"><Icon name=\"file-text\" /></span>\n <div style={{ minWidth: 0 }}>\n <div className=\"bpe-inspector__title\">Document</div>\n <div className=\"bpe-inspector__subtitle\">Page, styles and settings</div>\n </div>\n </div>\n <div className=\"bpe-inspector__body\">\n {features.pageSettings ? (\n <Section title=\"Page\" icon=\"layout\">\n <div className=\"bpe-prop-grid\">\n <Field label=\"Size\">\n <Select value={sizeName} onChange={(v) => setPage({ size: v === \"custom\" ? { width: 210, height: 297 } : (v as PageSettings[\"size\"]) })} options={SIZE_OPTIONS} />\n </Field>\n {sizeName === \"custom\" && typeof page.size === \"object\" ? (\n <>\n <Field label=\"Width\"><NumberInput value={page.size.width} onChange={(v) => setPage({ size: { width: v ?? 210, height: (page.size as { height: number }).height } })} min={50} max={2000} unit=\"mm\" /></Field>\n <Field label=\"Height\"><NumberInput value={page.size.height} onChange={(v) => setPage({ size: { width: (page.size as { width: number }).width, height: v ?? 297 } })} min={50} max={2000} unit=\"mm\" /></Field>\n </>\n ) : null}\n <Field label=\"Orientation\">\n <Segmented value={page.orientation} onChange={(v) => setPage({ orientation: v as PageSettings[\"orientation\"] })} options={[{ value: \"portrait\", label: \"Portrait\", icon: \"rectangle-vertical\" }, { value: \"landscape\", label: \"Landscape\", icon: \"rectangle-horizontal\" }]} />\n </Field>\n <Field label=\"Margins\" stacked>\n <div style={{ width: \"100%\" }}>\n <div className=\"bpe-spacing-grid\">\n {([\"top\", \"right\", \"bottom\", \"left\"] as const).map((s) => (\n <NumberInput key={s} value={page.margins[s]} onChange={(v) => setPage({ margins: { ...page.margins, [s]: v ?? 0 } })} min={0} max={80} aria-label={`${s} margin`} />\n ))}\n </div>\n <div className=\"bpe-spacing-grid\">{[\"top\", \"right\", \"bottom\", \"left\"].map((s) => <div key={s} className=\"bpe-spacing-grid__lbl\">{s}</div>)}</div>\n <div className=\"bpe-field__hint\">Millimetres</div>\n </div>\n </Field>\n <Field label=\"Background\"><ColorField value={page.background} onChange={(v) => setPage({ background: v })} theme={theme} placeholder=\"White\" /></Field>\n </div>\n </Section>\n ) : null}\n\n {features.headerFooter ? (\n <Section title=\"Header & footer\" icon=\"panel-top\">\n <div className=\"bpe-prop-grid\">\n <Field label=\"Header height\"><NumberInput value={page.header.height} onChange={(v) => setPage({ header: { ...page.header, height: v ?? 0 } })} min={0} max={100} unit=\"mm\" /></Field>\n <Field label=\"Footer height\"><NumberInput value={page.footer.height} onChange={(v) => setPage({ footer: { ...page.footer, height: v ?? 0 } })} min={0} max={100} unit=\"mm\" /></Field>\n <Field label=\"First page header\" hint=\"Use a different header on page 1 (e.g. a cover).\">\n <Switch checked={page.header.differentFirstPage} onChange={(v) => session.store.dispatch({ type: \"setRegionFirstPage\", region: \"header\", enabled: v })} />\n </Field>\n <Field label=\"First page footer\">\n <Switch checked={page.footer.differentFirstPage} onChange={(v) => session.store.dispatch({ type: \"setRegionFirstPage\", region: \"footer\", enabled: v })} />\n </Field>\n <div className=\"bpe-field__hint\">Click inside the header or footer area on the canvas to edit its content. Use the “Page number” block for numbering.</div>\n </div>\n </Section>\n ) : null}\n\n {features.documentStyles ? (\n <Section title=\"Text styles\" icon=\"type\">\n {editingStyle ? (\n <TextStyleEditor id={editingStyle} style={template.styles.text[editingStyle] ?? {}} onBack={() => setEditingStyle(null)} onChange={(patch) => session.store.dispatch({ type: \"setTextStyle\", id: editingStyle, patch }, { label: \"Document styles\", mergeKey: `textstyle:${editingStyle}` })} />\n ) : (\n <div>\n {Object.entries(template.styles.text).map(([id, s]) => (\n <button key={id} type=\"button\" className=\"bpe-doc-styles__item\" onClick={() => setEditingStyle(id)}>\n <span className=\"bpe-doc-styles__sample\" style={{ fontWeight: s.fontWeight as number | undefined, fontSize: Math.min(16, Math.max(10, (s.fontSize ?? 11) * 0.7)), textTransform: s.textTransform }}>\n {textStyleLabel(id)}\n </span>\n <span className=\"bpe-doc-styles__id\">{id} · {s.fontSize ?? \"–\"}px</span>\n <Icon name=\"chevron-right\" size={12} />\n </button>\n ))}\n <div className=\"bpe-field__hint\" style={{ padding: \"4px 12px 8px\" }}>Changing a style updates every block that uses it.</div>\n </div>\n )}\n </Section>\n ) : null}\n\n {features.documentStyles ? (\n <Section title=\"Tables & cards\" icon=\"table\" defaultOpen={false}>\n <div className=\"bpe-prop-grid\">\n <Field label=\"Table lines\">\n <Select value={template.styles.table.borders ?? \"horizontal\"} onChange={(v) => session.store.dispatch({ type: \"setDocumentStyles\", patch: { table: { borders: v as never } } })} options={[{ value: \"horizontal\", label: \"Horizontal\" }, { value: \"all\", label: \"Grid\" }, { value: \"outer\", label: \"Outer\" }, { value: \"none\", label: \"None\" }]} />\n </Field>\n <Field label=\"Header fill\"><ColorField value={template.styles.table.headerBackground} onChange={(v) => session.store.dispatch({ type: \"setDocumentStyles\", patch: { table: { headerBackground: v } } })} theme={theme} /></Field>\n <Field label=\"Zebra fill\"><ColorField value={template.styles.table.zebraBackground} onChange={(v) => session.store.dispatch({ type: \"setDocumentStyles\", patch: { table: { zebraBackground: v } } })} theme={theme} /></Field>\n <Field label=\"Table font\"><NumberInput value={template.styles.table.fontSize ?? null} onChange={(v) => session.store.dispatch({ type: \"setDocumentStyles\", patch: { table: { fontSize: v ?? undefined } } })} min={6} max={20} unit=\"px\" /></Field>\n <Field label=\"Cell padding\"><NumberInput value={template.styles.table.cellPaddingY ?? null} onChange={(v) => session.store.dispatch({ type: \"setDocumentStyles\", patch: { table: { cellPaddingY: v ?? undefined } } })} min={0} max={30} unit=\"px\" /></Field>\n <Field label=\"Card radius\"><NumberInput value={template.styles.card.borderRadius ?? null} onChange={(v) => session.store.dispatch({ type: \"setDocumentStyles\", patch: { card: { borderRadius: v ?? undefined } } })} min={0} max={40} unit=\"px\" /></Field>\n <Field label=\"Card padding\"><NumberInput value={template.styles.card.padding ?? null} onChange={(v) => session.store.dispatch({ type: \"setDocumentStyles\", patch: { card: { padding: v ?? undefined } } })} min={0} max={60} unit=\"px\" /></Field>\n <Field label=\"Card shadow\"><Switch checked={!!template.styles.card.shadow} onChange={(v) => session.store.dispatch({ type: \"setDocumentStyles\", patch: { card: { shadow: v } } })} /></Field>\n <Field label=\"Block gap\"><NumberInput value={template.styles.spacing.blockGap} onChange={(v) => session.store.dispatch({ type: \"setDocumentStyles\", patch: { spacing: { ...template.styles.spacing, blockGap: v ?? 8 } } })} min={0} max={60} unit=\"px\" /></Field>\n <Field label=\"Column gap\"><NumberInput value={template.styles.spacing.columnGap} onChange={(v) => session.store.dispatch({ type: \"setDocumentStyles\", patch: { spacing: { ...template.styles.spacing, columnGap: v ?? 16 } } })} min={0} max={80} unit=\"px\" /></Field>\n </div>\n </Section>\n ) : null}\n\n <Section title=\"Settings\" icon=\"settings\" defaultOpen={false}>\n <div className=\"bpe-prop-grid\">\n <Field label=\"Locale\" hint=\"Number and date formatting, e.g. en-GB, en-US, de-DE.\"><TextInput value={template.settings?.locale ?? \"\"} onChange={(v) => session.store.dispatch({ type: \"setSettings\", patch: { locale: v || undefined } })} lazy placeholder=\"en-GB\" /></Field>\n <Field label=\"Currency\"><TextInput value={template.settings?.currency ?? \"\"} onChange={(v) => session.store.dispatch({ type: \"setSettings\", patch: { currency: v.toUpperCase() || undefined } })} lazy placeholder=\"GBP\" /></Field>\n <Field label=\"Time zone\"><TextInput value={template.settings?.timeZone ?? \"\"} onChange={(v) => session.store.dispatch({ type: \"setSettings\", patch: { timeZone: v || undefined } })} lazy placeholder=\"Europe/London\" /></Field>\n <Field label=\"Template ID\"><code className=\"bpe-mono bpe-muted\" style={{ fontSize: 10 }}>{template.id}</code></Field>\n </div>\n </Section>\n </div>\n </>\n );\n}\n\nfunction TextStyleEditor({ id, style, onChange, onBack }: { id: string; style: TextStyle; onChange: (patch: TextStyle) => void; onBack: () => void }) {\n const session = useSession();\n const theme = session.activeTheme;\n return (\n <div className=\"bpe-prop-grid\">\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n <Button size=\"sm\" variant=\"ghost\" icon=\"chevron-right\" style={{ transform: \"rotate(180deg)\" }} onClick={onBack} tooltip=\"Back\" />\n <strong>{id}</strong>\n </div>\n <Field label=\"Font\">\n <Select value={style.fontFamily ?? \"\"} onChange={(v) => onChange({ fontFamily: v || undefined })} placeholder=\"Theme body font\" options={[{ value: \"$typography.headingFont\", label: \"Theme heading font\" }, { value: \"$typography.bodyFont\", label: \"Theme body font\" }, ...(theme.fonts ?? []).map((f) => ({ value: f.family, label: f.family }))]} />\n </Field>\n <Field label=\"Size\"><NumberInput value={style.fontSize ?? null} onChange={(v) => onChange({ fontSize: v ?? undefined })} min={4} max={120} unit=\"px\" /></Field>\n <Field label=\"Weight\"><Select value={style.fontWeight === undefined ? \"\" : String(style.fontWeight)} onChange={(v) => onChange({ fontWeight: v ? Number(v) : undefined })} placeholder=\"Regular\" options={[300, 400, 500, 600, 700, 800].map((w) => ({ value: String(w), label: String(w) }))} /></Field>\n <Field label=\"Line height\"><NumberInput value={style.lineHeight ?? null} onChange={(v) => onChange({ lineHeight: v ?? undefined })} min={0.8} max={3} step={0.05} /></Field>\n <Field label=\"Letter spacing\"><NumberInput value={style.letterSpacing ?? null} onChange={(v) => onChange({ letterSpacing: v ?? undefined })} min={-0.1} max={0.5} step={0.01} unit=\"em\" /></Field>\n <Field label=\"Case\"><Segmented value={style.textTransform ?? \"none\"} onChange={(v) => onChange({ textTransform: v === \"none\" ? undefined : (v as TextStyle[\"textTransform\"]) })} options={[{ value: \"none\", label: \"Aa\" }, { value: \"uppercase\", label: \"AA\" }, { value: \"capitalize\", label: \"Aa Bb\" }]} /></Field>\n <Field label=\"Colour\"><ColorField value={style.color} onChange={(v) => onChange({ color: v })} theme={theme} allowTransparent={false} placeholder=\"Theme text\" /></Field>\n <Field label=\"Space above\"><NumberInput value={style.marginTop ?? null} onChange={(v) => onChange({ marginTop: v ?? undefined })} min={0} max={100} unit=\"px\" /></Field>\n <Field label=\"Space below\"><NumberInput value={style.marginBottom ?? null} onChange={(v) => onChange({ marginBottom: v ?? undefined })} min={0} max={100} unit=\"px\" /></Field>\n <Field label=\"Keep with next\"><Switch checked={!!style.keepWithNext} onChange={(v) => onChange({ keepWithNext: v || undefined })} /></Field>\n </div>\n );\n}\n\nexport type { ReportTemplate };\n","import { useSession, useEditorState, useNode } from \"../state/context.js\";\nimport type { EditorActions } from \"../state/actions.js\";\nimport { NodeInspector } from \"./NodeInspector.js\";\nimport { DocumentInspector } from \"./DocumentInspector.js\";\nimport { Icon } from \"../ui/icons.js\";\nimport { Button } from \"../ui/primitives.js\";\n\nexport function Inspector({ actions }: { actions: EditorActions }) {\n const session = useSession();\n const selection = useEditorState((s) => s.selection);\n const mode = useEditorState((s) => s.mode);\n const entry = useNode(selection[0] ?? null);\n if (mode === \"preview\") {\n return (\n <aside className=\"bpe-inspector\" aria-label=\"Properties\">\n <div className=\"bpe-empty\" style={{ marginTop: 40 }}>\n <Icon name=\"eye\" />\n <div className=\"bpe-empty__title\">Preview mode</div>\n Properties are hidden while previewing. Switch back to Design to edit.\n <Button size=\"sm\" onClick={() => session.setMode(\"design\")} style={{ marginTop: 8 }}>Back to design</Button>\n </div>\n </aside>\n );\n }\n if (selection.length > 1) {\n return (\n <aside className=\"bpe-inspector\" aria-label=\"Properties\">\n <div className=\"bpe-inspector__header\">\n <span className=\"bpe-inspector__icon\"><Icon name=\"square-stack\" /></span>\n <div><div className=\"bpe-inspector__title\">{selection.length} blocks selected</div><div className=\"bpe-inspector__subtitle\">Actions apply to all</div></div>\n </div>\n <div className=\"bpe-prop-grid\">\n <Button icon=\"copy\" onClick={() => actions.duplicateSelection()}>Duplicate all</Button>\n <Button icon=\"panel-top\" onClick={() => actions.wrapSelectionIn(\"card\")}>Wrap in card</Button>\n <Button icon=\"link\" onClick={() => actions.wrapSelectionIn(\"keepTogether\")}>Keep together</Button>\n <Button icon=\"trash\" variant=\"danger\" onClick={() => actions.deleteSelection()}>Delete all</Button>\n </div>\n </aside>\n );\n }\n return (\n <aside className=\"bpe-inspector\" aria-label=\"Properties\">\n {entry ? <NodeInspector key={entry.node.id} entry={entry} actions={actions} /> : <DocumentInspector />}\n </aside>\n );\n}\n","import { useRef } from \"react\";\n\n/**\n * A drag handle on a panel's edge.\n *\n * The properties panel is a fixed 296px, which is the width at which a binding\n * expression, a colour swatch and a unit suffix all have to share one row. The\n * fields now stack rather than truncate, but some content — a long expression,\n * a table's column list — is simply better with more room, and how much room\n * that deserves is the user's call and nobody else's.\n *\n * Keyboard users get the same control: the handle is focusable and the arrow\n * keys move it, which is the part that usually gets left out.\n */\nexport function PanelResizer({ side, width, min, max, onChange, label }: { side: \"left\" | \"right\"; width: number; min: number; max: number; onChange: (width: number) => void; label: string }) {\n const start = useRef<{ x: number; width: number } | null>(null);\n const clamp = (w: number) => Math.round(Math.min(max, Math.max(min, w)));\n\n return (\n <div\n className={`bpe-resizer bpe-resizer--${side}`}\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={label}\n aria-valuenow={width}\n aria-valuemin={min}\n aria-valuemax={max}\n tabIndex={0}\n onPointerDown={(e) => {\n start.current = { x: e.clientX, width };\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n }}\n onPointerMove={(e) => {\n if (!start.current) return;\n const delta = e.clientX - start.current.x;\n onChange(clamp(start.current.width + (side === \"right\" ? -delta : delta)));\n }}\n onPointerUp={(e) => {\n start.current = null;\n (e.target as HTMLElement).releasePointerCapture(e.pointerId);\n }}\n onKeyDown={(e) => {\n const step = e.shiftKey ? 40 : 8;\n if (e.key === \"ArrowLeft\") onChange(clamp(width + (side === \"right\" ? step : -step)));\n else if (e.key === \"ArrowRight\") onChange(clamp(width + (side === \"right\" ? -step : step)));\n else return;\n e.preventDefault();\n }}\n onDoubleClick={() => onChange(clamp(side === \"right\" ? 296 : 272))}\n />\n );\n}\n","import { Component, type ErrorInfo, type ReactNode } from \"react\";\nimport { Button } from \"./primitives.js\";\nimport { Icon } from \"./icons.js\";\n\ninterface Props {\n /** What failed, in the words the panel uses for itself. */\n area: string;\n /** Grid area to occupy when the fallback replaces a whole region. */\n slot?: \"toolbar\" | \"left\" | \"canvas\" | \"right\";\n children: ReactNode;\n}\n\ninterface State {\n error: Error | null;\n}\n\n/**\n * Keeps one part of the designer's failure to itself.\n *\n * React unmounts the whole tree from the nearest boundary up, so without one a\n * single bad render — a panel reading a field that a host's `update()` has not\n * filled in yet, a custom block throwing in its inspector — replaces the entire\n * editor with a blank element, taking the user's unsaved template off the\n * screen with it. Each region gets its own boundary instead: the rest of the\n * designer keeps working, the document is still there, and the part that broke\n * offers to try again rather than needing the page reloaded.\n */\nexport class Boundary extends Component<Props, State> {\n override state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n override componentDidCatch(error: Error, info: ErrorInfo): void {\n // Hosts have their own reporting; ours is a console message that names the\n // area, because \"Cannot read properties of undefined\" on its own does not.\n console.error(`[broadpaper] ${this.props.area} failed to render`, error, info.componentStack);\n }\n\n override render(): ReactNode {\n const { error } = this.state;\n if (!error) return this.props.children;\n return (\n <div className=\"bpe-boundary\" role=\"alert\" style={this.props.slot ? { gridArea: this.props.slot } : undefined}>\n <Icon name=\"alert-triangle\" size={16} />\n <div className=\"bpe-boundary__body\">\n <div className=\"bpe-boundary__title\">{this.props.area} stopped</div>\n <div className=\"bpe-boundary__detail\">{error.message || \"Something went wrong.\"} The rest of the designer, and your document, are unaffected.</div>\n </div>\n <Button size=\"sm\" icon=\"rotate-ccw\" onClick={() => this.setState({ error: null })}>Try again</Button>\n </div>\n );\n }\n}\n","/* AUTO-GENERATED by scripts/css-to-ts.mjs — do not edit. */\nexport const EDITOR_CSS = \"/* BroadPaper editor design tokens.\\n `.bpe` is the editor shell; `.bpe-scope` is a token-only scope used by portalled\\n floating elements (tooltips, popovers) so they inherit the palette WITHOUT the\\n shell's grid layout, size and background. */\\n.bpe,\\n.bpe-scope {\\n /* colour */\\n --bpe-bg: #ffffff;\\n --bpe-bg-subtle: #f7f8fa;\\n --bpe-bg-muted: #eef0f4;\\n --bpe-bg-canvas: #e9ebf0;\\n --bpe-bg-elevated: #ffffff;\\n --bpe-fg: #111827;\\n --bpe-fg-secondary: #4b5563;\\n --bpe-fg-muted: #6b7280;\\n --bpe-fg-faint: #9ca3af;\\n --bpe-border: #e5e7eb;\\n --bpe-border-strong: #d1d5db;\\n --bpe-accent: #3b5bdb;\\n --bpe-accent-hover: #3451c7;\\n --bpe-accent-soft: rgba(59, 91, 219, 0.1);\\n --bpe-accent-soft-strong: rgba(59, 91, 219, 0.18);\\n --bpe-accent-fg: #ffffff;\\n\\n /* The one filled call to action — Export, and any host button asking for\\n `variant=\\\"primary\\\"`. Separate from the accent, and defaulting to it, because\\n a host wanting its brand on that button rarely wants the same colour on\\n selection outlines, focus rings and the active tab: BroadPaper's own is a\\n vermilion that reads as an error the moment it outlines a selected block,\\n and `--bpe-danger` is nearly the same red. Set this alone and the button is\\n yours while everything that means \\\"this is selected\\\" stays legible. */\\n --bpe-primary: var(--bpe-accent);\\n --bpe-primary-hover: var(--bpe-accent-hover);\\n --bpe-primary-fg: var(--bpe-accent-fg);\\n\\n --bpe-danger: #dc2626;\\n --bpe-danger-soft: rgba(220, 38, 38, 0.1);\\n --bpe-warning: #d97706;\\n --bpe-warning-soft: rgba(217, 119, 6, 0.12);\\n --bpe-success: #059669;\\n --bpe-success-soft: rgba(5, 150, 105, 0.12);\\n --bpe-token: #2f4f7f;\\n --bpe-token-bg: rgba(79, 111, 165, 0.14);\\n --bpe-selection: var(--bpe-accent);\\n --bpe-hover-outline: rgba(59, 91, 219, 0.45);\\n --bpe-drop: #10b981;\\n\\n /* typography */\\n --bpe-font: Inter, ui-sans-serif, system-ui, -apple-system, \\\"Segoe UI\\\", Roboto, Helvetica, Arial, sans-serif;\\n --bpe-font-mono: \\\"JetBrains Mono\\\", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\\n --bpe-text-xs: 10.5px;\\n --bpe-text-sm: 11.5px;\\n --bpe-text-md: 12.5px;\\n --bpe-text-lg: 14px;\\n --bpe-text-xl: 16px;\\n\\n /* geometry */\\n --bpe-radius-sm: 4px;\\n --bpe-radius: 6px;\\n --bpe-radius-lg: 10px;\\n --bpe-space-1: 4px;\\n --bpe-space-2: 8px;\\n --bpe-space-3: 12px;\\n --bpe-space-4: 16px;\\n --bpe-space-5: 20px;\\n --bpe-space-6: 24px;\\n --bpe-control-h: 28px;\\n --bpe-control-h-sm: 24px;\\n --bpe-panel-w: 272px;\\n --bpe-inspector-w: 296px;\\n --bpe-toolbar-h: 48px;\\n\\n /* effects */\\n --bpe-shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06);\\n --bpe-shadow: 0 1px 3px rgba(16, 24, 40, 0.1), 0 1px 2px rgba(16, 24, 40, 0.06);\\n --bpe-shadow-lg: 0 10px 30px rgba(16, 24, 40, 0.16), 0 2px 6px rgba(16, 24, 40, 0.08);\\n --bpe-shadow-page: 0 1px 2px rgba(16, 24, 40, 0.1), 0 12px 32px rgba(16, 24, 40, 0.1);\\n --bpe-focus: 0 0 0 2px var(--bpe-bg), 0 0 0 4px var(--bpe-accent);\\n --bpe-ease: cubic-bezier(0.2, 0, 0, 1);\\n --bpe-dur: 140ms;\\n}\\n\\n.bpe[data-appearance=\\\"dark\\\"],\\n.bpe-scope[data-appearance=\\\"dark\\\"] {\\n --bpe-bg: #17191e;\\n --bpe-bg-subtle: #1d2026;\\n --bpe-bg-muted: #23262d;\\n --bpe-bg-canvas: #101114;\\n --bpe-bg-elevated: #1f2228;\\n --bpe-fg: #e7e9ee;\\n --bpe-fg-secondary: #b9bec8;\\n --bpe-fg-muted: #8b919c;\\n --bpe-fg-faint: #5e636d;\\n --bpe-border: #2b2f37;\\n --bpe-border-strong: #3a3f49;\\n --bpe-accent: #6b8cff;\\n --bpe-accent-hover: #7e9bff;\\n --bpe-accent-soft: rgba(107, 140, 255, 0.16);\\n --bpe-accent-soft-strong: rgba(107, 140, 255, 0.28);\\n --bpe-accent-fg: #0e1220;\\n --bpe-token: #a9c0ff;\\n --bpe-token-bg: rgba(107, 140, 255, 0.2);\\n --bpe-hover-outline: rgba(107, 140, 255, 0.55);\\n --bpe-shadow: 0 1px 3px rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.3);\\n --bpe-shadow-lg: 0 10px 30px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.3);\\n --bpe-shadow-page: 0 1px 2px rgba(0, 0, 0, 0.4), 0 12px 32px rgba(0, 0, 0, 0.4);\\n}\\n\\n/* ===================================================================\\n BroadPaper editor — component styles. Scoped under .bpe.\\n =================================================================== */\\n\\n.bpe, .bpe *, .bpe *::before, .bpe *::after,\\n.bpe-scope, .bpe-scope *, .bpe-scope *::before, .bpe-scope *::after { box-sizing: border-box; }\\n.bpe {\\n position: relative;\\n display: grid;\\n grid-template-rows: var(--bpe-toolbar-h) 1fr;\\n grid-template-columns: var(--bpe-panel-w) minmax(0, 1fr) var(--bpe-inspector-w);\\n grid-template-areas: \\\"toolbar toolbar toolbar\\\" \\\"left canvas right\\\";\\n width: 100%;\\n height: 100%;\\n min-height: 480px;\\n background: var(--bpe-bg);\\n color: var(--bpe-fg);\\n font-family: var(--bpe-font);\\n font-size: var(--bpe-text-md);\\n line-height: 1.4;\\n -webkit-font-smoothing: antialiased;\\n overflow: hidden;\\n border: 1px solid var(--bpe-border);\\n border-radius: var(--bpe-radius-lg);\\n}\\n.bpe--no-left { grid-template-columns: 0 minmax(0, 1fr) var(--bpe-inspector-w); }\\n.bpe--no-right { grid-template-columns: var(--bpe-panel-w) minmax(0, 1fr) 0; }\\n.bpe--no-left.bpe--no-right { grid-template-columns: 0 minmax(0, 1fr) 0; }\\n.bpe--no-toolbar { grid-template-rows: 0 1fr; }\\n.bpe button, .bpe input, .bpe select, .bpe textarea,\\n.bpe-scope button, .bpe-scope input, .bpe-scope select, .bpe-scope textarea { font: inherit; color: inherit; }\\n.bpe button, .bpe-scope button { cursor: pointer; }\\n.bpe :focus-visible, .bpe-scope :focus-visible { outline: none; box-shadow: var(--bpe-focus); }\\n.bpe ::selection, .bpe-scope ::selection { background: var(--bpe-accent-soft-strong); }\\n.bpe-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }\\n.bpe-mono { font-family: var(--bpe-font-mono); }\\n.bpe-muted { color: var(--bpe-fg-muted); }\\n.bpe-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n\\n/* scrollbars */\\n.bpe *::-webkit-scrollbar, .bpe-scope *::-webkit-scrollbar { width: 10px; height: 10px; }\\n.bpe *::-webkit-scrollbar-thumb, .bpe-scope *::-webkit-scrollbar-thumb { background: var(--bpe-border-strong); border: 3px solid transparent; border-radius: 8px; background-clip: padding-box; }\\n.bpe *::-webkit-scrollbar-thumb:hover { background: var(--bpe-fg-faint); background-clip: padding-box; border: 3px solid transparent; }\\n.bpe *::-webkit-scrollbar-track { background: transparent; }\\n\\n/* ------------------------------------------------------------------ */\\n/* Primitives */\\n/* ------------------------------------------------------------------ */\\n.bpe-btn {\\n display: inline-flex; align-items: center; justify-content: center; gap: 6px;\\n height: var(--bpe-control-h); padding: 0 10px; border-radius: var(--bpe-radius);\\n border: 1px solid var(--bpe-border); background: var(--bpe-bg); color: var(--bpe-fg);\\n font-size: var(--bpe-text-sm); font-weight: 500; white-space: nowrap; user-select: none; flex-shrink: 0;\\n transition: background var(--bpe-dur) var(--bpe-ease), border-color var(--bpe-dur) var(--bpe-ease), color var(--bpe-dur) var(--bpe-ease), transform 80ms var(--bpe-ease);\\n}\\n.bpe-btn:hover { background: var(--bpe-bg-subtle); border-color: var(--bpe-border-strong); }\\n.bpe-btn:active { transform: translateY(0.5px); }\\n.bpe-btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }\\n.bpe-btn--primary { background: var(--bpe-primary); border-color: var(--bpe-primary); color: var(--bpe-primary-fg); }\\n.bpe-btn--primary:hover { background: var(--bpe-primary-hover); border-color: var(--bpe-primary-hover); }\\n.bpe-btn--ghost { border-color: transparent; background: transparent; }\\n.bpe-btn--ghost:hover { background: var(--bpe-bg-muted); border-color: transparent; }\\n.bpe-btn--danger { color: var(--bpe-danger); }\\n.bpe-btn--danger:hover { background: var(--bpe-danger-soft); border-color: transparent; }\\n.bpe-btn--sm { height: var(--bpe-control-h-sm); padding: 0 8px; font-size: var(--bpe-text-xs); }\\n.bpe-btn--icon { width: var(--bpe-control-h); padding: 0; }\\n.bpe-btn--sm.bpe-btn--icon { width: var(--bpe-control-h-sm); }\\n.bpe-btn--active { background: var(--bpe-accent-soft); border-color: transparent; color: var(--bpe-accent); }\\n.bpe-btn svg { width: 15px; height: 15px; flex-shrink: 0; }\\n.bpe-btn--sm svg { width: 13px; height: 13px; }\\n\\n.bpe-input, .bpe-select, .bpe-textarea {\\n width: 100%; height: var(--bpe-control-h); padding: 0 8px; border-radius: var(--bpe-radius);\\n border: 1px solid var(--bpe-border); background: var(--bpe-bg); color: var(--bpe-fg); font-size: var(--bpe-text-sm);\\n transition: border-color var(--bpe-dur) var(--bpe-ease), box-shadow var(--bpe-dur) var(--bpe-ease);\\n}\\n.bpe-input::placeholder, .bpe-textarea::placeholder { color: var(--bpe-fg-faint); }\\n.bpe-input:hover, .bpe-select:hover, .bpe-textarea:hover { border-color: var(--bpe-border-strong); }\\n.bpe-input:focus, .bpe-select:focus, .bpe-textarea:focus { border-color: var(--bpe-accent); box-shadow: 0 0 0 3px var(--bpe-accent-soft); }\\n.bpe-input--invalid { border-color: var(--bpe-danger) !important; }\\n.bpe-textarea { height: auto; min-height: 56px; padding: 6px 8px; resize: vertical; line-height: 1.45; }\\n.bpe-select { appearance: none; padding-right: 24px; background-image: url(\\\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' fill='none' stroke='%236b7280' stroke-width='1.5' stroke-linecap='round'/></svg>\\\"); background-repeat: no-repeat; background-position: right 8px center; }\\n.bpe-input-group { position: relative; display: flex; align-items: center; }\\n.bpe-input-group .bpe-input { padding-right: 28px; }\\n.bpe-input-group__suffix { position: absolute; right: 8px; font-size: var(--bpe-text-xs); color: var(--bpe-fg-faint); pointer-events: none; }\\n.bpe-input-group__btn { position: absolute; right: 2px; top: 2px; }\\n.bpe-number { display: flex; align-items: center; }\\n.bpe-number .bpe-input { text-align: left; }\\n\\n.bpe-switch { position: relative; display: inline-flex; width: 30px; height: 18px; border-radius: 9px; background: var(--bpe-border-strong); border: 0; padding: 0; transition: background var(--bpe-dur) var(--bpe-ease); flex-shrink: 0; }\\n.bpe-switch::after { content: \\\"\\\"; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: #fff; box-shadow: var(--bpe-shadow-sm); transition: transform var(--bpe-dur) var(--bpe-ease); }\\n.bpe-switch[aria-checked=\\\"true\\\"] { background: var(--bpe-accent); }\\n.bpe-switch[aria-checked=\\\"true\\\"]::after { transform: translateX(12px); }\\n\\n.bpe-segmented { display: inline-flex; padding: 2px; border-radius: var(--bpe-radius); background: var(--bpe-bg-muted); gap: 2px; width: 100%; }\\n.bpe-segmented__item { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 4px; height: 22px; padding: 0 6px; border: 0; border-radius: 4px; background: transparent; color: var(--bpe-fg-muted); font-size: var(--bpe-text-xs); font-weight: 500; transition: background var(--bpe-dur) var(--bpe-ease), color var(--bpe-dur) var(--bpe-ease); min-width: 0; }\\n.bpe-segmented__item:hover { color: var(--bpe-fg); }\\n.bpe-segmented__item[aria-pressed=\\\"true\\\"] { background: var(--bpe-bg-elevated); color: var(--bpe-fg); box-shadow: var(--bpe-shadow-sm); }\\n.bpe-segmented__item svg { width: 13px; height: 13px; }\\n\\n/* Five named tabs will not fit side by side in a 272px panel, so they stack\\n the label under the icon and share the row evenly. Names beat guessing at\\n icons; a second row of chrome does not. */\\n.bpe-tabs { display: flex; gap: 2px; padding: 6px 6px 0; border-bottom: 1px solid var(--bpe-border); }\\n.bpe-tab { position: relative; flex: 1 1 0; min-width: 0; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; height: 42px; padding: 0 2px; border: 0; background: transparent; color: var(--bpe-fg-muted); font-size: var(--bpe-text-xs); font-weight: 500; border-radius: var(--bpe-radius-sm) var(--bpe-radius-sm) 0 0; }\\n.bpe-tab > span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n.bpe-tab:hover { color: var(--bpe-fg); background: var(--bpe-bg-subtle); }\\n.bpe-tab[aria-selected=\\\"true\\\"] { color: var(--bpe-fg); }\\n.bpe-tab[aria-selected=\\\"true\\\"] { background: var(--bpe-bg-subtle); }\\n.bpe-tab[aria-selected=\\\"true\\\"]::after { content: \\\"\\\"; position: absolute; left: 6px; right: 6px; bottom: -1px; height: 2px; background: var(--bpe-accent); border-radius: 2px; }\\n.bpe-tab svg { width: 14px; height: 14px; }\\n\\n.bpe-popover { z-index: 1000; min-width: 180px; max-width: 340px; padding: 6px; border-radius: var(--bpe-radius-lg); border: 1px solid var(--bpe-border); background: var(--bpe-bg-elevated); color: var(--bpe-fg); box-shadow: var(--bpe-shadow-lg); font-family: var(--bpe-font); font-size: var(--bpe-text-sm); }\\n/* Entrance runs only once floating-ui has positioned the element, so it never\\n animates from the viewport corner. */\\n.bpe-floating--in { animation: bpe-pop var(--bpe-dur) var(--bpe-ease); }\\n@keyframes bpe-pop { from { opacity: 0; transform: translateY(-3px) scale(0.98); } to { opacity: 1; transform: none; } }\\n.bpe-menu__item { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 28px; padding: 4px 8px; border: 0; border-radius: var(--bpe-radius-sm); background: transparent; color: var(--bpe-fg); text-align: left; font-size: var(--bpe-text-sm); }\\n.bpe-menu__item--stacked { align-items: flex-start; padding: 6px 8px; }\\n.bpe-menu__item--stacked svg { margin-top: 2px; }\\n.bpe-menu__body { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }\\n.bpe-menu__label-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n.bpe-menu__desc { font-size: var(--bpe-text-xs); color: var(--bpe-fg-muted); line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }\\n.bpe-menu__item:hover, .bpe-menu__item:focus-visible { background: var(--bpe-bg-muted); box-shadow: none; }\\n.bpe-menu__item:disabled { opacity: 0.45; }\\n.bpe-menu__item svg { width: 14px; height: 14px; color: var(--bpe-fg-muted); }\\n.bpe-menu__item--danger { color: var(--bpe-danger); }\\n.bpe-menu__item--danger svg { color: var(--bpe-danger); }\\n.bpe-menu__sep { height: 1px; margin: 4px 0; background: var(--bpe-border); }\\n.bpe-menu__label { padding: 6px 8px 2px; font-size: var(--bpe-text-xs); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--bpe-fg-faint); }\\n.bpe-menu__hint { margin-left: auto; padding-left: 8px; color: var(--bpe-fg-faint); font-size: var(--bpe-text-xs); white-space: nowrap; flex-shrink: 0; }\\n/* The portal is a zero-width positioned box, which is the containing block for\\n everything floating inside it. A shrink-to-fit element therefore has no room\\n at all and wraps after every word; `max-content` is what stops that. */\\n.bpe-tooltip { width: max-content; z-index: 1100; padding: 4px 8px; border-radius: var(--bpe-radius-sm); background: #111827; color: #fff; font-size: var(--bpe-text-xs); font-family: var(--bpe-font); font-weight: 500; pointer-events: none; box-shadow: var(--bpe-shadow); max-width: 260px; }\\n.bpe-tooltip .bpe-kbd { margin-left: 6px; background: rgba(255,255,255,0.14); color: #fff; border-color: transparent; }\\n.bpe-kbd { display: inline-block; padding: 0 4px; border-radius: 3px; border: 1px solid var(--bpe-border); background: var(--bpe-bg-subtle); font-size: 10px; font-family: var(--bpe-font); color: var(--bpe-fg-muted); line-height: 15px; }\\n.bpe-badge { display: inline-flex; align-items: center; gap: 4px; height: 18px; padding: 0 6px; border-radius: 999px; background: var(--bpe-bg-muted); color: var(--bpe-fg-secondary); font-size: var(--bpe-text-xs); font-weight: 600; white-space: nowrap; }\\n.bpe-badge--accent { background: var(--bpe-accent-soft); color: var(--bpe-accent); }\\n.bpe-badge--warning { background: var(--bpe-warning-soft); color: var(--bpe-warning); }\\n.bpe-badge--danger { background: var(--bpe-danger-soft); color: var(--bpe-danger); }\\n.bpe-badge--success { background: var(--bpe-success-soft); color: var(--bpe-success); }\\n.bpe-chip { display: inline-flex; align-items: center; gap: 4px; height: 20px; padding: 0 7px; border-radius: 4px; background: var(--bpe-token-bg); color: var(--bpe-token); font-size: var(--bpe-text-xs); font-weight: 500; max-width: 100%; }\\n.bpe-chip svg { width: 11px; height: 11px; }\\n.bpe-chip__x { margin-left: 2px; border: 0; background: transparent; padding: 0; color: inherit; display: inline-flex; opacity: 0.6; }\\n.bpe-chip__x:hover { opacity: 1; }\\n.bpe-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; padding: 28px 16px; text-align: center; color: var(--bpe-fg-muted); font-size: var(--bpe-text-sm); }\\n.bpe-empty svg { width: 22px; height: 22px; color: var(--bpe-fg-faint); }\\n\\n/* One region's failure, contained. See ui/Boundary.tsx. */\\n.bpe-boundary { display: flex; align-items: flex-start; gap: 10px; overflow: auto; padding: 12px 14px; background: var(--bpe-bg); border: 1px solid var(--bpe-border); color: var(--bpe-fg); font-size: var(--bpe-text-sm); }\\n.bpe-boundary > svg { flex-shrink: 0; margin-top: 1px; color: var(--bpe-warning); }\\n.bpe-boundary__body { flex: 1; min-width: 0; }\\n.bpe-boundary__title { font-weight: 600; }\\n.bpe-boundary__detail { margin-top: 2px; color: var(--bpe-fg-muted); }\\n\\n/* Where it went. Applied to a block the canvas has just scrolled to, so an\\n insertion that landed on another page is visibly an insertion and not a\\n jump. Motion-sensitive users get the tint without the pulse. */\\n@keyframes bpe-flash {\\n 0% { box-shadow: 0 0 0 2px var(--bpe-accent), 0 0 0 7px var(--bpe-accent-soft); background-color: var(--bpe-accent-soft); }\\n 70% { box-shadow: 0 0 0 2px var(--bpe-accent), 0 0 0 7px var(--bpe-accent-soft); background-color: var(--bpe-accent-soft); }\\n 100% { box-shadow: 0 0 0 0 transparent, 0 0 0 0 transparent; background-color: transparent; }\\n}\\n.bpe-flash { animation: bpe-flash 1.2s ease-out both; border-radius: 3px; }\\n@media (prefers-reduced-motion: reduce) {\\n .bpe-flash { animation: none; background-color: var(--bpe-accent-soft); box-shadow: 0 0 0 2px var(--bpe-accent); }\\n}\\n.bpe-empty__title { font-weight: 600; color: var(--bpe-fg-secondary); }\\n\\n/* form field */\\n.bpe-field { display: grid; grid-template-columns: 96px minmax(0, 1fr); align-items: center; gap: 6px 10px; min-height: var(--bpe-control-h); }\\n.bpe-field--stacked { grid-template-columns: 1fr; gap: 4px; }\\n.bpe-field__label { font-size: var(--bpe-text-sm); color: var(--bpe-fg-secondary); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n.bpe-field__control { min-width: 0; display: flex; align-items: center; gap: 4px; }\\n.bpe-field__hint { grid-column: 1 / -1; min-width: 0; margin-top: -2px; font-size: var(--bpe-text-xs); color: var(--bpe-fg-muted); line-height: 1.35; overflow-wrap: anywhere; }\\n.bpe-field__error { grid-column: 1 / -1; font-size: var(--bpe-text-xs); color: var(--bpe-danger); }\\n.bpe-prop-grid { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; }\\n.bpe-section { border-bottom: 1px solid var(--bpe-border); }\\n.bpe-section__head { display: flex; align-items: center; gap: 4px; width: 100%; height: 34px; padding: 0 8px 0 0; }\\n.bpe-section__toggle { display: flex; align-items: center; gap: 6px; flex: 1; min-width: 0; height: 100%; padding: 0 4px 0 12px; border: 0; background: transparent; color: var(--bpe-fg); font-size: var(--bpe-text-sm); font-weight: 600; text-align: left; }\\n.bpe-section__toggle:hover { background: var(--bpe-bg-subtle); }\\n.bpe-section__toggle svg { width: 13px; height: 13px; color: var(--bpe-fg-faint); transition: transform var(--bpe-dur) var(--bpe-ease); }\\n.bpe-section__toggle[aria-expanded=\\\"false\\\"] svg.bpe-section__chev { transform: rotate(-90deg); }\\n.bpe-section__toggle .bpe-section__chev { margin-left: auto; }\\n.bpe-section__actions { display: inline-flex; }\\n.bpe-section__body { padding-bottom: 4px; }\\n\\n/* ------------------------------------------------------------------ */\\n/* Toolbar */\\n/* ------------------------------------------------------------------ */\\n/* The side tracks must be allowed to shrink. As plain `1fr` they refuse to go\\n below their own content, so the end group overflowed leftwards and drew the\\n brand picker on top of the Preview button instead of giving anything up. */\\n.bpe-toolbar { grid-area: toolbar; display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 8px; padding: 0 12px; border-bottom: 1px solid var(--bpe-border); background: var(--bpe-bg); z-index: 5; }\\n.bpe-toolbar__group { display: flex; align-items: center; gap: 4px; min-width: 0; }\\n.bpe-toolbar__group--end { justify-content: flex-end; }\\n.bpe-toolbar__sep { width: 1px; height: 20px; margin: 0 6px; background: var(--bpe-border); }\\n.bpe-toolbar__brand { display: flex; align-items: center; gap: 8px; margin-right: 6px; min-width: 0; }\\n/* The product mark. No tile behind it: the sheet is the shape, and a tile\\n would make it a second rectangle inside a rectangle. */\\n.bpe-toolbar__mark { display: grid; place-items: center; flex-shrink: 0; }\\n.bpe-toolbar__mark svg { width: 22px; height: 18px; display: block; }\\n.bpe-toolbar__name { height: 26px; flex: 0 1 auto; min-width: 0; width: 220px; max-width: 260px; padding: 0 6px; border: 1px solid transparent; border-radius: var(--bpe-radius-sm); background: transparent; font-weight: 600; font-size: var(--bpe-text-md); color: var(--bpe-fg); }\\n.bpe-toolbar__name:hover { border-color: var(--bpe-border); }\\n.bpe-toolbar__name:focus { border-color: var(--bpe-accent); box-shadow: 0 0 0 3px var(--bpe-accent-soft); }\\n/* The centre group never gives up room; the ends shrink around it. */\\n.bpe-toolbar__group--centre { flex: 0 0 auto; white-space: nowrap; }\\n.bpe-toolbar__group--start { overflow: hidden; }\\n\\n.bpe-save { display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 7px; border: 1px solid transparent; border-radius: var(--bpe-radius-sm); font-size: var(--bpe-text-xs); font-weight: 500; white-space: nowrap; flex-shrink: 0; }\\n.bpe-save__text { max-width: 130px; overflow: hidden; text-overflow: ellipsis; }\\n.bpe-save--muted, .bpe-save--clean { color: var(--bpe-fg-faint); }\\n.bpe-save--dirty { color: var(--bpe-warning); background: var(--bpe-bg-muted); }\\n.bpe-save--busy { color: var(--bpe-fg-secondary); }\\n.bpe-save--error { color: var(--bpe-danger); border-color: var(--bpe-danger); }\\n.bpe-save--action { cursor: pointer; }\\n.bpe-save--action:hover { background: var(--bpe-bg-subtle); }\\n.bpe-sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }\\n\\n.bpe-theme-select__name { max-width: 140px; }\\n\\n.bpe-issues { width: 340px; }\\n.bpe-issues__group + .bpe-issues__group { border-top: 1px solid var(--bpe-border); margin-top: 6px; padding-top: 8px; }\\n.bpe-issues__head { display: flex; align-items: center; gap: 6px; padding: 2px 10px 0; }\\n.bpe-issues__title { font-size: var(--bpe-text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--bpe-fg-secondary); }\\n.bpe-issues__blurb { margin: 2px 10px 6px; font-size: var(--bpe-text-xs); color: var(--bpe-fg-faint); line-height: 1.45; }\\n.bpe-issues__ok { display: flex; align-items: baseline; gap: 5px; padding: 2px 10px 6px; font-size: var(--bpe-text-xs); color: var(--bpe-fg-faint); flex-wrap: wrap; }\\n.bpe-issues__ok strong { color: var(--bpe-fg-secondary); font-weight: 600; }\\n.bpe-mode { width: auto; }\\n.bpe-mode .bpe-segmented__item { padding: 0 12px; height: 24px; }\\n.bpe-zoom { display: inline-flex; align-items: center; gap: 2px; }\\n.bpe-zoom__value { min-width: 44px; text-align: center; font-size: var(--bpe-text-sm); font-variant-numeric: tabular-nums; color: var(--bpe-fg-secondary); }\\n.bpe-theme-select { display: inline-flex; align-items: center; gap: 6px; height: var(--bpe-control-h); padding: 0 8px 0 6px; border: 1px solid var(--bpe-border); border-radius: var(--bpe-radius); background: var(--bpe-bg); font-size: var(--bpe-text-sm); font-weight: 500; }\\n.bpe-theme-select:hover { border-color: var(--bpe-border-strong); background: var(--bpe-bg-subtle); }\\n.bpe-swatches { display: inline-flex; gap: 2px; }\\n.bpe-swatch { width: 10px; height: 10px; border-radius: 3px; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08); }\\n\\n/* ------------------------------------------------------------------ */\\n/* Left panel */\\n/* ------------------------------------------------------------------ */\\n.bpe-left { grid-area: left; display: flex; flex-direction: column; min-height: 0; border-right: 1px solid var(--bpe-border); background: var(--bpe-bg); overflow: hidden; }\\n.bpe-left__body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }\\n.bpe-search { position: relative; padding: 8px 10px 6px; }\\n.bpe-search svg { position: absolute; left: 18px; top: 50%; transform: translateY(-50%); width: 13px; height: 13px; color: var(--bpe-fg-faint); pointer-events: none; }\\n.bpe-search .bpe-input { padding-left: 26px; }\\n.bpe-palette__group { padding: 4px 10px 10px; }\\n.bpe-palette__title { display: flex; align-items: center; gap: 6px; padding: 8px 2px 6px; font-size: var(--bpe-text-xs); font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--bpe-fg-faint); }\\n.bpe-palette__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }\\n.bpe-palette__item { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 8px 9px; border: 1px solid var(--bpe-border); border-radius: var(--bpe-radius); background: var(--bpe-bg); color: var(--bpe-fg); text-align: left; cursor: grab; user-select: none; transition: border-color var(--bpe-dur) var(--bpe-ease), background var(--bpe-dur) var(--bpe-ease), transform 120ms var(--bpe-ease), box-shadow var(--bpe-dur) var(--bpe-ease); }\\n.bpe-palette__item:hover { border-color: var(--bpe-border-strong); background: var(--bpe-bg-subtle); transform: translateY(-1px); box-shadow: var(--bpe-shadow); }\\n.bpe-palette__item:active { cursor: grabbing; transform: none; }\\n.bpe-palette__item svg { width: 16px; height: 16px; color: var(--bpe-fg-secondary); }\\n.bpe-palette__item-name { font-size: var(--bpe-text-sm); font-weight: 500; line-height: 1.2; }\\n.bpe-palette__tier { position: absolute; top: 4px; right: 5px; font-size: 8.5px; font-weight: 700; letter-spacing: 0.06em; color: var(--bpe-accent); }\\n.bpe-palette__item--locked { opacity: 0.55; cursor: not-allowed; }\\n.bpe-palette__item--locked .bpe-palette__tier { color: var(--bpe-fg-faint); }\\n.bpe-layouts__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }\\n.bpe-layout-item { display: flex; flex-direction: column; gap: 6px; padding: 8px; border: 1px solid var(--bpe-border); border-radius: var(--bpe-radius); background: var(--bpe-bg); cursor: grab; }\\n.bpe-layout-item:hover { border-color: var(--bpe-border-strong); background: var(--bpe-bg-subtle); }\\n.bpe-layout-item__cols { display: grid; gap: 3px; height: 22px; }\\n.bpe-layout-item__col { background: var(--bpe-bg-muted); border: 1px solid var(--bpe-border-strong); border-radius: 3px; }\\n.bpe-layout-item__name { font-size: var(--bpe-text-xs); color: var(--bpe-fg-secondary); font-weight: 500; }\\n\\n.bpe-data-tree { padding: 4px 6px 12px; }\\n.bpe-data-source { margin-bottom: 4px; }\\n.bpe-data-source__head { display: flex; align-items: center; gap: 6px; width: 100%; height: 28px; padding: 0 6px; border: 0; border-radius: var(--bpe-radius-sm); background: transparent; color: var(--bpe-fg); font-weight: 600; font-size: var(--bpe-text-sm); text-align: left; }\\n.bpe-data-source__head:hover { background: var(--bpe-bg-subtle); }\\n.bpe-data-source__head svg { width: 13px; height: 13px; color: var(--bpe-fg-faint); }\\n.bpe-data-field { display: flex; align-items: center; gap: 6px; width: 100%; height: 26px; padding: 0 6px; border: 0; border-radius: var(--bpe-radius-sm); background: transparent; color: var(--bpe-fg); font-size: var(--bpe-text-sm); text-align: left; cursor: grab; }\\n.bpe-data-field:hover { background: var(--bpe-accent-soft); }\\n.bpe-data-field__type { margin-left: auto; font-size: 9.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--bpe-fg-faint); }\\n.bpe-data-field__icon { width: 13px; height: 13px; color: var(--bpe-fg-muted); flex-shrink: 0; }\\n.bpe-data-field--group { color: var(--bpe-fg-secondary); cursor: default; }\\n.bpe-data-children { padding-left: 14px; border-left: 1px solid var(--bpe-border); margin-left: 12px; }\\n\\n.bpe-layers { padding: 6px 6px 12px; }\\n.bpe-layer { display: flex; align-items: center; gap: 5px; height: 26px; padding-right: 4px; border-radius: var(--bpe-radius-sm); color: var(--bpe-fg); font-size: var(--bpe-text-sm); cursor: default; user-select: none; }\\n.bpe-layer:hover { background: var(--bpe-bg-subtle); }\\n.bpe-layer--selected { background: var(--bpe-accent-soft) !important; color: var(--bpe-accent); }\\n.bpe-layer--hover { background: var(--bpe-bg-muted); }\\n.bpe-layer { cursor: grab; }\\n.bpe-layer:active { cursor: grabbing; }\\n/* Row actions stay out of the way until the row is wanted, so the tree still\\n reads as a tree rather than as a wall of buttons. */\\n.bpe-layer__actions { display: none; margin-left: auto; gap: 0; flex-shrink: 0; }\\n.bpe-layer:hover .bpe-layer__actions, .bpe-layer--selected .bpe-layer__actions { display: flex; }\\n.bpe-layer__actions .bpe-btn { width: 20px; height: 20px; }\\n.bpe-layer__actions .bpe-btn svg { width: 12px; height: 12px; }\\n.bpe-layer:hover .bpe-layer__meta, .bpe-layer--selected .bpe-layer__meta { display: none; }\\n\\n.bpe-layer__toggle { display: grid; place-items: center; width: 18px; height: 18px; border: 0; background: transparent; color: var(--bpe-fg-faint); padding: 0; border-radius: 3px; flex-shrink: 0; }\\n.bpe-layer__toggle svg { width: 12px; height: 12px; transition: transform var(--bpe-dur) var(--bpe-ease); }\\n.bpe-layer__toggle[aria-expanded=\\\"false\\\"] svg { transform: rotate(-90deg); }\\n.bpe-layer__icon { width: 13px; height: 13px; color: var(--bpe-fg-muted); flex-shrink: 0; }\\n.bpe-layer--selected .bpe-layer__icon { color: var(--bpe-accent); }\\n.bpe-layer__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n.bpe-layer__meta { font-size: var(--bpe-text-xs); color: var(--bpe-fg-faint); }\\n\\n.bpe-library__item { display: flex; align-items: center; gap: 8px; padding: 8px 10px; margin: 0 8px 6px; border: 1px solid var(--bpe-border); border-radius: var(--bpe-radius); cursor: grab; background: var(--bpe-bg); }\\n.bpe-library__item:hover { border-color: var(--bpe-border-strong); background: var(--bpe-bg-subtle); }\\n.bpe-library__item svg { width: 15px; height: 15px; color: var(--bpe-fg-secondary); }\\n.bpe-library__name { font-weight: 500; font-size: var(--bpe-text-sm); }\\n.bpe-library__desc { font-size: var(--bpe-text-xs); color: var(--bpe-fg-muted); }\\n\\n/* ------------------------------------------------------------------ */\\n/* Canvas */\\n/* ------------------------------------------------------------------ */\\n.bpe-canvas { grid-area: canvas; position: relative; display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--bpe-bg-canvas); }\\n.bpe-canvas__scroll { position: relative; flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; }\\n.bpe-canvas__scroll:focus-visible { box-shadow: none; }\\n.bpe-canvas__inner { position: relative; padding: 32px 40px 80px; display: flex; flex-direction: column; align-items: center; min-width: min-content; }\\n.bpe-pages { position: relative; display: flex; flex-direction: column; transform-origin: top center; }\\n.bpe-page-slot { position: relative; box-shadow: var(--bpe-shadow-page); background: #fff; }\\n.bpe-page-slot--placeholder { background: #fff; opacity: 0.9; }\\n.bpe-page-number { position: absolute; left: 0; top: -20px; font-size: var(--bpe-text-xs); color: var(--bpe-fg-muted); font-weight: 500; user-select: none; }\\n.bpe-canvas--design .bp-page__region { outline: 1px dashed rgba(59, 91, 219, 0.22); outline-offset: -1px; }\\n.bpe-canvas--design .bp-page__region:hover { outline-color: rgba(59, 91, 219, 0.5); }\\n.bpe-canvas--design .bp-page__region::before { content: attr(data-region); position: absolute; right: 0; top: -14px; font: 600 9px/1 var(--bpe-font); letter-spacing: 0.08em; text-transform: uppercase; color: rgba(59, 91, 219, 0.55); opacity: 0; transition: opacity var(--bpe-dur); }\\n.bpe-canvas--design .bp-page__region:hover::before, .bpe-canvas--design .bp-page__region--active::before { opacity: 1; }\\n.bpe-canvas--design .bp-page__footer::before { top: auto; bottom: -14px; }\\n.bpe-canvas--design .bp-page__body { outline: 1px dashed transparent; }\\n.bpe-canvas--design.bpe-canvas--guides .bp-page__body { outline-color: rgba(0,0,0,0.08); }\\n.bpe-canvas--design .bp-node { cursor: default; }\\n.bpe-canvas--design .bp-node--text .bp-text, .bpe-canvas--design .bp-heading { cursor: text; }\\n.bpe-canvas--design .bp-node[data-editing] > * { visibility: hidden; }\\n.bpe-canvas--design a { pointer-events: none; }\\n.bpe-canvas--dragging, .bpe-canvas--dragging * { cursor: grabbing !important; user-select: none !important; }\\n\\n/* overlays */\\n.bpe-overlay { position: absolute; inset: 0; pointer-events: none; z-index: 3; }\\n.bpe-outline { position: absolute; border: 1.5px solid var(--bpe-hover-outline); border-radius: 2px; pointer-events: none; transition: none; }\\n.bpe-outline--selected { border-color: var(--bpe-selection); border-width: 2px; box-shadow: 0 0 0 1px rgba(255,255,255,0.7) inset; }\\n.bpe-outline--section { border-style: dashed; border-color: rgba(59,91,219,0.35); }\\n.bpe-outline__label { position: absolute; left: -2px; top: -20px; display: inline-flex; align-items: center; gap: 4px; height: 18px; padding: 0 6px; border-radius: 4px 4px 0 0; background: var(--bpe-selection); color: #fff; font: 600 10px/1 var(--bpe-font); letter-spacing: 0.02em; white-space: nowrap; }\\n.bpe-outline--hover .bpe-outline__label { background: var(--bpe-hover-outline); }\\n.bpe-outline__label svg { width: 10px; height: 10px; }\\n.bpe-block-toolbar { position: absolute; z-index: 4; display: inline-flex; align-items: center; gap: 2px; padding: 3px; border-radius: 7px; border: 1px solid var(--bpe-border); background: var(--bpe-bg-elevated); box-shadow: var(--bpe-shadow-lg); pointer-events: auto; animation: bpe-pop var(--bpe-dur) var(--bpe-ease); }\\n.bpe-block-toolbar .bpe-btn--icon { width: 24px; height: 24px; }\\n.bpe-block-toolbar .bpe-btn svg { width: 13px; height: 13px; }\\n.bpe-block-toolbar__handle { cursor: grab; }\\n.bpe-block-toolbar__handle:active { cursor: grabbing; }\\n.bpe-block-toolbar__type { padding: 0 6px 0 4px; font-size: var(--bpe-text-xs); font-weight: 600; color: var(--bpe-fg-secondary); white-space: nowrap; }\\n/* The field list offered while a \\\"{{\\\" is open. Positioned in the overlay's\\n coordinate space, so it tracks the caret rather than the block. */\\n.bpe-suggest { position: absolute; z-index: 40; width: 340px; max-height: 268px; overflow-y: auto; padding: 4px; border-radius: var(--bpe-radius); border: 1px solid var(--bpe-border); background: var(--bpe-bg-elevated); box-shadow: var(--bpe-shadow-lg); font-size: var(--bpe-text-sm); }\\n.bpe-suggest__item { display: flex; align-items: center; gap: 7px; min-width: 0; padding: 5px 8px; border-radius: var(--bpe-radius-sm); cursor: pointer; }\\n.bpe-suggest__item--active { background: var(--bpe-accent-soft); }\\n.bpe-suggest__icon { color: var(--bpe-fg-faint); flex-shrink: 0; }\\n.bpe-suggest__item--active .bpe-suggest__icon { color: var(--bpe-accent); }\\n.bpe-suggest__label { flex: 1; min-width: 0; color: var(--bpe-fg); }\\n.bpe-suggest__expr { flex-shrink: 0; max-width: 45%; color: var(--bpe-fg-faint); font-family: var(--bpe-font-mono); font-size: 10.5px; }\\n.bpe-suggest__hint { padding: 6px 8px 3px; color: var(--bpe-fg-faint); font-size: 10.5px; border-top: 1px solid var(--bpe-border); margin-top: 4px; }\\n.bpe-suggest__hint kbd { display: inline-block; padding: 0 3px; border: 1px solid var(--bpe-border); border-bottom-width: 2px; border-radius: 3px; font-family: inherit; font-size: 9.5px; }\\n\\n/* Where a click said the next block should go. Quieter than a drop line,\\n because it is a standing intention rather than something happening now. */\\n.bpe-caret { position: absolute; height: 2px; margin-top: -1px; border-radius: 2px; background: var(--bpe-accent); opacity: 0.85; pointer-events: none; z-index: 4; animation: bpe-caret-blink 1.1s ease-in-out infinite; }\\n.bpe-caret::before { content: \\\"\\\"; position: absolute; left: -4px; top: -3px; width: 8px; height: 8px; border-radius: 50%; background: var(--bpe-accent); }\\n@keyframes bpe-caret-blink { 0%, 100% { opacity: 0.85; } 50% { opacity: 0.35; } }\\n@media (prefers-reduced-motion: reduce) { .bpe-caret { animation: none; } }\\n\\n.bpe-drop-line { position: absolute; height: 3px; margin-top: -1.5px; border-radius: 2px; background: var(--bpe-drop); box-shadow: 0 0 0 1px rgba(255,255,255,0.8), 0 0 8px rgba(16,185,129,0.5); pointer-events: none; z-index: 5; }\\n.bpe-drop-line::before, .bpe-drop-line::after { content: \\\"\\\"; position: absolute; top: -3.5px; width: 10px; height: 10px; border-radius: 50%; background: var(--bpe-drop); box-shadow: 0 0 0 2px #fff; }\\n.bpe-drop-line::before { left: -5px; }\\n.bpe-drop-line::after { right: -5px; }\\n.bpe-drop-zone { position: absolute; border: 2px solid var(--bpe-drop); border-radius: 4px; background: rgba(16,185,129,0.06); pointer-events: none; z-index: 4; }\\n.bpe-drop-zone--invalid { border-color: var(--bpe-danger); background: var(--bpe-danger-soft); }\\n.bpe-drag-ghost { position: fixed; z-index: 2000; pointer-events: none; display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; border-radius: var(--bpe-radius); background: var(--bpe-fg); color: var(--bpe-bg); font: 500 12px var(--bpe-font); box-shadow: var(--bpe-shadow-lg); transform: translate(12px, 12px); }\\n.bpe-drag-ghost svg { width: 14px; height: 14px; }\\n.bpe-page-gap { position: absolute; left: 0; right: 0; display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity var(--bpe-dur); pointer-events: auto; }\\n.bpe-page-gap:hover { opacity: 1; }\\n\\n.bpe-canvas__bar { display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 10px; border-top: 1px solid var(--bpe-border); background: var(--bpe-bg); font-size: var(--bpe-text-xs); color: var(--bpe-fg-muted); }\\n.bpe-breadcrumb { display: flex; align-items: center; gap: 2px; min-width: 0; overflow: hidden; }\\n.bpe-breadcrumb__item { display: inline-flex; align-items: center; gap: 4px; height: 20px; padding: 0 6px; border: 0; border-radius: 4px; background: transparent; color: var(--bpe-fg-muted); font-size: var(--bpe-text-xs); white-space: nowrap; }\\n.bpe-breadcrumb__item:hover { background: var(--bpe-bg-muted); color: var(--bpe-fg); }\\n.bpe-breadcrumb__item--current { color: var(--bpe-fg); font-weight: 600; }\\n.bpe-breadcrumb__sep { color: var(--bpe-fg-faint); }\\n.bpe-canvas__bar-end { margin-left: auto; display: flex; align-items: center; gap: 8px; }\\n\\n/* inline editor */\\n.bpe-inline-editor { position: absolute; z-index: 6; outline: none; }\\n.bpe-inline-editor .ProseMirror { outline: none; white-space: pre-wrap; word-wrap: break-word; min-height: 1em; }\\n.bpe-inline-editor .ProseMirror p { margin: 0; }\\n.bpe-inline-editor .ProseMirror ul, .bpe-inline-editor .ProseMirror ol { margin: 0; padding-left: 1.4em; }\\n.bpe-inline-editor .ProseMirror .bp-token { display: inline; padding: 0 5px; margin: 0 1px; border-radius: 4px; background: var(--bpe-token-bg); color: var(--bpe-token); font-size: 0.92em; font-weight: 500; white-space: nowrap; user-select: none; }\\n.bpe-inline-editor .ProseMirror .bp-token.ProseMirror-selectednode { outline: 2px solid var(--bpe-accent); }\\n.bpe-inline-editor .ProseMirror-gapcursor { display: none; }\\n.bpe-inline-editor__frame { position: absolute; inset: -4px; border: 1.5px solid var(--bpe-accent); border-radius: 3px; pointer-events: none; }\\n.bpe-bubble { position: absolute; z-index: 7; display: inline-flex; align-items: center; gap: 2px; padding: 3px; border-radius: 8px; border: 1px solid var(--bpe-border); background: var(--bpe-bg-elevated); box-shadow: var(--bpe-shadow-lg); animation: bpe-pop var(--bpe-dur) var(--bpe-ease); }\\n.bpe-bubble .bpe-btn--icon { width: 26px; height: 26px; }\\n.bpe-bubble__sep { width: 1px; height: 18px; margin: 0 2px; background: var(--bpe-border); }\\n\\n/* ------------------------------------------------------------------ */\\n/* Inspector */\\n/* ------------------------------------------------------------------ */\\n.bpe-inspector { grid-area: right; display: flex; flex-direction: column; min-height: 0; border-left: 1px solid var(--bpe-border); background: var(--bpe-bg); overflow: hidden; }\\n.bpe-inspector__header { display: flex; align-items: center; gap: 8px; height: 44px; padding: 0 12px; border-bottom: 1px solid var(--bpe-border); }\\n.bpe-inspector__icon { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 6px; background: var(--bpe-accent-soft); color: var(--bpe-accent); flex-shrink: 0; }\\n.bpe-inspector__icon svg { width: 14px; height: 14px; }\\n.bpe-inspector__title { font-weight: 600; font-size: var(--bpe-text-md); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n.bpe-inspector__subtitle { font-size: var(--bpe-text-xs); color: var(--bpe-fg-muted); }\\n.bpe-inspector__body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }\\n.bpe-inspector__actions { margin-left: auto; display: flex; gap: 2px; }\\n.bpe-spacing-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px; }\\n.bpe-spacing-grid .bpe-input { padding: 0 4px; text-align: center; }\\n.bpe-spacing-grid__lbl { font-size: 9px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--bpe-fg-faint); text-align: center; margin-top: 2px; }\\n.bpe-color-btn { display: inline-flex; align-items: center; gap: 6px; height: var(--bpe-control-h); width: 100%; padding: 0 8px 0 6px; border: 1px solid var(--bpe-border); border-radius: var(--bpe-radius); background: var(--bpe-bg); font-size: var(--bpe-text-sm); text-align: left; }\\n.bpe-color-btn:hover { border-color: var(--bpe-border-strong); }\\n.bpe-color-btn__swatch { width: 16px; height: 16px; border-radius: 4px; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12); flex-shrink: 0; background-image: linear-gradient(45deg, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%), linear-gradient(45deg, #ddd 25%, transparent 25%, transparent 75%, #ddd 75%); background-size: 8px 8px; background-position: 0 0, 4px 4px; }\\n.bpe-color-btn__swatch::after { content: \\\"\\\"; display: block; width: 100%; height: 100%; border-radius: 4px; background: var(--c, transparent); }\\n.bpe-color-btn__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n.bpe-color-popover { width: 236px; }\\n.bpe-color-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 4px; padding: 4px; }\\n.bpe-color-grid__item { position: relative; width: 24px; height: 24px; border-radius: 6px; border: 1px solid rgba(0,0,0,0.08); background: var(--c); padding: 0; }\\n.bpe-color-grid__item[aria-pressed=\\\"true\\\"] { box-shadow: 0 0 0 2px var(--bpe-bg), 0 0 0 4px var(--bpe-accent); }\\n.bpe-color-token { display: flex; align-items: center; gap: 8px; width: 100%; height: 26px; padding: 0 6px; border: 0; border-radius: 4px; background: transparent; font-size: var(--bpe-text-sm); text-align: left; color: var(--bpe-fg); }\\n.bpe-color-token:hover { background: var(--bpe-bg-muted); }\\n.bpe-color-token[aria-pressed=\\\"true\\\"] { background: var(--bpe-accent-soft); color: var(--bpe-accent); }\\n.bpe-color-token__sw { width: 14px; height: 14px; border-radius: 4px; background: var(--c); box-shadow: inset 0 0 0 1px rgba(0,0,0,0.1); }\\n.bpe-color-token__val { margin-left: auto; font-family: var(--bpe-font-mono); font-size: 10px; color: var(--bpe-fg-faint); }\\n.bpe-binding { display: flex; align-items: center; gap: 4px; width: 100%; min-width: 0; }\\n/* The image field's file input is opened by the button beside it. Hidden with\\n clip rather than display:none so the browser still counts it as a real\\n control and the button's click reaches it. */\\n.bpe-image__file { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }\\n.bpe-binding__btn { display: flex; align-items: center; gap: 6px; flex: 1; min-width: 0; height: var(--bpe-control-h); padding: 0 8px; border: 1px solid var(--bpe-border); border-radius: var(--bpe-radius); background: var(--bpe-bg); text-align: left; font-size: var(--bpe-text-sm); }\\n.bpe-binding__btn:hover { border-color: var(--bpe-border-strong); }\\n.bpe-binding__btn--empty { color: var(--bpe-fg-faint); }\\n.bpe-binding__btn svg { width: 13px; height: 13px; flex-shrink: 0; color: var(--bpe-fg-muted); }\\n.bpe-expr { font-family: var(--bpe-font-mono); font-size: 11px; }\\n.bpe-picker { width: 300px; max-height: 380px; display: flex; flex-direction: column; padding: 0; overflow: hidden; }\\n.bpe-picker__search { padding: 8px; border-bottom: 1px solid var(--bpe-border); }\\n.bpe-picker__list { flex: 1; overflow-y: auto; padding: 4px; }\\n.bpe-picker__foot { display: flex; gap: 6px; align-items: center; padding: 8px; border-top: 1px solid var(--bpe-border); }\\n.bpe-picker__foot .bpe-input { flex: 1; }\\n.bpe-picker__group { padding: 6px 6px 2px; font-size: var(--bpe-text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--bpe-fg-faint); }\\n.bpe-cond { display: flex; flex-direction: column; gap: 6px; min-width: 0; }\\n.bpe-cond__rule { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px; min-width: 0; padding: 6px; border: 1px solid var(--bpe-border); border-radius: var(--bpe-radius); background: var(--bpe-bg-subtle); }\\n.bpe-cond__row { display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px; min-width: 0; }\\n.bpe-cond__op { display: flex; align-items: center; gap: 6px; }\\n.bpe-cond__group { padding: 6px; border: 1px dashed var(--bpe-border-strong); border-radius: var(--bpe-radius); }\\n.bpe-list-editor { display: flex; flex-direction: column; gap: 6px; min-width: 0; }\\n.bpe-list-editor__item { border: 1px solid var(--bpe-border); border-radius: var(--bpe-radius); background: var(--bpe-bg-subtle); }\\n.bpe-list-editor__head { display: flex; align-items: center; gap: 4px; min-width: 0; overflow: hidden; height: 28px; padding: 0 4px 0 8px; font-size: var(--bpe-text-sm); font-weight: 500; }\\n.bpe-list-editor__head .bpe-truncate { flex: 1 1 0; min-width: 0; }\\n.bpe-list-editor__item { min-width: 0; }\\n.bpe-list-editor__body { padding: 6px 8px 8px; border-top: 1px solid var(--bpe-border); display: flex; flex-direction: column; gap: 6px; }\\n.bpe-list-editor__drag { cursor: grab; color: var(--bpe-fg-faint); display: inline-flex; }\\n.bpe-issue { display: flex; gap: 8px; align-items: flex-start; width: 100%; padding: 6px 8px; border: 0; border-radius: var(--bpe-radius-sm); background: transparent; text-align: left; font-size: var(--bpe-text-sm); color: var(--bpe-fg); }\\n.bpe-issue:hover { background: var(--bpe-bg-muted); }\\n.bpe-issue svg { width: 13px; height: 13px; flex-shrink: 0; margin-top: 2px; }\\n.bpe-issue--error svg { color: var(--bpe-danger); }\\n.bpe-issue--warning svg { color: var(--bpe-warning); }\\n.bpe-issue--info svg { color: var(--bpe-fg-muted); }\\n.bpe-issue__meta { display: block; margin-top: 2px; font-size: var(--bpe-text-xs); color: var(--bpe-fg-muted); }\\n.bpe-text-style-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 6px; }\\n.bpe-text-style-preview { font-weight: 600; }\\n.bpe-doc-styles__item { display: flex; align-items: center; gap: 8px; width: 100%; height: 32px; padding: 0 12px; border: 0; background: transparent; text-align: left; color: var(--bpe-fg); font-size: var(--bpe-text-sm); }\\n.bpe-doc-styles__item:hover { background: var(--bpe-bg-subtle); }\\n.bpe-doc-styles__sample { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n.bpe-doc-styles__id { font-family: var(--bpe-font-mono); font-size: 10px; color: var(--bpe-fg-faint); }\\n.bpe-preview-bar { display: flex; align-items: center; gap: 8px; padding: 6px 12px; background: var(--bpe-accent-soft); color: var(--bpe-accent); font-size: var(--bpe-text-sm); font-weight: 500; border-bottom: 1px solid var(--bpe-border); }\\n.bpe-toast { position: absolute; left: 50%; bottom: 44px; transform: translateX(-50%); z-index: 20; display: inline-flex; align-items: center; gap: 8px; padding: 8px 12px; border-radius: var(--bpe-radius); background: var(--bpe-fg); color: var(--bpe-bg); font-size: var(--bpe-text-sm); box-shadow: var(--bpe-shadow-lg); animation: bpe-pop var(--bpe-dur) var(--bpe-ease); }\\n.bpe-toast svg { width: 14px; height: 14px; }\\n.bpe-portal { position: absolute; width: 0; height: 0; overflow: visible; }\\n.bpe-scope { font-family: var(--bpe-font); }\\n\\n.bpe-pager { display: inline-flex; align-items: center; gap: 2px; }\\n.bpe-pager__label { min-width: 92px; text-align: center; font-variant-numeric: tabular-nums; }\\n\\n/* Panel resize handles sit on the boundary rather than in the grid, so the\\n three-column shell stays three columns and the handles stay draggable even\\n when a panel is scrolled. */\\n.bpe-resizer { position: absolute; top: var(--bpe-toolbar-h); bottom: 0; width: 9px; cursor: col-resize; z-index: 6; background: transparent; touch-action: none; }\\n.bpe-resizer--left { left: var(--bpe-panel-w); margin-left: -4px; }\\n.bpe-resizer--right { right: var(--bpe-inspector-w); margin-right: -4px; }\\n.bpe-resizer::after { content: \\\"\\\"; position: absolute; inset: 0 3px; border-radius: 2px; background: transparent; transition: background var(--bpe-dur) var(--bpe-ease); }\\n.bpe-resizer:hover::after, .bpe-resizer:focus-visible::after { background: var(--bpe-accent); }\\n.bpe-resizer:focus-visible { outline: none; }\\n\\n/* A long label stops being a column and becomes a line of its own. */\\n.bpe-field--stacked .bpe-field__label { white-space: normal; overflow: visible; }\\n\\n.bpe-block-toolbar__edit { font-weight: 500; }\\n\\n.bpe-legend { width: 340px; }\\n.bpe-legend__body { padding: 12px 14px 10px; }\\n.bpe-legend__title { margin: 0 0 6px; font-size: var(--bpe-text-md); font-weight: 600; }\\n.bpe-legend__intro { margin: 0 0 10px; font-size: var(--bpe-text-xs); color: var(--bpe-fg-secondary); line-height: 1.5; }\\n.bpe-legend__list { margin: 0; display: flex; flex-direction: column; gap: 10px; }\\n.bpe-legend__entry { display: flex; gap: 9px; align-items: flex-start; }\\n.bpe-legend__swatch { flex: 0 0 auto; display: grid; place-items: center; min-width: 22px; padding-top: 1px; color: var(--bpe-fg-muted); }\\n.bpe-legend__entry dt { font-size: var(--bpe-text-xs); font-weight: 600; color: var(--bpe-fg); }\\n.bpe-legend__entry dd { margin: 1px 0 0; font-size: var(--bpe-text-xs); color: var(--bpe-fg-muted); line-height: 1.45; }\\n.bpe-legend__token { font-size: 9px; padding: 1px 4px; }\\n.bpe-legend__foot { margin: 10px 0 0; padding-top: 8px; border-top: 1px solid var(--bpe-border); font-size: var(--bpe-text-xs); color: var(--bpe-fg-faint); }\\n\\n/* ===================================================================\\n Narrow — the designer in a container too small for three columns.\\n\\n Set by the shell from the root element's own width, not a media query:\\n the designer is embedded, so a phone and a narrow pane in a wide page\\n are the same problem and the window answers neither. Below the\\n breakpoint the panels stop being columns and become drawers over the\\n canvas, because 272 + 296 of panel leaves a phone about forty pixels\\n of page — which is not a cramped canvas, it is no canvas.\\n =================================================================== */\\n\\n/* Two classes deliberately: `.bpe--no-left.bpe--no-right` is also two, and a\\n single-class rule would lose to it exactly when both panels are shut —\\n which on a phone is the normal state. */\\n.bpe.bpe--narrow { grid-template-columns: minmax(0, 1fr); grid-template-areas: \\\"toolbar\\\" \\\"canvas\\\"; }\\n\\n/* Both panels occupy the canvas cell rather than one of their own, so the\\n canvas keeps its full width whether a drawer is open or not — nothing\\n reflows underneath when one opens, which is what makes it a drawer\\n rather than a column that happens to overlap. */\\n.bpe--narrow .bpe-left, .bpe--narrow .bpe-inspector {\\n grid-area: canvas;\\n z-index: 20;\\n width: min(88%, 360px);\\n max-width: 100%;\\n box-shadow: 0 24px 48px -24px rgba(0, 0, 0, 0.45);\\n animation: bpe-drawer-in 180ms var(--bpe-ease) both;\\n}\\n.bpe--narrow .bpe-left { justify-self: start; border-right: 1px solid var(--bpe-border); }\\n.bpe--narrow .bpe-inspector { justify-self: end; border-left: 1px solid var(--bpe-border); }\\n@keyframes bpe-drawer-in { from { transform: translateX(var(--bpe-drawer-from, -8%)); opacity: 0; } to { transform: none; opacity: 1; } }\\n.bpe--narrow .bpe-inspector { --bpe-drawer-from: 8%; }\\n@media (prefers-reduced-motion: reduce) { .bpe--narrow .bpe-left, .bpe--narrow .bpe-inspector { animation: none; } }\\n\\n/* Tapping the canvas beside an open drawer closes it. A button rather than\\n a div so it is reachable by keyboard and announces itself; it sits under\\n the drawer and over everything else. */\\n.bpe-scrim { grid-area: canvas; z-index: 15; border: 0; padding: 0; background: rgba(23, 21, 17, 0.32); cursor: default; animation: bpe-fade-in 180ms var(--bpe-ease) both; }\\n@keyframes bpe-fade-in { from { opacity: 0; } to { opacity: 1; } }\\n@media (prefers-reduced-motion: reduce) { .bpe-scrim { animation: none; } }\\n\\n/* The page needs the room more than the margin around it does. */\\n.bpe--narrow .bpe-canvas__inner { padding: 12px 12px 48px; }\\n/* Touch targets, and a scroll that does not fight the page it is embedded in. */\\n.bpe--narrow .bpe-btn { min-height: 32px; }\\n.bpe--narrow .bpe-canvas__scroll { -webkit-overflow-scrolling: touch; }\\n\\n/* The toolbar's three tracks assume a row wide enough for all of them. On a\\n phone the centre group alone — Design/Preview plus the zoom controls, both\\n of which refuse to wrap — takes the whole width, leaving the leading and\\n trailing tracks measuring zero and their contents drawn off the edge. So\\n narrow, it wraps: the groups keep their order and their contents, and the\\n toolbar takes the two rows it needs. `.bpe` gives it an auto row to grow\\n into rather than the fixed height a single row assumed. */\\n.bpe.bpe--narrow { grid-template-rows: auto 1fr; }\\n.bpe--narrow .bpe-toolbar { display: flex; flex-wrap: wrap; justify-content: space-between; row-gap: 6px; padding: 6px 8px; }\\n.bpe--narrow .bpe-toolbar__group--start { overflow: visible; flex: 1 1 auto; }\\n.bpe--narrow .bpe-toolbar__group--centre { order: 3; flex: 1 0 100%; justify-content: center; }\\n.bpe--narrow .bpe-toolbar__group--end { flex: 0 0 auto; }\\n/* The report name gives up its fixed width first; it is the one thing in the\\n leading group that can shrink without losing a control. */\\n.bpe--narrow .bpe-toolbar__name { width: auto; min-width: 80px; max-width: none; flex: 1 1 80px; }\\n/* A backstop for the very narrowest: if the mode switch and the zoom controls\\n still will not sit on one row, they take two rather than one of them being\\n drawn off the edge. */\\n.bpe--narrow .bpe-toolbar__group--centre { flex-wrap: wrap; white-space: normal; row-gap: 6px; }\\n\";\n"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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","names":["ensureStyle","useEffect","useMemo","useRef","useState","useSyncExternalStore","useSyncExternalStore","useSyncExternalStore","createContext","useContext","jsx","createContext","useContext","useState","useState","jsx","jsxs","Button","TextInput","useState","useState","jsx","jsxs","jsx","jsxs","useState","useMemo","useState","jsx","jsxs","useState","useMemo","useEffect","useLayoutEffect","useMemo","useRef","useState","cloneWithNewIds","createNode","createRow","richTextFromTemplate","isRichTextDoc","useEffect","useRef","jsx","jsxs","PageView","useLayoutEffect","useState","jsx","jsxs","useState","useLayoutEffect","useEffect","useLayoutEffect","useRef","useState","createSchemaScope","Plugin","handlers","state","Plugin","useEffect","useMemo","useRef","useState","forwardRef","useMemo","useState","jsx","jsxs","useState","useMemo","jsx","jsxs","forwardRef","TokenSuggestions","useState","useRef","useMemo","useEffect","useState","jsx","jsxs","useState","Fragment","jsx","jsxs","useRef","useState","createSchemaScope","useLayoutEffect","useEffect","parentNode","jsx","jsxs","jsx","jsxs","jsx","jsxs","useRef","useState","useEffect","useLayoutEffect","mode","pages","node","isRichTextDoc","richTextFromTemplate","createNode","layout","createRow","cloneWithNewIds","useMemo","useMemo","ROW_LAYOUTS","createSchemaScope","ancestors","useEffect","useRef","useState","checkExpressionSyntax","createSchemaScope","richTextToPlain","richTextFromTemplate","isRichTextDoc","useMemo","createSchemaScope","parseExpression","labelForPath","jsx","jsxs","useMemo","createSchemaScope","parseExpression","labelForPath","useRef","useState","jsx","jsxs","useRef","useState","url","checkExpressionSyntax","useState","jsx","jsxs","checkExpressionSyntax","useState","createId","Fragment","jsx","jsxs","useState","createId","value","jsx","jsxs","isRichTextDoc","richTextFromTemplate","richTextToPlain","checkExpressionSyntax","useRef","createSchemaScope","useEffect","useState","textStyleLabel","Fragment","jsx","jsxs","textStyleLabel","Fragment","jsx","jsxs","ancestors","createSchemaScope","useMemo","label","ROW_LAYOUTS","useState","textStyleLabel","Fragment","jsx","jsxs","useState","textStyleLabel","jsx","jsxs","useRef","jsx","jsx","jsxs","Fragment","jsx","jsxs","useMemo","useState","useRef","useEffect","leftWidth","rightWidth","ensureStyle"]}