Skip to content

[4.x][8221][8222] Accesibility - snack duration, animations enabling/disabling#4898

Open
jvega190 wants to merge 11 commits into
craftercms:support/4.xfrom
jvega190:enhancement/4.x/8221
Open

[4.x][8221][8222] Accesibility - snack duration, animations enabling/disabling#4898
jvega190 wants to merge 11 commits into
craftercms:support/4.xfrom
jvega190:enhancement/4.x/8221

Conversation

@jvega190

Copy link
Copy Markdown
Member

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@jvega190, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 35 minutes and 5 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 47309bc6-ea43-4dc3-b228-83d839fd4afe

📥 Commits

Reviewing files that changed from the base of the PR and between 35eb4df and 1651580.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (3)
  • ui/app/package.json
  • ui/app/src/components/AccountManagement/AccountManagement.tsx
  • ui/app/src/utils/state.ts

Walkthrough

Adds two user accessibility preferences—snackbar notification duration and animation toggle—backed by localStorage. New state utilities, two useSyncExternalStore hooks, and a new Accessibility panel in AccountManagement are introduced. CrafterCMSNextBridge and CrafterThemeProvider are updated to consume these preferences reactively.

Changes

Accessibility Preferences: Storage, Hooks, UI, and Provider Wiring

Layer / File(s) Summary
localStorage state utilities for preferences
ui/app/src/utils/state.ts
Adds custom-event-driven subscribe*, set*, get*, and remove* helpers for snackbar duration (number) and enable-animations (boolean), plus DEFAULT_SNACKBAR_DURATION = 5000 constant.
useSnackbarDuration and useEnableAnimations hooks
ui/app/src/hooks/useSnackbarDuration.ts, ui/app/src/hooks/useEnableAnimations.ts
Two new hooks use useSyncExternalStore with the subscribe functions to expose reactive per-user preferences; both fall back to defaults for SSR or when username is absent.
Wiring hooks into providers
ui/app/src/components/CrafterCMSNextBridge/CrafterCMSNextBridge.tsx, ui/app/src/components/CrafterThemeProvider/CrafterThemeProvider.tsx
CrafterCMSNextBridge passes useSnackbarDuration() to SnackbarProvider.autoHideDuration instead of a hardcoded value; CrafterThemeProvider uses useEnableAnimations() to conditionally disable MUI transitions, ripple effects, and global CSS animations via MuiCssBaseline and MuiButtonBase overrides.
Accessibility settings panel in AccountManagement
ui/app/src/components/AccountManagement/AccountManagement.tsx, ui/app/package.json
Adds snackDuration/enableAnimations state (initialized from storage), onSaveAccessibility handler (persists both values, dispatches notification), and the full Accessibility section UI with a NumberField (seconds display, ms storage), reset button, animations checkbox, and Save button. Includes new @base-ui-components/react dependency for the NumberField component.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant AccountManagement
  participant state.ts
  participant localStorage
  participant useSnackbarDuration
  participant useEnableAnimations
  participant CrafterCMSNextBridge
  participant CrafterThemeProvider

  User->>AccountManagement: Update notification duration / animations checkbox
  User->>AccountManagement: Click Save
  AccountManagement->>state.ts: setStoredSnackbarDuration(user, value)
  AccountManagement->>state.ts: setStoredEnableAnimations(user, value)
  state.ts->>localStorage: persist values
  state.ts->>window: dispatch custom events

  window-->>useSnackbarDuration: storage/custom event triggers re-read
  useSnackbarDuration-->>CrafterCMSNextBridge: updated autoHideDuration

  window-->>useEnableAnimations: storage/custom event triggers re-read
  useEnableAnimations-->>CrafterThemeProvider: updated enableAnimations → theme rebuilt
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • craftercms/studio-ui#4889: Overlaps the same files (AccountManagement, CrafterThemeProvider, CrafterCMSNextBridge) and likely introduces the initial structure that this PR extends with the accessibility preferences.

