/** * Workbook styles table handle (M1.2). * * Parse/serialize `xl/styles.xml`, baseline on first dirty write, preserve * collection order and indexes. Public cell authoring is * {@link Cell.style} / {@link Cell.numberFormat}; conditional-formatting * differentials use `ConditionalFormat.format`. The `add*` / `ensure*` * factories, table getters, counters, and part-state properties are * `@private` (stripped from the shipped `.d.ts`). * * Citations: `docs/specs/styles-table.md`, ECMA-376-1 §12.3.20 / §18.8. */ import { Alignment, Border, CellBorder, CellStyle, CellFormat, Color, DifferentialFormatInput, DifferentialFormatView, DxfEntry, FillEntry, Fill, FontEntry, Font, NumFmtEntry, Protection, StylesXmlModel } from './styles-xml'; export { Alignment, Border, CellStyle, CellFormat, DifferentialFormatInput, DifferentialFormatView, FillEntry, Fill, Font, NumFmtEntry, Protection, }; export { BorderEdge, Color, DifferentialNumFmtInput, PatternType, UnderlineValue, FontSchemeValue, HorizontalAlignment, VerticalAlignment, } from './styles-xml'; /** * Manages the styles available in a workbook, letting you look up and reuse * its number formats, fonts, fills, borders, and cell formats. * * @private Advanced styles-table handle. Public cell authoring is * {@link Cell.style} / {@link Cell.numberFormat}; CF uses * `ConditionalFormat.format`. Stripped from the shipped package `.d.ts`. */ export declare class WorkbookStyles { private collections; private unknownChildrenXml; private rootExtraAttrsXml; private _dirty; /** True when a styles part was present on open (even if empty). */ private readonly hadPart; private partName; private readonly maxEntries; private baselineEnsured; /** * Ordered custom/loaded `numFmt` rows. Built-in ids 0–163 are not authored as * rows by the library (may still appear if present on disk — preserved). */ private numFmts; /** Exact `formatCode` → first matching `numFmtId` for ensure reuse. */ private formatCodeIndex; /** Ordered font rows (positional indexes). */ private fonts; /** Exact-match key → first font index. */ private fontKeyIndex; /** Ordered fill rows (positional; 0=none, 1=gray125 reserved when baseline). */ private fills; /** Exact-match key → first fill index. */ private fillKeyIndex; /** Ordered border rows (positional indexes). */ private borders; /** Exact-match key → first border index. */ private borderKeyIndex; /** Ordered cellXfs xf rows (positional indexes → `c@s`). */ private cellXfs; /** Exact-match key → first cellXf index. */ private cellXfKeyIndex; /** Ordered dxf rows (positional indexes → `cfRule/@dxfId`). */ private dxfs; /** * Theme + indexed palette used only to compute {@link Color.rgbColor}. * Never written back. Defaults to the Office scheme until a theme part * is bound. */ private colorContext; /** Exact-match key → first dxf index. */ private dxfKeyIndex; private constructor(); /** * Empty styles (no part on disk yet). * @private */ static empty(options?: { readonly maxEntries?: number; readonly partName?: string; }): WorkbookStyles; /** * Load from part bytes. Missing part should use {@link empty} instead. * @private */ static fromPartBytes(bytes: Uint8Array, partName: string, options?: { readonly maxEntries?: number; }): WorkbookStyles; /** * @private */ static fromModel(model: StylesXmlModel, options: { readonly partName: string | undefined; readonly maxEntries?: number; readonly hadPart: boolean; readonly dirty: boolean; }): WorkbookStyles; /** @private * Zero-based `cellXfs` length (0 when absent). */ readonly cellXfCount: number; /** @private * Whether the styles model should be considered modified. */ readonly isDirty: boolean; /** @private * Whether a styles part existed when the workbook was opened. */ readonly hadStylesPart: boolean; /** @private * Part name when known (loaded or assigned for create). */ readonly stylesPartName: string | undefined; /** @private * True when save should emit the part (had part, or dirty with baseline/content). */ shouldWritePart(): boolean; /** @private * Snapshot of `cellXfs[index]`. Throws {@link InvalidStyleIndexError} when OOB. */ getCellXf(index: number): CellFormat; /** @private * Number of `numFmt` rows currently stored (including any loaded built-in rows). */ readonly numFmtCount: number; /** * Snapshot of a stored `numFmt` row by table order (not by `numFmtId`). * @private test helper */ getNumFmtAt(index: number): NumFmtEntry | undefined; /** * Lookup `formatCode` for a `numFmtId`, with locale prefix tokens stripped. * * Resolution order: * 1. Package / library `numFmts` rows (custom ≥164, or any built-in row that * was present on disk and preserved) — first matching row wins. * 2. ECMA-376-1 §18.8.30 "All Languages" implied built-in table for ids that * are not authored as `numFmt` elements (e.g. id 14 → `m/d/yyyy`). * * Built-in fallback is read-only: it never appends rows to `numFmts` and * never dirties the styles part. Locale-only built-ins not listed in the * language-neutral table remain `undefined` until a package row exists. * * Strips leading OOXML locale tokens (e.g. `[$-409]`) from the returned * format code for client compatibility with formatting libraries. * * Citations: ECMA-376-1 §18.8.30 / §18.8.31; `docs/specs/styles-table.md`. * * @private */ getFormatCode(numFmtId: number): string | undefined; /** @private Number of font rows. */ readonly fontCount: number; /** * Snapshot of `fonts[index]`. * @private test helper */ getFontAt(index: number): FontEntry | undefined; /** @private Number of fill rows. */ readonly fillCount: number; /** * Snapshot of `fills[index]`. * @private test helper */ getFillAt(index: number): FillEntry | undefined; /** @private Number of border rows. */ readonly borderCount: number; /** * @private * Number of differential format (`dxf`) rows. */ readonly dxfCount: number; /** * Snapshot of `dxfs[index]`. * @private test helper */ getDxfAt(index: number): DxfEntry | undefined; /** * @private * Public view of `dxfs[index]` (font / numFmt / fill / border only). * Alignment and protection stay internal on the wire entry when present. * Throws {@link InvalidStyleIndexError} when out of range. */ getDifferentialFormat(index: number): DifferentialFormatView; /** * Snapshot of `borders[index]`. * @private test helper */ getBorderAt(index: number): CellBorder | undefined; /** * Ensure a custom number format row exists for `formatCode`. * * - Empty / whitespace-only codes throw {@link InvalidNumberFormatError}. * - Exact `formatCode` match reuses the existing `numFmtId` (no renumber). * - New codes append with `numFmtId = max(existing, 163) + 1` (≥ 164). * - Does not emit built-in 0–163 rows. * * Citations: ECMA-376-1 §18.8.31; `CT_NumFmt` in transitional sml.xsd. * * @returns Stable custom `numFmtId` (≥ 164 for library-allocated ids). * * @private */ ensureCustomNumberFormat(formatCode: string): number; /** * Ensure a font row exists. Exact-match reuse returns the existing index; * otherwise appends. Never renumbers existing indexes. * * Citations: ECMA-376-1 §18.8.22; `CT_Font` in transitional sml.xsd. * * @returns Zero-based font index. * * @private */ ensureFont(font: Font): number; /** * Ensure a fill row exists. Indexes 0 (`none`) and 1 (`gray125`) are reserved * by baseline and never replaced. Exact-match reuse returns existing index; * otherwise appends (≥ 2 after baseline). Never renumbers. * * Citations: ECMA-376-1 §18.8.21; `CT_Fill` / `CT_PatternFill`. * * @returns Zero-based fill index. * * @private */ ensureFill(fill: Fill): number; /** * Ensure a border row exists. Exact-match reuse returns existing index; * otherwise appends. Library-created edges use Transitional * left/right/top/bottom/diagonal. Never renumbers. * * Citations: ECMA-376-1 §18.8.4; `CT_Border` in transitional sml.xsd. * * @returns Zero-based border index. * * @private */ ensureBorder(border: Border): number; /** * Ensure a `cellXfs` xf row exists. Exact-match reuse returns the existing * index; otherwise appends. Never renumbers existing indexes. * * Nested `font` / `fill` / `border` inputs go through the corresponding * `ensure*` helpers. `apply*` flags are set when the corresponding input is * present. `xfId` defaults to 0. Default component ids are 0 when omitted. * * Citations: ECMA-376-1 §18.8.10 / §18.8.45; `CT_Xf` in transitional sml.xsd. * * @returns Zero-based cellXfs index (for `c@s` / {@link Cell.styleIndex}). * Called by {@link Cell.style} / {@link Cell.numberFormat} authoring. * * @private */ ensureCellXf(style: CellStyle): number; /** * Add or reuse a custom number format code. * * Thin alias of {@link ensureCustomNumberFormat}. Not part of the public API; * cell authors use {@link Cell.numberFormat}. * * @returns Stable custom numFmtId (≥ 164 for library-allocated ids). * @private */ addNumberFormat(formatCode: string): number; /** * Add or reuse a font row. * * Thin alias of {@link ensureFont}. Not part of the public API; cell authors * use {@link Cell.style}. * * @returns Zero-based font index. * @private */ addFont(font: Font): number; /** * Add or reuse a fill row. * * Thin alias of {@link ensureFill}. Not part of the public API; cell authors * use {@link Cell.style}. * * @returns Zero-based fill index. * @private */ addFill(fill: Fill): number; /** * Add or reuse a border row. * * Thin alias of {@link ensureBorder}. Not part of the public API; cell * authors use {@link Cell.style}. * * @returns Zero-based border index. * @private */ addBorder(border: Border): number; /** * Add or reuse a cellXf style row. * * Thin alias of {@link ensureCellXf}. Not part of the public API; cell * authors use {@link Cell.style} / {@link Cell.numberFormat}. * * @returns Zero-based cellXfs index (for c@s). * @private */ addCellStyle(style: CellStyle): number; /** * Ensure a differential format (`dxf`) row exists. Exact-match reuse returns * the existing index; otherwise appends. Never renumbers existing indexes. * * Public authoring children: font / numFmt / fill / border (inline under * `dxf`, not fontId/fillId table refs). Alignment/protection are not * authored here; loaded rows that carry them are preserved on serialize. * Baseline fonts/fills/borders are still seeded when the stylesheet is empty * so the part remains Excel-compatible on first write. * * Citations: ECMA-376-1 §18.8.14 / §18.8.15 / §18.8.30; `CT_Dxf` / `CT_Dxfs`. * * @returns Zero-based dxf index (for `cfRule/@dxfId`). * * @private */ ensureDxf(format: DifferentialFormatInput): number; /** * @private * Add or reuse a differential format row under `dxfs`. * * Used by conditional formatting `format` authoring; public consumers reach * it through `ConditionalFormat.format`, not this method. * * @returns Zero-based dxf index (for `cfRule/@dxfId`). */ addDifferentialFormat(format: DifferentialFormatInput): number; /** * Mark dirty and ensure library baseline tables exist (for first write). * @private */ markDirty(): void; /** * Assign part name used when creating the part on save. * @private */ assignPartName(partName: string): void; /** * Serialize the workbook's styles into the bytes of the styles part * written on save. Any pending changes are applied first, so the bytes * always reflect the current fonts, fills, borders, and number formats. * * @returns the styles-part content, ready to be written to the package. * @private */ toPartBytes(): Uint8Array; /** * Bind theme-part XML used only to resolve {@link Color.rgbColor}. * Does not mark the styles part dirty and does not rewrite the theme. * @private */ bindThemeXml(themeXml: string | undefined): void; /** * Copy a stored color and attach {@link Color.rgbColor} when it can be * resolved. Does not mutate the stored color or the styles part. * @private */ colorWithRgb(color: Color): Color; /** * @private test helper — collection local names in current store order. */ collectionNames(): ReadonlyArray; /** * @private test helper — raw collection XML by name. */ collectionXml(name: string): string | undefined; private cellXfEntryToFormat; private ensureBaseline; private applyStructuredBaselineArrays; private syncAllStructuredCollections; private syncDxfsCollection; /** * Write or remove the `numFmts` collection from `collections` to match * `this.numFmts`. Preserves relative order among other collections via * schema-ordered serialize. */ private syncNumFmtsCollection; private syncFontsCollection; private syncFillsCollection; private syncBordersCollection; private syncCellXfsCollection; private upsertCollection; private rebuildFormatCodeIndex; private rebuildFontKeyIndex; private rebuildFillKeyIndex; private rebuildBorderKeyIndex; private rebuildCellXfKeyIndex; private rebuildDxfKeyIndex; private collectionCount; private collectionItems; }