Skip to content

feat(hub): reinterpret grouped dock entry category as in-group sub-category#130

Merged
antfu merged 3 commits into
mainfrom
feat/hub-grouped-dock-category
Jul 23, 2026
Merged

feat(hub): reinterpret grouped dock entry category as in-group sub-category#130
antfu merged 3 commits into
mainfrom
feat/hub-grouped-dock-category

Conversation

@antfubot

Copy link
Copy Markdown
Collaborator

Intent

Dock entries carry a category (their outer bucket on the dock bar) and an optional groupId (flat membership pointer that collapses an entry under a group's button). Downstream viewers (e.g. Vite DevTools) are adopting a refined rule where these two fields cooperate:

When a dock entry's groupId resolves to a registered group, its outer category bucket is the group's own category, and the entry's own category is reinterpreted as an in-group sub-category used to sub-divide/sort members inside the group's popover / sub-navigation.

No new field is introduced — the existing category is reinterpreted based on whether groupId resolves.

This PR makes the hub side consistent with that rule and documents it.

What changed

  • Docstrings (packages/hub/src/types/docks.ts) — document the dual role of category and groupId, the group's category as the shared outer bucket for the group button and all its members, and the default/orphan fallbacks. Keeps the "grouping is one level deep" invariant.
  • Client grouping (packages/hub/src/client/host.ts) — groupByCategory now buckets a member whose groupId resolves to a registered group under the group's category (falling back to 'default'); orphan members (unregistered group) keep their own category. Hub still does not render the group-collapse popover — this only fixes which outer bucket a grouped member lands in for standalone hub viewers.
  • Category order (packages/hub/src/constants.ts) — DEFAULT_CATEGORIES_ORDER now puts framework first (framework: -100), matching what Vite DevTools ships. It's now exported from the main, node, and client public entry points (in addition to ./constants) so downstream kits can import the single source of truth.
  • Tests — added coverage for grouped members (outer bucket = group's category), group-with-no-category (members → default), and orphan members (own category), plus category ordering (framework first).
  • Docsdocs/guide/hub.md grouping section now describes the dual role and fallback/orphan rules; docs/guide/client-context.md groupedEntries note clarified.
  • Updated tsnapi public-API snapshots for the new exports.

Fallback rules honored

  • Group with no category → members' outer bucket is 'default'.
  • Member with groupId but no category → its in-group sub-bucket is 'default'.
  • Orphan tolerance: groupId referencing an unregistered group → entry renders top-level using its own category.

Gates run: pnpm lint, pnpm vitest run (850 passed), pnpm typecheck, pnpm build — all green.

This PR was created with the help of an agent.

…tegory

Adopt the refined dock-grouping semantics downstream viewers are moving to:
when a dock entry's groupId resolves to a registered group, the group's own
category is the entry's outer dock-bar bucket, and the entry's own category is
reinterpreted as an in-group sub-category. Orphan entries (groupId with no
registered group) keep using their own category as the outer bucket.

- Document the dual role of category/groupId and the group's category on the
  types (DevframeDockEntryBase, DevframeViewGroup) plus the hub grouping docs.
- Make the client host's groupByCategory bucket grouped members under their
  group's category (default fallback), orphans under their own, so hub's own
  groupedEntries agrees with the refined semantics for standalone viewers.
- Reconcile DEFAULT_CATEGORIES_ORDER to put framework first (matching what
  Vite DevTools ships) and export it from the main, node and client public
  entry points so downstream kits can import the single source of truth.

Created with the help of an agent.
@netlify

netlify Bot commented Jul 23, 2026

Copy link
Copy Markdown

Deploy Preview for devfra ready!

Name Link
🔨 Latest commit b07b234
🔍 Latest deploy log https://app.netlify.com/projects/devfra/deploys/6a6181144d776c00085f6d61
😎 Deploy Preview https://deploy-preview-130--devfra.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

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

antfubot and others added 2 commits July 23, 2026 02:32
Extend the known dock category vocabulary with four more buckets and slot
them into DEFAULT_CATEGORIES_ORDER between the existing ones (intentional
weight gaps let kits interleave their own):

- ui (150) — components, design system, styling
- data (250) — state, storage, queries, database
- performance (350) — profiling, metrics, budgets
- docs (500) — documentation, references

Also list the full category vocabulary in the hub grouping docs. The
DevframeDockEntryCategory union still allows arbitrary strings via
`(string & {})`, so kits keep passing custom ids.

Created with the help of an agent.
@antfu
antfu merged commit 2e111eb into main Jul 23, 2026
11 of 12 checks passed
@antfu
antfu deleted the feat/hub-grouped-dock-category branch July 23, 2026 02:50
antfubot added a commit that referenced this pull request Jul 23, 2026
Implement the hub side of the shared-iframe soft-nav design: extend
DevframeViewIframe with navTarget + a subTabs anchor flag (and NavTarget /
FrameSubTabsConfig types), and ship a viewer-side frame-nav adapter
(attachFrameNavClient) that the client host auto-attaches to a subTabs
anchor iframe.

The adapter runs a versioned, origin-locked host<->iframe postMessage
handshake, materializes one client-only member dock per reported tab (via
the client docks.register from #129, keyed <frameId>:<tabId>), and drives a
bidirectional nav loop: selecting a member posts navigate; the app's
navigated report moves the dock highlight. An idempotent guard breaks the
echo, a declarative manifest snapshot reconciles add/update/remove
(clearing selection when the active tab vanishes), and a handshake timeout
degrades to no-shim (anchor stays a single plain iframe dock).

Grouping stays orthogonal to frameId and follows the #130 category rule.
Covered by client host + adapter tests; hub API snapshots updated.
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