Suggested reviewers

  • rart
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description only contains issue links without substantive explanation of what was implemented or why. Add details about what was implemented, how it works, and which components were modified to address the issues.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding accessibility features for snackbar duration and animations control.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
ui/app/src/hooks/useSnackbarDuration.ts (1)

17-17: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Decouple hook defaults from component modules.

Line 17 creates an unnecessary hook→component dependency. Move DEFAULT_SNACKBAR_DURATION to a shared constants/state module and import it from both places.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/app/src/hooks/useSnackbarDuration.ts` at line 17, The import statement in
useSnackbarDuration.ts currently imports DEFAULT_SNACKBAR_DURATION from the
AccountManagement component module, creating an unnecessary coupling. Move the
DEFAULT_SNACKBAR_DURATION constant to a shared constants module (create one if
it doesn't exist, such as in a constants or config directory), then update the
import statement in useSnackbarDuration.ts to import from the new shared
constants module instead of from AccountManagement. Also update
AccountManagement to import from the same shared constants module to keep the
constant definition centralized.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ui/app/src/components/AccountManagement/AccountManagement.tsx`:
- Around line 393-395: The NumberField component in AccountManagement.tsx is
performing arithmetic operations directly on snackDuration without explicitly
handling the null case. Add null checks before dividing or multiplying the
values to ensure that null states are preserved and not coerced into unexpected
values. Specifically, in both the value prop calculation (snackDuration / 1000)
and the onValueChange handler (value * 1000), add conditional logic to return
null or handle the null case explicitly rather than allowing JavaScript coercion
to bypass the intended null state gate.

In `@ui/app/src/utils/state.ts`:
- Around line 468-470: The removeStoredSnackbarDuration function removes a
storage item but does not emit a change event to notify same-tab subscribers
using useSyncExternalStore, causing their data to become stale. After calling
window.localStorage.removeItem in removeStoredSnackbarDuration, emit a change
event to notify subscribers of the removal (use the same notification mechanism
used elsewhere in this file for storage updates). Apply the same fix to the
other function mentioned around lines 498-500 that also removes storage keys
without notifying subscribers.
- Around line 463-466: The getStoredSnackbarDuration function can return NaN
when the stored value is malformed or non-numeric, since parseInt(value, 10)
returns NaN for invalid inputs. This NaN value will bypass the null fallback in
the consuming hook and leak invalid values into snackbar configuration. After
parsing the value with parseInt in the return statement, validate that the
result is not NaN by using Number.isNaN() or checking if the parsed value is a
valid number before returning it; return null instead when the parsed value is
NaN.

---

Nitpick comments:
In `@ui/app/src/hooks/useSnackbarDuration.ts`:
- Line 17: The import statement in useSnackbarDuration.ts currently imports
DEFAULT_SNACKBAR_DURATION from the AccountManagement component module, creating
an unnecessary coupling. Move the DEFAULT_SNACKBAR_DURATION constant to a shared
constants module (create one if it doesn't exist, such as in a constants or
config directory), then update the import statement in useSnackbarDuration.ts to
import from the new shared constants module instead of from AccountManagement.
Also update AccountManagement to import from the same shared constants module to
keep the constant definition centralized.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 390e4b7f-5565-442e-be79-10de3fdc8d02

📥 Commits

Reviewing files that changed from the base of the PR and between 2ddd8f6 and dc2814c.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (6)
  • ui/app/src/components/AccountManagement/AccountManagement.tsx
  • ui/app/src/components/CrafterCMSNextBridge/CrafterCMSNextBridge.tsx
  • ui/app/src/components/CrafterThemeProvider/CrafterThemeProvider.tsx
  • ui/app/src/hooks/useEnableAnimations.ts
  • ui/app/src/hooks/useSnackbarDuration.ts
  • ui/app/src/utils/state.ts

Comment thread ui/app/src/components/AccountManagement/AccountManagement.tsx
Comment thread ui/app/src/utils/state.ts
Comment thread ui/app/src/utils/state.ts
@jvega190

