Skip to content

Model custom table styles on the shared diffStyles list#56

Draft
gthb wants to merge 15 commits into
jsfkit:mainfrom
gthb:table-styles-on-dxf-model
Draft

Model custom table styles on the shared diffStyles list#56
gthb wants to merge 15 commits into
jsfkit:mainfrom
gthb:table-styles-on-dxf-model

Conversation

@gthb

@gthb gthb commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

What

Model workbook-defined (custom) table and pivot table styles, with each region's formatting referenced from the shared diffStyles list (#55) by index.

  • Add TableStyleDefinition, TableStyleElement, TableStyleElementType, and Workbook.tableStyles (keyed by style name).
  • Widen TableStyle.name and PivotTableStyle.name to also accept a workbook-defined name, not just the built-in names.
  • TableStyleElement references its formatting via diffStyleId (an index into Workbook.diffStyles), the same way PivotFormat does.

Why

A table or pivot table can declare a custom style defined in the workbook rather than a built-in one. Today the name unions allow only built-in names and there is no model for the definitions, so a custom style can't be represented and is lost on round-trip. This adds the model, and points each region's formatting at the shared diffStyles list so table styles, pivot formats, and future overlay features all draw from one differential-style list instead of inlining their own.

Stacked on #55

Built on the diffStyles foundation in #55. Until #55 merges, this PR's diff includes the foundation changes too; it collapses to just the table-style additions once #55 lands.

This supersedes the inline-style approach in #54 — the review there asked to model the formatting as an index into a shared differential-style list rather than inlining it, which is exactly what this does. The review fixes from #54 are carried over: plain Name | string | null name unions, the table?: 'table' | 'pivot' | 'all' applicability field, and the doc-table for TableStyleElementType.

gthb added 15 commits June 11, 2026 19:48
Add Workbook.tableStyles: custom table/pivot style definitions keyed
by style name, following the namedStyles precedent. Each definition
carries pivot/table applicability flags and a list of per-region
elements with differential Style formatting (the inline-style
approach of PivotFormat.style), so no JSF-level dxf table is needed.

New types:
- TableStyleDefinition: one named custom style
- TableStyleElement: formatting of one table region (+ stripe size)
- TableStyleElementType: the 28 region kinds (ST_TableStyleType)
Widen the name fields to PivotTableStyleName | (string & {}) (and the
table equivalent) so workbook-defined style names are representable.
The (string & {}) intersection keeps editor autocomplete for the
built-in names while admitting any string. The closed unions remain
exported unchanged, still meaning "a built-in style name".

Names that are neither built-in nor defined in Workbook.tableStyles
are documented to render unstyled, matching an omitted name.
Replace the inline `Name | (string & {})` idiom on the table and pivot
table style `name` properties with a named, documented utility type:

    LooseAutocomplete<T extends string> = T | (string & {})

It accepts any string while preserving editor autocomplete for the known
literals in T; the `& {}` on the string arm prevents TypeScript from
collapsing the union to plain `string` (microsoft/TypeScript#29729).

Applied to:
- TableStyle.name?: LooseAutocomplete<TableStyleName> | null
- PivotTableStyle.name?: LooseAutocomplete<PivotTableStyleName> | null

Behaviourally identical to the inline form; this is a clarity rename.
Per review: drop the LooseAutocomplete helper (a code-editor-autocomplete
convenience to be discussed in its own PR, if at all) and widen the style name
fields with plain `string`:

- TableStyle.name?: TableStyleName | string | null

- PivotTableStyle.name?: PivotTableStyleName | string | null

Delete src/types/LooseAutocomplete.ts, its index export, and the now
unused imports.
Per review: replace the `pivot?`/`table?` boolean pair (which allows the
nonsensical "applies to neither" combination) with a single enum:

  table?: 'table' | 'pivot' | 'all'   // @default "all"

... and drop the TableStyleDefinition docstring's OOXML sentence.
Per review: per-member comments in a union type don't render in the generated
docs, so move them into a markdown table in the type's JSDoc (matching the
CellValueType / TextVerticalType pattern).

Add a Kind column indicating whether each region applies to tables, pivot
tables, or both. Also apply the review's reworded "Some regions only occur in
tables…" intro.
Introduce a workbook-level list of differential styles (dxf records) that
formatting-overlay features reference by index, instead of each feature
inlining a full Style. This is the differential-overlay analog of
Workbook.styles: where Cell.s indexes a complete cell style, an overlay's
dxfId indexes a partial override.

The list element type reuses the existing Style type, which is already
all-optional; what differs is interpretation (absent property means
"leave unchanged", not "use the default") and the list it lives in, not
the structure. A separate DiffStyle type would duplicate ~25 identical
properties for no structural gain, mirroring OOXML where <dxf> reuses the
same children as <xf>.

- Workbook.diffStyles?: Style[]  (name provisional)
- PivotFormat: replace inline `style?: Style` with `dxfId?: integer`
  indexing into Workbook.diffStyles.

BREAKING: this changes the shipped 2.5.0 PivotFormat.style (inline Style)
to PivotFormat.dxfId (index). Done intentionally to avoid baking the
inline-Style "legacy" deeper before more features depend on it.
Replace TableStyleElement's inline `style?: Style` with `dxfId?: integer`
indexing into Workbook.diffStyles, so custom table styles share the same
differential-style list as pivot formats (and future dynamic styles)
instead of inlining their own copies.
Rename the differential-style index field from `dxfId` to `diffStyleId`
(PivotFormat.diffStyleId) and update the Workbook.diffStyles docstring and
@see references to match. The old name echoed a file-format attribute
name; `diffStyleId` keeps the model naming consistent with `diffStyles`
and free of format-specific terms.

Also drop the "name is provisional" note from the diffStyles docstring —
the name is now final.
The formats docstring still said each format carries its differential
style inline and that there is no separate style table, and linked the
removed PivotFormat.style. Both are now false: formats reference a shared
differential style by index. Point at PivotFormat.diffStyleId and
Workbook.diffStyles instead.
Match the renamed index field on the shared differential-style model:
TableStyleElement now references Workbook.diffStyles via diffStyleId
(updating its docstring and @see) instead of dxfId.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant