@embedpdf/core-ui 3.0.0-next.13 → 3.0.0-next.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1238 -250
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +598 -127
- package/dist/index.d.ts +598 -127
- package/dist/index.js +1195 -245
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["makeGroup"],"sources":["../src/schema.ts","../src/transforms.ts","../src/helpers.ts","../src/solver.ts","../src/projection.ts","../src/shortcuts.ts"],"sourcesContent":["/**\n * @embedpdf/core-ui — the structure-only schema vocabulary.\n *\n * The schema contains ONLY what a designer decides and the runtime cannot\n * compute: order, grouping, importance, and each item's degradation ladder.\n * Everything the runtime CAN compute is banned from it by construction:\n * no breakpoints, no show/hide lists, no locale overrides, no dividers, no\n * spacers, no hand-written overflow menus. Fit is measured and solved at\n * runtime (see solver.ts); the overflow menu is derived (see projection.ts).\n */\n\n/** Presentation ladder for a command button, richest first. */\nexport type Variant = 'icon+label' | 'icon' | 'label';\n\n/**\n * Who yields space first. 1 = first to degrade/overflow · 3 = default ·\n * 5 = pinned: may still degrade variants, but NEVER leaves the bar.\n */\nexport type Importance = 1 | 2 | 3 | 4 | 5;\n\nexport const PINNED: Importance = 5;\n\nexport interface BarItem {\n /** The command this button runs — the only required field. */\n readonly command: string;\n /** Degradation ladder, richest first. Default: ['icon']. */\n readonly variants?: readonly Variant[];\n readonly importance?: Importance;\n}\n\n/**\n * An app-rendered slot (e.g. the inline zoom strip). Each named variant is\n * measured like any command button. The ladder MUST terminate in a command\n * (`terminal`) so the item always has a menu form when it overflows — this\n * is what makes the overflow projection total.\n */\nexport interface CustomItem {\n readonly slot: string;\n /** Named presentation variants, richest first. Default: ['default']. */\n readonly variants?: readonly string[];\n /** The command that stands in for this slot in menus (its last resort). */\n readonly terminal: string;\n readonly importance?: Importance;\n}\n\nexport type BarChild = BarItem | CustomItem | string; // string = { command }\n\nexport interface BarGroup {\n readonly id: string;\n /** Titles the group's menu form (labeled submenu / section heading). */\n readonly labelKey?: string;\n /** Presentation hint: 'tabs' renders as a tab strip and projects as radio rows. */\n readonly role?: 'buttons' | 'tabs';\n /**\n * Stage 1 of the GROUP degradation ladder: under pressure, move trailing\n * children (rightmost first, at the CHILD's importance) into a derived\n * group-local disclosure — a trigger rendered inside the group opening a\n * menu of the hidden children. Never sheds the last visible child: below\n * that floor the group `collapse`s (stage 2) or overflows whole. This is\n * v2's `overflow-tabs-button`, computed instead of authored.\n */\n readonly shed?: boolean;\n /**\n * Stage 2: what the WHOLE group degrades to once its children have\n * exhausted their ladders (and shedding, if enabled, has hit its floor): a\n * single menu button or a select-style picker. Groups with neither `shed`\n * nor `collapse` send children to the global overflow menu one by one.\n */\n readonly collapse?: 'menu' | 'select';\n readonly importance?: Importance;\n readonly items: readonly BarChild[];\n}\n\n/**\n * Alignment regions. Separators derive between adjacent visible groups\n * within a section — never across sections, never from schema data.\n *\n * The names are direction-aware (RTL flips start/end) and `center` is a\n * SOFT contract: \"balance this segment in the space left over by start and\n * end\". With symmetric flanks that coincides with true centering; with a\n * heavy flank the segment drifts rather than fights — segments never\n * overlap, matching how every toolbar convention (including v2's\n * spacer-flanked tabs) treats its middle region. Strict geometric centering\n * would be a solver concern (a tighter budget: 2×max(start,end)+center),\n * deliberately not offered until a product needs it.\n */\nexport interface BarSections {\n readonly start?: readonly BarGroup[];\n readonly center?: readonly BarGroup[];\n readonly end?: readonly BarGroup[];\n}\n\nexport interface BarSchema {\n readonly id: string;\n readonly sections: BarSections;\n}\n\n/** A run of command rows; separators derive between sections. */\nexport interface MenuSection {\n /** Optional section heading (i18n key). */\n readonly labelKey?: string;\n readonly items: readonly string[];\n}\n\nexport interface MenuSchema {\n readonly id: string;\n readonly sections: readonly MenuSection[];\n}\n\n/**\n * The shell FRAME — region arrangement and visibility. Regions are a FIXED\n * vocabulary (each carries semantics the shell must own: the toolbar's\n * measurement physics, the document gate, aria landmarks); what's YOURS is\n * where they sit, whether they show, and — through the region slots — what\n * fills them. Part of the chrome value because it is structure: owned, never\n * merged. Free-form layout is deliberately not offered — wanting a different\n * frame architecture is what headless is for.\n */\nexport interface FrameSchema {\n /** Where the main bar lives. Its mode band rides the CONTENT side (below a\n * top bar, above a bottom bar). Default: 'top'. */\n readonly toolbar?: 'top' | 'bottom';\n /** Document tab strip: 'multiple' shows it only with >1 tab. A hidden\n * region hides its SLOT too — visibility outranks slotted content.\n * Default: 'always'. */\n readonly tabs?: 'always' | 'multiple' | 'never';\n /** The header row — a socket only: the chrome ships no header of its own,\n * so it renders nothing until a `slot=\"header\"` child fills it. `false`\n * removes the socket, keeping a slotted header out. Default: true. */\n readonly header?: boolean;\n}\n\nexport interface ChromeSchema {\n /** Standalone bars (e.g. the main toolbar). */\n readonly bars: Readonly<Record<string, BarSchema>>;\n /** Secondary bars keyed by tool mode — WHICH one shows is derived from the\n * interaction hub's active tool, never stored. */\n readonly modeBars?: Readonly<Record<string, BarSchema>>;\n /** Named dropdown menus referenced by commands' `menu:` targets. */\n readonly menus?: Readonly<Record<string, MenuSchema>>;\n /** Contextual strips (selection menus) — same BarSchema, same fit engine. */\n readonly strips?: Readonly<Record<string, BarSchema>>;\n /** Region arrangement & visibility. Omitted = the default frame. */\n readonly frame?: FrameSchema;\n}\n\n// ── authoring sugar ───────────────────────────────────────────────────────────\n\nexport function item(command: string, opts?: Omit<BarItem, 'command'>): BarItem {\n return { command, ...opts };\n}\n\nexport function custom(slot: string, opts: Omit<CustomItem, 'slot'>): CustomItem {\n return { slot, ...opts };\n}\n\nexport function group(id: string, items: readonly BarChild[]): BarGroup;\nexport function group(\n id: string,\n opts: Omit<BarGroup, 'id' | 'items'> & { items?: readonly BarChild[] },\n items?: readonly BarChild[],\n): BarGroup;\nexport function group(\n id: string,\n optsOrItems:\n | readonly BarChild[]\n | (Omit<BarGroup, 'id' | 'items'> & { items?: readonly BarChild[] }),\n items?: readonly BarChild[],\n): BarGroup {\n if (Array.isArray(optsOrItems)) return { id, items: optsOrItems as readonly BarChild[] };\n const { items: optItems, ...opts } = optsOrItems as Omit<BarGroup, 'id' | 'items'> & {\n items?: readonly BarChild[];\n };\n return { id, ...opts, items: items ?? optItems ?? [] };\n}\n\n// ── normalized form — what the solver and projection consume ─────────────────\n\nexport type NormalizedUnit =\n | {\n readonly kind: 'command';\n /** Unique within the bar: `${groupId}:${command}`. Measurement + assignment key. */\n readonly key: string;\n readonly command: string;\n readonly variants: readonly string[];\n readonly importance: Importance;\n }\n | {\n readonly kind: 'custom';\n readonly key: string;\n readonly slot: string;\n readonly variants: readonly string[];\n readonly terminal: string;\n readonly importance: Importance;\n };\n\nexport interface NormalizedGroup {\n readonly id: string;\n readonly labelKey?: string;\n readonly role: 'buttons' | 'tabs';\n readonly shed: boolean;\n readonly collapse?: 'menu' | 'select';\n readonly importance: Importance;\n readonly units: readonly NormalizedUnit[];\n}\n\nexport interface NormalizedSection {\n readonly name: 'start' | 'center' | 'end';\n readonly groups: readonly NormalizedGroup[];\n}\n\nexport interface NormalizedBar {\n readonly id: string;\n readonly sections: readonly NormalizedSection[];\n}\n\nexport const DEFAULT_IMPORTANCE: Importance = 3;\nconst DEFAULT_COMMAND_VARIANTS: readonly Variant[] = ['icon'];\nconst DEFAULT_CUSTOM_VARIANTS: readonly string[] = ['default'];\n\nfunction normalizeChild(groupId: string, child: BarChild, seen: Set<string>): NormalizedUnit {\n const asItem: BarItem | CustomItem = typeof child === 'string' ? { command: child } : child;\n const unit: NormalizedUnit =\n 'slot' in asItem\n ? {\n kind: 'custom',\n key: `${groupId}:${asItem.slot}`,\n slot: asItem.slot,\n variants: asItem.variants ?? DEFAULT_CUSTOM_VARIANTS,\n terminal: asItem.terminal,\n importance: asItem.importance ?? DEFAULT_IMPORTANCE,\n }\n : {\n kind: 'command',\n key: `${groupId}:${asItem.command}`,\n command: asItem.command,\n variants: asItem.variants ?? DEFAULT_COMMAND_VARIANTS,\n importance: asItem.importance ?? DEFAULT_IMPORTANCE,\n };\n if (unit.variants.length === 0) throw new Error(`[ui-core] empty variant ladder: ${unit.key}`);\n if (seen.has(unit.key)) throw new Error(`[ui-core] duplicate unit in bar: ${unit.key}`);\n seen.add(unit.key);\n return unit;\n}\n\n/** Resolve shorthands + defaults; validate uniqueness. Solver/projection input. */\nexport function normalizeBar(bar: BarSchema): NormalizedBar {\n const seen = new Set<string>();\n const groupIds = new Set<string>();\n const sections: NormalizedSection[] = [];\n for (const name of ['start', 'center', 'end'] as const) {\n const groups = bar.sections[name];\n if (!groups || groups.length === 0) continue;\n sections.push({\n name,\n groups: groups.map((g) => {\n if (groupIds.has(g.id)) throw new Error(`[ui-core] duplicate group in bar: ${g.id}`);\n groupIds.add(g.id);\n return {\n id: g.id,\n labelKey: g.labelKey,\n role: g.role ?? 'buttons',\n shed: g.shed ?? false,\n collapse: g.collapse,\n importance: g.importance ?? DEFAULT_IMPORTANCE,\n units: g.items.map((c) => normalizeChild(g.id, c, seen)),\n };\n }),\n });\n }\n return { id: bar.id, sections };\n}\n\n/**\n * Drop units whose command is currently invisible (permissions, disabled\n * categories, contextual visibility) BEFORE solving — an invisible unit must\n * not consume budget or appear in the overflow. Groups that empty out vanish\n * naturally in the solver's separator math and in the projection.\n */\nexport function filterBar(\n bar: NormalizedBar,\n keep: (unit: NormalizedUnit) => boolean,\n): NormalizedBar {\n return {\n id: bar.id,\n sections: bar.sections.map((s) => ({\n name: s.name,\n groups: s.groups.map((g) => ({ ...g, units: g.units.filter(keep) })),\n })),\n };\n}\n\n/**\n * Identity + validation. Checks what is checkable without a command registry:\n * bars normalize cleanly, and every `menu` a strip/bar could reference exists\n * is left to `validateChrome` (which also takes the known command ids).\n */\nexport function defineChrome<T extends ChromeSchema>(chrome: T): T {\n for (const bar of Object.values(chrome.bars)) normalizeBar(bar);\n for (const bar of Object.values(chrome.modeBars ?? {})) normalizeBar(bar);\n for (const strip of Object.values(chrome.strips ?? {})) normalizeBar(strip);\n return chrome;\n}\n\n/** Dev-time cross-check: every command referenced by the chrome exists. */\nexport function validateChrome(chrome: ChromeSchema, knownCommands: ReadonlySet<string>): string[] {\n const problems: string[] = [];\n const checkBar = (bar: BarSchema, where: string) => {\n for (const section of normalizeBar(bar).sections)\n for (const g of section.groups)\n for (const u of g.units) {\n const refs = u.kind === 'command' ? [u.command] : [u.terminal];\n for (const c of refs)\n if (!knownCommands.has(c)) problems.push(`${where}: unknown command \"${c}\"`);\n }\n };\n for (const [id, bar] of Object.entries(chrome.bars)) checkBar(bar, `bars.${id}`);\n for (const [id, bar] of Object.entries(chrome.modeBars ?? {})) checkBar(bar, `modeBars.${id}`);\n for (const [id, strip] of Object.entries(chrome.strips ?? {})) checkBar(strip, `strips.${id}`);\n for (const [id, menu] of Object.entries(chrome.menus ?? {}))\n for (const section of menu.sections)\n for (const c of section.items)\n if (!knownCommands.has(c)) problems.push(`menus.${id}: unknown command \"${c}\"`);\n return problems;\n}\n","/**\n * Pure transforms over ChromeSchema — the \"surgical edit\" tier of the\n * customization ladder, between \"pass nothing\" and \"own the whole value\".\n * They are ordinary functions over data: no registry, no merge grammar, no\n * order sensitivity beyond function composition. Anything they can't express\n * is a sign the caller should write the schema value instead.\n *\n * Addressing is by BAR ID across all three bar collections (bars, modeBars,\n * strips). Mode bars may also be addressed by their surface key\n * ('mode:annotate') since that is what appears in `chrome.modeBars`.\n */\nimport {\n group as makeGroup,\n type BarChild,\n type BarGroup,\n type BarSchema,\n type BarSections,\n type ChromeSchema,\n type CustomItem,\n} from './schema';\n\nexport interface AddItemSpec {\n /** Bar id ('main', 'annotate', …) or a modeBars surface key ('mode:annotate'). */\n readonly bar: string;\n readonly section: keyof BarSections;\n /** Target group id. Unknown in the bar → a new group is created at the end\n * of `section`; known but in a DIFFERENT section → error (group ids are\n * bar-unique, so that is a contradiction, not a request). */\n readonly group: string;\n readonly item: BarChild;\n /** Insert position within the group. Default: append. */\n readonly at?: number;\n}\n\nconst SECTION_NAMES: readonly (keyof BarSections)[] = ['start', 'center', 'end'];\n\nconst isCustom = (child: BarChild): child is CustomItem =>\n typeof child !== 'string' && 'slot' in child;\n\nconst commandOf = (child: BarChild): string | null =>\n typeof child === 'string' ? child : isCustom(child) ? null : child.command;\n\n/** Every (collection, key) location whose bar matches `id`. */\nfunction locate(schema: ChromeSchema, id: string): ['bars' | 'modeBars' | 'strips', string][] {\n const hits: ['bars' | 'modeBars' | 'strips', string][] = [];\n for (const coll of ['bars', 'modeBars', 'strips'] as const) {\n for (const [key, bar] of Object.entries(schema[coll] ?? {})) {\n if (bar.id === id || key === id) hits.push([coll, key]);\n }\n }\n return hits;\n}\n\nfunction withBar(\n schema: ChromeSchema,\n coll: 'bars' | 'modeBars' | 'strips',\n key: string,\n bar: BarSchema,\n): ChromeSchema {\n return { ...schema, [coll]: { ...schema[coll], [key]: bar } };\n}\n\n/** Insert `spec.item` into a group of one bar. See AddItemSpec for semantics. */\nexport function addItem(schema: ChromeSchema, spec: AddItemSpec): ChromeSchema {\n const hits = locate(schema, spec.bar);\n if (hits.length === 0)\n throw new Error(`[ui-core] addItem: no bar \"${spec.bar}\" in bars/modeBars/strips`);\n if (hits.length > 1)\n throw new Error(\n `[ui-core] addItem: bar id \"${spec.bar}\" is ambiguous (${hits.map(([c]) => c).join(', ')})`,\n );\n const [coll, key] = hits[0];\n const bar = schema[coll]![key];\n\n for (const name of SECTION_NAMES) {\n if (name === spec.section) continue;\n if (bar.sections[name]?.some((g) => g.id === spec.group))\n throw new Error(\n `[ui-core] addItem: group \"${spec.group}\" lives in section \"${name}\", not \"${spec.section}\"`,\n );\n }\n\n const groups = bar.sections[spec.section] ?? [];\n const idx = groups.findIndex((g) => g.id === spec.group);\n const nextGroups =\n idx === -1\n ? [...groups, makeGroup(spec.group, [spec.item])]\n : groups.map((g, i) => {\n if (i !== idx) return g;\n const items = [...g.items];\n items.splice(spec.at ?? items.length, 0, spec.item);\n return { ...g, items };\n });\n\n return withBar(schema, coll, key, {\n ...bar,\n sections: { ...bar.sections, [spec.section]: nextGroups },\n });\n}\n\n/**\n * Purge commands (or custom slots, by slot name) from every bar, mode bar,\n * strip, and menu. Groups and menu sections that empty out are dropped;\n * emptied menus keep their key (commands may still target them) with no rows.\n */\nexport function removeItems(schema: ChromeSchema, ids: readonly string[]): ChromeSchema {\n const gone = new Set(ids);\n const keep = (child: BarChild): boolean => {\n const cmd = commandOf(child);\n return cmd !== null ? !gone.has(cmd) : !gone.has((child as CustomItem).slot);\n };\n\n const filterGroups = (groups: readonly BarGroup[] | undefined) =>\n groups?.map((g) => ({ ...g, items: g.items.filter(keep) })).filter((g) => g.items.length > 0);\n\n const filterBarSchema = (bar: BarSchema): BarSchema => ({\n ...bar,\n sections: Object.fromEntries(\n SECTION_NAMES.flatMap((name) => {\n const groups = filterGroups(bar.sections[name]);\n return groups && groups.length > 0 ? [[name, groups]] : [];\n }),\n ),\n });\n\n const filterColl = <T extends Readonly<Record<string, BarSchema>> | undefined>(coll: T): T =>\n coll &&\n (Object.fromEntries(Object.entries(coll).map(([k, b]) => [k, filterBarSchema(b)])) as T);\n\n return {\n ...schema,\n bars: filterColl(schema.bars)!,\n modeBars: filterColl(schema.modeBars),\n strips: filterColl(schema.strips),\n menus:\n schema.menus &&\n Object.fromEntries(\n Object.entries(schema.menus).map(([k, menu]) => [\n k,\n {\n ...menu,\n sections: menu.sections\n .map((s) => ({ ...s, items: s.items.filter((c) => !gone.has(c)) }))\n .filter((s) => s.items.length > 0),\n },\n ]),\n ),\n };\n}\n\n/**\n * Swap a command in place everywhere it appears — bars, mode bars, strips,\n * and (when the replacement is itself a plain command) menu rows.\n */\nexport function replaceItem(schema: ChromeSchema, id: string, item: BarChild): ChromeSchema {\n const replacementCommand = commandOf(item);\n const swap = (child: BarChild): BarChild => (commandOf(child) === id ? item : child);\n\n const mapBar = (bar: BarSchema): BarSchema => ({\n ...bar,\n sections: Object.fromEntries(\n SECTION_NAMES.flatMap((name) => {\n const groups = bar.sections[name];\n return groups ? [[name, groups.map((g) => ({ ...g, items: g.items.map(swap) }))]] : [];\n }),\n ),\n });\n\n const mapColl = <T extends Readonly<Record<string, BarSchema>> | undefined>(coll: T): T =>\n coll && (Object.fromEntries(Object.entries(coll).map(([k, b]) => [k, mapBar(b)])) as T);\n\n return {\n ...schema,\n bars: mapColl(schema.bars)!,\n modeBars: mapColl(schema.modeBars),\n strips: mapColl(schema.strips),\n menus:\n replacementCommand === null\n ? schema.menus\n : schema.menus &&\n Object.fromEntries(\n Object.entries(schema.menus).map(([k, menu]) => [\n k,\n {\n ...menu,\n sections: menu.sections.map((s) => ({\n ...s,\n items: s.items.map((c) => (c === id ? replacementCommand : c)),\n })),\n },\n ]),\n ),\n };\n}\n","/**\n * The helpers bundle handed to `chrome: (base, h) => …` transforms — the\n * surgical edits plus the authoring sugar, so simple customizations need no\n * imports at all. One object, frozen shape: it IS public API (the vanilla\n * snippet passes it across the config boundary), so additions are features\n * and removals are breaking.\n */\nimport { custom, defineChrome, group, item } from './schema';\nimport { addItem, removeItems, replaceItem } from './transforms';\n\nexport const chromeHelpers = {\n addItem,\n removeItems,\n replaceItem,\n item,\n group,\n custom,\n defineChrome,\n} as const;\n\nexport type ChromeHelpers = typeof chromeHelpers;\n","/**\n * The fit solver — pure. Given a normalized bar, measured widths, and the\n * container budget, decide what every unit renders as: a variant, shed into\n * its group's disclosure, part of a collapsed group, or the overflow menu.\n *\n * Deterministic degradation policy, applied while over budget:\n * 1. among all available steps, take the one owned by the LOWEST-importance\n * unit/group; ties prefer variant < shed < group-collapse < overflow;\n * remaining ties degrade the RIGHTMOST first (end of bar yields first).\n * 2. a unit's variant steps run out before it may shed or overflow.\n * 3. a `shed` group moves children (at the CHILD's importance) into a\n * group-local disclosure, but never below ONE visible child — the floor.\n * 4. a group with `collapse` collapses only after every child sits on its\n * last variant AND shedding (if enabled) has hit its floor; once\n * collapsed it degrades further as ONE unit (the whole group overflows\n * together — a select can't half-overflow). A shed group WITHOUT\n * `collapse` overflows whole at the floor instead.\n * 5. pinned (importance 5) units/groups may degrade variants but never\n * shed, collapse away, or overflow. Everything else can ALWAYS reach the\n * overflow menu, so any bar fits any width whose pinned floor fits.\n *\n * So the full group ladder mirrors the item ladder:\n * items: richest variant → … → smallest variant → (shed |) overflow\n * groups: all children → shed to floor → collapsed control → overflow\n *\n * The overflow trigger occupies space only when something overflowed: solve\n * once without it; if anything overflowed, solve again with the trigger's\n * width reserved (a smaller budget can only overflow MORE, so two passes\n * reach the fixpoint). A group's disclosure trigger is budgeted the same way,\n * inside `measure`, whenever that group has shed children.\n *\n * Missing measurements count as width 0 and are reported via `complete:\n * false` — callers render the first frame from an incomplete solve and\n * re-solve when the ResizeObserver delivers real numbers.\n */\nimport type { NormalizedBar, NormalizedGroup, NormalizedUnit } from './schema';\nimport { PINNED } from './schema';\n\nexport interface FitMetrics {\n /** Width of unit `key` rendered at `variant`; undefined = not yet measured. */\n unit(key: string, variant: string): number | undefined;\n /** Width of group `id` rendered in its collapsed form ('menu' | 'select'). */\n groupCollapsed(groupId: string): number | undefined;\n /** Width of group `id`'s disclosure trigger (shed groups only). */\n groupTrigger(groupId: string): number | undefined;\n /** Width of the overflow trigger button. */\n readonly overflowTrigger: number;\n /** Gap between adjacent visible units. */\n readonly gap: number;\n /** Width of a derived separator between adjacent visible groups (with its gaps). */\n readonly separator: number;\n}\n\nexport type UnitAssignment =\n | { readonly kind: 'variant'; readonly variant: string }\n | { readonly kind: 'shed' } // hidden behind its group's disclosure trigger\n | { readonly kind: 'collapsed' } // hidden behind its group's collapsed control\n | { readonly kind: 'overflow' };\n\nexport interface GroupAssignment {\n /** How many children sit behind the group's disclosure trigger. */\n readonly shedCount: number;\n /** The group renders as its single collapsed control. */\n readonly collapsed: boolean;\n /** No part of the group is visible in the bar. */\n readonly overflowed: boolean;\n}\n\nexport interface FitResult {\n readonly units: ReadonlyMap<string, UnitAssignment>;\n readonly groups: ReadonlyMap<string, GroupAssignment>;\n readonly hasOverflow: boolean;\n /** Total visible width at this assignment (diagnostics + tests). */\n readonly width: number;\n /** False when any consulted measurement was missing (treated as 0). */\n readonly complete: boolean;\n}\n\n// ── internal mutable solve state ──────────────────────────────────────────────\n\ninterface UnitState {\n unit: NormalizedUnit;\n group: GroupState;\n /** Index into unit.variants (0 = richest). */\n variantIndex: number;\n shed: boolean;\n overflowed: boolean;\n /** Position in bar order — rightmost-first tie-breaking. */\n position: number;\n}\n\ninterface GroupState {\n group: NormalizedGroup;\n section: 'start' | 'center' | 'end';\n collapsed: boolean;\n overflowed: boolean;\n units: UnitState[];\n}\n\ntype Step =\n | { type: 'variant'; importance: number; position: number; unit: UnitState }\n | { type: 'shed'; importance: number; position: number; unit: UnitState }\n | { type: 'collapse'; importance: number; position: number; group: GroupState }\n | { type: 'overflow-unit'; importance: number; position: number; unit: UnitState }\n | { type: 'overflow-group'; importance: number; position: number; group: GroupState };\n\n/** variant < shed < collapse < overflow when importance ties. */\nconst STEP_RANK: Record<Step['type'], number> = {\n variant: 0,\n shed: 1,\n collapse: 2,\n 'overflow-unit': 3,\n 'overflow-group': 3,\n};\n\nfunction buildState(bar: NormalizedBar): GroupState[] {\n const groups: GroupState[] = [];\n let position = 0;\n for (const section of bar.sections) {\n for (const g of section.groups) {\n const gs: GroupState = {\n group: g,\n section: section.name,\n collapsed: false,\n overflowed: false,\n units: [],\n };\n for (const u of g.units) {\n gs.units.push({\n unit: u,\n group: gs,\n variantIndex: 0,\n shed: false,\n overflowed: false,\n position,\n });\n position += 1;\n }\n groups.push(gs);\n }\n }\n return groups;\n}\n\nfunction nextStep(groups: GroupState[]): Step | null {\n let best: Step | null = null;\n const consider = (step: Step) => {\n if (\n !best ||\n step.importance < best.importance ||\n (step.importance === best.importance &&\n (STEP_RANK[step.type] < STEP_RANK[best.type] ||\n (STEP_RANK[step.type] === STEP_RANK[best.type] && step.position > best.position)))\n ) {\n best = step;\n }\n };\n\n for (const gs of groups) {\n if (gs.overflowed) continue;\n const groupPosition = gs.units.length ? gs.units[gs.units.length - 1].position : 0;\n\n if (gs.collapsed) {\n // A collapsed group degrades as one unit: overflow it whole.\n if (gs.group.importance < PINNED)\n consider({\n type: 'overflow-group',\n importance: gs.group.importance,\n position: groupPosition,\n group: gs,\n });\n continue;\n }\n\n let childrenExhausted = true;\n const visibleCount = gs.units.filter((u) => !u.overflowed && !u.shed).length;\n for (const us of gs.units) {\n if (us.overflowed || us.shed) continue;\n if (us.variantIndex < us.unit.variants.length - 1) {\n childrenExhausted = false;\n consider({\n type: 'variant',\n importance: us.unit.importance,\n position: us.position,\n unit: us,\n });\n } else if (us.unit.importance < PINNED) {\n if (gs.group.shed && visibleCount > 1) {\n // Stage 1: move the child behind the group's disclosure trigger —\n // never below one visible child (the floor).\n consider({\n type: 'shed',\n importance: us.unit.importance,\n position: us.position,\n unit: us,\n });\n } else if (!gs.group.shed && !gs.group.collapse) {\n // Plain group: children go to the GLOBAL overflow individually.\n consider({\n type: 'overflow-unit',\n importance: us.unit.importance,\n position: us.position,\n unit: us,\n });\n }\n }\n }\n\n // Stage 2 (terminal for the expanded form): available only once variants\n // are exhausted AND shedding — if enabled — sits at its floor.\n const shedExhausted = !gs.group.shed || visibleCount <= 1;\n if (childrenExhausted && shedExhausted && gs.group.importance < PINNED) {\n if (gs.group.collapse) {\n consider({\n type: 'collapse',\n importance: gs.group.importance,\n position: groupPosition,\n group: gs,\n });\n } else if (gs.group.shed) {\n // Shed group without a collapsed form: at the floor the WHOLE group\n // (visible + shed children) moves to the global overflow together.\n consider({\n type: 'overflow-group',\n importance: gs.group.importance,\n position: groupPosition,\n group: gs,\n });\n }\n }\n }\n return best;\n}\n\nfunction applyStep(step: Step): void {\n switch (step.type) {\n case 'variant':\n step.unit.variantIndex += 1;\n return;\n case 'shed':\n step.unit.shed = true;\n return;\n case 'collapse':\n step.group.collapsed = true;\n return;\n case 'overflow-unit': {\n step.unit.overflowed = true;\n if (step.unit.group.units.every((u) => u.overflowed)) step.unit.group.overflowed = true;\n return;\n }\n case 'overflow-group': {\n step.group.overflowed = true;\n for (const u of step.group.units) u.overflowed = true;\n return;\n }\n }\n}\n\ninterface Measured {\n width: number;\n complete: boolean;\n}\n\n/**\n * Visible width of the current assignment: unit widths + gaps + derived\n * separators. Gaps are counted between ALL adjacent visible units, including\n * across section boundaries — deliberately conservative: the adapter's layout\n * spaces sections with collapsing auto margins, so the cross-section gap\n * allowance (≤ 2×gap) is slack those margins absorb, never an overlap risk.\n */\nfunction measure(groups: GroupState[], metrics: FitMetrics, hasTrigger: boolean): Measured {\n let width = 0;\n let complete = true;\n let visibleUnits = 0;\n\n // Separators derive between adjacent visible groups within a section.\n const visibleBySection = new Map<string, number>();\n\n for (const gs of groups) {\n if (gs.overflowed) continue;\n if (gs.collapsed) {\n const w = metrics.groupCollapsed(gs.group.id);\n if (w === undefined) complete = false;\n width += w ?? 0;\n visibleUnits += 1;\n visibleBySection.set(gs.section, (visibleBySection.get(gs.section) ?? 0) + 1);\n continue;\n }\n let groupVisible = false;\n let shedCount = 0;\n for (const us of gs.units) {\n if (us.overflowed) continue;\n if (us.shed) {\n shedCount += 1;\n continue;\n }\n const w = metrics.unit(us.unit.key, us.unit.variants[us.variantIndex]);\n if (w === undefined) complete = false;\n width += w ?? 0;\n visibleUnits += 1;\n groupVisible = true;\n }\n if (shedCount > 0) {\n // The group's disclosure trigger takes real space, like any unit.\n const w = metrics.groupTrigger(gs.group.id);\n if (w === undefined) complete = false;\n width += w ?? 0;\n visibleUnits += 1;\n groupVisible = true;\n }\n if (groupVisible) visibleBySection.set(gs.section, (visibleBySection.get(gs.section) ?? 0) + 1);\n }\n\n if (hasTrigger) {\n width += metrics.overflowTrigger;\n visibleUnits += 1;\n }\n if (visibleUnits > 1) width += metrics.gap * (visibleUnits - 1);\n for (const count of visibleBySection.values())\n if (count > 1) width += metrics.separator * (count - 1);\n\n return { width, complete };\n}\n\nfunction anyOverflow(groups: GroupState[]): boolean {\n return groups.some((gs) => gs.units.some((u) => u.overflowed));\n}\n\nfunction solvePass(\n bar: NormalizedBar,\n metrics: FitMetrics,\n budget: number,\n hasTrigger: boolean,\n): { groups: GroupState[]; measured: Measured } {\n const groups = buildState(bar);\n let measured = measure(groups, metrics, hasTrigger);\n while (measured.width > budget) {\n const step = nextStep(groups);\n if (!step) break; // pinned floor — nothing left to shed\n applyStep(step);\n measured = measure(groups, metrics, hasTrigger);\n }\n return { groups, measured };\n}\n\nexport function solve(bar: NormalizedBar, metrics: FitMetrics, containerWidth: number): FitResult {\n // Pass 1: assume no trigger. If nothing overflows, done.\n let pass = solvePass(bar, metrics, containerWidth, false);\n if (anyOverflow(pass.groups)) {\n // Pass 2: same budget, trigger now takes real space in `measure`. The step\n // sequence is budget-independent, so pass 2 degrades strictly further than\n // pass 1 — overflow can't disappear, and the trigger stays justified.\n pass = solvePass(bar, metrics, containerWidth, true);\n }\n\n const units = new Map<string, UnitAssignment>();\n const groupAssignments = new Map<string, GroupAssignment>();\n for (const gs of pass.groups) {\n // Overflow ≻ collapsed ≻ shed: a group that shed a few children and THEN\n // collapsed (or overflowed) subsumes them into the later, stronger state.\n const shedCount = gs.units.filter((u) => u.shed && !u.overflowed && !gs.collapsed).length;\n groupAssignments.set(gs.group.id, {\n shedCount,\n collapsed: gs.collapsed,\n overflowed: gs.overflowed,\n });\n for (const us of gs.units) {\n units.set(\n us.unit.key,\n us.overflowed\n ? { kind: 'overflow' }\n : gs.collapsed\n ? { kind: 'collapsed' }\n : us.shed\n ? { kind: 'shed' }\n : { kind: 'variant', variant: us.unit.variants[us.variantIndex] },\n );\n }\n }\n return {\n units,\n groups: groupAssignments,\n hasOverflow: anyOverflow(pass.groups),\n width: pass.measured.width,\n complete: pass.measured.complete,\n };\n}\n","/**\n * Overflow projection — pure. The overflow menu is never authored: it is the\n * complement of the visible set, projected into menu form. The projection is\n * TOTAL because every unit has a canonical menu form by construction:\n *\n * command → command row (label/icon/active resolve live)\n * command with a `menu` target → submenu row pointing at that menu\n * custom item → its `terminal` command's form\n * group → section (renderers separate sections)\n * group with `labelKey` → labeled section (title or nested submenu —\n * presentation is the renderer's choice)\n * `role: 'tabs'` group → section marked radio\n *\n * Groups project in bar order; a partially-overflowed group projects only its\n * overflowed units; empty sections vanish. This is what replaces every\n * hand-written overflow/action menu in v2 — same information, one source.\n */\nimport type { NormalizedBar, NormalizedGroup, NormalizedUnit } from './schema';\nimport type { FitResult } from './solver';\n\nexport type OverflowRow =\n /** A plain command row. The renderer resolves label/icon/active from the registry. */\n | { readonly type: 'command'; readonly command: string }\n /** A command that opens a menu — renders as `label ▸` nesting that menu. */\n | { readonly type: 'submenu'; readonly command: string; readonly menu: string };\n\nexport interface OverflowSection {\n /** From the group's labelKey — render as a section title or a nested submenu. */\n readonly labelKey?: string;\n /** 'radio' when the group is a tab strip: exactly one row is active. */\n readonly role?: 'radio';\n readonly rows: readonly OverflowRow[];\n}\n\n/**\n * The one fact projection needs about a command: does it open a menu?\n * (Label, icon, and active state stay live in the renderer.) Return null for\n * unknown commands — they project as plain rows and resolve at render time.\n */\nexport type ResolveMenuTarget = (commandId: string) => { menu?: string } | null;\n\nfunction projectUnit(unit: NormalizedUnit, resolve: ResolveMenuTarget): OverflowRow {\n // A custom item's menu form is its terminal command's form.\n const command = unit.kind === 'custom' ? unit.terminal : unit.command;\n const menu = resolve(command)?.menu;\n return menu ? { type: 'submenu', command, menu } : { type: 'command', command };\n}\n\nexport function projectOverflow(\n bar: NormalizedBar,\n fit: FitResult,\n resolve: ResolveMenuTarget,\n): OverflowSection[] {\n const sections: OverflowSection[] = [];\n for (const section of bar.sections) {\n for (const group of section.groups) {\n // Shed units are NOT here: they're reachable through the group's own\n // disclosure trigger (projectShed). Only true overflow leaves the group.\n const rows = group.units\n .filter((u) => fit.units.get(u.key)?.kind === 'overflow')\n .map((u) => projectUnit(u, resolve));\n if (rows.length === 0) continue;\n sections.push({\n labelKey: group.labelKey,\n role: group.role === 'tabs' ? 'radio' : undefined,\n rows,\n });\n }\n }\n return sections;\n}\n\n/**\n * The content of a group's disclosure trigger: its shed units, in bar order,\n * in menu form — same totality rules as the global overflow. This is v2's\n * hand-written `mode-tabs-overflow-menu`, derived.\n */\nexport function projectShed(\n group: NormalizedGroup,\n fit: FitResult,\n resolve: ResolveMenuTarget,\n): OverflowRow[] {\n return group.units\n .filter((u) => fit.units.get(u.key)?.kind === 'shed')\n .map((u) => projectUnit(u, resolve));\n}\n\n/** One strip group: a separator boundary, its visible commands in bar order. */\nexport interface StripGroup {\n readonly id: string;\n readonly labelKey?: string;\n readonly commands: readonly string[];\n}\n\n/**\n * Strip projection — a bar projected for UN-measured rendering (a contextual\n * strip anchored to a selection has no fit pressure to solve). The schema\n * declares what COULD appear; `visible` (the command registry's runtime truth)\n * decides what DOES: hidden commands drop out, groups that empty out vanish,\n * and an all-hidden bar projects to [] — \"render nothing\" falls out. Custom\n * units project through their `terminal` command, same totality rule as the\n * overflow. Upgrading a strip to measured/overflowing rendering later is a\n * renderer swap (<Toolbar>), never a schema change.\n */\nexport function projectStrip(\n bar: NormalizedBar,\n visible: (command: string) => boolean,\n): StripGroup[] {\n const groups: StripGroup[] = [];\n for (const section of bar.sections) {\n for (const group of section.groups) {\n const commands = group.units\n .map((u) => (u.kind === 'custom' ? u.terminal : u.command))\n .filter(visible);\n if (commands.length === 0) continue;\n groups.push({ id: group.id, labelKey: group.labelKey, commands });\n }\n }\n return groups;\n}\n","/**\n * Shortcut parsing + matching — pure. No `navigator`: platform is an input\n * (`isMac`), decided by the embedder, same rule as plugin-i18n's locale.\n *\n * Grammar: modifiers and one key joined by '+', e.g. 'Mod+K', 'Ctrl+=',\n * 'Shift+Alt+D', 'Meta+NumpadAdd'. 'Mod' is ⌘ on mac and Ctrl elsewhere.\n * Keys longer than one character (F1, Escape, NumpadAdd, ArrowLeft) match\n * `event.key` OR `event.code` case-insensitively, so numpad shortcuts work.\n */\n\nexport interface ParsedShortcut {\n readonly key: string; // lowercase\n readonly mod: boolean; // platform-resolved at match time\n readonly ctrl: boolean;\n readonly meta: boolean;\n readonly alt: boolean;\n readonly shift: boolean;\n}\n\n/** The subset of KeyboardEvent the matcher reads — keeps this module DOM-free. */\nexport interface KeyStroke {\n readonly key: string;\n readonly code?: string;\n readonly ctrlKey: boolean;\n readonly metaKey: boolean;\n readonly altKey: boolean;\n readonly shiftKey: boolean;\n}\n\nconst MODIFIERS = new Set([\n 'mod',\n 'ctrl',\n 'control',\n 'meta',\n 'cmd',\n 'command',\n 'alt',\n 'option',\n 'shift',\n]);\n\nexport function parseShortcut(shortcut: string): ParsedShortcut {\n const tokens = shortcut.split('+').map((t) => t.trim());\n // 'Ctrl+=' splits to ['Ctrl', '', ''] — an empty tail means the key IS '+'.\n const keyToken = tokens[tokens.length - 1] === '' ? '+' : tokens[tokens.length - 1];\n const parsed = {\n key: keyToken.toLowerCase(),\n mod: false,\n ctrl: false,\n meta: false,\n alt: false,\n shift: false,\n };\n for (const token of tokens.slice(0, -1)) {\n const t = token.toLowerCase();\n if (t === '') continue; // artifact of a literal '+' key\n if (!MODIFIERS.has(t))\n throw new Error(`[ui-core] unknown modifier \"${token}\" in \"${shortcut}\"`);\n if (t === 'mod') parsed.mod = true;\n else if (t === 'ctrl' || t === 'control') parsed.ctrl = true;\n else if (t === 'meta' || t === 'cmd' || t === 'command') parsed.meta = true;\n else if (t === 'alt' || t === 'option') parsed.alt = true;\n else parsed.shift = true;\n }\n if (parsed.key === '') throw new Error(`[ui-core] empty key in shortcut \"${shortcut}\"`);\n return parsed;\n}\n\nexport function matchShortcut(\n parsed: ParsedShortcut,\n stroke: KeyStroke,\n opts: { isMac: boolean },\n): boolean {\n const wantCtrl = parsed.ctrl || (parsed.mod && !opts.isMac);\n const wantMeta = parsed.meta || (parsed.mod && opts.isMac);\n if (stroke.ctrlKey !== wantCtrl) return false;\n if (stroke.metaKey !== wantMeta) return false;\n if (stroke.altKey !== parsed.alt) return false;\n // Shift changes what `key` IS for printable characters ('=' vs '+'), so only\n // enforce declared shift; an undeclared shift is rejected for non-printables.\n if (parsed.shift && !stroke.shiftKey) return false;\n if (!parsed.shift && stroke.shiftKey && parsed.key.length > 1) return false;\n\n const key = stroke.key.toLowerCase();\n if (key === parsed.key) return true;\n // Long names ('numpadadd', 'f1', …) may be codes rather than keys.\n return (\n parsed.key.length > 1 && stroke.code !== undefined && stroke.code.toLowerCase() === parsed.key\n );\n}\n\n/** Display form for menu rows: '⌘K' on mac, 'Ctrl+K' elsewhere. */\nexport function formatShortcut(shortcut: string, opts: { isMac: boolean }): string {\n const parsed = parseShortcut(shortcut);\n const key = parsed.key.length === 1 ? parsed.key.toUpperCase() : capitalize(parsed.key);\n if (opts.isMac) {\n const mods = [\n parsed.ctrl ? '⌃' : '',\n parsed.alt ? '⌥' : '',\n parsed.shift ? '⇧' : '',\n parsed.meta || parsed.mod ? '⌘' : '',\n ].join('');\n return `${mods}${key}`;\n }\n const mods = [\n parsed.ctrl || parsed.mod ? 'Ctrl' : '',\n parsed.meta ? 'Meta' : '',\n parsed.alt ? 'Alt' : '',\n parsed.shift ? 'Shift' : '',\n ].filter(Boolean);\n return [...mods, key].join('+');\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["barsOf","EDGES","FLOAT_POSITIONS"],"sources":["../src/schema.ts","../src/suggestions.ts","../src/layout.ts","../src/layout-compile.ts","../src/layout-validate.ts","../src/solver.ts","../src/projection.ts","../src/toolbar-layout.ts","../src/shortcuts.ts"],"sourcesContent":["/**\n * @embedpdf/core-ui — the structure-only bar vocabulary.\n *\n * A bar contains only what a designer decides and the runtime cannot\n * compute: order, grouping, importance, and each item's degradation ladder.\n * Everything the runtime can compute is banned from it by construction:\n * no breakpoints, no show/hide lists, no locale overrides, no dividers, no\n * spacers, no hand-written overflow menus. Fit is measured and solved at\n * runtime (see solver.ts); the overflow menu is derived (see projection.ts).\n * Where bars go, and the menus and panels around them, is the viewer's\n * layout (see layout.ts).\n */\n\n/** Presentation ladder for a command button, richest first. */\nexport type Variant = 'icon+label' | 'icon' | 'label';\n\n/**\n * Who yields space first. 1 = first to degrade/overflow · 3 = default ·\n * 5 = pinned: may still degrade variants, but never leaves the bar.\n */\nexport type Importance = 1 | 2 | 3 | 4 | 5;\n\nexport const PINNED: Importance = 5;\n\nexport interface BarItem {\n /** The command this button runs — the only required field. */\n readonly command: string;\n /** Degradation ladder, richest first. Default: ['icon']. */\n readonly variants?: readonly Variant[];\n readonly importance?: Importance;\n}\n\n/**\n * An app-rendered slot (e.g. the inline zoom strip). Each named variant is\n * measured like any command button. Its `terminal` command is its menu form,\n * what it becomes when it overflows; an item without one never leaves the bar\n * (it is pinned, and so is its group), which keeps the overflow projection\n * total.\n */\nexport interface CustomItem {\n readonly slot: string;\n /** Named presentation variants, richest first. Default: ['default']. */\n readonly variants?: readonly string[];\n /** The command that stands in for this slot in menus (its last resort). */\n readonly terminal?: string;\n readonly importance?: Importance;\n}\n\nexport type BarChild = BarItem | CustomItem | string; // string = { command }\n\nexport interface BarGroup {\n readonly id: string;\n /** Titles the group's menu form (labeled submenu / section heading). */\n readonly labelKey?: string;\n /** Presentation hint: 'tabs' renders as a tab strip and projects as radio rows. */\n readonly role?: 'buttons' | 'tabs';\n /**\n * Stage 1 of the group degradation ladder: under pressure, move trailing\n * children (rightmost first, at the child's importance) into a derived\n * group-local disclosure — a trigger rendered inside the group opening a\n * menu of the hidden children. Never sheds the last visible child: below\n * that floor the group `collapse`s (stage 2) or overflows whole. The\n * disclosure is computed, never authored.\n */\n readonly shed?: boolean;\n /**\n * Stage 2: what the whole group degrades to once its children have\n * exhausted their ladders (and shedding, if enabled, has hit its floor): a\n * single menu button or a select-style picker. Groups with neither `shed`\n * nor `collapse` send children to the global overflow menu one by one.\n */\n readonly collapse?: 'menu' | 'select';\n readonly importance?: Importance;\n /**\n * Shows only while something that isn't dependent shows in the same bar, like undo and redo\n * beside a mode's tools: a bar with only dependent groups left shows nothing.\n */\n readonly dependent?: boolean;\n readonly items: readonly BarChild[];\n}\n\n/**\n * Alignment regions. Separators derive between adjacent visible groups\n * within a section — never across sections, never from schema data.\n *\n * The names are direction-aware (RTL flips start/end) and `center` is a\n * soft contract: \"balance this segment in the space left over by start and\n * end\". With symmetric flanks that coincides with true centering; with a\n * heavy flank the segment drifts rather than fights — segments never\n * overlap, matching how every toolbar convention (including spacer-flanked\n * tabs) treats its middle region. Strict geometric centering\n * would be a solver concern (a tighter budget: 2×max(start,end)+center),\n * deliberately not offered until a product needs it.\n */\nexport interface BarSections {\n readonly start?: readonly BarGroup[];\n readonly center?: readonly BarGroup[];\n readonly end?: readonly BarGroup[];\n}\n\nexport interface BarSchema {\n readonly id: string;\n readonly sections: BarSections;\n}\n\n// ── authoring sugar ───────────────────────────────────────────────────────────\n\n/** A command button: `item('zoom:in', { variants: ['icon+label', 'icon'] })`. */\nexport function item(command: string, options?: Omit<BarItem, 'command'>): BarItem {\n return { command, ...options };\n}\n\n/**\n * An item you draw yourself, by its slot name, and the command it becomes in the \"More\" menu:\n * `custom('page-number', 'page:go-to', { variants: ['full', 'compact'] })`. Without a command,\n * the item never leaves the bar.\n */\nexport function custom(\n slot: string,\n terminal?: string,\n options?: Omit<CustomItem, 'slot' | 'terminal'>,\n): CustomItem {\n return terminal === undefined ? { slot, ...options } : { slot, terminal, ...options };\n}\n\n/** A group of items, with a separator between groups: `group('zoom', ['zoom:out', 'zoom:in'])`. */\nexport function group(\n id: string,\n items: readonly BarChild[],\n options?: Omit<BarGroup, 'id' | 'items'>,\n): BarGroup {\n return { id, ...options, items };\n}\n\n// ── normalized form — what the solver and projection consume ─────────────────\n\nexport type NormalizedUnit =\n | {\n readonly kind: 'command';\n /** Unique within the bar: `${groupId}:${command}`. Measurement + assignment key. */\n readonly key: string;\n readonly command: string;\n readonly variants: readonly string[];\n readonly importance: Importance;\n }\n | {\n readonly kind: 'custom';\n readonly key: string;\n readonly slot: string;\n readonly variants: readonly string[];\n /**\n * The command it becomes in menus, or null for an item without one, which\n * {@link filterBar} keeps, pinned.\n */\n readonly terminal: string | null;\n readonly importance: Importance;\n };\n\nexport interface NormalizedGroup {\n readonly id: string;\n readonly labelKey?: string;\n readonly role: 'buttons' | 'tabs';\n readonly shed: boolean;\n readonly collapse?: 'menu' | 'select';\n readonly importance: Importance;\n /** See {@link BarGroup.dependent}; the rule is {@link hasVisibleUnits}. */\n readonly dependent: boolean;\n readonly units: readonly NormalizedUnit[];\n}\n\nexport interface NormalizedSection {\n readonly name: 'start' | 'center' | 'end';\n readonly groups: readonly NormalizedGroup[];\n}\n\nexport interface NormalizedBar {\n readonly id: string;\n readonly sections: readonly NormalizedSection[];\n}\n\nexport const DEFAULT_IMPORTANCE: Importance = 3;\nconst DEFAULT_COMMAND_VARIANTS: readonly Variant[] = ['icon'];\nconst DEFAULT_CUSTOM_VARIANTS: readonly string[] = ['default'];\n\n/** Whether a unit is a custom item with no command to become in menus: it never leaves the bar. */\nexport const isStandaloneUnit = (unit: NormalizedUnit): boolean =>\n unit.kind === 'custom' && unit.terminal === null;\n\n/** The command a unit runs: its own, or a custom item's `terminal`; null for a standalone item. */\nexport const commandOfUnit = (unit: NormalizedUnit): string | null =>\n unit.kind === 'command' ? unit.command : unit.terminal;\n\nfunction normalizeChild(groupId: string, child: BarChild, seen: Set<string>): NormalizedUnit {\n const asItem: BarItem | CustomItem = typeof child === 'string' ? { command: child } : child;\n const unit: NormalizedUnit =\n 'slot' in asItem\n ? {\n kind: 'custom',\n key: `${groupId}:${asItem.slot}`,\n slot: asItem.slot,\n variants: asItem.variants ?? DEFAULT_CUSTOM_VARIANTS,\n terminal: asItem.terminal ?? null,\n importance:\n asItem.terminal === undefined ? PINNED : (asItem.importance ?? DEFAULT_IMPORTANCE),\n }\n : {\n kind: 'command',\n key: `${groupId}:${asItem.command}`,\n command: asItem.command,\n variants: asItem.variants ?? DEFAULT_COMMAND_VARIANTS,\n importance: asItem.importance ?? DEFAULT_IMPORTANCE,\n };\n if (unit.variants.length === 0) throw new Error(`[ui-core] empty variant ladder: ${unit.key}`);\n if (seen.has(unit.key)) throw new Error(`[ui-core] duplicate unit in bar: ${unit.key}`);\n seen.add(unit.key);\n return unit;\n}\n\n/**\n * Resolve shorthands + defaults; validate uniqueness. Solver/projection input.\n * A group holding a custom item without a command is pinned with it: it never\n * collapses or overflows whole, so the item stays in the bar.\n */\nexport function normalizeBar(bar: BarSchema): NormalizedBar {\n const seen = new Set<string>();\n const groupIds = new Set<string>();\n const sections: NormalizedSection[] = [];\n for (const name of ['start', 'center', 'end'] as const) {\n const groups = bar.sections[name];\n if (!groups || groups.length === 0) continue;\n sections.push({\n name,\n groups: groups.map((group) => {\n if (groupIds.has(group.id))\n throw new Error(`[ui-core] duplicate group in bar: ${group.id}`);\n groupIds.add(group.id);\n const units = group.items.map((child) => normalizeChild(group.id, child, seen));\n return {\n id: group.id,\n labelKey: group.labelKey,\n role: group.role ?? 'buttons',\n shed: group.shed ?? false,\n collapse: group.collapse,\n importance: units.some(isStandaloneUnit)\n ? PINNED\n : (group.importance ?? DEFAULT_IMPORTANCE),\n dependent: group.dependent === true,\n units,\n };\n }),\n });\n }\n return { id: bar.id, sections };\n}\n\n/**\n * Drop units whose command is currently invisible (permissions, disabled\n * categories, contextual visibility) before solving — an invisible unit must\n * not consume budget or appear in the overflow. Groups that empty out vanish\n * naturally in the solver's separator math and in the projection. A custom\n * item without a command has nothing to ask `keep` about, and stays. A bar\n * that shows nothing ({@link hasVisibleUnits}) keeps no unit at all, so its\n * dependent groups go too.\n */\nexport function filterBar(\n bar: NormalizedBar,\n keep: (unit: NormalizedUnit) => boolean,\n): NormalizedBar {\n const shows = hasVisibleUnits(bar, keep);\n return {\n id: bar.id,\n sections: bar.sections.map((section) => ({\n name: section.name,\n groups: section.groups.map((group) => ({\n ...group,\n units: shows ? group.units.filter((unit) => isStandaloneUnit(unit) || keep(unit)) : [],\n })),\n })),\n };\n}\n\n/**\n * Whether the bar shows anything once `keep` (as for {@link filterBar}) has had its say: a unit\n * left in a group that isn't dependent. Dependent groups show only beside one, so a bar with\n * only dependent groups left shows nothing.\n */\nexport function hasVisibleUnits(\n bar: NormalizedBar,\n keep: (unit: NormalizedUnit) => boolean,\n): boolean {\n return bar.sections.some((section) =>\n section.groups.some(\n (group) =>\n !group.dependent && group.units.some((unit) => isStandaloneUnit(unit) || keep(unit)),\n ),\n );\n}\n","/**\n * \"Did you mean …?\" for ids: the closest known id to one that doesn't exist,\n * by edit distance, when it is close enough to be a typo.\n */\n\n/**\n * The number of single-character inserts, deletes, substitutions and swaps of two neighbours\n * that turn `left` into `right`.\n */\nexport function editDistance(left: string, right: string): number {\n if (left === right) return 0;\n let beforePrevious: number[] = [];\n let previous = Array.from({ length: right.length + 1 }, (_, j) => j);\n for (let i = 1; i <= left.length; i++) {\n const current = [i];\n for (let j = 1; j <= right.length; j++) {\n const cost = left[i - 1] === right[j - 1] ? 0 : 1;\n let distance = Math.min(previous[j]! + 1, current[j - 1]! + 1, previous[j - 1]! + cost);\n if (i > 1 && j > 1 && left[i - 1] === right[j - 2] && left[i - 2] === right[j - 1]) {\n distance = Math.min(distance, beforePrevious[j - 2]! + 1);\n }\n current.push(distance);\n }\n beforePrevious = previous;\n previous = current;\n }\n return previous[right.length]!;\n}\n\n/**\n * The candidate closest to `id`, or `null` when none is within a typo's reach: at most a third\n * of the id's length, and never more than 3 edits apart.\n */\nexport function closestMatch(id: string, candidates: Iterable<string>): string | null {\n const reach = Math.min(3, Math.max(1, Math.floor(id.length / 3)));\n let best: string | null = null;\n let bestDistance = reach + 1;\n for (const candidate of candidates) {\n if (candidate === id) continue;\n const distance = editDistance(id, candidate);\n if (distance < bestDistance) {\n best = candidate;\n bestDistance = distance;\n }\n }\n return best;\n}\n\n/** `' (did you mean \"x\"?)'` for the closest candidate, or `''` when there is none. */\nexport function didYouMean(id: string, candidates: Iterable<string>): string {\n const match = closestMatch(id, candidates);\n return match === null ? '' : ` (did you mean \"${match}\"?)`;\n}\n","/**\n * The viewer's layout: where every bar, menu and panel goes, as plain data\n * ({@link LayoutData}), and the immutable value whose edits change it\n * ({@link Layout}). Every edit returns a new layout, so edits chain. An edit\n * that names an id the layout doesn't have changes nothing and records a\n * warning with the closest id that does exist; `validateLayout` returns those\n * warnings with the rest, so a typo never stops the viewer.\n *\n * Placing bars, drawing menus and opening panels is the viewer's job: a bar\n * reaches a toolbar through `compileBar` (layout-compile.ts).\n */\nimport type { Importance, Variant } from './schema';\nimport { didYouMean } from './suggestions';\n\n// ── the data ─────────────────────────────────────────────────────────────────\n\n/** An edge of the viewer. `start` and `end` follow the language: left and right, swapped in a right-to-left one. */\nexport type BarEdge = 'top' | 'bottom' | 'start' | 'end';\n\n/** Where a floating bar sits over the pages. */\nexport type FloatPosition =\n | 'top-start'\n | 'top'\n | 'top-end'\n | 'start'\n | 'end'\n | 'bottom-start'\n | 'bottom'\n | 'bottom-end';\n\n/** What a bar over a selection follows: selected text, or selected annotations. */\nexport type SelectionTarget = 'selection' | 'annotation';\n\n/**\n * Where a bar goes: along an edge, floating over the pages, along another bar on the side of the\n * pages, or over what's selected. Bars on one edge stack from the outside in, in the order they\n * were added; `before` and `after` put a bar next to another bar on that edge.\n */\nexport type BarPlace =\n | BarEdge\n | { readonly edge: BarEdge; readonly before?: string; readonly after?: string }\n | { readonly float: FloatPosition }\n | { readonly with: string }\n | { readonly at: SelectionTarget };\n\n/** A command with options. */\nexport interface LayoutCommandItem {\n readonly command: string;\n /** How it may show, richest first. Default `['icon']`. */\n readonly variants?: readonly Variant[];\n /** Who makes room first: `1` to `5` (never leaves the bar). Default `3`. */\n readonly importance?: Importance;\n}\n\n/** Your own component, by its id. `command` is what it becomes in the \"More\" menu; without one, it never leaves the bar. */\nexport interface LayoutCustomItem {\n readonly custom: string;\n readonly command?: string;\n /** Your component's forms, largest first. Default `['default']`. */\n readonly variants?: readonly string[];\n readonly importance?: Importance;\n}\n\n/** A command id, a command with options, or your own component. */\nexport type LayoutItem = string | LayoutCommandItem | LayoutCustomItem;\n\n/** A group that needs a name or options. */\nexport interface LayoutGroupObject {\n /** Its name, so `add(item, { group })` can find it. */\n readonly id?: string;\n readonly items: readonly LayoutItem[];\n /** Fold into one button with a menu (`'menu'`) or a dropdown (`'select'`) when there's no room. */\n readonly collapse?: 'menu' | 'select';\n /** Move items behind a button inside the group before the group folds or leaves the bar. */\n readonly shed?: boolean;\n /** Who makes room first: `1` to `5`. Default `3`. */\n readonly importance?: Importance;\n /** Its title in the \"More\" menu, as a translation key. */\n readonly titleKey?: string;\n /**\n * Show only while something in the bar that isn't dependent shows, like undo and redo beside a\n * mode's tools. A bar with only dependent groups left is empty, and a mode's tab goes with it.\n */\n readonly dependent?: boolean;\n}\n\n/** A group of items, with a line between groups: an array, or an object when it needs a name or options. */\nexport type LayoutGroup = readonly LayoutItem[] | LayoutGroupObject;\n\n/** A section of a bar: its groups in order. A lone item is a group of one. */\nexport type LayoutSection = readonly (LayoutGroup | LayoutItem)[];\n\n/** A bar's sections: `start` (left), `center` and `end` (right); `start` and `end` swap in a right-to-left language. */\nexport type SectionName = 'start' | 'center' | 'end';\n\nexport interface LayoutBar {\n readonly place: BarPlace;\n /** Shown in this mode only. The mode gets a tab, titled by the bar's title, and a `mode:<mode>` command. */\n readonly mode?: string;\n readonly title?: string;\n /** The title as a translation key. */\n readonly titleKey?: string;\n readonly start?: LayoutSection;\n readonly center?: LayoutSection;\n readonly end?: LayoutSection;\n}\n\n/** A section of a menu: an array of command ids, or an object when it has a title. */\nexport type LayoutMenuSection =\n | readonly string[]\n | {\n readonly title?: string;\n /** The title as a translation key. */\n readonly titleKey?: string;\n readonly items: readonly string[];\n };\n\n/** A menu: its sections, with a line between them. */\nexport type LayoutMenu = readonly LayoutMenuSection[];\n\n/** How a panel opens: beside the pages, over them, or up from the bottom. */\nexport type PanelPresentation = 'dock' | 'overlay' | 'sheet';\n\n/** How a panel opens at each of the viewer's sizes. A size left out opens the default way. */\nexport interface PanelPresentationBySize {\n readonly compact?: PanelPresentation;\n readonly medium?: PanelPresentation;\n readonly expanded?: PanelPresentation;\n}\n\n/** A panel's width: the one it starts at, and the narrowest and widest it can be dragged to. */\nexport interface PanelWidth {\n /** In px. Default `288`. */\n readonly initial?: number;\n /** In px. Default `200`. */\n readonly min?: number;\n /** In px. Default `640`. A docked panel never takes more than half the viewer. */\n readonly max?: number;\n}\n\nexport interface LayoutPanel {\n /** Default `'end'`. */\n readonly side?: 'start' | 'end';\n readonly title?: string;\n /** The title as a translation key. */\n readonly titleKey?: string;\n /** Its button's icon. */\n readonly icon?: string;\n /**\n * How it opens: the same way at every size, or per size. Default\n * `{ compact: 'sheet', medium: 'overlay', expanded: 'dock' }`.\n */\n readonly present?: PanelPresentation | PanelPresentationBySize;\n /** Its width in px (where it starts), or where it starts and how far it drags. Default `288`. */\n readonly width?: number | PanelWidth;\n /** Whether people can drag its edge to change its width. Default `true`. */\n readonly resizable?: boolean;\n}\n\n/**\n * Changes to a panel: the fields to set. `present` and `width` change only what they name: a\n * map of sizes keeps the other sizes, and a number or `{ initial }` keeps `min` and `max`.\n */\nexport type LayoutPanelPatch = Partial<LayoutPanel>;\n\n/** When the document tabs show: always, while more than one document is open, or never. */\nexport type TabsVisibility = 'always' | 'multiple' | 'never';\n\n/** A layout as plain data: bars, menus and panels, each by id. */\nexport interface LayoutData {\n readonly bars?: Readonly<Record<string, LayoutBar>>;\n readonly menus?: Readonly<Record<string, LayoutMenu>>;\n readonly panels?: Readonly<Record<string, LayoutPanel>>;\n readonly tabs?: TabsVisibility;\n}\n\n// ── the layout ───────────────────────────────────────────────────────────────\n\n/** Where {@link Layout.add} puts an item. */\nexport interface AddItemOptions {\n /** The bar or menu. A bar wins over a menu with the same id. */\n readonly to: string;\n /** The bar's section for a new group. Default `'end'`. */\n readonly section?: SectionName;\n /** The group to join, by id; a new id starts a new group at the end of the section. */\n readonly group?: string;\n /** An item to put it before, in that item's group. */\n readonly before?: string;\n /** An item to put it after, in that item's group. */\n readonly after?: string;\n}\n\n/** Where {@link Layout.remove} takes items from. */\nexport interface RemoveItemOptions {\n /** The bar or menu: always one place. To leave something out everywhere, turn it off instead. */\n readonly from: string;\n}\n\n/**\n * A layout: its data and the edits. Every edit returns a new layout and leaves this one as it\n * was; an edit that names an id the layout doesn't have changes nothing and records a warning.\n */\nexport interface Layout {\n /** Move a bar. */\n place(bar: string, place: BarPlace): Layout;\n /** Add a bar, or replace the bar with that id. */\n addBar(id: string, bar: LayoutBar): Layout;\n /** Remove a bar. Removing a mode's bar removes its tab. */\n removeBar(id: string): Layout;\n /** Put an item in a bar or a menu: at the end of a section, in a group, or next to an item. */\n add(item: LayoutItem, options: AddItemOptions): Layout;\n /** Take items out of one bar or menu; a group or section with nothing left goes with them. */\n remove(ids: string | readonly string[], options: RemoveItemOptions): Layout;\n /** Put another item in an item's place, in every bar and menu. */\n replace(id: string, item: LayoutItem): Layout;\n /** Add a menu, or replace the menu with that id. */\n addMenu(id: string, sections: LayoutMenu): Layout;\n /** Add a panel, or replace the panel with that id. */\n addPanel(id: string, panel: LayoutPanel): Layout;\n /** Change a panel's fields. */\n panel(id: string, changes: LayoutPanelPatch): Layout;\n /**\n * Change every panel's fields, as `panel(id, changes)` changes one: every panel the layout has\n * so far, so a panel added after it keeps its own.\n */\n panels(changes: LayoutPanelPatch): Layout;\n /** Remove a panel, and its `panel:<id>` button from every bar and menu. */\n removePanel(id: string): Layout;\n /** When the document tabs show. */\n tabs(visibility: TabsVisibility): Layout;\n /** The layout as plain data. */\n toJSON(): LayoutData;\n}\n\ninterface LayoutState {\n readonly data: LayoutData;\n readonly warnings: readonly string[];\n}\n\nconst states = new WeakMap<Layout, LayoutState>();\n\n/** A layout of `data`, which it never changes. */\nexport function createLayout(data: LayoutData = {}): Layout {\n return layoutOf(data, []);\n}\n\n/** Whether `value` is a layout made by {@link createLayout} or one of its edits. */\nexport function isLayout(value: unknown): value is Layout {\n return typeof value === 'object' && value !== null && states.has(value as Layout);\n}\n\n/** What the edits that made `layout` couldn't do. */\nexport function layoutWarningsOf(layout: Layout): readonly string[] {\n return states.get(layout)?.warnings ?? [];\n}\n\n/** `layout` with one more warning. */\nexport function withLayoutWarning(layout: Layout, warning: string): Layout {\n const state = states.get(layout);\n return state ? layoutOf(state.data, [...state.warnings, warning]) : layout;\n}\n\ntype Edited = readonly [LayoutData, readonly string[]];\n\nfunction layoutOf(data: LayoutData, warnings: readonly string[]): Layout {\n const next = ([nextData, added]: Edited): Layout =>\n layoutOf(nextData, added.length > 0 ? [...warnings, ...added] : warnings);\n const layout: Layout = Object.freeze({\n place: (bar: string, place: BarPlace) => next(placeBar(data, bar, place)),\n addBar: (id: string, bar: LayoutBar) => next([withRecord(data, 'bars', id, bar), []]),\n removeBar: (id: string) => next(removeBar(data, id)),\n add: (item: LayoutItem, options: AddItemOptions) => next(addItem(data, item, options)),\n remove: (ids: string | readonly string[], options: RemoveItemOptions) =>\n next(removeItems(data, typeof ids === 'string' ? [ids] : ids, options)),\n replace: (id: string, item: LayoutItem) => next(replaceItem(data, id, item)),\n addMenu: (id: string, sections: LayoutMenu) =>\n next([withRecord(data, 'menus', id, sections), []]),\n addPanel: (id: string, panel: LayoutPanel) => next([withRecord(data, 'panels', id, panel), []]),\n panel: (id: string, changes: LayoutPanelPatch) => next(updatePanel(data, id, changes)),\n panels: (changes: LayoutPanelPatch) => next([updatePanels(data, changes), []]),\n removePanel: (id: string) => next(removePanel(data, id)),\n tabs: (visibility: TabsVisibility) => next([{ ...data, tabs: visibility }, []]),\n toJSON: () => data,\n });\n states.set(layout, { data, warnings });\n return layout;\n}\n\n// ── reading the data ─────────────────────────────────────────────────────────\n\nexport const SECTION_NAMES: readonly SectionName[] = ['start', 'center', 'end'];\n\n/** One entry of a section: a group, or a lone item. */\nexport type SectionEntry = LayoutGroup | LayoutItem;\n\n/** Whether a section entry is a group written as an object. */\nexport const isGroupObject = (entry: SectionEntry): entry is LayoutGroupObject =>\n typeof entry === 'object' && entry !== null && !Array.isArray(entry) && 'items' in entry;\n\n/**\n * A bar section's entries; none for a section that isn't a list. Layout data comes from\n * people: what isn't the right shape is skipped here and named by `validateLayout`.\n */\nexport function entriesOf(bar: LayoutBar, name: SectionName): readonly SectionEntry[] {\n const entries: unknown = bar[name];\n return Array.isArray(entries) ? (entries as readonly SectionEntry[]) : [];\n}\n\n/** A section entry's items: a group's, or the lone item. */\nexport function itemsOfEntry(entry: SectionEntry): readonly LayoutItem[] {\n if (Array.isArray(entry)) return entry as readonly LayoutItem[];\n if (isGroupObject(entry)) return Array.isArray(entry.items) ? entry.items : [];\n return [entry as LayoutItem];\n}\n\n/** What an item is called in edits: its command id, your component's id, or `''` for a non-item. */\nexport function itemIdOf(item: LayoutItem): string {\n if (typeof item === 'string') return item;\n if (typeof item !== 'object' || item === null) return '';\n return 'custom' in item ? item.custom : item.command;\n}\n\n/** The command an item runs or stands for in menus, or `null` for your component without one. */\nexport function itemCommandOf(item: LayoutItem): string | null {\n if (typeof item === 'string') return item;\n if (typeof item !== 'object' || item === null) return null;\n return 'custom' in item ? (item.command ?? null) : item.command;\n}\n\n/** Whether `value` has an item's shape: a command id, `{ command }` or `{ custom }`. */\nexport function isLayoutItem(value: unknown): value is LayoutItem {\n if (typeof value === 'string') return value.length > 0;\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const item = value as { command?: unknown; custom?: unknown };\n return typeof item.custom === 'string' || typeof item.command === 'string';\n}\n\n/** Every item id in a bar, in order, once each. */\nexport function itemIdsOfBar(bar: LayoutBar): string[] {\n const ids = new Set<string>();\n for (const name of SECTION_NAMES)\n for (const entry of entriesOf(bar, name))\n for (const item of itemsOfEntry(entry)) if (isLayoutItem(item)) ids.add(itemIdOf(item));\n return [...ids];\n}\n\n/** A menu section's items; none for a section that isn't one. */\nexport function itemsOfMenuSection(section: LayoutMenuSection): readonly string[] {\n if (Array.isArray(section)) return section as readonly string[];\n const items: unknown = (section as { items?: unknown } | null)?.items;\n return Array.isArray(items) ? (items as readonly string[]) : [];\n}\n\n/** A menu's sections; none for a menu that isn't a list. */\nexport const sectionsOfMenu = (menu: LayoutMenu): readonly LayoutMenuSection[] =>\n Array.isArray(menu) ? menu : [];\n\n/** Every item in a menu, in order, once each. */\nexport const itemIdsOfMenu = (menu: LayoutMenu): string[] => [\n ...new Set(sectionsOfMenu(menu).flatMap((section) => itemsOfMenuSection(section))),\n];\n\nconst barsOf = (data: LayoutData) => data.bars ?? {};\nconst menusOf = (data: LayoutData) => data.menus ?? {};\nconst panelsOf = (data: LayoutData) => data.panels ?? {};\n\nfunction withRecord<Key extends 'bars' | 'menus' | 'panels'>(\n data: LayoutData,\n key: Key,\n id: string,\n value: NonNullable<LayoutData[Key]>[string],\n): LayoutData {\n return { ...data, [key]: { ...data[key], [id]: value } };\n}\n\nfunction withoutRecord(data: LayoutData, key: 'bars' | 'menus' | 'panels', id: string): LayoutData {\n const { [id]: _removed, ...rest } = data[key] ?? {};\n return { ...data, [key]: rest };\n}\n\n/**\n * The entry with its items replaced: `null` when the edit took its last one, so the group goes.\n * A group that held none to begin with stays: the `modes` group, whose tabs are derived.\n */\nfunction withEntryItems(entry: SectionEntry, items: readonly LayoutItem[]): SectionEntry | null {\n if (items.length === 0) return itemsOfEntry(entry).length === 0 ? entry : null;\n if (isGroupObject(entry)) return { ...entry, items };\n if (Array.isArray(entry)) return items;\n // A lone item that gained a neighbour becomes a group of its own.\n return items.length === 1 ? items[0]! : items;\n}\n\n/** The bar with each entry mapped; entries mapped to `null` and sections left empty go. */\nfunction mapEntries(\n bar: LayoutBar,\n map: (entry: SectionEntry, section: SectionName, index: number) => SectionEntry | null,\n): LayoutBar {\n const next: { -readonly [Name in SectionName]?: LayoutSection } = {};\n for (const name of SECTION_NAMES) {\n const entries = entriesOf(bar, name);\n if (entries.length === 0) continue;\n const mapped = entries\n .map((entry, index) => map(entry, name, index))\n .filter((entry): entry is SectionEntry => entry !== null);\n if (mapped.length > 0) next[name] = mapped;\n }\n const { start: _start, center: _center, end: _end, ...rest } = bar;\n return { ...rest, ...next };\n}\n\nfunction withMenuSectionItems(\n section: LayoutMenuSection,\n items: readonly string[],\n): LayoutMenuSection | null {\n if (items.length === 0) return null;\n return Array.isArray(section) ? items : { ...(section as object), items };\n}\n\nconst notFound = (verb: string, id: string, where: string, candidates: Iterable<string>) =>\n `${verb}: \"${id}\" is not in \"${where}\"${didYouMean(id, candidates)}`;\n\n// ── the edits ────────────────────────────────────────────────────────────────\n\nfunction placeBar(data: LayoutData, id: string, place: BarPlace): Edited {\n const bar = barsOf(data)[id];\n if (!bar) return [data, [`place: no bar \"${id}\"${didYouMean(id, Object.keys(barsOf(data)))}`]];\n return [withRecord(data, 'bars', id, { ...bar, place }), []];\n}\n\nfunction removeBar(data: LayoutData, id: string): Edited {\n if (!barsOf(data)[id])\n return [data, [`removeBar: no bar \"${id}\"${didYouMean(id, Object.keys(barsOf(data)))}`]];\n return [withoutRecord(data, 'bars', id), []];\n}\n\nfunction addItem(data: LayoutData, item: LayoutItem, options: AddItemOptions | undefined): Edited {\n if (!isLayoutItem(item)) return [data, [`add: ${JSON.stringify(item)} is not an item`]];\n const to = options?.to;\n if (!to) return [data, [`add: \"${itemIdOf(item)}\" needs a bar or menu to go to ({ to })`]];\n const bar = barsOf(data)[to];\n if (bar) return addToBar(data, to, bar, item, options);\n const menu = menusOf(data)[to];\n if (menu) return addToMenu(data, to, menu, item, options);\n const places = [...Object.keys(barsOf(data)), ...Object.keys(menusOf(data))];\n return [data, [`add: no bar or menu \"${to}\"${didYouMean(to, places)}`]];\n}\n\nfunction addToBar(\n data: LayoutData,\n barId: string,\n bar: LayoutBar,\n item: LayoutItem,\n options: AddItemOptions,\n): Edited {\n const id = itemIdOf(item);\n const warnings: string[] = [];\n const twice = (items: readonly LayoutItem[]) => items.some((each) => itemIdOf(each) === id);\n const already = `add: \"${id}\" is already in that group of \"${barId}\"`;\n\n const anchor = options.before ?? options.after;\n if (anchor !== undefined) {\n for (const name of SECTION_NAMES) {\n const entries = entriesOf(bar, name);\n for (let index = 0; index < entries.length; index++) {\n const items = itemsOfEntry(entries[index]!);\n const at = items.findIndex((each) => itemIdOf(each) === anchor);\n if (at === -1) continue;\n if (twice(items)) return [data, [already]];\n const cut = options.before !== undefined ? at : at + 1;\n const nextItems = [...items.slice(0, cut), item, ...items.slice(cut)];\n const nextBar = mapEntries(bar, (entry, section, i) =>\n section === name && i === index ? withEntryItems(entry, nextItems) : entry,\n );\n return [withRecord(data, 'bars', barId, nextBar), []];\n }\n }\n // Not found: the item still goes in, where it would go without `before`/`after`.\n warnings.push(notFound('add', anchor, barId, itemIdsOfBar(bar)));\n }\n\n if (options.group !== undefined) {\n for (const name of SECTION_NAMES) {\n const entries = entriesOf(bar, name);\n const index = entries.findIndex(\n (entry) => isGroupObject(entry) && entry.id === options.group,\n );\n if (index === -1) continue;\n const items = itemsOfEntry(entries[index]!);\n if (twice(items)) return [data, [already]];\n const nextBar = mapEntries(bar, (entry, section, i) =>\n section === name && i === index ? withEntryItems(entry, [...items, item]) : entry,\n );\n return [withRecord(data, 'bars', barId, nextBar), warnings];\n }\n }\n\n let section = options.section ?? 'end';\n if (!SECTION_NAMES.includes(section)) {\n warnings.push(`add: \"${section}\" is not a section (start, center or end); using \"end\"`);\n section = 'end';\n }\n const entry: SectionEntry =\n options.group !== undefined ? { id: options.group, items: [item] } : [item];\n const nextBar: LayoutBar = { ...bar, [section]: [...entriesOf(bar, section), entry] };\n return [withRecord(data, 'bars', barId, nextBar), warnings];\n}\n\nfunction addToMenu(\n data: LayoutData,\n menuId: string,\n menu: LayoutMenu,\n item: LayoutItem,\n options: AddItemOptions,\n): Edited {\n const command = typeof item === 'string' ? item : 'custom' in item ? null : item.command;\n if (command === null)\n return [data, [`add: \"${menuId}\" is a menu, which holds commands, not your own components`]];\n if (itemIdsOfMenu(menu).includes(command))\n return [data, [`add: \"${command}\" is already in \"${menuId}\"`]];\n\n const warnings: string[] = [];\n const anchor = options.before ?? options.after;\n if (anchor !== undefined) {\n const sections = sectionsOfMenu(menu);\n const index = sections.findIndex((section) => itemsOfMenuSection(section).includes(anchor));\n if (index !== -1) {\n const items = itemsOfMenuSection(sections[index]!);\n const at = items.indexOf(anchor);\n const cut = options.before !== undefined ? at : at + 1;\n const nextItems = [...items.slice(0, cut), command, ...items.slice(cut)];\n const nextMenu = sections.map((section, i) =>\n i === index ? withMenuSectionItems(section, nextItems)! : section,\n );\n return [withRecord(data, 'menus', menuId, nextMenu), []];\n }\n warnings.push(notFound('add', anchor, menuId, itemIdsOfMenu(menu)));\n }\n return [withRecord(data, 'menus', menuId, [...sectionsOfMenu(menu), [command]]), warnings];\n}\n\nfunction removeItems(\n data: LayoutData,\n ids: readonly string[],\n options: RemoveItemOptions | undefined,\n): Edited {\n const from = options?.from;\n if (!from)\n return [\n data,\n [\n `remove: ${ids.map((id) => `\"${id}\"`).join(', ')} needs a bar or menu to come out of ({ from }); ` +\n 'to leave something out everywhere, turn it off with `disable`',\n ],\n ];\n const gone = new Set(ids);\n const found = new Set<string>();\n const bar = barsOf(data)[from];\n if (bar) {\n const nextBar = mapEntries(bar, (entry) =>\n withEntryItems(\n entry,\n itemsOfEntry(entry).filter((each) => {\n const id = itemIdOf(each);\n if (!gone.has(id)) return true;\n found.add(id);\n return false;\n }),\n ),\n );\n const missing = ids.filter((id) => !found.has(id));\n return [\n found.size > 0 ? withRecord(data, 'bars', from, nextBar) : data,\n missing.map((id) => notFound('remove', id, from, itemIdsOfBar(bar))),\n ];\n }\n const menu = menusOf(data)[from];\n if (menu) {\n const nextMenu = sectionsOfMenu(menu)\n .map((section) =>\n withMenuSectionItems(\n section,\n itemsOfMenuSection(section).filter((id) => {\n if (!gone.has(id)) return true;\n found.add(id);\n return false;\n }),\n ),\n )\n .filter((section): section is LayoutMenuSection => section !== null);\n const missing = ids.filter((id) => !found.has(id));\n return [\n found.size > 0 ? withRecord(data, 'menus', from, nextMenu) : data,\n missing.map((id) => notFound('remove', id, from, itemIdsOfMenu(menu))),\n ];\n }\n const places = [...Object.keys(barsOf(data)), ...Object.keys(menusOf(data))];\n return [data, [`remove: no bar or menu \"${from}\"${didYouMean(from, places)}`]];\n}\n\nfunction replaceItem(data: LayoutData, id: string, item: LayoutItem): Edited {\n if (!isLayoutItem(item)) return [data, [`replace: ${JSON.stringify(item)} is not an item`]];\n let found = false;\n const bars: Record<string, LayoutBar> = {};\n for (const [barId, bar] of Object.entries(barsOf(data))) {\n if (!itemIdsOfBar(bar).includes(id)) {\n bars[barId] = bar;\n continue;\n }\n found = true;\n bars[barId] = mapEntries(bar, (entry) =>\n withEntryItems(\n entry,\n itemsOfEntry(entry).map((each) => (itemIdOf(each) === id ? item : each)),\n ),\n );\n }\n // A menu row is a command: your own component has no place there.\n const command = typeof item === 'string' ? item : 'custom' in item ? null : item.command;\n const menus: Record<string, LayoutMenu> = {};\n for (const [menuId, menu] of Object.entries(menusOf(data))) {\n if (command === null || !itemIdsOfMenu(menu).includes(id)) {\n menus[menuId] = menu;\n continue;\n }\n found = true;\n menus[menuId] = sectionsOfMenu(menu).map(\n (section) =>\n withMenuSectionItems(\n section,\n itemsOfMenuSection(section).map((each) => (each === id ? command : each)),\n )!,\n );\n }\n if (!found) {\n const everywhere = [\n ...Object.values(barsOf(data)).flatMap(itemIdsOfBar),\n ...Object.values(menusOf(data)).flatMap(itemIdsOfMenu),\n ];\n return [data, [`replace: \"${id}\" is in no bar or menu${didYouMean(id, everywhere)}`]];\n }\n return [{ ...data, bars, menus }, []];\n}\n\n/** A panel's `present` as a map of sizes: one way at every size, or the sizes it names. */\nexport const panelPresentationsOf = (\n present: PanelPresentation | PanelPresentationBySize,\n): PanelPresentationBySize =>\n typeof present === 'string' ? { compact: present, medium: present, expanded: present } : present;\n\n/** A panel's `width` as its fields: a number is where it starts. */\nexport const panelWidthFieldsOf = (width: number | PanelWidth): PanelWidth =>\n typeof width === 'number' ? { initial: width } : width;\n\n/**\n * `panel` with `changes`: each field replaced, except `present` and `width`, which change only\n * what the change names (a map of sizes keeps the other sizes, `{ initial }` keeps the limits).\n */\nfunction changedPanel(panel: LayoutPanel, changes: LayoutPanelPatch): LayoutPanel {\n const next: Record<string, unknown> = { ...panel };\n for (const [field, value] of Object.entries(changes)) {\n if (value !== undefined) next[field] = value;\n }\n const { present, width } = changes;\n if (typeof present === 'object' && panel.present !== undefined)\n next.present = { ...panelPresentationsOf(panel.present), ...present };\n if (\n width !== undefined &&\n panel.width !== undefined &&\n (typeof width === 'object' || typeof panel.width === 'object')\n )\n next.width = { ...panelWidthFieldsOf(panel.width), ...panelWidthFieldsOf(width) };\n return next as LayoutPanel;\n}\n\nfunction updatePanel(data: LayoutData, id: string, changes: LayoutPanelPatch): Edited {\n const panel = panelsOf(data)[id];\n if (!panel)\n return [data, [`panel: no panel \"${id}\"${didYouMean(id, Object.keys(panelsOf(data)))}`]];\n return [withRecord(data, 'panels', id, changedPanel(panel, changes)), []];\n}\n\nfunction updatePanels(data: LayoutData, changes: LayoutPanelPatch): LayoutData {\n const panels = Object.fromEntries(\n Object.entries(panelsOf(data)).map(([id, panel]) => [id, changedPanel(panel, changes)]),\n );\n return { ...data, panels };\n}\n\nfunction removePanel(data: LayoutData, id: string): Edited {\n if (!panelsOf(data)[id])\n return [data, [`removePanel: no panel \"${id}\"${didYouMean(id, Object.keys(panelsOf(data)))}`]];\n // Its button goes with it, from every bar and menu.\n const button = `panel:${id}`;\n const bars = Object.fromEntries(\n Object.entries(barsOf(data)).map(([barId, bar]) => [\n barId,\n itemIdsOfBar(bar).includes(button)\n ? mapEntries(bar, (entry) =>\n withEntryItems(\n entry,\n itemsOfEntry(entry).filter((each) => itemIdOf(each) !== button),\n ),\n )\n : bar,\n ]),\n );\n const menus = Object.fromEntries(\n Object.entries(menusOf(data)).map(([menuId, menu]) => [\n menuId,\n itemIdsOfMenu(menu).includes(button)\n ? sectionsOfMenu(menu)\n .map((section) =>\n withMenuSectionItems(\n section,\n itemsOfMenuSection(section).filter((each) => each !== button),\n ),\n )\n .filter((section): section is LayoutMenuSection => section !== null)\n : menu,\n ]),\n );\n return [{ ...withoutRecord(data, 'panels', id), bars, menus }, []];\n}\n\n// ── the viewer's size ────────────────────────────────────────────────────────\n\n/** The viewer's size class, from its own width. */\nexport type ViewerSize = 'compact' | 'medium' | 'expanded';\n\n/** What the layout function knows about the viewer, measured on the viewer itself. */\nexport interface LayoutEnv {\n /** `'compact'` under 600 px, `'medium'` to 1023 px, `'expanded'` from 1024 px. */\n readonly size: ViewerSize;\n /** The viewer's width, in px. */\n readonly width: number;\n /** Whether the main way of pointing is a finger. */\n readonly touch: boolean;\n /** How the user's language reads. */\n readonly dir: 'ltr' | 'rtl';\n}\n\n/** The narrowest a medium viewer is, in px. */\nexport const MEDIUM_MIN_WIDTH_PX = 600;\n/** The narrowest an expanded viewer is, in px. */\nexport const EXPANDED_MIN_WIDTH_PX = 1024;\n\n/** The size class of a viewer this wide. */\nexport function sizeOf(widthPx: number): ViewerSize {\n if (widthPx < MEDIUM_MIN_WIDTH_PX) return 'compact';\n return widthPx < EXPANDED_MIN_WIDTH_PX ? 'medium' : 'expanded';\n}\n\n/** Whether two envs are the same: the layout function runs again only when one of the fields changes. */\nexport const sameLayoutEnv = (left: LayoutEnv, right: LayoutEnv): boolean =>\n left.size === right.size &&\n left.width === right.width &&\n left.touch === right.touch &&\n left.dir === right.dir;\n\n// ── the layout option ────────────────────────────────────────────────────────\n\n/** Gets the default layout and the viewer's env, and returns your layout. */\nexport type LayoutFunction = (layout: Layout, env: LayoutEnv) => Layout | LayoutData;\n\n/** What the `layout` config takes: a layout, plain layout data, or a function of the default. */\nexport type LayoutOption = Layout | LayoutData | LayoutFunction;\n\n/**\n * The layout an option gives at this env: the default without one, the function's result, or\n * the option itself. A function that throws or returns no layout gives the default, with a\n * warning saying so.\n */\nexport function resolveLayout(\n option: LayoutOption | null | undefined,\n defaults: Layout,\n env: LayoutEnv,\n): Layout {\n if (option === undefined || option === null) return defaults;\n if (typeof option === 'function') {\n let result: unknown;\n try {\n result = option(defaults, env);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return withLayoutWarning(\n defaults,\n `the layout function threw (${message}); showing the default layout`,\n );\n }\n return toLayout(result, defaults, 'the layout function returned');\n }\n return toLayout(option, defaults, 'layout is');\n}\n\nfunction toLayout(value: unknown, defaults: Layout, what: string): Layout {\n if (isLayout(value)) return value;\n if (typeof value === 'object' && value !== null && !Array.isArray(value))\n return createLayout(value as LayoutData);\n return withLayoutWarning(\n defaults,\n `${what} ${value === undefined ? 'nothing' : typeof value}, not a layout; showing the default layout`,\n );\n}\n","/**\n * A layout read the way the viewer places it: the bars on an edge in their\n * order, the bars floating over the pages, the bars that ride along another bar\n * or follow a selection, the modes and their tabs, the menus' sections, when the\n * document tabs show, and each bar as the {@link BarSchema} a toolbar fits.\n *\n * The mode tabs are derived, never written: the group with id `modes` lists\n * View, then one tab per mode of the layout's bars, in bar order, before any\n * items of its own.\n */\nimport type {\n BarEdge,\n BarPlace,\n FloatPosition,\n LayoutBar,\n LayoutData,\n LayoutItem,\n LayoutMenuSection,\n SectionName,\n SelectionTarget,\n TabsVisibility,\n} from './layout';\nimport {\n SECTION_NAMES,\n entriesOf,\n isGroupObject,\n isLayoutItem,\n itemIdOf,\n itemsOfEntry,\n itemsOfMenuSection,\n sectionsOfMenu,\n} from './layout';\nimport type {\n BarChild,\n BarGroup,\n BarItem,\n BarSchema,\n BarSections,\n CustomItem,\n NormalizedBar,\n} from './schema';\nimport { commandOfUnit, hasVisibleUnits, normalizeBar } from './schema';\n\n/** The id of the group that holds the mode tabs. */\nexport const MODES_GROUP = 'modes';\n\n/** The command of the mode with no bar of its own: viewing. */\nexport const VIEW_MODE_COMMAND = 'mode:view';\n\n/** The command that opens a mode, and its tab. */\nexport const modeCommandOf = (mode: string): string => `mode:${mode}`;\n\n/** The command that opens and closes a panel, and its button. */\nexport const panelCommandOf = (panel: string): string => `panel:${panel}`;\n\nconst EDGES: readonly BarEdge[] = ['top', 'bottom', 'start', 'end'];\n\n/** Every place a bar can float over the pages: each corner, and the middle of each side. */\nexport const FLOAT_POSITIONS: readonly FloatPosition[] = [\n 'top-start',\n 'top',\n 'top-end',\n 'start',\n 'end',\n 'bottom-start',\n 'bottom',\n 'bottom-end',\n];\n\n/** The layout's bars, by id, in order: the ones that are objects (`validateLayout` names the rest). */\nconst barsOf = (data: LayoutData): [string, LayoutBar][] =>\n Object.entries(data.bars ?? {}).filter(\n (entry): entry is [string, LayoutBar] => typeof entry[1] === 'object' && entry[1] !== null,\n );\n\n/** The edge a place is on, or `null` for a place that isn't an edge. */\nexport function edgeOf(place: BarPlace | undefined): BarEdge | null {\n if (typeof place === 'string') return EDGES.includes(place) ? place : null;\n if (typeof place === 'object' && place !== null && 'edge' in place)\n return EDGES.includes(place.edge) ? place.edge : null;\n return null;\n}\n\n/** The bar a place rides along, or `null`. */\nexport function hostOf(place: BarPlace | undefined): string | null {\n return typeof place === 'object' && place !== null && 'with' in place ? place.with : null;\n}\n\n/** What a place follows when it is over a selection, or `null`. */\nexport function selectionOf(place: BarPlace | undefined): SelectionTarget | null {\n return typeof place === 'object' && place !== null && 'at' in place ? place.at : null;\n}\n\n/** Where a place floats over the pages, or `null` for a place that doesn't float. */\nexport function floatOf(place: BarPlace | undefined): FloatPosition | null {\n return typeof place === 'object' &&\n place !== null &&\n 'float' in place &&\n FLOAT_POSITIONS.includes(place.float)\n ? place.float\n : null;\n}\n\n/**\n * The bars along an edge, from the outside in: in the order they were added, then each bar\n * with `before` or `after` put next to the bar it names. A bar that names a bar not on this\n * edge goes innermost.\n */\nexport function barsOnEdge(data: LayoutData, edge: BarEdge): string[] {\n const placed = barsOf(data).filter(([, bar]) => edgeOf(bar.place) === edge);\n const anchorOf = (place: BarPlace) =>\n typeof place === 'object' && place !== null && 'edge' in place\n ? place.before !== undefined\n ? { id: place.before, after: false }\n : place.after !== undefined\n ? { id: place.after, after: true }\n : null\n : null;\n const stack = placed.filter(([, bar]) => anchorOf(bar.place) === null).map(([id]) => id);\n let pending = placed.filter(([, bar]) => anchorOf(bar.place) !== null);\n // Anchors may name bars that are themselves anchored: place what can be placed, again.\n for (let placedOne = true; placedOne && pending.length > 0; ) {\n placedOne = false;\n pending = pending.filter(([id, bar]) => {\n const anchor = anchorOf(bar.place)!;\n const index = stack.indexOf(anchor.id);\n if (index === -1) return true;\n stack.splice(anchor.after ? index + 1 : index, 0, id);\n placedOne = true;\n return false;\n });\n }\n return [...stack, ...pending.map(([id]) => id)];\n}\n\n/** The bars that ride along `host`, in the order they were added, nearest first. */\nexport function barsWith(data: LayoutData, host: string): string[] {\n return barsOf(data)\n .filter(([, bar]) => hostOf(bar.place) === host)\n .map(([id]) => id);\n}\n\n/** `bars` in order, each followed by the bars that ride along it (nearest first), and theirs. */\nfunction withRiders(data: LayoutData, bars: readonly string[]): string[] {\n const stack: string[] = [];\n const visit = (id: string) => {\n if (stack.includes(id)) return;\n stack.push(id);\n for (const rider of barsWith(data, id)) visit(rider);\n };\n for (const id of bars) visit(id);\n return stack;\n}\n\n/**\n * Every bar drawn along an edge, from the outside in: each bar on the edge, followed by the bars\n * that ride along it (nearest first) and the bars that ride along those.\n */\nexport function edgeStackOf(data: LayoutData, edge: BarEdge): string[] {\n return withRiders(data, barsOnEdge(data, edge));\n}\n\n/** The bars floating at `position`, in the order they were added. */\nexport function barsFloating(data: LayoutData, position: FloatPosition): string[] {\n return barsOf(data)\n .filter(([, bar]) => floatOf(bar.place) === position)\n .map(([id]) => id);\n}\n\n/**\n * Every bar drawn floating at `position`, from the viewer's edge in: each bar floating there,\n * followed by the bars that ride along it, as {@link edgeStackOf} orders an edge.\n */\nexport function floatStackOf(data: LayoutData, position: FloatPosition): string[] {\n return withRiders(data, barsFloating(data, position));\n}\n\n/** The bars over a selection of this kind, in the order they were added. */\nexport function barsAt(data: LayoutData, target: SelectionTarget): string[] {\n return barsOf(data)\n .filter(([, bar]) => selectionOf(bar.place) === target)\n .map(([id]) => id);\n}\n\n/** Every mode of the layout's bars, once each, in bar order. */\nexport function modesOf(data: LayoutData): string[] {\n const modes = new Set<string>();\n for (const [, bar] of barsOf(data))\n if (typeof bar.mode === 'string' && bar.mode.length > 0) modes.add(bar.mode);\n return [...modes];\n}\n\n/** The bars shown in a mode, in bar order. */\nexport function barsInMode(data: LayoutData, mode: string): string[] {\n return barsOf(data)\n .filter(([, bar]) => bar.mode === mode)\n .map(([id]) => id);\n}\n\n/** What {@link compileBar} leaves out. */\nexport interface CompileBarOptions {\n /**\n * Command ids to leave out, as if the bar didn't name them: a mode tab whose bars show nothing,\n * a button whose menu is empty. With every mode tab left out, View goes too.\n */\n readonly omit?: ReadonlySet<string>;\n}\n\nconst NOTHING: ReadonlySet<string> = new Set();\n\nconst toBarChild = (item: LayoutItem): BarChild => {\n if (typeof item === 'string') return item;\n if ('custom' in item) {\n const custom: { -readonly [Key in keyof CustomItem]: CustomItem[Key] } = { slot: item.custom };\n if (item.command !== undefined) custom.terminal = item.command;\n if (item.variants !== undefined) custom.variants = item.variants;\n if (item.importance !== undefined) custom.importance = item.importance;\n return custom;\n }\n const command: { -readonly [Key in keyof BarItem]: BarItem[Key] } = { command: item.command };\n if (item.variants !== undefined) command.variants = item.variants;\n if (item.importance !== undefined) command.importance = item.importance;\n return command;\n};\n\n/** The mode tabs, each a label at importance 1, so the tab strip is the first to compact. */\nfunction modeTabsOf(data: LayoutData, omit: ReadonlySet<string>): BarItem[] {\n const modes = modesOf(data)\n .map(modeCommandOf)\n .filter((command) => !omit.has(command));\n if (modes.length === 0) return [];\n const commands = omit.has(VIEW_MODE_COMMAND) ? modes : [VIEW_MODE_COMMAND, ...modes];\n return commands.map((command) => ({ command, variants: ['label'], importance: 1 }));\n}\n\n/**\n * A bar as the toolbar fits it, or `null` for a bar the layout doesn't have. Groups written as\n * arrays and lone items get ids of their own (`start-0`, …); an item twice in one group shows\n * once; a group with nothing left goes.\n */\nexport function compileBar(\n data: LayoutData,\n id: string,\n options: CompileBarOptions = {},\n): BarSchema | null {\n const bar = data.bars?.[id];\n if (typeof bar !== 'object' || bar === null) return null;\n const omit = options.omit ?? NOTHING;\n const used = new Set<string>();\n const uniqueId = (wanted: string): string => {\n let groupId = wanted;\n for (let count = 2; used.has(groupId); count++) groupId = `${wanted}-${count}`;\n used.add(groupId);\n return groupId;\n };\n\n const sections: { -readonly [Name in SectionName]?: readonly BarGroup[] } = {};\n for (const name of SECTION_NAMES) {\n const groups: BarGroup[] = [];\n entriesOf(bar, name).forEach((entry, index) => {\n const object = isGroupObject(entry) ? entry : null;\n const seen = new Set<string>();\n let items: LayoutItem[] = itemsOfEntry(entry).filter((item) => {\n if (!isLayoutItem(item)) return false;\n const itemId = itemIdOf(item);\n if (seen.has(itemId)) return false;\n seen.add(itemId);\n return typeof item === 'object' && 'custom' in item ? true : !omit.has(itemId);\n });\n const isModes = object?.id === MODES_GROUP;\n if (isModes)\n items = [...modeTabsOf(data, omit).filter((tab) => !seen.has(tab.command)), ...items];\n if (items.length === 0) return;\n const group: { -readonly [Key in keyof BarGroup]: BarGroup[Key] } = {\n id: uniqueId(object?.id ?? `${name}-${index}`),\n items: items.map(toBarChild),\n };\n if (isModes) group.role = 'tabs';\n if (object?.titleKey !== undefined) group.labelKey = object.titleKey;\n if (object?.shed !== undefined) group.shed = object.shed;\n if (object?.collapse !== undefined) group.collapse = object.collapse;\n if (object?.importance !== undefined) group.importance = object.importance;\n if (object?.dependent === true) group.dependent = true;\n groups.push(group);\n });\n if (groups.length > 0) sections[name] = groups;\n }\n return { id, sections: sections as BarSections };\n}\n\n/** When the document tabs show: as the layout says, else while more than one document is open. */\nexport function tabsOf(data: LayoutData): TabsVisibility {\n return data.tabs ?? 'multiple';\n}\n\n/** A menu section, read: its title and its command ids. */\nexport interface MenuSection {\n readonly title?: string;\n readonly titleKey?: string;\n readonly items: readonly string[];\n}\n\n/** A menu's sections, or `null` for a menu the layout doesn't have. An empty section goes. */\nexport function menuOf(data: LayoutData, id: string): readonly MenuSection[] | null {\n const menu = data.menus?.[id];\n if (!menu) return null;\n const commandsOf = (section: LayoutMenuSection) => [\n ...new Set(itemsOfMenuSection(section).filter((item) => typeof item === 'string')),\n ];\n return sectionsOfMenu(menu)\n .map((section: LayoutMenuSection): MenuSection => {\n if (Array.isArray(section) || typeof section !== 'object' || section === null)\n return { items: commandsOf(section) };\n const titled = section as Exclude<LayoutMenuSection, readonly string[]>;\n const read: { -readonly [Key in keyof MenuSection]: MenuSection[Key] } = {\n items: commandsOf(section),\n };\n if (titled.title !== undefined) read.title = titled.title;\n if (titled.titleKey !== undefined) read.titleKey = titled.titleKey;\n return read;\n })\n .filter((section) => section.items.length > 0);\n}\n\n// ── what shows nothing ───────────────────────────────────────────────────────\n\n/** What {@link omittedCommandsOf} reads of a command; plugin-commands' `ResolvedCommand` satisfies it. */\nexport interface OmissionCommand {\n readonly visible: boolean;\n readonly menu?: string;\n}\n\n/** A layout's mode bars and menus, read once per layout data. */\ninterface LayoutReach {\n readonly modes: readonly (readonly [string, readonly NormalizedBar[]])[];\n readonly menus: ReadonlyMap<string, readonly string[]>;\n /** Every command a bar names: the ones that may open a menu. */\n readonly buttons: readonly string[];\n}\n\nconst reachByData = new WeakMap<LayoutData, LayoutReach>();\n\nfunction reachOf(data: LayoutData): LayoutReach {\n const known = reachByData.get(data);\n if (known) return known;\n const modes = modesOf(data).map(\n (mode) =>\n [mode, barsInMode(data, mode).map((id) => normalizeBar(compileBar(data, id)!))] as const,\n );\n const menus = new Map(\n Object.keys(data.menus ?? {}).map((id) => [\n id,\n menuOf(data, id)!.flatMap((section) => section.items),\n ]),\n );\n const buttons = new Set<string>();\n for (const [, bar] of barsOf(data))\n for (const name of SECTION_NAMES)\n for (const entry of entriesOf(bar, name))\n for (const item of itemsOfEntry(entry))\n if (typeof item === 'string') buttons.add(item);\n else if (isLayoutItem(item) && !('custom' in item)) buttons.add(item.command);\n const reach = { modes, menus, buttons: [...buttons] };\n reachByData.set(data, reach);\n return reach;\n}\n\n/**\n * The commands the bars leave out because what they lead to shows nothing: the tab of a mode\n * whose bars have nothing visible ({@link hasVisibleUnits}: dependent groups alone don't count),\n * and a button whose menu has nothing visible (or that the layout has no menu for). Sorted, so\n * two equal results compare equal; pass it to {@link compileBar} as `omit`. Cheap to call on every change: what it reads of the layout is\n * read once per layout data.\n */\nexport function omittedCommandsOf(\n data: LayoutData,\n resolve: (id: string) => OmissionCommand | null,\n): string[] {\n const reach = reachOf(data);\n const isVisible = (id: string) => resolve(id)?.visible === true;\n const omitted: string[] = [];\n for (const [mode, bars] of reach.modes) {\n const shows = bars.some((bar) =>\n hasVisibleUnits(bar, (unit) => {\n const command = commandOfUnit(unit);\n return command !== null && isVisible(command);\n }),\n );\n if (!shows) omitted.push(modeCommandOf(mode));\n }\n for (const button of reach.buttons) {\n const menu = resolve(button)?.menu;\n if (menu !== undefined && !(reach.menus.get(menu) ?? []).some(isVisible)) omitted.push(button);\n }\n return omitted.sort();\n}\n","/**\n * Checks a layout against the viewer it runs in: every id it names exists,\n * every place is a place, and every bar it is placed next to is where the\n * place says. Each problem is one sentence with the id, and the closest id\n * that exists when there is one, for a console warning: the viewer still\n * starts with a layout that has problems, and leaves out what it can't place.\n */\nimport type {\n BarPlace,\n Layout,\n LayoutBar,\n LayoutData,\n LayoutItem,\n LayoutMenu,\n LayoutPanel,\n} from './layout';\nimport {\n SECTION_NAMES,\n isGroupObject,\n isLayout,\n isLayoutItem,\n itemCommandOf,\n itemIdOf,\n itemsOfEntry,\n itemsOfMenuSection,\n layoutWarningsOf,\n} from './layout';\nimport {\n VIEW_MODE_COMMAND,\n edgeOf,\n hostOf,\n modeCommandOf,\n modesOf,\n panelCommandOf,\n} from './layout-compile';\nimport { didYouMean } from './suggestions';\n\n/** What the viewer has, to check a layout's ids against. */\nexport interface LayoutKnownIds {\n /**\n * Every command id the viewer has. The ones the layout makes itself need not be listed: the\n * mode tabs (`mode:view`, `mode:<mode>`) and the panel buttons (`panel:<id>`).\n */\n readonly commands: Iterable<string>;\n /** Whether a command id exists that `commands` can't list, such as one of a family's. */\n readonly hasCommand?: (id: string) => boolean;\n}\n\nconst EDGES: readonly string[] = ['top', 'bottom', 'start', 'end'];\nconst FLOAT_POSITIONS: readonly string[] = [\n 'top-start',\n 'top',\n 'top-end',\n 'start',\n 'end',\n 'bottom-start',\n 'bottom',\n 'bottom-end',\n];\nconst SELECTION_TARGETS: readonly string[] = ['selection', 'annotation'];\nconst PRESENTATIONS: readonly string[] = ['dock', 'overlay', 'sheet'];\nconst SIZES: readonly string[] = ['compact', 'medium', 'expanded'];\nconst WIDTH_FIELDS: readonly string[] = ['initial', 'min', 'max'];\nconst TABS: readonly string[] = ['always', 'multiple', 'never'];\n\n/**\n * Every problem with a layout, as sentences: what its edits couldn't do first, then what its\n * data names that the viewer doesn't have. Empty when there is none.\n */\nexport function validateLayout(layout: Layout | LayoutData, known: LayoutKnownIds): string[] {\n const problems: string[] = isLayout(layout) ? [...layoutWarningsOf(layout)] : [];\n const data = isLayout(layout) ? layout.toJSON() : layout;\n if (typeof data !== 'object' || data === null)\n return [...problems, 'the layout is not an object'];\n\n const bars = data.bars ?? {};\n const knownCommands = new Set(known.commands);\n const commands = new Set(knownCommands);\n for (const mode of modesOf(data)) commands.add(modeCommandOf(mode));\n if (modesOf(data).length > 0) commands.add(VIEW_MODE_COMMAND);\n for (const panel of Object.keys(data.panels ?? {})) commands.add(panelCommandOf(panel));\n\n const checkCommand = (where: string, command: string) => {\n if (!commands.has(command) && known.hasCommand?.(command) !== true)\n problems.push(`${where}: no command \"${command}\"${didYouMean(command, commands)}`);\n };\n\n for (const [id, bar] of Object.entries(bars)) {\n const where = `bar \"${id}\"`;\n if (typeof bar !== 'object' || bar === null) {\n problems.push(`${where} is not a bar`);\n continue;\n }\n problems.push(...placeProblems(where, id, bar.place, data));\n if (bar.mode !== undefined && bar.title === undefined && bar.titleKey === undefined) {\n if (!knownCommands.has(modeCommandOf(bar.mode)))\n problems.push(\n `${where}: its mode \"${bar.mode}\" has no title, so its tab reads \"${bar.mode}\"`,\n );\n }\n problems.push(...itemProblems(where, bar, checkCommand));\n }\n\n for (const [id, menu] of Object.entries(data.menus ?? {}))\n problems.push(...menuProblems(`menu \"${id}\"`, menu, checkCommand));\n\n for (const [id, panel] of Object.entries(data.panels ?? {}))\n problems.push(...panelProblems(`panel \"${id}\"`, panel));\n\n if (data.tabs !== undefined && !TABS.includes(data.tabs))\n problems.push(`tabs: \"${data.tabs}\" is not one of always, multiple or never`);\n\n return problems;\n}\n\nfunction placeProblems(\n where: string,\n id: string,\n place: BarPlace | undefined,\n data: LayoutData,\n): string[] {\n const bars = data.bars ?? {};\n const notAPlace = (shown: string) =>\n `${where}: ${shown} is not a place (an edge, { edge, before | after }, { float }, { with } or { at })`;\n if (place === undefined) return [`${where} has no place`];\n if (typeof place === 'string') return EDGES.includes(place) ? [] : [notAPlace(`\"${place}\"`)];\n if (typeof place !== 'object' || place === null) return [notAPlace(String(place))];\n\n if ('edge' in place) {\n if (!EDGES.includes(place.edge)) return [`${where}: \"${place.edge}\" is not an edge`];\n const anchor = place.before ?? place.after;\n if (anchor === undefined) return [];\n const side = place.before !== undefined ? 'before' : 'after';\n const onEdge = Object.keys(bars).filter(\n (other) => other !== id && edgeOf(bars[other]!.place) === place.edge,\n );\n if (onEdge.includes(anchor)) return [];\n if (bars[anchor])\n return [`${where} goes ${side} \"${anchor}\", which is not on the ${place.edge} edge`];\n return [`${where} goes ${side} \"${anchor}\": no such bar${didYouMean(anchor, onEdge)}`];\n }\n if ('float' in place)\n return FLOAT_POSITIONS.includes(place.float)\n ? []\n : [\n `${where}: \"${place.float}\" is not a floating position${didYouMean(place.float, FLOAT_POSITIONS)}`,\n ];\n if ('with' in place) {\n if (place.with === id) return [`${where} rides along itself`];\n if (!bars[place.with])\n return [\n `${where} rides along \"${place.with}\": no such bar${didYouMean(place.with, Object.keys(bars))}`,\n ];\n // A chain of `with` that comes back to this bar has nowhere to go.\n const seen = new Set([id]);\n for (let host: string | null = place.with; host !== null; host = hostOf(bars[host]?.place)) {\n if (seen.has(host)) return [`${where} rides along a bar that rides along it`];\n seen.add(host);\n }\n return [];\n }\n if ('at' in place)\n return SELECTION_TARGETS.includes(place.at)\n ? []\n : [`${where}: \"${place.at}\" is not selection or annotation`];\n return [notAPlace(JSON.stringify(place))];\n}\n\nfunction itemProblems(\n where: string,\n bar: LayoutBar,\n checkCommand: (where: string, command: string) => void,\n): string[] {\n const problems: string[] = [];\n const groupIds = new Set<string>();\n let groups = 0;\n let dependentGroups = 0;\n for (const name of SECTION_NAMES) {\n const entries = bar[name];\n if (entries === undefined) continue;\n if (!Array.isArray(entries)) {\n problems.push(`${where}: its ${name} section is not a list of groups`);\n continue;\n }\n for (const entry of entries) {\n if (isGroupObject(entry) && entry.id !== undefined) {\n if (groupIds.has(entry.id)) problems.push(`${where}: two groups are called \"${entry.id}\"`);\n groupIds.add(entry.id);\n }\n groups++;\n if (isGroupObject(entry) && entry.dependent !== undefined) {\n const dependent: unknown = entry.dependent;\n if (dependent === true) dependentGroups++;\n else if (dependent !== false)\n problems.push(\n `${where}: ${entry.id === undefined ? 'a group' : `group \"${entry.id}\"`} has dependent ` +\n `${JSON.stringify(dependent)}, which is not true or false`,\n );\n }\n const seen = new Set<string>();\n for (const item of itemsOfEntry(entry) as readonly unknown[]) {\n if (!isLayoutItem(item)) {\n problems.push(`${where}: ${JSON.stringify(item)} is not an item`);\n continue;\n }\n const id = itemIdOf(item as LayoutItem);\n if (seen.has(id)) problems.push(`${where}: \"${id}\" is twice in one group`);\n seen.add(id);\n const command = itemCommandOf(item as LayoutItem);\n if (command !== null) checkCommand(where, command);\n }\n }\n }\n if (groups > 0 && dependentGroups === groups)\n problems.push(`${where}: every group in it is dependent, so it never shows`);\n return problems;\n}\n\nfunction menuProblems(\n where: string,\n menu: LayoutMenu,\n checkCommand: (where: string, command: string) => void,\n): string[] {\n if (!Array.isArray(menu)) return [`${where} is not a list of sections`];\n const problems: string[] = [];\n const seen = new Set<string>();\n for (const section of menu) {\n for (const command of itemsOfMenuSection(section) as readonly unknown[]) {\n if (typeof command !== 'string') {\n problems.push(`${where}: ${JSON.stringify(command)} is not a command id`);\n continue;\n }\n if (seen.has(command)) problems.push(`${where}: \"${command}\" is in it twice`);\n seen.add(command);\n checkCommand(where, command);\n }\n }\n return problems;\n}\n\nconst isWidthPx = (value: unknown): boolean =>\n typeof value === 'number' && Number.isFinite(value) && value > 0;\n\nfunction presentProblems(where: string, present: unknown): string[] {\n if (typeof present === 'string') {\n return PRESENTATIONS.includes(present)\n ? []\n : [`${where}: present \"${present}\" is not dock, overlay or sheet`];\n }\n if (typeof present !== 'object' || present === null || Array.isArray(present))\n return [`${where}: present ${JSON.stringify(present)} is not a way to open, or one per size`];\n const problems: string[] = [];\n for (const [size, way] of Object.entries(present)) {\n if (!SIZES.includes(size))\n problems.push(`${where}: present has \"${size}\", not a size${didYouMean(size, SIZES)}`);\n else if (way !== undefined && !PRESENTATIONS.includes(way as string))\n problems.push(`${where}: present.${size} \"${way}\" is not dock, overlay or sheet`);\n }\n return problems;\n}\n\nfunction widthProblems(where: string, width: unknown): string[] {\n if (typeof width === 'number')\n return isWidthPx(width) ? [] : [`${where}: width ${width} is not a width in px`];\n if (typeof width !== 'object' || width === null || Array.isArray(width))\n return [\n `${where}: width ${JSON.stringify(width)} is not a width in px, or { initial, min, max }`,\n ];\n const problems: string[] = [];\n const fields = width as Record<string, unknown>;\n for (const [field, value] of Object.entries(fields)) {\n if (!WIDTH_FIELDS.includes(field))\n problems.push(`${where}: width has \"${field}\", not initial, min or max`);\n else if (value !== undefined && !isWidthPx(value))\n problems.push(`${where}: width.${field} ${JSON.stringify(value)} is not a width in px`);\n }\n if (\n isWidthPx(fields.min) &&\n isWidthPx(fields.max) &&\n (fields.min as number) > (fields.max as number)\n )\n problems.push(`${where}: width.min ${fields.min} is wider than width.max ${fields.max}`);\n return problems;\n}\n\nfunction panelProblems(where: string, panel: LayoutPanel): string[] {\n if (typeof panel !== 'object' || panel === null) return [`${where} is not a panel`];\n const problems: string[] = [];\n if (panel.side !== undefined && panel.side !== 'start' && panel.side !== 'end')\n problems.push(`${where}: side \"${panel.side}\" is not start or end`);\n if (panel.present !== undefined) problems.push(...presentProblems(where, panel.present));\n if (panel.width !== undefined) problems.push(...widthProblems(where, panel.width));\n if (panel.resizable !== undefined && typeof panel.resizable !== 'boolean')\n problems.push(`${where}: resizable ${JSON.stringify(panel.resizable)} is not true or false`);\n return problems;\n}\n","/**\n * The fit solver — pure. Given a normalized bar, measured lengths, and the\n * container budget, decide what every unit renders as: a variant, shed into\n * its group's disclosure, part of a collapsed group, or the overflow menu.\n *\n * A length is a size along the bar: a width in a horizontal bar, a height in\n * a vertical one. The solver never knows which; the adapter measures the axis\n * its bar runs along.\n *\n * Deterministic degradation policy, applied while over budget:\n * 1. among all available steps, take the one owned by the lowest-importance\n * unit/group; ties prefer variant < shed < group-collapse < overflow;\n * remaining ties degrade the one nearest the bar's end first.\n * 2. a unit's variant steps run out before it may shed or overflow.\n * 3. a `shed` group moves children (at the child's importance) into a\n * group-local disclosure, but never below one visible child — the floor.\n * 4. a group with `collapse` collapses only after every child sits on its\n * last variant and shedding (if enabled) has hit its floor; once\n * collapsed it degrades further as one unit (the whole group overflows\n * together — a select can't half-overflow). A shed group without\n * `collapse` overflows whole at the floor instead.\n * 5. pinned (importance 5) units/groups may degrade variants but never\n * shed, collapse away, or overflow. Everything else can always reach the\n * overflow menu, so any bar fits any length whose pinned floor fits.\n *\n * So the full group ladder mirrors the item ladder:\n * items: richest variant → … → smallest variant → (shed |) overflow\n * groups: all children → shed to floor → collapsed control → overflow\n *\n * The overflow trigger occupies space only when something overflowed: solve\n * once without it; if anything overflowed, solve again with the trigger's\n * length reserved (a smaller budget can only overflow more, so two passes\n * reach the fixpoint). A group's disclosure trigger is budgeted the same way,\n * inside `measure`, whenever that group has shed children.\n *\n * Missing measurements count as length 0 and are reported via `complete:\n * false` — callers render the first frame from an incomplete solve and\n * re-solve when the ResizeObserver delivers real numbers.\n */\nimport type { NormalizedBar, NormalizedGroup, NormalizedUnit } from './schema';\nimport { PINNED } from './schema';\n\nexport interface FitMetrics {\n /** Length of unit `key` rendered at `variant`; undefined = not yet measured. */\n unit(key: string, variant: string): number | undefined;\n /** Length of group `id` rendered in its collapsed form ('menu' | 'select'). */\n groupCollapsed(groupId: string): number | undefined;\n /** Length of group `id`'s disclosure trigger (shed groups only). */\n groupTrigger(groupId: string): number | undefined;\n /** Length of the overflow trigger button. */\n readonly overflowTrigger: number;\n /** Gap between adjacent visible units. */\n readonly gap: number;\n /** Length of a derived separator between adjacent visible groups (with its gaps). */\n readonly separator: number;\n}\n\nexport type UnitAssignment =\n | { readonly kind: 'variant'; readonly variant: string }\n | { readonly kind: 'shed' } // hidden behind its group's disclosure trigger\n | { readonly kind: 'collapsed' } // hidden behind its group's collapsed control\n | { readonly kind: 'overflow' };\n\nexport interface GroupAssignment {\n /** How many children sit behind the group's disclosure trigger. */\n readonly shedCount: number;\n /** The group renders as its single collapsed control. */\n readonly collapsed: boolean;\n /** No part of the group is visible in the bar. */\n readonly overflowed: boolean;\n}\n\nexport interface FitResult {\n readonly units: ReadonlyMap<string, UnitAssignment>;\n readonly groups: ReadonlyMap<string, GroupAssignment>;\n readonly hasOverflow: boolean;\n /** Total visible length at this assignment (diagnostics + tests). */\n readonly length: number;\n /** False when any consulted measurement was missing (treated as 0). */\n readonly complete: boolean;\n}\n\n// ── internal mutable solve state ──────────────────────────────────────────────\n\ninterface UnitState {\n unit: NormalizedUnit;\n group: GroupState;\n /** Index into unit.variants (0 = richest). */\n variantIndex: number;\n shed: boolean;\n overflowed: boolean;\n /** Position in bar order — end-first tie-breaking. */\n position: number;\n}\n\ninterface GroupState {\n group: NormalizedGroup;\n section: 'start' | 'center' | 'end';\n collapsed: boolean;\n overflowed: boolean;\n units: UnitState[];\n}\n\ntype Step =\n | { type: 'variant'; importance: number; position: number; unit: UnitState }\n | { type: 'shed'; importance: number; position: number; unit: UnitState }\n | { type: 'collapse'; importance: number; position: number; group: GroupState }\n | { type: 'overflow-unit'; importance: number; position: number; unit: UnitState }\n | { type: 'overflow-group'; importance: number; position: number; group: GroupState };\n\n/** variant < shed < collapse < overflow when importance ties. */\nconst STEP_RANK: Record<Step['type'], number> = {\n variant: 0,\n shed: 1,\n collapse: 2,\n 'overflow-unit': 3,\n 'overflow-group': 3,\n};\n\nfunction buildState(bar: NormalizedBar): GroupState[] {\n const groups: GroupState[] = [];\n let position = 0;\n for (const section of bar.sections) {\n for (const group of section.groups) {\n const gs: GroupState = {\n group: group,\n section: section.name,\n collapsed: false,\n overflowed: false,\n units: [],\n };\n for (const unit of group.units) {\n gs.units.push({\n unit: unit,\n group: gs,\n variantIndex: 0,\n shed: false,\n overflowed: false,\n position,\n });\n position += 1;\n }\n groups.push(gs);\n }\n }\n return groups;\n}\n\nfunction nextStep(groups: GroupState[]): Step | null {\n let best: Step | null = null;\n const consider = (step: Step) => {\n if (\n !best ||\n step.importance < best.importance ||\n (step.importance === best.importance &&\n (STEP_RANK[step.type] < STEP_RANK[best.type] ||\n (STEP_RANK[step.type] === STEP_RANK[best.type] && step.position > best.position)))\n ) {\n best = step;\n }\n };\n\n for (const gs of groups) {\n if (gs.overflowed) continue;\n const groupPosition = gs.units.length ? gs.units[gs.units.length - 1].position : 0;\n\n if (gs.collapsed) {\n // A collapsed group degrades as one unit: overflow it whole.\n if (gs.group.importance < PINNED)\n consider({\n type: 'overflow-group',\n importance: gs.group.importance,\n position: groupPosition,\n group: gs,\n });\n continue;\n }\n\n let childrenExhausted = true;\n const visibleCount = gs.units.filter((unit) => !unit.overflowed && !unit.shed).length;\n for (const us of gs.units) {\n if (us.overflowed || us.shed) continue;\n if (us.variantIndex < us.unit.variants.length - 1) {\n childrenExhausted = false;\n consider({\n type: 'variant',\n importance: us.unit.importance,\n position: us.position,\n unit: us,\n });\n } else if (us.unit.importance < PINNED) {\n if (gs.group.shed && visibleCount > 1) {\n // Stage 1: move the child behind the group's disclosure trigger —\n // never below one visible child (the floor).\n consider({\n type: 'shed',\n importance: us.unit.importance,\n position: us.position,\n unit: us,\n });\n } else if (!gs.group.shed && !gs.group.collapse) {\n // Plain group: children go to the global overflow individually.\n consider({\n type: 'overflow-unit',\n importance: us.unit.importance,\n position: us.position,\n unit: us,\n });\n }\n }\n }\n\n // Stage 2 (terminal for the expanded form): available only once variants\n // are exhausted and shedding — if enabled — sits at its floor.\n const shedExhausted = !gs.group.shed || visibleCount <= 1;\n if (childrenExhausted && shedExhausted && gs.group.importance < PINNED) {\n if (gs.group.collapse) {\n consider({\n type: 'collapse',\n importance: gs.group.importance,\n position: groupPosition,\n group: gs,\n });\n } else if (gs.group.shed) {\n // Shed group without a collapsed form: at the floor the whole group\n // (visible + shed children) moves to the global overflow together.\n consider({\n type: 'overflow-group',\n importance: gs.group.importance,\n position: groupPosition,\n group: gs,\n });\n }\n }\n }\n return best;\n}\n\nfunction applyStep(step: Step): void {\n switch (step.type) {\n case 'variant':\n step.unit.variantIndex += 1;\n return;\n case 'shed':\n step.unit.shed = true;\n return;\n case 'collapse':\n step.group.collapsed = true;\n return;\n case 'overflow-unit': {\n step.unit.overflowed = true;\n if (step.unit.group.units.every((unit) => unit.overflowed)) step.unit.group.overflowed = true;\n return;\n }\n case 'overflow-group': {\n step.group.overflowed = true;\n for (const unit of step.group.units) unit.overflowed = true;\n return;\n }\n }\n}\n\ninterface Measured {\n length: number;\n complete: boolean;\n}\n\n/**\n * Visible length of the current assignment: unit lengths + gaps + derived\n * separators. Gaps are counted between all adjacent visible units, including\n * across section boundaries — deliberately conservative: the adapter's layout\n * spaces sections with collapsing auto margins, so the cross-section gap\n * allowance (≤ 2×gap) is slack those margins absorb, never an overlap risk.\n */\nfunction measure(groups: GroupState[], metrics: FitMetrics, hasTrigger: boolean): Measured {\n let length = 0;\n let complete = true;\n let visibleUnits = 0;\n\n // Separators derive between adjacent visible groups within a section.\n const visibleBySection = new Map<string, number>();\n\n for (const gs of groups) {\n if (gs.overflowed) continue;\n if (gs.collapsed) {\n const collapsedLength = metrics.groupCollapsed(gs.group.id);\n if (collapsedLength === undefined) complete = false;\n length += collapsedLength ?? 0;\n visibleUnits += 1;\n visibleBySection.set(gs.section, (visibleBySection.get(gs.section) ?? 0) + 1);\n continue;\n }\n let groupVisible = false;\n let shedCount = 0;\n for (const us of gs.units) {\n if (us.overflowed) continue;\n if (us.shed) {\n shedCount += 1;\n continue;\n }\n const unitLength = metrics.unit(us.unit.key, us.unit.variants[us.variantIndex]);\n if (unitLength === undefined) complete = false;\n length += unitLength ?? 0;\n visibleUnits += 1;\n groupVisible = true;\n }\n if (shedCount > 0) {\n // The group's disclosure trigger takes real space, like any unit.\n const triggerLength = metrics.groupTrigger(gs.group.id);\n if (triggerLength === undefined) complete = false;\n length += triggerLength ?? 0;\n visibleUnits += 1;\n groupVisible = true;\n }\n if (groupVisible) visibleBySection.set(gs.section, (visibleBySection.get(gs.section) ?? 0) + 1);\n }\n\n if (hasTrigger) {\n length += metrics.overflowTrigger;\n visibleUnits += 1;\n }\n if (visibleUnits > 1) length += metrics.gap * (visibleUnits - 1);\n for (const count of visibleBySection.values())\n if (count > 1) length += metrics.separator * (count - 1);\n\n return { length, complete };\n}\n\nfunction anyOverflow(groups: GroupState[]): boolean {\n return groups.some((gs) => gs.units.some((unit) => unit.overflowed));\n}\n\nfunction solvePass(\n bar: NormalizedBar,\n metrics: FitMetrics,\n budget: number,\n hasTrigger: boolean,\n): { groups: GroupState[]; measured: Measured } {\n const groups = buildState(bar);\n let measured = measure(groups, metrics, hasTrigger);\n while (measured.length > budget) {\n const step = nextStep(groups);\n if (!step) break; // pinned floor — nothing left to shed\n applyStep(step);\n measured = measure(groups, metrics, hasTrigger);\n }\n return { groups, measured };\n}\n\n/** Fit `bar` into `containerLength`, the room along its axis. */\nexport function solve(bar: NormalizedBar, metrics: FitMetrics, containerLength: number): FitResult {\n // Pass 1: assume no trigger. If nothing overflows, done.\n let pass = solvePass(bar, metrics, containerLength, false);\n if (anyOverflow(pass.groups)) {\n // Pass 2: same budget, trigger now takes real space in `measure`. The step\n // sequence is budget-independent, so pass 2 degrades strictly further than\n // pass 1 — overflow can't disappear, and the trigger stays justified.\n pass = solvePass(bar, metrics, containerLength, true);\n }\n\n const units = new Map<string, UnitAssignment>();\n const groupAssignments = new Map<string, GroupAssignment>();\n for (const gs of pass.groups) {\n // Overflow ≻ collapsed ≻ shed: a group that shed a few children and then\n // collapsed (or overflowed) subsumes them into the later, stronger state.\n const shedCount = gs.units.filter(\n (unit) => unit.shed && !unit.overflowed && !gs.collapsed,\n ).length;\n groupAssignments.set(gs.group.id, {\n shedCount,\n collapsed: gs.collapsed,\n overflowed: gs.overflowed,\n });\n for (const us of gs.units) {\n units.set(\n us.unit.key,\n us.overflowed\n ? { kind: 'overflow' }\n : gs.collapsed\n ? { kind: 'collapsed' }\n : us.shed\n ? { kind: 'shed' }\n : { kind: 'variant', variant: us.unit.variants[us.variantIndex] },\n );\n }\n }\n return {\n units,\n groups: groupAssignments,\n hasOverflow: anyOverflow(pass.groups),\n length: pass.measured.length,\n complete: pass.measured.complete,\n };\n}\n","/**\n * Overflow projection — pure. The overflow menu is never authored: it is the\n * complement of the visible set, projected into menu form. The projection is\n * total because every unit has a canonical menu form by construction:\n *\n * command → command row (label/icon/active resolve live)\n * command with a `menu` target → submenu row pointing at that menu\n * custom item → its `terminal` command's form\n * group → section (renderers separate sections)\n * group with `labelKey` → labeled section (title or nested submenu —\n * presentation is the renderer's choice)\n * `role: 'tabs'` group → section marked radio\n *\n * Groups project in bar order; a partially-overflowed group projects only its\n * overflowed units; empty sections vanish. Overflow and action menus are\n * projected here rather than hand-written — same information, one source.\n */\nimport type { NormalizedBar, NormalizedGroup, NormalizedUnit } from './schema';\nimport { commandOfUnit, filterBar } from './schema';\nimport type { FitResult } from './solver';\n\nexport type OverflowRow =\n /** A plain command row. The renderer resolves label/icon/active from the registry. */\n | { readonly type: 'command'; readonly command: string }\n /** A command that opens a menu — renders as `label ▸` nesting that menu. */\n | { readonly type: 'submenu'; readonly command: string; readonly menu: string };\n\nexport interface OverflowSection {\n /** From the group's labelKey — render as a section title or a nested submenu. */\n readonly labelKey?: string;\n /** 'radio' when the group is a tab strip: exactly one row is active. */\n readonly role?: 'radio';\n readonly rows: readonly OverflowRow[];\n}\n\n/**\n * The one fact projection needs about a command: does it open a menu?\n * (Label, icon, and active state stay live in the renderer.) Return null for\n * unknown commands — they project as plain rows and resolve at render time.\n */\nexport type ResolveMenuTarget = (commandId: string) => { menu?: string } | null;\n\n/** A unit's menu form; a custom item's is its terminal command's. A standalone item has none. */\nfunction projectUnit(unit: NormalizedUnit, resolve: ResolveMenuTarget): OverflowRow[] {\n const command = commandOfUnit(unit);\n if (command === null) return [];\n const menu = resolve(command)?.menu;\n return [menu ? { type: 'submenu', command, menu } : { type: 'command', command }];\n}\n\nexport function projectOverflow(\n bar: NormalizedBar,\n fit: FitResult,\n resolve: ResolveMenuTarget,\n): OverflowSection[] {\n const sections: OverflowSection[] = [];\n for (const section of bar.sections) {\n for (const group of section.groups) {\n // Shed units are not here: they're reachable through the group's own\n // disclosure trigger (projectShed). Only true overflow leaves the group.\n const rows = group.units\n .filter((unit) => fit.units.get(unit.key)?.kind === 'overflow')\n .flatMap((unit) => projectUnit(unit, resolve));\n if (rows.length === 0) continue;\n sections.push({\n labelKey: group.labelKey,\n role: group.role === 'tabs' ? 'radio' : undefined,\n rows,\n });\n }\n }\n return sections;\n}\n\n/**\n * The content of a group's disclosure trigger: its shed units, in bar order,\n * in menu form — same totality rules as the global overflow.\n */\nexport function projectShed(\n group: NormalizedGroup,\n fit: FitResult,\n resolve: ResolveMenuTarget,\n): OverflowRow[] {\n return group.units\n .filter((unit) => fit.units.get(unit.key)?.kind === 'shed')\n .flatMap((unit) => projectUnit(unit, resolve));\n}\n\n/** One strip group: a separator boundary, its visible commands in bar order. */\nexport interface StripGroup {\n readonly id: string;\n readonly labelKey?: string;\n readonly commands: readonly string[];\n}\n\n/**\n * Strip projection — a bar projected for un-measured rendering (a contextual\n * strip anchored to a selection has no fit pressure to solve). The schema\n * declares what could appear; `visible` (the command registry's runtime truth)\n * decides what does: hidden commands drop out, groups that empty out vanish,\n * and an all-hidden bar projects to [] — \"render nothing\" falls out, as it\n * does for a bar with only dependent groups left ({@link filterBar}). Custom\n * units project through their `terminal` command, same totality rule as the\n * overflow. Upgrading a strip to measured/overflowing rendering later is a\n * renderer swap (<Toolbar>), never a schema change.\n */\nexport function projectStrip(\n bar: NormalizedBar,\n visible: (command: string) => boolean,\n): StripGroup[] {\n const shown = filterBar(bar, (unit) => {\n const command = commandOfUnit(unit);\n return command !== null && visible(command);\n });\n const groups: StripGroup[] = [];\n for (const section of shown.sections) {\n for (const group of section.groups) {\n const commands = group.units\n .map(commandOfUnit)\n .filter((command): command is string => command !== null);\n if (commands.length === 0) continue;\n groups.push({ id: group.id, labelKey: group.labelKey, commands });\n }\n }\n return groups;\n}\n","/**\n * What a toolbar draws, as data, the same for every framework adapter. The fit\n * decides (`filterBar`, `solve`, `projectOverflow`); `layoutToolbar` turns a\n * fit into the parts an adapter draws, in the live row and in the hidden\n * measurement layer, each with its command already resolved and its run\n * bound. `groupMenuView` is the menu a folded group or a group's trigger\n * opens, and `stripGroupsOf` is a bar resolved for a strip that doesn't fit\n * itself. A bar runs either way: the fit counts lengths along its axis, and a\n * vertical bar draws its commands as icons.\n *\n * The command is whatever the app's registry resolves (plugin-commands'\n * `ResolvedCommand`): this package reads only its `id` and `visible`, and\n * hands it back untouched. Adapters call these again on every change and only\n * draw.\n */\nimport type { NormalizedBar, NormalizedGroup, NormalizedUnit } from './schema';\nimport { commandOfUnit, filterBar } from './schema';\nimport type { FitMetrics, FitResult } from './solver';\nimport { solve } from './solver';\nimport type { OverflowSection, ResolveMenuTarget } from './projection';\nimport { projectOverflow, projectStrip } from './projection';\n\n/** What the layout reads of a resolved command; plugin-commands' `ResolvedCommand` satisfies it. */\nexport interface ToolbarCommand {\n readonly id: string;\n readonly visible: boolean;\n}\n\n// ── the views a drawn part receives ──────────────────────────────────────────\n\n/** A group folded into one control: a menu button, or a `<select>`. */\nexport interface CollapsedGroupView<Command extends ToolbarCommand = ToolbarCommand> {\n readonly id: string;\n readonly labelKey?: string;\n readonly collapse: 'menu' | 'select';\n readonly role: 'buttons' | 'tabs';\n /** The group's visible commands (a custom item through its terminal command), resolved live. */\n readonly commands: readonly Command[];\n execute(id: string): void;\n}\n\n/**\n * The button inside a group that shed some of its items. `commands` is what\n * sits behind it, in bar order, resolved live. In the measurement layer it is\n * measured with the whole group behind it, so a trigger that shows a count\n * (\"+3\") is budgeted at its widest.\n */\nexport interface GroupDisclosureView<Command extends ToolbarCommand = ToolbarCommand> {\n readonly id: string;\n readonly labelKey?: string;\n readonly role: 'buttons' | 'tabs';\n readonly commands: readonly Command[];\n execute(id: string): void;\n}\n\n/** The \"More\" menu: what didn't fit, in sections, and the calls a menu needs. */\nexport interface OverflowMenuView<Command extends ToolbarCommand = ToolbarCommand> {\n readonly sections: readonly OverflowSection[];\n readonly isOpen: boolean;\n close(): void;\n /** A row's command, resolved live, or `null` for an unknown id. */\n resolve(id: string): Command | null;\n execute(id: string): void;\n}\n\n/** What a custom item's renderer receives besides the item's variant. */\nexport interface CustomSlotCtx {\n /** `'live'` in the visible row, `'measure'` in the hidden measurement layer. */\n layer: 'live' | 'measure';\n /**\n * Report the item's length yourself (its width, or its height in a vertical\n * bar), for content the measurement layer can't hold.\n */\n measure: (length: number) => void;\n}\n\n// ── the parts ────────────────────────────────────────────────────────────────\n\n/**\n * One thing in the toolbar. `key` is its identity in the live row, the same\n * at every variant; `measureKey` is the key its length is reported under,\n * unique across the whole toolbar. A `custom` part is the app's to draw;\n * without a renderer for it, an adapter draws a native `<slot>` socket\n * measured where it renders, and leaves it out of the measurement layer: only\n * the first `<slot>` of a name gets the projected children.\n */\nexport type ToolbarPart<Command extends ToolbarCommand = ToolbarCommand> =\n | {\n readonly kind: 'command';\n readonly key: string;\n readonly measureKey: string;\n readonly command: Command;\n readonly variant: string;\n readonly run: () => void;\n }\n | {\n readonly kind: 'custom';\n readonly key: string;\n readonly measureKey: string;\n /** The item's name, from `custom(name, terminal)`. */\n readonly name: string;\n readonly variant: string;\n /** The command it becomes in the \"More\" menu; drawn when no renderer draws the item. */\n readonly terminal: Command | null;\n readonly runTerminal: () => void;\n }\n | {\n readonly kind: 'collapsed';\n readonly key: string;\n readonly measureKey: string;\n readonly view: CollapsedGroupView<Command>;\n }\n | {\n readonly kind: 'disclosure';\n readonly key: string;\n readonly measureKey: string;\n readonly view: GroupDisclosureView<Command>;\n };\n\n/** A group in the live row: its visible parts. Every group but a section's first has a separator before it. */\nexport interface LiveGroup<Command extends ToolbarCommand = ToolbarCommand> {\n readonly id: string;\n readonly parts: readonly ToolbarPart<Command>[];\n}\n\n/** A section of the live row (`start`, `center` or `end`), with only its visible groups. */\nexport interface LiveSection<Command extends ToolbarCommand = ToolbarCommand> {\n readonly name: 'start' | 'center' | 'end';\n readonly groups: readonly LiveGroup<Command>[];\n}\n\nexport interface ToolbarLayout<Command extends ToolbarCommand = ToolbarCommand> {\n /** Always the three sections, in order. */\n readonly sections: readonly LiveSection<Command>[];\n /**\n * What the measurement layer draws, each reporting its length under its\n * `measureKey`: every unit in every variant, each collapsible group folded,\n * each shed group's trigger with the whole group behind it.\n */\n readonly measured: readonly ToolbarPart<Command>[];\n readonly hasOverflow: boolean;\n /** The \"More\" menu, derived from what didn't fit. */\n readonly overflow: readonly OverflowSection[];\n}\n\n/** The keys a measurement layer reports lengths under; `@embedpdf/web`'s `toolbarMeasureKey` satisfies it. */\nexport interface ToolbarMeasureKeys {\n unit(unitKey: string, variant: string): string;\n group(groupId: string): string;\n groupTrigger(groupId: string): string;\n}\n\n/** What {@link layoutToolbar} reads. */\nexport interface ToolbarLayoutInput<Command extends ToolbarCommand> {\n /** The bar, from `normalizeBar`. */\n readonly bar: NormalizedBar;\n /** A command for the toolbar's document, or `null` for an id no plugin registered. */\n readonly resolve: (id: string) => Command | null;\n /** What an id no plugin registered draws as: a disabled command named by its id. */\n readonly unregistered: (id: string) => Command;\n /** Run a command for the toolbar's document. */\n readonly execute: (id: string) => void;\n /** Which menu a command opens, for the \"More\" menu's submenu rows. */\n readonly menuTarget: ResolveMenuTarget;\n /** The measured lengths, along the toolbar's axis. */\n readonly metrics: FitMetrics;\n /** The keys the measured lengths are reported under. */\n readonly measureKey: ToolbarMeasureKeys;\n /** The length the toolbar fills: its width, or its height when vertical. */\n readonly containerLength: number;\n /**\n * Which way the toolbar runs. A vertical toolbar draws every command at\n * `'icon'`, with no smaller step, and leaves its label to a tooltip. Default\n * `'horizontal'`.\n */\n readonly orientation?: 'horizontal' | 'vertical';\n}\n\nconst SECTIONS = ['start', 'center', 'end'] as const;\n\nconst ICON_ONLY: readonly string[] = ['icon'];\n\n/** The bar as a vertical toolbar draws it: every command an icon; custom items keep their variants. */\nfunction iconsOnly(bar: NormalizedBar): NormalizedBar {\n return {\n ...bar,\n sections: bar.sections.map((section) => ({\n ...section,\n groups: section.groups.map((group) => ({\n ...group,\n units: group.units.map((unit) =>\n unit.kind === 'command' ? { ...unit, variants: ICON_ONLY } : unit,\n ),\n })),\n })),\n };\n}\n\n/** Fit the bar into `containerLength` and describe what to draw. */\nexport function layoutToolbar<Command extends ToolbarCommand>(\n input: ToolbarLayoutInput<Command>,\n): ToolbarLayout<Command> {\n const { resolve, execute, measureKey } = input;\n /** A unit's command, resolved; null for a standalone item or an unregistered command. */\n const resolveUnit = (unit: NormalizedUnit): Command | null => {\n const command = commandOfUnit(unit);\n return command === null ? null : resolve(command);\n };\n // `=== true` and not `!== false`: an unregistered command resolves to null, and a unit the\n // registry can't name must not render or take room.\n const visible = filterBar(input.bar, (unit) => resolveUnit(unit)?.visible === true);\n const bar = input.orientation === 'vertical' ? iconsOnly(visible) : visible;\n const fit = solve(bar, input.metrics, input.containerLength);\n\n const visibleCommands = (units: readonly NormalizedUnit[]): Command[] =>\n units\n .map(resolveUnit)\n .filter((command): command is Command => command !== null && command.visible);\n\n const parts: PartBuilders<Command> = {\n unit: (unit, variant) => {\n if (unit.kind === 'custom') {\n return {\n kind: 'custom',\n key: unit.key,\n measureKey: measureKey.unit(unit.key, variant),\n name: unit.slot,\n variant,\n terminal: resolveUnit(unit),\n runTerminal: () => {\n if (unit.terminal !== null) execute(unit.terminal);\n },\n };\n }\n const command = resolve(unit.command);\n return {\n kind: 'command',\n key: unit.key,\n measureKey: measureKey.unit(unit.key, variant),\n command: command ?? input.unregistered(unit.command),\n variant,\n run: command ? () => execute(unit.command) : () => {},\n };\n },\n collapsed: (group) => ({\n kind: 'collapsed',\n key: group.id,\n measureKey: measureKey.group(group.id),\n view: {\n id: group.id,\n labelKey: group.labelKey,\n collapse: group.collapse ?? 'menu',\n role: group.role,\n commands: visibleCommands(group.units),\n execute,\n },\n }),\n // The shed children for the live trigger; the whole group for the measured one.\n disclosure: (group, allChildren) => ({\n kind: 'disclosure',\n key: `${group.id}::trigger`,\n measureKey: measureKey.groupTrigger(group.id),\n view: {\n id: group.id,\n labelKey: group.labelKey,\n role: group.role,\n commands: visibleCommands(\n group.units.filter((unit) => allChildren || fit.units.get(unit.key)?.kind === 'shed'),\n ),\n execute,\n },\n }),\n };\n\n return {\n sections: SECTIONS.map((name) => liveSection(name, bar, fit, parts)),\n measured: measuredParts(bar, parts),\n hasOverflow: fit.hasOverflow,\n overflow: projectOverflow(bar, fit, input.menuTarget),\n };\n}\n\n/** How one fit builds each kind of part. */\ninterface PartBuilders<Command extends ToolbarCommand> {\n unit(unit: NormalizedUnit, variant: string): ToolbarPart<Command>;\n collapsed(group: NormalizedGroup): ToolbarPart<Command>;\n disclosure(group: NormalizedGroup, allChildren: boolean): ToolbarPart<Command>;\n}\n\nfunction liveSection<Command extends ToolbarCommand>(\n name: LiveSection['name'],\n bar: NormalizedBar,\n fit: FitResult,\n parts: PartBuilders<Command>,\n): LiveSection<Command> {\n const section = bar.sections.find((each) => each.name === name);\n const groups: LiveGroup<Command>[] = [];\n for (const group of section?.groups ?? []) {\n const assignment = fit.groups.get(group.id);\n if (!assignment || assignment.overflowed) continue;\n if (assignment.collapsed) {\n groups.push({ id: group.id, parts: [parts.collapsed(group)] });\n continue;\n }\n const drawn: ToolbarPart<Command>[] = [];\n for (const unit of group.units) {\n const placed = fit.units.get(unit.key);\n if (placed?.kind === 'variant') drawn.push(parts.unit(unit, placed.variant));\n }\n // The group's own button for the items it shed.\n if (assignment.shedCount > 0) drawn.push(parts.disclosure(group, false));\n if (drawn.length > 0) groups.push({ id: group.id, parts: drawn });\n }\n return { name, groups };\n}\n\nfunction measuredParts<Command extends ToolbarCommand>(\n bar: NormalizedBar,\n parts: PartBuilders<Command>,\n): ToolbarPart<Command>[] {\n const measured: ToolbarPart<Command>[] = [];\n for (const section of bar.sections) {\n for (const group of section.groups) {\n for (const unit of group.units) {\n for (const variant of unit.variants) measured.push(parts.unit(unit, variant));\n }\n if (group.collapse) measured.push(parts.collapsed(group));\n if (group.shed) measured.push(parts.disclosure(group, true));\n }\n }\n return measured;\n}\n\n/**\n * The menu a default folded group or group trigger opens: one section of the\n * group's commands, a radio group when the group is tabs.\n */\nexport function groupMenuView<Command extends ToolbarCommand>(\n view: CollapsedGroupView<Command> | GroupDisclosureView<Command>,\n isOpen: boolean,\n close: () => void,\n): OverflowMenuView<Command> {\n return {\n sections: [\n {\n labelKey: view.labelKey,\n role: view.role === 'tabs' ? 'radio' : undefined,\n rows: view.commands.map((command) => ({ type: 'command' as const, command: command.id })),\n },\n ],\n isOpen,\n close,\n resolve: (id) => view.commands.find((command) => command.id === id) ?? null,\n execute: (id) => view.execute(id),\n };\n}\n\n// ── strips ───────────────────────────────────────────────────────────────────\n\n/** A group of a strip: its visible commands, in bar order. Groups are separator boundaries. */\nexport interface StripViewGroup<Command extends ToolbarCommand = ToolbarCommand> {\n readonly id: string;\n readonly labelKey?: string;\n readonly commands: readonly Command[];\n}\n\n/** A strip, resolved: only visible commands, only groups with one. */\nexport interface StripView<Command extends ToolbarCommand = ToolbarCommand> {\n readonly groups: readonly StripViewGroup<Command>[];\n /** Run a command for the strip's document. */\n execute(id: string): void;\n}\n\n/**\n * A bar as a strip shows it now (`projectStrip`), each command resolved: the\n * schema says what could appear, each command's `visible` decides what does.\n * Empty while nothing applies.\n */\nexport function stripGroupsOf<Command extends ToolbarCommand>(\n bar: NormalizedBar,\n resolve: (id: string) => Command | null,\n): StripViewGroup<Command>[] {\n const resolved = new Map<string, Command>();\n const visible = (id: string) => {\n const command = resolve(id);\n if (command) resolved.set(id, command);\n return command?.visible === true;\n };\n return projectStrip(bar, visible).map((group) => ({\n id: group.id,\n labelKey: group.labelKey,\n commands: group.commands.map((id) => resolved.get(id)!),\n }));\n}\n\n/**\n * Whether two resolved strips show the same, group by group and command by\n * command (`sameCommand` is plugin-commands' `resolvedCommandsEqual`): a\n * strip's readers pass it on only when this is false.\n */\nexport function sameStripGroups<Command extends ToolbarCommand>(\n left: readonly StripViewGroup<Command>[],\n right: readonly StripViewGroup<Command>[],\n sameCommand: (left: Command, right: Command) => boolean,\n): boolean {\n return (\n left.length === right.length &&\n left.every(\n (group, i) =>\n group.id === right[i]!.id &&\n group.commands.length === right[i]!.commands.length &&\n group.commands.every((command, j) => sameCommand(command, right[i]!.commands[j]!)),\n )\n );\n}\n","/**\n * Shortcut parsing + matching — pure. No `navigator`: platform is an input\n * (`isMac`), decided by the embedder, same rule as plugin-i18n's locale.\n *\n * Grammar: modifiers and one key joined by '+', e.g. 'Mod+K', 'Ctrl+=',\n * 'Shift+Alt+D', 'Meta+NumpadAdd'. 'Mod' is ⌘ on mac and Ctrl elsewhere.\n * Keys longer than one character (F1, Escape, NumpadAdd, ArrowLeft) match\n * `event.key` or `event.code` case-insensitively, so numpad shortcuts work.\n */\n\nexport interface ParsedShortcut {\n readonly key: string; // lowercase\n readonly mod: boolean; // platform-resolved at match time\n readonly ctrl: boolean;\n readonly meta: boolean;\n readonly alt: boolean;\n readonly shift: boolean;\n}\n\n/** The subset of KeyboardEvent the matcher reads — keeps this module DOM-free. */\nexport interface KeyStroke {\n readonly key: string;\n readonly code?: string;\n readonly ctrlKey: boolean;\n readonly metaKey: boolean;\n readonly altKey: boolean;\n readonly shiftKey: boolean;\n}\n\nconst MODIFIERS = new Set([\n 'mod',\n 'ctrl',\n 'control',\n 'meta',\n 'cmd',\n 'command',\n 'alt',\n 'option',\n 'shift',\n]);\n\nexport function parseShortcut(shortcut: string): ParsedShortcut {\n const tokens = shortcut.split('+').map((token) => token.trim());\n // 'Ctrl+=' splits to ['Ctrl', '', ''] — an empty tail means the key is '+'.\n const keyToken = tokens[tokens.length - 1] === '' ? '+' : tokens[tokens.length - 1];\n const parsed = {\n key: keyToken.toLowerCase(),\n mod: false,\n ctrl: false,\n meta: false,\n alt: false,\n shift: false,\n };\n for (const token of tokens.slice(0, -1)) {\n const modifier = token.toLowerCase();\n if (modifier === '') continue; // artifact of a literal '+' key\n if (!MODIFIERS.has(modifier))\n throw new Error(`[ui-core] unknown modifier \"${token}\" in \"${shortcut}\"`);\n if (modifier === 'mod') parsed.mod = true;\n else if (modifier === 'ctrl' || modifier === 'control') parsed.ctrl = true;\n else if (modifier === 'meta' || modifier === 'cmd' || modifier === 'command')\n parsed.meta = true;\n else if (modifier === 'alt' || modifier === 'option') parsed.alt = true;\n else parsed.shift = true;\n }\n if (parsed.key === '') throw new Error(`[ui-core] empty key in shortcut \"${shortcut}\"`);\n return parsed;\n}\n\nexport function matchShortcut(\n parsed: ParsedShortcut,\n stroke: KeyStroke,\n options: { isMac: boolean },\n): boolean {\n const wantCtrl = parsed.ctrl || (parsed.mod && !options.isMac);\n const wantMeta = parsed.meta || (parsed.mod && options.isMac);\n if (stroke.ctrlKey !== wantCtrl) return false;\n if (stroke.metaKey !== wantMeta) return false;\n if (stroke.altKey !== parsed.alt) return false;\n // Shift changes what `key` is for printable characters ('=' vs '+'), so only\n // enforce declared shift; an undeclared shift is rejected for non-printables,\n // and for letters, where it only changes the case: 'Mod+Z' isn't\n // 'Shift+Mod+Z'.\n if (parsed.shift && !stroke.shiftKey) return false;\n const hasCase = parsed.key !== parsed.key.toUpperCase();\n if (!parsed.shift && stroke.shiftKey && (parsed.key.length > 1 || hasCase)) return false;\n\n const key = stroke.key.toLowerCase();\n if (key === parsed.key) return true;\n // Long names ('numpadadd', 'f1', …) may be codes rather than keys.\n return (\n parsed.key.length > 1 && stroke.code !== undefined && stroke.code.toLowerCase() === parsed.key\n );\n}\n\n/**\n * Whether two shortcuts are pressed with the same keys on this platform: `'Mod+S'` and\n * `'Ctrl+s'` are where `Mod` is Ctrl, and not on a Mac.\n */\nexport function sameShortcut(left: string, right: string, options: { isMac: boolean }): boolean {\n const keysOf = (shortcut: string) => {\n const parsed = parseShortcut(shortcut);\n return [\n parsed.key,\n parsed.ctrl || (parsed.mod && !options.isMac),\n parsed.meta || (parsed.mod && options.isMac),\n parsed.alt,\n parsed.shift,\n ].join(' ');\n };\n return keysOf(left) === keysOf(right);\n}\n\n/**\n * How a key shows, by its lowercase name, where that isn't the name itself:\n * on a Mac, then elsewhere. Matches what each platform's own menus show.\n */\nconst KEY_NAMES: Readonly<Record<string, readonly [mac: string, other: string]>> = {\n arrowleft: ['←', '←'],\n arrowright: ['→', '→'],\n arrowup: ['↑', '↑'],\n arrowdown: ['↓', '↓'],\n backspace: ['⌫', 'Backspace'],\n delete: ['⌦', 'Delete'],\n enter: ['↩', 'Enter'],\n escape: ['Esc', 'Esc'],\n tab: ['⇥', 'Tab'],\n ' ': ['Space', 'Space'],\n space: ['Space', 'Space'],\n pageup: ['Page Up', 'Page Up'],\n pagedown: ['Page Down', 'Page Down'],\n numpadadd: ['Num +', 'Num +'],\n numpadsubtract: ['Num -', 'Num -'],\n};\n\n/** A shortcut as a menu or a tooltip shows it: `'⌘K'` on a Mac, `'Ctrl+K'` elsewhere. */\nexport function formatShortcut(shortcut: string, options: { isMac: boolean }): string {\n const parsed = parseShortcut(shortcut);\n const named = KEY_NAMES[parsed.key];\n const key = named\n ? named[options.isMac ? 0 : 1]\n : parsed.key.length === 1\n ? parsed.key.toUpperCase()\n : capitalize(parsed.key);\n if (options.isMac) {\n const mods = [\n parsed.ctrl ? '⌃' : '',\n parsed.alt ? '⌥' : '',\n parsed.shift ? '⇧' : '',\n parsed.meta || parsed.mod ? '⌘' : '',\n ].join('');\n return `${mods}${key}`;\n }\n const mods = [\n parsed.ctrl || parsed.mod ? 'Ctrl' : '',\n parsed.meta ? 'Meta' : '',\n parsed.alt ? 'Alt' : '',\n parsed.shift ? 'Shift' : '',\n ].filter(Boolean);\n return [...mods, key].join('+');\n}\n\nfunction capitalize(text: string): string {\n return text.charAt(0).toUpperCase() + text.slice(1);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@embedpdf/core-ui",
|
|
3
|
-
"version": "3.0.0-next.
|
|
3
|
+
"version": "3.0.0-next.15",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Pure chrome core: the structure-only schema vocabulary, the toolbar fit solver (measure → solve → overflow), the overflow-to-menu projection, and the shortcut parser/matcher. DOM-free, kernel-free, framework-free.",
|
|
6
6
|
"type": "module",
|