Skip to content

feat(inspector): adopt @antfu/design and set up Storybook#178

Open
antfubot wants to merge 10 commits into
antfu:mainfrom
antfubot:eleven-mirrors-melt
Open

feat(inspector): adopt @antfu/design and set up Storybook#178
antfubot wants to merge 10 commits into
antfu:mainfrom
antfubot:eleven-mirrors-melt

Conversation

@antfubot

@antfubot antfubot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

What & why

Replaces the hand-maintained design layer with @antfu/design (now on v0.3.2) and replaces as many in-house components as possible with the design system's, so theming and components have a single source of truth. Some visual change is expected and accepted — that's the point.

Design layer

  • UnoCSS (src/uno.config.ts): presetAnthonyDesign() — drops the duplicated primary ramp, every semantic shortcut the preset provides (color-base, bg-*, border-*, btn-action*, badge-color-*, bg-glass, color-scale-*, op-*), and (as of 0.3.x) the in-house icon-catppuccin shortcut too. Only app-specific tokens remain (named z-* layers, color-deprecated, page-padding*). Fonts are left to presetWebFonts (the design preset has no opinion on typography as of 0.3.x — see below).
  • Styles: @antfu/design/styles.css, replacing the in-house Floating Vue overrides and base surface rules.

Component replacement

@antfu/design/components is registered as a Nuxt auto-import dir. Deleted in-house, replaced by the design system: option/CheckboxFormCheckbox, ui/DrawerOverlayDrawer, display/SafeImageDisplayAvatar, display/VersionDisplayVersion, display/NumberBadgeDisplayNumberBadge, ui/DonutDisplayDonut, the dark toggle → ActionIconButton (composed with our own isDark/toggleDark), MaintainerActionTypePillDisplayBadge. Rebased on design utils: FileSizeBadge, DateBadge, DurationBadge, EmptyStateFeedbackTip. Kept in-house deliberately: PackageName (deprecated/vulnerable coloring must inherit from context), SelectGroup (radio semantics + non-string values), Percentage (labeled segments).

Following the 0.2.2 → 0.3.2 breaking changes

  • ActionDarkToggle was removed entirely (the package now owns no dark-mode state/toggle — see its own recipes.md) → NavRight's three nav buttons move to ActionIconButton.
  • FormCheckbox dropped its "bare" mode (now always renders its own <label>) → restructured all 19 call sites: adjacent content moves into its default slot where there was a hand-written outer <label>; OptionItem gets :div="true" where it wrapped a bare checkbox with no adjacent content, to avoid invalid nested <label>s.
  • DisplayBadge dropped its size prop (sized off font-size now) → explicit text-xs added at the two MaintainerActionTypePill call sites.
  • bg-active was repurposed from generic hover feedback to a persisted selected/checked/open state (primary-tinted), with a new bg-hover taking over the old neutral-gray transient-hover meaning → reclassified ~115 in-house bg-active/hover:bg-active usages across 33 files (hover-only → bg-hover; genuine persisted state kept as bg-active; two decorative backgrounds → the new bg-ambient).
  • Also fixed a genuine font-fallback regression along the way: the design preset used to overwrite theme.fontFamily with a bare font name, dropping the base preset's generic fallback chain (serif flash on slow font load) — reported upstream and fixed there in 0.2.2 (presetAnthonyDesign now has no opinion on fonts at all).

Storybook

Setup per the @antfu/design recipe: theme-synced manager/preview, autodocs, co-located stories for app-specific components (ClusterBadge, Logo), and an Overview page generated from the stories on disk (scripts/gen-overview.mjs, pnpm docs:overview) so it never drifts. Generic primitives are documented by the design package's own Storybook.

Deps

@antfu/design, reka-ui, colorjs.io, storybook + @storybook/{vue3-vite,addon-docs}, @vitejs/plugin-vue via new catalog entries.

Verification

vue-tsc --noEmit, eslint, pnpm build (SPA prerender + libs), vitest run (87/87) and storybook build all pass — verified against the genuinely-installed pinned versions at each step, not just the design repo's source. Live-browser-verified: light/dark, every restructured FormCheckbox site (no new nested-<label>s, single-click toggles), the ActionIconButton nav (including the GitHub link, now a real <a href>), the maintainer-actions drawer, and the merged-in-from-main "Exclude Dev Dependencies" filter.