Copy link
Copy Markdown
Member Author

@coderabbitai can you check if everything looks good? Please give it a final review before I hand over for human review

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== AccountManagement.tsx ===" 
cat ui/app/src/components/AccountManagement/AccountManagement.tsx
echo ""
echo "=== CrafterCMSNextBridge.tsx ===" 
cat ui/app/src/components/CrafterCMSNextBridge/CrafterCMSNextBridge.tsx
echo ""
echo "=== CrafterThemeProvider.tsx ===" 
cat ui/app/src/components/CrafterThemeProvider/CrafterThemeProvider.tsx
echo ""
echo "=== useEnableAnimations.ts ===" 
cat ui/app/src/hooks/useEnableAnimations.ts
echo ""
echo "=== useSnackbarDuration.ts ===" 
cat ui/app/src/hooks/useSnackbarDuration.ts
echo ""
echo "=== state.ts ===" 
cat ui/app/src/utils/state.ts

Length of output: 52783



@jvega190 The implementation looks solid overall — the useSyncExternalStore pattern for reactive localStorage state is well-applied, the animation disabling is comprehensive (MUI transitions, ripple, and CSS overrides), and the subscribe/unsubscribe cleanup is correct. A few items to address before human review:


🐛 Issues

1. Typo in helper text — AccountManagement.tsx

"How long notifications stay visible at on the screen before closing automatically."

Should be "on the screen".


2. Unreachable null check — AccountManagement.tsx

onValueChange never sets snackDuration to null because clearing the input fires value = null, and Number.isFinite(null) is false, falling back to DEFAULT_SNACKBAR_DURATION:

// Current — null path is never reached
onValueChange={(value) =>
  setSnackDuration(Number.isFinite(value) ? Number(value) * 1000 : DEFAULT_SNACKBAR_DURATION)
}

The Save button's disabled={snackDuration === null || ...} guard becomes dead code. Either allow null on clear (to disable Save), or keep the fallback and remove the null check from the disabled prop:

// Option A: allow null when cleared
onValueChange={(value) =>
  setSnackDuration(value === null ? null : Math.round(value * 1000))
}

// Option B: always keep a valid value, simplify disabled check
disabled={initialSnackDuration === snackDuration && initialEnableAnimations === enableAnimations}

3. DEFAULT_SNACKBAR_DURATION lives in a component file

useSnackbarDuration.ts imports DEFAULT_SNACKBAR_DURATION from AccountManagement.tsx, which is unusual for a hook importing from a component. Consider moving this constant to state.ts or a dedicated constants.ts to avoid the awkward cross-layer dependency.


⚠️ Minor nits

4. Storage key matching — state.ts

Both subscribeSnackbarDuration and subscribeEnableAnimations use .includes() for the storage event key check, which could match partially-named keys. Using .endsWith() is more precise:

