Description
The generated ModeBar type in src/types/generated/components/modebar.d.ts is less specific than the hand-written ModeBar in @types/plotly.js. The type generator faithfully maps valType: 'string' to string and valType: 'any' to any, but this loses semantic type information for the add, remove, and uirevision properties.
| Property |
Generated type |
Expected type (per DT) |
add |
string | string[] |
ModeBarDefaultButtons | ModeBarDefaultButtons[] |
remove |
string | string[] |
ModeBarDefaultButtons | ModeBarDefaultButtons[] |
uirevision |
any |
number | string |
uid |
missing |
string |
Consumers lose autocomplete for valid modebar button names when using layout.modebar.add or layout.modebar.remove.
Steps to reproduce
- Use
layout.modebar.add in a TypeScript project importing from plotly.js
- Observe that the type accepts any
string instead of suggesting valid button names like 'lasso2d', 'select2d', 'zoom2d', etc.
Notes
Root cause: The add and remove attributes in src/components/modebar/attributes.ts use valType: 'string' with arrayOk: true. The type generation pipeline (ValTypeToTS in src/types/lib/attributes.d.ts) already supports narrowing StringAttr to a literal union when a values array is provided — but the modebar attributes don't provide one. The button names are dynamically computed at runtime in src/components/modebar/constants.js (foreButtons is built by iterating over the button registry), so they can't be passed as a static as const array.
Possible solutions:
-
Override the generated type in layout.d.ts — Import the generated ModeBar and re-export a refined version using Omit + tighter property types. Keeps the generated base while tightening the public API. Low effort, no changes to the generator or attribute system.
-
Inline static values in the attribute definition — Add values: ['lasso2d', 'select2d', ...] as const directly to the add and remove attributes in src/components/modebar/attributes.ts. The existing ValTypeToTS conditional would then produce the union automatically. Downside: duplicates the button list (source of truth is the button registry, not this array).
-
Make foreButtons statically typed — Convert src/components/modebar/constants.js to TypeScript with static as const arrays instead of dynamically computing the list from the button registry. The attributes could then reference the const array as values. Downside: requires restructuring how buttons are registered and breaks the dynamic discovery pattern.
Description
The generated
ModeBartype insrc/types/generated/components/modebar.d.tsis less specific than the hand-writtenModeBarin@types/plotly.js. The type generator faithfully mapsvalType: 'string'tostringandvalType: 'any'toany, but this loses semantic type information for theadd,remove, anduirevisionproperties.addstring | string[]ModeBarDefaultButtons | ModeBarDefaultButtons[]removestring | string[]ModeBarDefaultButtons | ModeBarDefaultButtons[]uirevisionanynumber | stringuidstringConsumers lose autocomplete for valid modebar button names when using
layout.modebar.addorlayout.modebar.remove.Steps to reproduce
layout.modebar.addin a TypeScript project importing from plotly.jsstringinstead of suggesting valid button names like'lasso2d','select2d','zoom2d', etc.Notes
Root cause: The
addandremoveattributes insrc/components/modebar/attributes.tsusevalType: 'string'witharrayOk: true. The type generation pipeline (ValTypeToTSinsrc/types/lib/attributes.d.ts) already supports narrowingStringAttrto a literal union when avaluesarray is provided — but the modebar attributes don't provide one. The button names are dynamically computed at runtime insrc/components/modebar/constants.js(foreButtonsis built by iterating over the button registry), so they can't be passed as a staticas constarray.Possible solutions:
Override the generated type in
layout.d.ts— Import the generatedModeBarand re-export a refined version usingOmit+ tighter property types. Keeps the generated base while tightening the public API. Low effort, no changes to the generator or attribute system.Inline static
valuesin the attribute definition — Addvalues: ['lasso2d', 'select2d', ...] as constdirectly to theaddandremoveattributes insrc/components/modebar/attributes.ts. The existingValTypeToTSconditional would then produce the union automatically. Downside: duplicates the button list (source of truth is the button registry, not this array).Make
foreButtonsstatically typed — Convertsrc/components/modebar/constants.jsto TypeScript with staticas constarrays instead of dynamically computing the list from the button registry. The attributes could then reference the const array asvalues. Downside: requires restructuring how buttons are registered and breaks the dynamic discovery pattern.