From 1c80e94e5e260e78f1a7a5fe02f8cb731b2768c1 Mon Sep 17 00:00:00 2001 From: Shurong Cao <170531907+CAOShurong@users.noreply.github.com> Date: Thu, 17 Sep 2026 05:52:11 +0800 Subject: [PATCH 1/2] fix(types): support nested attribute path strings in relayout, restyle, and update In plotly.js runtime, Plotly.relayout, Plotly.restyle, and Plotly.update support updating nested properties using dotted attribute paths (e.g. 'xaxis.autorange', 'xaxis.range[0]', 'annotations[0].text') as well as the 2-parameter string invocation form (Plotly.relayout(gd, 'xaxis.autorange', true)). - Update tasks/generate_schema_types.mjs to generate common nested axis and title properties alongside dotted/indexed template literal index signatures on Layout, while preserving strict excess-property checking on top-level layout typos. - Add 2-parameter string attribute path overloads for relayout and restyle in api.d.ts. - Allow Partial | Record in restyle and update trace arguments. - Export LayoutUpdate type alias in layout.d.ts and lib/index.d.ts. - Regenerate src/types/generated/schema.d.ts. Fixes #8047 --- lib/index.d.ts | 1 + src/types/core/api.d.ts | 48 ++++++++++++++++++++++++++++----- src/types/core/layout.d.ts | 13 +++++++++ src/types/generated/schema.d.ts | 21 +++++++++++++++ tasks/generate_schema_types.mjs | 23 ++++++++++++++++ 5 files changed, 99 insertions(+), 7 deletions(-) diff --git a/lib/index.d.ts b/lib/index.d.ts index 583bd7811a3..b542b7aca30 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -59,6 +59,7 @@ export type { ModeBarButton, ModeBarButtonAny, ModeBarDefaultButtons, + LayoutUpdate, Template } from '../src/types/core/layout'; diff --git a/src/types/core/api.d.ts b/src/types/core/api.d.ts index 4f9f73d2ffb..2f153d1ce4f 100644 --- a/src/types/core/api.d.ts +++ b/src/types/core/api.d.ts @@ -208,30 +208,64 @@ export function newPlot( figure: PlotlyDataLayoutConfig ): Promise; -/** Update layout properties on an existing plot. */ +/** + * Update layout properties on an existing plot using an update object. + * + * @param root - Graph div id or element + * @param layout - Partial layout object or attribute path mapping (e.g. `{'xaxis.autorange': true}`) + */ export function relayout(root: Root, layout: Partial): Promise; +/** + * Update a single layout property on an existing plot using an attribute path string. + * + * @param root - Graph div id or element + * @param astr - Attribute path string (e.g. `'xaxis.autorange'`, `'title.text'`) + * @param val - Value to assign to the attribute + */ +export function relayout(root: Root, astr: string, val: any): Promise; + /** Re-render the plot at `root` from its current data/layout. */ export function redraw(root: Root): Promise; /** Remove a plot and its event listeners from the DOM. */ export function purge(root: Root): void; /** - * Update trace properties (style) on the existing plot. + * Update trace properties (style) on the existing plot using an update object. + * + * @param root - Graph div id or element + * @param aobj - Update object with trace properties or attribute paths + * @param traces - Trace index/indices to update (defaults to all) + */ +export function restyle( + root: Root, + aobj: Partial | Record, + traces?: number[] | number +): Promise; +/** + * Update a single trace property on an existing plot using an attribute path string. * - * @param aobj - Update object whose keys are attribute paths + * @param root - Graph div id or element + * @param astr - Attribute path string (e.g. `'marker.color'`) + * @param val - Value or array of values to assign to the attribute * @param traces - Trace index/indices to update (defaults to all) */ -export function restyle(root: Root, aobj: Data, traces?: number[] | number): Promise; +export function restyle( + root: Root, + astr: string, + val: any, + traces?: number[] | number +): Promise; /** * Update both trace and layout properties in a single call. * - * @param traceUpdate - Per-trace updates - * @param layoutUpdate - Layout updates + * @param root - Graph div id or element + * @param traceUpdate - Per-trace updates or attribute paths + * @param layoutUpdate - Layout updates or attribute paths * @param traces - Trace index/indices `traceUpdate` applies to */ export function update( root: Root, - traceUpdate: Data, + traceUpdate: Partial | Record, layoutUpdate: Partial, traces?: number[] | number ): Promise; diff --git a/src/types/core/layout.d.ts b/src/types/core/layout.d.ts index 4ede682efae..b32efbd5093 100644 --- a/src/types/core/layout.d.ts +++ b/src/types/core/layout.d.ts @@ -157,3 +157,16 @@ export interface Template { /** Template layout defaults. */ layout?: Partial | undefined; } + +// --------------------------------------------------------------------------- +// Relayout & update types +// --------------------------------------------------------------------------- + +/** + * Layout update object accepted by `Plotly.relayout` and `Plotly.update`. + * + * An alias for `Partial`, which supports both standard nested layout + * properties and dotted/indexed attribute paths (e.g. `'xaxis.autorange'`). + */ +export type LayoutUpdate = Partial; + diff --git a/src/types/generated/schema.d.ts b/src/types/generated/schema.d.ts index fda9a6817e9..35a2bb6e944 100644 --- a/src/types/generated/schema.d.ts +++ b/src/types/generated/schema.d.ts @@ -16606,6 +16606,27 @@ export interface Layout { [key: `ternary${number}`]: TernaryLayout; [key: `xaxis${number}`]: LayoutAxis; [key: `yaxis${number}`]: LayoutAxis; + + // Nested property updates for relayout and update + 'xaxis.autorange'?: LayoutAxis['autorange']; + 'yaxis.autorange'?: LayoutAxis['autorange']; + 'xaxis.range'?: LayoutAxis['range']; + 'xaxis.range[0]'?: any; + 'xaxis.range[1]'?: any; + 'yaxis.range'?: LayoutAxis['range']; + 'yaxis.range[0]'?: any; + 'yaxis.range[1]'?: any; + 'xaxis.type'?: LayoutAxis['type']; + 'yaxis.type'?: LayoutAxis['type']; + 'xaxis.title'?: string | LayoutAxis['title']; + 'yaxis.title'?: string | LayoutAxis['title']; + 'xaxis.title.text'?: string; + 'yaxis.title.text'?: string; + 'title.text'?: string; + + // Dotted and indexed attribute path index signatures + [key: `${string}.${string}`]: any; + [key: `${string}[${string}`]: any; } // --------------------------------------------------------------------------- diff --git a/tasks/generate_schema_types.mjs b/tasks/generate_schema_types.mjs index 01c9ed5961d..d250eae089d 100644 --- a/tasks/generate_schema_types.mjs +++ b/tasks/generate_schema_types.mjs @@ -1112,6 +1112,29 @@ function generateLayoutProperties(layoutAttrs, sharedTypes, subplotGroups, array } } + // Nested property updates for relayout and update (common axis/title properties) + lines.push(''); + lines.push(' // Nested property updates for relayout and update'); + lines.push(" 'xaxis.autorange'?: LayoutAxis['autorange'];"); + lines.push(" 'yaxis.autorange'?: LayoutAxis['autorange'];"); + lines.push(" 'xaxis.range'?: LayoutAxis['range'];"); + lines.push(" 'xaxis.range[0]'?: any;"); + lines.push(" 'xaxis.range[1]'?: any;"); + lines.push(" 'yaxis.range'?: LayoutAxis['range'];"); + lines.push(" 'yaxis.range[0]'?: any;"); + lines.push(" 'yaxis.range[1]'?: any;"); + lines.push(" 'xaxis.type'?: LayoutAxis['type'];"); + lines.push(" 'yaxis.type'?: LayoutAxis['type'];"); + lines.push(" 'xaxis.title'?: string | LayoutAxis['title'];"); + lines.push(" 'yaxis.title'?: string | LayoutAxis['title'];"); + lines.push(" 'xaxis.title.text'?: string;"); + lines.push(" 'yaxis.title.text'?: string;"); + lines.push(" 'title.text'?: string;"); + lines.push(''); + lines.push(' // Dotted and indexed attribute path index signatures'); + lines.push(' [key: `${string}.${string}`]: any;'); + lines.push(' [key: `${string}[${string}`]: any;'); + return lines; } From af5ee4900637948ad22ba56c21182a55d70eb07b Mon Sep 17 00:00:00 2001 From: Shurong Cao <170531907+CAOShurong@users.noreply.github.com> Date: Thu, 17 Sep 2026 05:52:37 +0800 Subject: [PATCH 2/2] docs(draftlog): add draftlog for PR #8050 --- draftlogs/8050_fix.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 draftlogs/8050_fix.md diff --git a/draftlogs/8050_fix.md b/draftlogs/8050_fix.md new file mode 100644 index 00000000000..31581756fb1 --- /dev/null +++ b/draftlogs/8050_fix.md @@ -0,0 +1 @@ +- Support nested attribute path strings in `relayout`, `restyle`, and `update` TypeScript definitions [[#8050](https://github.com/plotly/plotly.js/pull/8050)], with thanks to @CAOShurong for the contribution! \ No newline at end of file