This PR was created with the help of an agent.

antfubot added 10 commits July 2, 2026 01:34
Replace the hand-maintained design layer with the @antfu/design UnoCSS
preset and shipped styles so theming is consistent and there is a single
source of truth for tokens, overlays and severity scales.

- uno.config: use presetAnthonyDesign(); drop the duplicated primary ramp
  and every semantic shortcut the preset now provides, keeping only the
  app-specific z-index layers and paddings.
- styles: import @antfu/design/styles.css and remove the in-house Floating
  Vue overrides and base surface rules it supersedes.
- swap the bespoke Donut for DisplayDonut and the dark-mode button for
  ActionDarkToggle (gaining the animated view-transition reveal).
- add a Storybook setup following the @antfu/design recipe: theme-synced
  manager/preview, autodocs, an Overview page and co-located stories for
  the presentational components.

Created with the help of an agent.
…alents

Register the @antfu/design components directory for Nuxt auto-import and
replace the in-house implementations wholesale, so generic primitives come
from the design system and only app-specific components remain:

- delete option/Checkbox → FormCheckbox (reka-ui) across all 19 call sites
- delete ui/Drawer → OverlayDrawer (title header, Esc/backdrop handled by
  reka-ui; app-level width override for the maintainer action drawer)
- delete display/SafeImage → DisplayAvatar (hash-tinted initials fallback)
  in author and funding entries
- delete display/Version and display/NumberBadge → the design DisplayVersion
  and DisplayNumberBadge take over the same auto-import tag names
- MaintainerActionTypePill pills → DisplayBadge
- rebase FileSizeBadge, DateBadge, DurationBadge and EmptyState on the design
  utils/components (formatBytes, getBytesColor, getAgeColor, DisplayDate,
  FeedbackTip), fixing a latent non-class fallback in FileSizeBadge
- drop stories for deleted components; Overview.mdx now points to the design
  package's own Storybook for the generic primitives

Also make the module-type test resolve packages from the test file itself
instead of the hoist-order-dependent root, pinning h3 as a tools devDep.

Created with the help of an agent.
Follow the @antfu/design Storybook recipe fully: the Overview page is now
produced by scripts/gen-overview.mjs (pnpm docs:overview) so it never drifts
from the stories, and the intentionally-shadowed DisplayPackageName is
excluded from the design components dir to silence the duplicate-name warning.

Created with the help of an agent.
presetAnthonyDesign merges its `fonts` values into the theme verbatim, so the
default bare "DM Sans"/"DM Mono" names replaced the full family stacks and the
page fell back to the browser default (serif) whenever the webfont wasn't
loaded. Pass complete stacks with generic fallbacks instead.

Created with the help of an agent.
Instead of hand-writing the font stacks in the design preset options, feed
presetAnthonyDesign the wind3 default fontFamily (imported, not hardcoded) so
its font merge is a no-op, and presetWebFonts — which downloads and serves the
fonts — prepends the brand families exactly like before the migration.

Created with the help of an agent.
Created with the help of an agent.
…round

0.2.2 fixes the exact issue reported upstream (antfu/design#17):
presetAnthonyDesign no longer touches theme.fontFamily/theme.font at all, so
it can't clobber the base preset's fallback chain. That removes the fonts
option entirely, which also removes the need for the wind3-passthrough
no-op workaround added to make the previous version's font merge harmless —
presetWebFonts is now unambiguously the only thing setting font-sans/
font-mono, composed onto presetWind3's own generic fallback, matching the
pre-migration stack exactly with no duplication.

Created with the help of an agent.
Merge origin/main (devframe v0.6/0.7, verkit replacing semver, dep bumps,
node-modules-inspector v2.2.0 release) into this branch.

- pnpm-workspace.yaml / package.json: keep this branch's additions
  (@antfu/design, storybook, reka-ui, colorjs.io, @vitejs/plugin-vue)
  alongside main's version bumps and its semver -> verkit swap.
- packages/node-modules-tools: the module-type "dual" test asserted on `h3`,
  which main's own dependency bump made ESM-only (no more `require` export
  condition) — swap the fixture to `tinyglobby` (still genuinely dual) and
  keep resolving it from the test file itself (not the hoist-order-dependent
  root) via a pinned devDependency.