// Before
if (e.key?.includes('.snackbarDuration')) {

// After
if (e.key?.endsWith('.snackbarDuration')) {

5. Missing i18n id props on new strings

The Accessibility section messages (title, notification duration label, helper text, "Enable animations") don't have id props, inconsistent with the established defineMessages pattern used for the other messages in the same file. If auto-IDs are intentional (e.g., FormatJS babel plugin), this is fine — just worth flagging for the human reviewer.

6. Copyright year in AccountManagement.tsx

Still reads 2007-2022 while the new hook files say 2007-2026.


✅ What looks good

  • useSyncExternalStore + custom events pattern is well-suited here and handles same-tab and cross-tab (storage event) changes correctly.
  • OutlinedInputWithRef with inputRef is the right fix for Base UI needing the <input> element directly.
  • CrafterThemeProvider animation disabling is thorough: JS transitions, ripple, and the nuclear '*, *::before, *::after' CSS override.
  • onSaveAccessibility shows the notification with the new duration as a preview, which is a nice UX touch.
  • Subscriber cleanup (removeEventListener) is correctly implemented in all subscribe functions.

…o state utility, update imports, and improve helper text clarity in AccountManagement component.
@jvega190

Copy link
Copy Markdown
Member Author

@coderabbitai can you check if everything looks good? Please give it a final review before I hand over for human review.
Please note that weuse babel for ids generation in i18n and copyright updates won't be handled in here

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== AccountManagement.tsx (relevant sections) ==="
grep -n "snackDuration\|onValueChange\|How long\|at on\|disabled=\|DEFAULT_SNACKBAR_DURATION\|null" ui/app/src/components/AccountManagement/AccountManagement.tsx | head -80

echo ""
echo "=== state.ts (subscribe functions key checks) ==="
grep -n "includes\|endsWith\|snackbarDuration\|enableAnimations" ui/app/src/utils/state.ts

echo ""
echo "=== useSnackbarDuration.ts import source ==="
grep -n "import" ui/app/src/hooks/useSnackbarDuration.ts

echo ""
echo "=== DEFAULT_SNACKBAR_DURATION definition location ==="
grep -rn "DEFAULT_SNACKBAR_DURATION" ui/app/src/

Length of output: 4642



@jvega190 Good progress! Points #5 (i18n IDs via Babel) and #6 (copyright) are noted and withdrawn. Here's the updated status on the remaining items:

Fixed — Typo (#1): Helper text now correctly reads "on the screen."

Fixed — Cross-layer import (#3): DEFAULT_SNACKBAR_DURATION has been moved to state.ts and both the hook and component import from there.

⚠️ Still present — .includes() in subscribeEnableAnimations (#4): subscribeSnackbarDuration was updated to use .endsWith(), but subscribeEnableAnimations (line 495 of state.ts) still uses .includes('.enableAnimations'). For consistency and precision, it should also be .endsWith():

// state.ts line 495 — change to:
if (e.key?.endsWith('.enableAnimations')) {

⚠️ Still present — dead null code (#2): The state type is still number | null and the guard if (snackDuration === null) return; (line 192) remains, but onValueChange never produces null (it always falls back to DEFAULT_SNACKBAR_DURATION). The disabled prop no longer checks snackDuration === null which is good. The remaining dead code is minor but worth cleaning up before human review:

// Either allow null on clear:
onValueChange={(value) => setSnackDuration(value === null ? null : Math.round(value * 1000))}

// Or drop the null type/guard entirely since it can never be null:
const [snackDuration, setSnackDuration] = useState<number>(
  getStoredSnackbarDuration(user.username) ?? DEFAULT_SNACKBAR_DURATION
);
// and remove: if (snackDuration === null) return;

Two quick one-liners to sort out before handoff, then it should be good to go! 🐇


✏️ Learnings added
Learnt from: jvega190
URL: https://github.com/craftercms/studio-ui/pull/4898

Timestamp: 2026-06-22T16:15:58.848Z
Learning: In the craftercms/studio-ui repository, Babel is used for automatic i18n message ID generation via the FormatJS Babel plugin. Review comments about missing `id` props on `defineMessages` / `FormattedMessage` should not be raised, as IDs are auto-generated at build time.

Learnt from: jvega190
URL: https://github.com/craftercms/studio-ui/pull/4898

Timestamp: 2026-06-22T16:15:58.848Z
Learning: In the craftercms/studio-ui repository, copyright header year updates are explicitly out of scope for individual PRs and should not be flagged in code reviews.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
ui/app/package.json (1)

57-57: 🧹 Nitpick | 🔵 Trivial

Pin the RC dependency to a specific version for stability.

At Line 57, ^1.0.0-rc.0 can float to newer release-candidate versions (e.g., 1.0.0-rc.1) and will also match the stable 1.0.0 release. For pre-release dependencies in production, pin to the exact version (e.g., "1.0.0-rc.0" instead of "^1.0.0-rc.0") to prevent unexpected upgrades during installs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/app/package.json` at line 57, The `@base-ui-components/react` dependency is
specified with a caret prefix (^1.0.0-rc.0), which allows version floating to
newer release candidates and stable releases. Remove the caret prefix from the
`@base-ui-components/react` version specification in package.json and pin it to
the exact version (1.0.0-rc.0) to ensure stability and prevent unexpected
version upgrades during package installations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@ui/app/package.json`:
- Line 57: The `@base-ui-components/react` dependency is specified with a caret
prefix (^1.0.0-rc.0), which allows version floating to newer release candidates
and stable releases. Remove the caret prefix from the `@base-ui-components/react`
version specification in package.json and pin it to the exact version
(1.0.0-rc.0) to ensure stability and prevent unexpected version upgrades during
package installations.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 64573075-a319-464c-9022-8ad0aecb26fe

📥 Commits

Reviewing files that changed from the base of the PR and between dc2814c and 35eb4df.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (4)
  • ui/app/package.json
  • ui/app/src/components/AccountManagement/AccountManagement.tsx
  • ui/app/src/hooks/useSnackbarDuration.ts
  • ui/app/src/utils/state.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • ui/app/src/hooks/useSnackbarDuration.ts
  • ui/app/src/utils/state.ts

…ent: remove null handling and ensure proper type definition. Update localStorage event listener condition in state utility for better clarity.
@jvega190

Copy link
Copy Markdown
Member Author

@coderabbitai can you check if everything looks good? Please give it a final review before I hand over for human review.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== state.ts subscribe functions key checks ==="
grep -n "includes\|endsWith\|snackbarDuration\|enableAnimations" ui/app/src/utils/state.ts

echo ""
echo "=== AccountManagement.tsx null-related lines ==="
grep -n "snackDuration\|null\|onValueChange\|useState\|disabled=" ui/app/src/components/AccountManagement/AccountManagement.tsx | head -60

Length of output: 3071



@jvega190 Both previously open items are now resolved:

Fixed — .endsWith() in subscribeEnableAnimations (#4): Line 495 of state.ts now correctly uses .endsWith('.enableAnimations').

Fixed — Dead null code (#2): snackDuration is now typed as number (no more number | null), and the if (snackDuration === null) return; guard is gone. The disabled check on line 423 is clean.

One last tiny nit (optional): Line 391 still has a dead-code null conditional:

value={snackDuration === null ? null : snackDuration / 1000}

Since snackDuration is now number, the === null branch can never be reached. It can be simplified to:

value={snackDuration / 1000}

This is cosmetic — TypeScript might even warn about it. Up to you whether to clean it before handoff, but it doesn't block review.

Everything else looks good. The implementation is solid and ready for human review! 🐇

@jvega190

Copy link
Copy Markdown
Member Author

@coderabbitai can you check if everything looks good? Please give it a final review before I hand over for human review.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== AccountManagement.tsx — snackDuration-related lines ==="
grep -n "snackDuration\|null\|onValueChange\|useState\|disabled=\|value=" ui/app/src/components/AccountManagement/AccountManagement.tsx | head -80

echo ""
echo "=== state.ts — subscribe key checks ==="
grep -n "endsWith\|includes\|snackbarDuration\|enableAnimations" ui/app/src/utils/state.ts

echo ""
echo "=== useSnackbarDuration.ts ==="
cat ui/app/src/hooks/useSnackbarDuration.ts

echo ""
echo "=== useEnableAnimations.ts ==="
cat ui/app/src/hooks/useEnableAnimations.ts

echo ""
echo "=== CrafterThemeProvider.tsx — new lines ==="
grep -n "enableAnimations\|transitions\|ripple\|animation\|MuiCssBaseline" ui/app/src/components/CrafterThemeProvider/CrafterThemeProvider.tsx

echo ""
echo "=== CrafterCMSNextBridge.tsx — snackbar lines ==="
grep -n "snackbar\|autoHide\|useSnackbar" ui/app/src/components/CrafterCMSNextBridge/CrafterCMSNextBridge.tsx

Length of output: 7439



@jvega190 Everything is clean — all previously flagged items are resolved:

Typo — "at on the screen" → "on the screen"
Cross-layer importDEFAULT_SNACKBAR_DURATION lives in state.ts
.endsWith() consistency — both subscribeSnackbarDuration (line 463) and subscribeEnableAnimations (line 495) use .endsWith()
Dead null codesnackDuration is typed as number, and value={snackDuration / 1000} is clean
i18n / copyright — noted as intentional / out of scope

The implementation is solid and ready for human review. 🐇

@jvega190 jvega190 marked this pull request as ready for review June 22, 2026 16:34
@jvega190 jvega190 requested a review from rart as a code owner June 22, 2026 16:34
Comment thread ui/app/package.json Outdated
@jvega190

Copy link
Copy Markdown
Member Author

@coderabbitai can you check if everything looks good? Please give it a final review before I hand over for human review.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== AST outlines ==="
ast-grep outline ui/app/src/components/AccountManagement/AccountManagement.tsx --view expanded || true
ast-grep outline ui/app/src/utils/state.ts --view expanded || true
ast-grep outline ui/app/src/hooks/useSnackbarDuration.ts --view expanded || true
ast-grep outline ui/app/src/hooks/useEnableAnimations.ts --view expanded || true
ast-grep outline ui/app/src/components/CrafterThemeProvider/CrafterThemeProvider.tsx --view expanded || true
ast-grep outline ui/app/src/components/CrafterCMSNextBridge/CrafterCMSNextBridge.tsx --view expanded || true

echo
echo "=== Targeted searches ==="
echo "-- AccountManagement: snackbar/accessibility state and UI --"
rg -n -C 3 "DEFAULT_SNACKBAR_DURATION|snackDuration|enableAnimations|onValueChange|onSaveAccessibility|value=|disabled=|on the screen|at on" ui/app/src/components/AccountManagement/AccountManagement.tsx || true

echo
echo "-- state.ts: storage subscriptions and constants --"
rg -n -C 3 "DEFAULT_SNACKBAR_DURATION|subscribeSnackbarDuration|subscribeEnableAnimations|endsWith|includes|snackbarDuration|enableAnimations" ui/app/src/utils/state.ts || true

echo
echo "-- hook imports and snapshots --"
sed -n '1,220p' ui/app/src/hooks/useSnackbarDuration.ts
echo
sed -n '1,220p' ui/app/src/hooks/useEnableAnimations.ts

echo
echo "-- CrafterThemeProvider animation handling --"
rg -n -C 3 "useEnableAnimations|transitions|MuiTouchRipple|disableRipple|MuiCssBaseline|animation|transition" ui/app/src/components/CrafterThemeProvider/CrafterThemeProvider.tsx || true

echo
echo "-- CrafterCMSNextBridge snackbar provider duration --"
rg -n -C 3 "useSnackbarDuration|autoHideDuration|SnackbarProvider" ui/app/src/components/CrafterCMSNextBridge/CrafterCMSNextBridge.tsx || true

echo
echo "=== Focused file slices ==="
sed -n '140,470p' ui/app/src/components/AccountManagement/AccountManagement.tsx
echo
sed -n '430,540p' ui/app/src/utils/state.ts

Length of output: 44189



@jvega190 I re-checked the touched files, and everything looks good from my side.

What I verified:

  • helper text typo is fixed
  • DEFAULT_SNACKBAR_DURATION now lives in ui/app/src/utils/state.ts
  • both storage listeners use precise .endsWith(...) checks
  • the snackbar duration flow is clean now (snackDuration is a number, and the save-state logic is consistent)
  • useSnackbarDuration() is correctly wired into SnackbarProvider
  • animation disabling in CrafterThemeProvider is still comprehensive and consistent with the accessibility toggle

I don’t see any remaining blockers in these changes. This looks ready to hand over for human review.

@jvega190 jvega190 requested a review from rart June 25, 2026 18:39
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.

2 participants