Skip to content

fix: update onSave to pass nested tree values and handle save errors#65

Merged
mrabbani merged 4 commits intomainfrom
fix/onsave-signature
Mar 6, 2026
Merged

fix: update onSave to pass nested tree values and handle save errors#65
mrabbani merged 4 commits intomainfrom
fix/onsave-signature

Conversation

@mrabbani
Copy link
Member

@mrabbani mrabbani commented Mar 6, 2026

Summary

  • Tree values: onSave now receives a nested object built from dot-separated keys (e.g. {"dokan": {"general": {"store_name": "..."}}}) as the second argument, with the original flat dot-keyed values as the third
  • Consistent signatures: Aligned onSave type across SettingsContextValue, SettingsProviderProps, and SettingsProps to (scopeId, treeValues, flatValues)
  • Error handling: Wrapped save in try/catch — dirty state only resets on success, and server-side field errors (thrown with { errors: {...} }) are merged into the errors state
  • Bug fix: Added setErrors to useCallback dependency array to prevent stale closure

Test plan

  • Verify onSave receives (scopeId, treeValues, flatValues) with correct shapes
  • Verify dirty state is preserved when onSave throws
  • Verify field errors display when onSave throws { errors: { fieldKey: "message" } }

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Breaking Changes

    • Settings save callback signature changed: handlers now receive both nested (tree) and flat value representations along with the scope ID — update save/onSave handlers accordingly.
  • Documentation

    • Settings documentation and examples updated to show the new save callback shape.
    • Added a new high-level project guide covering architecture, patterns, the Settings system, and development guidance.

- Add dot-key-to-nested-object tree building in handleOnSave
- Pass both treeValues and flatValues to onSave callback
- Align onSave signature across all interfaces (SettingsContextValue,
  SettingsProviderProps, SettingsProps)
- Only reset dirty state on successful save
- Handle server-side validation errors by merging into errors state
- Add setErrors to useCallback deps to prevent stale closure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 6, 2026

📝 Walkthrough

Walkthrough

Settings save behavior was changed: the provider now constructs a nested treeValues from dot-keyed flat values and calls the consumer save/onSave with (scopeId, treeValues, flatValues). The context exposes save (mapped to internal handler); docs, types, examples, and error-merging were updated.

Changes

Cohort / File(s) Summary
Documentation & Examples
DEVELOPER_GUIDE.md, src/DeveloperGuide.mdx, src/components/settings/Settings.mdx
Examples and prose updated to use the new onSave/save signature (scopeId, treeValues, flatValues) and to show treeValues alongside flat payloads in examples and tables.
Context & Provider
src/components/settings/settings-context.tsx
SettingsProvider.handleOnSave now builds treeValues from dot-keyed pageValues, calls onSave(pageId, treeValues, pageValues), resets per-page dirty state on success, and merges error.errors into local errors on failure. onSave type in props updated and context now exposes save.
Component wiring
src/components/settings/settings-content.tsx
References switched from onSave to save; save-area visibility and save invocation now depend on save provided by context.
Type Definitions
src/components/settings/settings-types.ts
SettingsProps.onSave signature changed to (scopeId: string, treeValues: Record<string, any>, flatValues: Record<string, any>) and related docstrings updated.
New docs
CLAUDE.md
Added comprehensive project overview and developer guidance (architecture, settings system, theme, components, WP integration, conventions, CI/dev workflow).

Sequence Diagram(s)

sequenceDiagram
    participant UI as "Settings UI"
    participant Provider as "SettingsProvider"
    participant App as "Consumer onSave / App"
    participant Server as "Server/API"

    UI->>Provider: submit save (flat pageValues)
    Provider->>Provider: build treeValues from dot-keys
    Provider->>App: call onSave(pageId, treeValues, pageValues)
    alt success
        App->>Server: persist payload (treeValues / flatValues)
        Server-->>App: success
        App-->>Provider: resolve
        Provider->>UI: clear dirty state
    else error
        App-->>Provider: throws with error.errors
        Provider->>Provider: merge field-level errors into errors state
        Provider->>UI: surface field errors
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~35 minutes

Possibly related PRs

  • Feat/settings components #52 — Prior PR touching Settings onSave API, SettingsContextValue/SettingsProvider wiring; closely related API/signature changes.

Poem

🐰 I hopped through dotted keys and leaves,