- Fix two `defineModel` call sites (ExpendableContainer, PackageMultiSelectInput)
  that main's vue-tsc bump now infers as literal types instead of the
  widened primitive — add explicit type arguments.

Verified: vue-tsc --noEmit, eslint, vitest (87/87) and pnpm build all pass
against this state in isolation.

Created with the help of an agent.
0.2.2 -> 0.3.2 carries several breaking changes; adapt each call site rather
than pin back:

- ActionDarkToggle was removed entirely (the package now owns no dark-mode
  state or toggle component — see its recipes.md). NavRight's three nav
  buttons move to ActionIconButton (which gained href/to link-mode and
  font-size-driven sizing in this range), composed with our own
  isDark/toggleDark; losing the view-transition animation is accepted, this
  reverts to the pre-@antfu/design behavior.
- FormCheckbox dropped its "bare" mode — it now always renders its own
  <label>, where before a bare instance let the caller own the label. All 19
  call sites nested it inside our own <label> (directly, or via OptionItem's
  label-by-default root), which would now produce invalid nested <label>s and
  risk double-toggling. Fix per site: where FormCheckbox sat beside adjacent
  content in a hand-written <label>, move that content into its default slot
  and drop the outer <label>; where it sat bare inside OptionItem with no
  adjacent content, pass OptionItem `:div="true"` so it stops rendering its
  own <label>.
- DisplayBadge dropped its `size` prop (sized off font-size now, with no
  default) — MaintainerActionTypePill's two direct usages need an explicit
  text-xs to keep their prior size; DisplayNumberBadge (our ~17 indirect call
  sites) is unaffected, the package updated it internally to match.
- `bg-active` was repurposed from generic hover feedback to a *persisted*
  selected/checked/open state (now primary-tinted), with a new `bg-hover`
  taking over the old neutral-gray transient-hover meaning. Reclassify every
  in-house `bg-active`/`hover:bg-active` usage: ~115 genuine hover-only sites
  across 33 files rename to `bg-hover`; the few that mark real persisted
  state (selected list row, current breadcrumb/tab, keyboard-highlighted
  option, valid-badge highlight) keep `bg-active` — arguably more correct now;
  two decorative avatar/chip backgrounds move to the new `bg-ambient`.
- `icon-catppuccin` now ships from the preset itself (identical semantics,
  confirmed by diffing the generated CSS) — delete the in-house duplicate.
- Register the new DisplayIconifyRemoteIcon in the components-dir ignore list
  (needs the optional `dompurify` peer we don't use), alongside the existing
  LayoutSplitPane/LayoutVirtualList/DisplayPackageName exclusions.

Verified against the genuinely-pinned 0.3.2 (not just the design repo's
source): vue-tsc --noEmit, eslint, vitest (87/87), pnpm build and the
Storybook build all pass; live-clicked through every restructured
FormCheckbox site (no nested <label>s beyond the pre-existing, unrelated
SelectGroup-in-OptionItem pattern; single-click toggles correctly), the
GitHub link (now a real `<a href>`, unlike under the old ActionIconButton
shape), the dark toggle, and the maintainer-actions drawer (i-ph:x close
icon, correctly-sized PROD badge).

Created with the help of an agent.
Merge origin/main (antfu#181 exclude dev dependencies filter, antfu#182 e2e OTP fix,
another own-repo module-type test fix) into this branch.

- FiltersOptionExcludes.vue: the new "Exclude Dev Dependencies" OptionItem
  applies the same FormCheckbox treatment (`:div="true"` on OptionItem) as
  its siblings.
- module-type.test.ts: main independently hit and fixed the same h3-became-
  ESM-only issue (swapping the "dual" fixture to `vue`) — take their fixture
  choice for consistency with upstream, keep this branch's more robust
  deterministic (file-relative, not hoist-order-dependent) resolution. `vue`
  resolves consistently regardless of which installed patch gets hoisted
  (same dual exports shape across 3.5.x), so no pinned devDependency needed;
  drop the now-unused tinyglobby one.

Verified: vue-tsc --noEmit, eslint, vitest (87/87) and pnpm build all pass;
live-checked the new Exclude Dev Dependencies checkbox renders and is
positioned correctly.

Created with the help of an agent.
@pkg-pr-new

pkg-pr-new Bot commented Jul 21, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/node-modules-inspector@178
npm i https://pkg.pr.new/node-modules-tools@178

commit: a31ed46

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