Skip to content

fix: resolve the 3 critical findings from the code review - #7

Merged
carllosnc merged 3 commits into
masterfrom
fix/review-criticals
Oct 27, 2026
Merged

carllosnc merged 3 commits into
masterfrom
fix/review-criticals

Conversation

@carllosnc

Copy link
Copy Markdown
Owner

Summary

This PR fixes the three critical issues identified in the recent code review of the Dashkit UI project, organized as three independent commits.

1. CLI output did not compile (fix(cli): make add output compile)

  • Missing registryDependencies: button→spinner, modal→backdrop+iconbutton, drawer→backdrop, sidebar→tooltip, statscard→divider. dashkit add previously emitted components referencing files it never installed.
  • utils/ incomplete: add only copied cn.ts, but Modal/Drawer/ImageExpander also import utils/scrollLock. Now every non-test file under src/dashkit/utils/ is copied by both add and init.
  • program.parse() → parseAsync() so async action handlers are awaited.
  • New static registry test that scans every cross-component relative import and fails if it isn't covered by registryDependencies (it caught a real gap: badge→floatbadge), plus e2e CLI tests for compilable output.
  • Regenerated the committed exec/cli.js bundle.

2. Functional bugs (fix: make Sidebar.setIsOpen and Accordion.disabled actually work)

  • Sidebar discarded the setIsOpen returned by useSidebarState and passed a no-op; calling setIsOpen from useSidebar() silently did nothing. Wired the real setter through and memoized the context.
  • AccordionItem accepted disabled but only painted a CSS class — the trigger still toggled. disabled now flows through the item context; AccordionTrigger blocks the click, sets disabled/aria-disabled, and exposes aria-expanded.

3. Accessibility (fix(a11y): add dialog, tab, trigger, tooltip and toast semantics)

  • Modal & Drawer: role="dialog" + aria-modal, focus moves into the overlay on open and is restored on close, and Tab is trapped within the dialog (shared utils/useFocusTrap).
  • Tabs: full ARIA (tablist/tab/tabpanel, aria-selected, aria-controls, roving tabindex) + Arrow/Home/End keyboard navigation.
  • Dropdown & Popover triggers: plain-text triggers become an accessible, keyboard-operable button (role/tabIndex/aria-expanded/aria-haspopup); element-child triggers stay plain wrappers to avoid nesting interactive semantics (keeps docs/tests valid).
  • Tooltip: role="tooltip", aria-describedby association, shows on focus, clears the pending timer on unmount.
  • Toast: aria-live region with role=alert for errors / status otherwise.
  • IconButton: keeps outline-none but adds a focus-visible ring.

Testing

  • bun run check:all passes: 272 tests, lint clean, tsc + build clean.
  • New/updated component tests for every behavior above.

Notes

  • Medium/low findings from the review are intentionally out of scope here and can be a follow-up.

The CLI emitted component code whose imports it never installed:

- Missing registryDependencies: button->spinner, modal->backdrop+iconbutton,
  drawer->backdrop, sidebar->tooltip, statscard->divider.
- add only copied utils/cn.ts, but Modal/Drawer/ImageExpander also import
  utils/scrollLock. Now copies every non-test file under src/dashkit/utils in
  both add and init.
- program.parse() -> parseAsync() so async action handlers are awaited.

Adds a static registry test asserting every cross-component relative import is
covered by registryDependencies, plus e2e CLI tests for compilable output.
- Sidebar discarded the setIsOpen returned by useSidebarState and passed a
  no-op, so calling setIsOpen from useSidebar() silently did nothing. Wire the
  real setter through and memoize the context value.
- AccordionItem accepted a disabled prop but only painted a CSS class; the
  trigger still toggled on click. Plumb disabled through the item context and
  make AccordionTrigger set the disabled/aria-disabled attributes, guard the
  click handler, and expose aria-expanded.

Adds tests for both behaviors.
- Modal & Drawer: role="dialog" + aria-modal, move focus into the overlay on
  open and restore it on close, and trap Tab within the dialog (shared
  utils/useFocusTrap).
- Tabs: full ARIA (tablist/tab/tabpanel, aria-selected, aria-controls,
  roving tabindex) plus Arrow/Home/End keyboard navigation.
- Dropdown & Popover triggers: promote plain-text triggers to an accessible,
  keyboard-operable button (role/tabIndex/aria-expanded) while leaving
  element-child triggers as plain wrappers to avoid nesting interactive
  semantics.
- Tooltip: role="tooltip", aria-describedby association, show on focus, and
  clear the pending timer on unmount.
- Toast: aria-live region with role=alert for errors / status otherwise.
- IconButton: keep outline-none but add a focus-visible ring.

Adds/updates component tests for each.
@netlify

netlify Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for dashkit ready!

Name Link
🔨 Latest commit 04aa97c
🔍 Latest deploy log https://app.netlify.com/projects/dashkit/deploys/6ae029e113026c512951a873
😎 Deploy Preview https://deploy-preview-7--dashkit.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@carllosnc
carllosnc merged commit 5f5f843 into master Oct 27, 2026
5 checks passed
@carllosnc
carllosnc deleted the fix/review-criticals branch October 27, 2026 05:13
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