Turned flat lines into branching trees,
Two forms now travel, hand in paw,
Saved together — neat and law! 🌿

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: updating onSave to pass nested tree values and implementing error handling for save operations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/onsave-signature

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Update examples and API reference tables to reflect the new
onSave(scopeId, treeValues, flatValues) signature.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/DeveloperGuide.mdx (1)

915-917: Example shows only two onSave parameters but API accepts three.

The example destructures only (scopeId, treeValues), but the actual signature is (scopeId, treeValues, flatValues). While this works since flatValues is optional to use, consider showing the full signature for completeness:

-      onSave={async (scopeId, treeValues) => {
-        await apiFetch({ path: `/my-plugin/v1/settings/${scopeId}`, method: 'POST', data: treeValues });
+      onSave={async (scopeId, treeValues, flatValues) => {
+        // treeValues: nested object, flatValues: original dot-keyed values
+        await apiFetch({ path: `/my-plugin/v1/settings/${scopeId}`, method: 'POST', data: treeValues });
       }}

This aligns with the documented API in Settings.mdx lines 80-84 which shows all three parameters.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/DeveloperGuide.mdx` around lines 915 - 917, Update the onSave handler
example to match the real API signature by including the third parameter: change
the parameter list from (scopeId, treeValues) to (scopeId, treeValues,
flatValues) in the onSave callback so it reflects the actual signature used by
Settings (refer to the onSave handler and Settings API docs), and adjust any
example usage inside the handler to accept but not necessarily use flatValues.
DEVELOPER_GUIDE.md (1)

1131-1136: Example shows only two onSave parameters for consistency with Storybook guide.

Similar to src/DeveloperGuide.mdx, this example omits flatValues. While functionally correct, consider aligning with the full signature documented in Settings.mdx for API completeness:

-      onSave={async (scopeId, treeValues) => {
+      onSave={async (scopeId, treeValues, _flatValues) => {
         await apiFetch({
           path: `/my-plugin/v1/settings/${scopeId}`,
           method: 'POST',
           data: treeValues,
         });
       }}

Using _flatValues signals it's intentionally unused while showing the full signature.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@DEVELOPER_GUIDE.md` around lines 1131 - 1136, Update the example onSave
handler to show the full signature by adding the unused flatValues parameter
(use a named _flatValues to signal it's intentionally unused) so it matches the
signature used in Settings.mdx and DeveloperGuide.mdx; locate the onSave arrow
function (onSave={async (scopeId, treeValues) => { ... }}) and change its
parameters to (scopeId, treeValues, _flatValues) and leave the body unchanged
except for using the same apiFetch call.
src/components/settings/settings-context.tsx (1)

270-271: Edge case: typeof null === 'object' in JavaScript.

If an intermediate key has a null value, this check passes but the subsequent assignment fails. Consider adding a null check:

-                if (!(parts[i] in cursor) || typeof cursor[parts[i]] !== 'object') {
+                if (!(parts[i] in cursor) || cursor[parts[i]] === null || typeof cursor[parts[i]] !== 'object') {

This is unlikely in practice for settings data, but worth hardening if keys could theoretically have null values.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/settings/settings-context.tsx` around lines 270 - 271, The
current traversal in the SettingsContext (the block using variables cursor and
parts[]) checks typeof cursor[parts[i]] !== 'object' but misses the null case;
update the condition in the loop that builds intermediate keys (the code that
assigns cursor[parts[i]] = {}) to also verify cursor[parts[i]] !== null (i.e.
only treat it as an object when not null) so that null values are replaced with
a new object before continuing. Ensure the change is applied where cursor and
parts are iterated in the settings-context.tsx function that mutates nested
settings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/settings/settings-types.ts`:
- Around line 139-140: The onSave callback in the settings types is currently
declared to return void but must allow async handlers; update the onSave
signature in settings-types (the onSave?: (scopeId: string, treeValues:
Record<string, any>, flatValues: Record<string, any>) => void) to return void |
Promise<void> so it matches how handleOnSave in settings-context.tsx awaits
Promise.resolve(onSave(...)) and avoids TypeScript mismatches.

---

Nitpick comments:
In `@DEVELOPER_GUIDE.md`:
- Around line 1131-1136: Update the example onSave handler to show the full
signature by adding the unused flatValues parameter (use a named _flatValues to
signal it's intentionally unused) so it matches the signature used in
Settings.mdx and DeveloperGuide.mdx; locate the onSave arrow function
(onSave={async (scopeId, treeValues) => { ... }}) and change its parameters to
(scopeId, treeValues, _flatValues) and leave the body unchanged except for using
the same apiFetch call.

In `@src/components/settings/settings-context.tsx`:
- Around line 270-271: The current traversal in the SettingsContext (the block
using variables cursor and parts[]) checks typeof cursor[parts[i]] !== 'object'
but misses the null case; update the condition in the loop that builds
intermediate keys (the code that assigns cursor[parts[i]] = {}) to also verify
cursor[parts[i]] !== null (i.e. only treat it as an object when not null) so
that null values are replaced with a new object before continuing. Ensure the
change is applied where cursor and parts are iterated in the
settings-context.tsx function that mutates nested settings.

In `@src/DeveloperGuide.mdx`:
- Around line 915-917: Update the onSave handler example to match the real API
signature by including the third parameter: change the parameter list from
(scopeId, treeValues) to (scopeId, treeValues, flatValues) in the onSave
callback so it reflects the actual signature used by Settings (refer to the
onSave handler and Settings API docs), and adjust any example usage inside the
handler to accept but not necessarily use flatValues.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b4e2a492-8900-4b6c-a043-606a00f8b0a2

📥 Commits

Reviewing files that changed from the base of the PR and between 3d3c206 and 5061700.

📒 Files selected for processing (5)
  • DEVELOPER_GUIDE.md
  • src/DeveloperGuide.mdx
  • src/components/settings/Settings.mdx
  • src/components/settings/settings-context.tsx
  • src/components/settings/settings-types.ts

Comment on lines +139 to +140
/** Called when the save button is clicked. Receives the scope ID, nested tree values, and flat dot-keyed values. */
onSave?: (scopeId: string, treeValues: Record<string, any>, flatValues: Record<string, any>) => void;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Return type mismatch: void vs void | Promise<void>.

The onSave return type here is void, but in settings-context.tsx (lines 72 and 91), the same callback is typed as void | Promise<void>. This inconsistency may cause TypeScript errors for consumers using async onSave handlers.

Since handleOnSave in the context uses await Promise.resolve(onSave(...)), the Promise return type should be supported:

     /** Called when the save button is clicked. Receives the scope ID, nested tree values, and flat dot-keyed values. */
-    onSave?: (scopeId: string, treeValues: Record<string, any>, flatValues: Record<string, any>) => void;
+    onSave?: (scopeId: string, treeValues: Record<string, any>, flatValues: Record<string, any>) => void | Promise<void>;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/** Called when the save button is clicked. Receives the scope ID, nested tree values, and flat dot-keyed values. */
onSave?: (scopeId: string, treeValues: Record<string, any>, flatValues: Record<string, any>) => void;
/** Called when the save button is clicked. Receives the scope ID, nested tree values, and flat dot-keyed values. */
onSave?: (scopeId: string, treeValues: Record<string, any>, flatValues: Record<string, any>) => void | Promise<void>;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/settings/settings-types.ts` around lines 139 - 140, The onSave
callback in the settings types is currently declared to return void but must
allow async handlers; update the onSave signature in settings-types (the
onSave?: (scopeId: string, treeValues: Record<string, any>, flatValues:
Record<string, any>) => void) to return void | Promise<void> so it matches how
handleOnSave in settings-context.tsx awaits Promise.resolve(onSave(...)) and
avoids TypeScript mismatches.

Provides architecture overview, component API surface, settings system
usage, theme system, WordPress integration patterns, and CI checks.
Not included in npm package (not in files array).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CLAUDE.md`:
- Line 195: The documentation text uses an incorrect casing for "GitHub" —
update the string in CLAUDE.md (the sentence referencing the CI pipeline
`.github/workflows/ci.yml`) to use the official casing "GitHub" so the reference
reads "The CI pipeline (`.github/workflows/ci.yml`) runs these on
`ubuntu-latest` with Node 24." ensuring consistent capitalization throughout the
file.
- Around line 7-17: The Markdown code fence containing the architecture tree
lacks a language tag (triggers markdownlint MD040); update the opening
triple-backticks to include a language (use ```text) so the block becomes fenced
with ```text and resolves the lint error while preserving the existing content.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e677a136-7cde-4eca-890d-0dc1670bc83e

📥 Commits

Reviewing files that changed from the base of the PR and between 5061700 and f32dad7.

📒 Files selected for processing (1)
  • CLAUDE.md

Comment on lines +7 to +17
```
src/
├── components/
│ ├── ui/ # Core ShadCN-style components (150+ exports)
│ ├── settings/ # Schema-driven settings system
│ └── wordpress/ # WordPress integration (Layout, DataViews)
├── providers/ # ThemeProvider (CSS variable injection)
├── themes/ # Built-in theme presets
├── hooks/ # useMobile, useWindowDimensions
└── lib/ # Utilities (cn, renderIcon, WpMedia, wordpress-date)
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a language tag to the architecture code fence.

This block is missing a fence language, which will keep tripping markdownlint (MD040). text would be the right fit here.

🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 7-7: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CLAUDE.md` around lines 7 - 17, The Markdown code fence containing the
architecture tree lacks a language tag (triggers markdownlint MD040); update the
opening triple-backticks to include a language (use ```text) so the block
becomes fenced with ```text and resolves the lint error while preserving the
existing content.

npm run typecheck # tsc --noEmit
```

Both must pass. The CI pipeline (`.github/workflows/ci.yml`) runs these on `ubuntu-latest` with Node 24.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Capitalize GitHub consistently.

Use the official casing here to avoid a docs/style nit slipping into a reference section.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~195-~195: The official name of this software platform is spelled with a capital “H”.
Context: ...t ``` Both must pass. The CI pipeline (.github/workflows/ci.yml) runs these on `ubunt...

(GITHUB)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CLAUDE.md` at line 195, The documentation text uses an incorrect casing for
"GitHub" — update the string in CLAUDE.md (the sentence referencing the CI
pipeline `.github/workflows/ci.yml`) to use the official casing "GitHub" so the
reference reads "The CI pipeline (`.github/workflows/ci.yml`) runs these on
`ubuntu-latest` with Node 24." ensuring consistent capitalization throughout the
file.

The context's internal save wrapper (2 args) shared the same name as the
consumer's onSave prop (3 args), causing a TS2554 error in settings-content.
Rename to `save` in SettingsContextValue and update JSDoc across types and docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/components/settings/settings-context.tsx (1)

264-276: Consider defensive handling for tree-building edge cases.

Two concerns with the current tree-building logic:

  1. Outside try/catch: If pageValues is unexpectedly malformed, the loop would throw before reaching the try/catch block.

  2. Null intermediate values: If typeof cursor[parts[i]] === 'object' passes for null (since typeof null === 'object'), the subsequent cursor = cursor[parts[i]] assigns null, causing cursor[parts[parts.length - 1]] = val to throw.

🛡️ Proposed fix: Guard against null and wrap in try/catch
         if (!onSave) return;
+        try {
         // Build nested tree from dot-separated keys
         const treeValues: Record<string, any> = {};
         for (const [dotKey, val] of Object.entries(pageValues)) {
             const parts = dotKey.split('.');
             let cursor: Record<string, any> = treeValues;
             for (let i = 0; i < parts.length - 1; i++) {
-                if (!(parts[i] in cursor) || typeof cursor[parts[i]] !== 'object') {
+                if (!(parts[i] in cursor) || cursor[parts[i]] === null || typeof cursor[parts[i]] !== 'object') {
                     cursor[parts[i]] = {};
                 }
                 cursor = cursor[parts[i]];
             }
             cursor[parts[parts.length - 1]] = val;
         }
-        try {
             await Promise.resolve(onSave(pageId, treeValues, pageValues));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/settings/settings-context.tsx` around lines 264 - 276, The
tree-building loop that converts pageValues into treeValues should be made
defensive: wrap the entire for..of over Object.entries(pageValues) in a
try/catch and on error log or rethrow with context; when iterating parts, guard
against null by checking cursor[parts[i]] !== null && typeof cursor[parts[i]]
=== 'object' before assigning cursor = cursor[parts[i]] and if the existing
value is missing or not a non-null object, replace it with an empty object
(cursor[parts[i]] = {}) so traversal never sets cursor to null; reference the
treeValues, pageValues, parts and cursor variables and ensure any caught error
includes context about the offending dotKey.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/settings/settings-context.tsx`:
- Line 91: The onSave callback signature in settings-context.tsx changed to
onSave?: (scopeId: string, treeValues: Record<string, any>, flatValues:
Record<string, any>) => void | Promise<void>, so update all call sites that
still use two parameters (e.g., the Settings.stories usage and the Developer
Guide examples) to accept the third flatValues argument or explicitly ignore it
(for example change (scopeId, treeValues) => ... to (scopeId, treeValues,
flatValues) => ... or (scopeId, treeValues, ..._rest) => ...), ensuring any
handlers that call or implement onSave (named onSave) match the new
three-parameter signature.

---

Nitpick comments:
In `@src/components/settings/settings-context.tsx`:
- Around line 264-276: The tree-building loop that converts pageValues into
treeValues should be made defensive: wrap the entire for..of over
Object.entries(pageValues) in a try/catch and on error log or rethrow with
context; when iterating parts, guard against null by checking cursor[parts[i]]
!== null && typeof cursor[parts[i]] === 'object' before assigning cursor =
cursor[parts[i]] and if the existing value is missing or not a non-null object,
replace it with an empty object (cursor[parts[i]] = {}) so traversal never sets
cursor to null; reference the treeValues, pageValues, parts and cursor variables
and ensure any caught error includes context about the offending dotKey.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fc6177cf-8b86-42fd-9304-505509463687

📥 Commits

Reviewing files that changed from the base of the PR and between f32dad7 and 5ea0769.

📒 Files selected for processing (4)
  • src/components/settings/Settings.mdx
  • src/components/settings/settings-content.tsx
  • src/components/settings/settings-context.tsx
  • src/components/settings/settings-types.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/components/settings/Settings.mdx
  • src/components/settings/settings-types.ts

values?: Record<string, any>;
onChange?: (scopeId: string, key: string, value: any) => void;
onSave?: (scopeId: string, values: Record<string, any>) => void | Promise<void>;
onSave?: (scopeId: string, treeValues: Record<string, any>, flatValues: Record<string, any>) => void | Promise<void>;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, read the settings-context.tsx file to see the context around line 91
head -100 src/components/settings/settings-context.tsx | tail -20

Repository: getdokan/plugin-ui

Length of output: 895


🏁 Script executed:

# Get more context - read the full file or at least the type/interface definition
wc -l src/components/settings/settings-context.tsx

Repository: getdokan/plugin-ui

Length of output: 110


🏁 Script executed:

# Search for onSave usages in the codebase
rg -n 'onSave' --type=ts --type=tsx -B 2 -A 2 | head -100

Repository: getdokan/plugin-ui

Length of output: 89


🏁 Script executed:

# Search for onSave usages without type filters
rg -n 'onSave' -B 2 -A 2

Repository: getdokan/plugin-ui

Length of output: 15495


🏁 Script executed:

# Also check how onSave is called/invoked in the file
rg -n 'onSave\s*\(' -B 1 -A 1

Repository: getdokan/plugin-ui

Length of output: 1625


🏁 Script executed:

# Verify the exact line in Settings.stories.tsx to understand the context better
sed -n '1080,1095p' src/components/settings/Settings.stories.tsx

Repository: getdokan/plugin-ui

Length of output: 911


🏁 Script executed:

# Check if there are any other invocations of onSave callback we might have missed
rg -n 'onSave\s*\(\s*[^)]*\s*\)' -B 1 -A 1

Repository: getdokan/plugin-ui

Length of output: 1625


Breaking change: onSave signature updated — some call sites still need updating.

The new signature (scopeId, treeValues, flatValues) is a breaking change. Several usages have not been updated:

  • src/components/settings/Settings.stories.tsx line 1084 still uses 2 parameters
  • src/DeveloperGuide.mdx and DEVELOPER_GUIDE.md examples still use 2 parameters

Update these call sites to accept the new third parameter flatValues or ignore it with a rest parameter if unused.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/settings/settings-context.tsx` at line 91, The onSave callback
signature in settings-context.tsx changed to onSave?: (scopeId: string,
treeValues: Record<string, any>, flatValues: Record<string, any>) => void |
Promise<void>, so update all call sites that still use two parameters (e.g., the
Settings.stories usage and the Developer Guide examples) to accept the third
flatValues argument or explicitly ignore it (for example change (scopeId,
treeValues) => ... to (scopeId, treeValues, flatValues) => ... or (scopeId,
treeValues, ..._rest) => ...), ensuring any handlers that call or implement
onSave (named onSave) match the new three-parameter signature.

@mrabbani mrabbani merged commit 3233426 into main Mar 6, 2026
1 check passed
@mrabbani mrabbani deleted the fix/onsave-signature branch March 6, 2026 08:49
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