@design-ai/cli 4.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +164 -0
- package/AGENTS.ko.md +126 -0
- package/AGENTS.md +182 -0
- package/CHANGELOG.md +6883 -0
- package/CLAUDE.md +39 -0
- package/LICENSE +21 -0
- package/README.ko.md +245 -0
- package/README.md +277 -0
- package/agents/README.md +14 -0
- package/agents/a11y-reviewer.md +121 -0
- package/agents/component-architect.md +57 -0
- package/agents/design-critic.md +46 -0
- package/agents/token-extractor.md +63 -0
- package/cli/bin/design-ai-mcp.mjs +6 -0
- package/cli/bin/design-ai.mjs +40 -0
- package/cli/commands/audit.mjs +111 -0
- package/cli/commands/check.mjs +226 -0
- package/cli/commands/doctor.mjs +141 -0
- package/cli/commands/examples.mjs +58 -0
- package/cli/commands/help.mjs +271 -0
- package/cli/commands/install.mjs +161 -0
- package/cli/commands/learn.mjs +1871 -0
- package/cli/commands/list.mjs +143 -0
- package/cli/commands/mcp.mjs +27 -0
- package/cli/commands/pack.mjs +211 -0
- package/cli/commands/prompt.mjs +199 -0
- package/cli/commands/route.mjs +247 -0
- package/cli/commands/search.mjs +60 -0
- package/cli/commands/show.mjs +52 -0
- package/cli/commands/site.mjs +558 -0
- package/cli/commands/status.mjs +161 -0
- package/cli/commands/uninstall.mjs +119 -0
- package/cli/commands/update.mjs +184 -0
- package/cli/commands/version.mjs +94 -0
- package/cli/commands/workspace.mjs +176 -0
- package/cli/lib/brief.mjs +52 -0
- package/cli/lib/check.mjs +642 -0
- package/cli/lib/dispatch.mjs +109 -0
- package/cli/lib/doctor.mjs +505 -0
- package/cli/lib/examples.mjs +258 -0
- package/cli/lib/exec.mjs +63 -0
- package/cli/lib/help-flags.mjs +5 -0
- package/cli/lib/learn.mjs +3694 -0
- package/cli/lib/log.mjs +47 -0
- package/cli/lib/mcp-server.mjs +426 -0
- package/cli/lib/output.mjs +101 -0
- package/cli/lib/pack.mjs +599 -0
- package/cli/lib/paths.mjs +63 -0
- package/cli/lib/prompt.mjs +603 -0
- package/cli/lib/route.mjs +740 -0
- package/cli/lib/search.mjs +158 -0
- package/cli/lib/show.mjs +161 -0
- package/cli/lib/signals.mjs +2337 -0
- package/cli/lib/site.mjs +6617 -0
- package/cli/lib/skill-proposals.mjs +2046 -0
- package/cli/lib/suggest.mjs +66 -0
- package/cli/lib/workspace.mjs +1056 -0
- package/commands/README.md +25 -0
- package/commands/component-spec.md +34 -0
- package/commands/conversational.md +44 -0
- package/commands/design-from-brief.md +141 -0
- package/commands/design-review.md +62 -0
- package/commands/document-from-brief.md +47 -0
- package/commands/extract-tokens.md +38 -0
- package/commands/game-ui.md +40 -0
- package/commands/illustration.md +37 -0
- package/commands/iterate.md +167 -0
- package/commands/motion-design.md +54 -0
- package/commands/palette-from-brand.md +50 -0
- package/commands/print.md +49 -0
- package/commands/slide-deck.md +46 -0
- package/commands/spatial.md +47 -0
- package/commands/stability-review.md +74 -0
- package/commands/video.md +42 -0
- package/commands/website-improvement.md +77 -0
- package/docs/AGENT-DEVELOPMENT.md +658 -0
- package/docs/AI-LEARNING.md +429 -0
- package/docs/AIDER-INTEGRATION.md +224 -0
- package/docs/ARCHITECTURE.ko.md +183 -0
- package/docs/ARCHITECTURE.md +105 -0
- package/docs/CODEX-INTEGRATION.md +311 -0
- package/docs/COMPANY-WEBSITE-DOGFOOD.ko.md +144 -0
- package/docs/COMPANY-WEBSITE-DOGFOOD.md +150 -0
- package/docs/COMPANY-WEBSITE-INTAKE-TEMPLATE.ko.md +153 -0
- package/docs/COMPANY-WEBSITE-INTAKE-TEMPLATE.md +154 -0
- package/docs/CONTRIBUTING.ko.md +203 -0
- package/docs/CONTRIBUTING.md +242 -0
- package/docs/CURSOR-INTEGRATION.md +220 -0
- package/docs/DISTRIBUTION.ko.md +248 -0
- package/docs/DISTRIBUTION.md +253 -0
- package/docs/DOGFOOD-FINDINGS.md +180 -0
- package/docs/DOGFOOD-V4-FINDINGS.md +139 -0
- package/docs/DOGFOOD-V4-MKDOCS-FINDINGS.md +233 -0
- package/docs/DOGFOOD-V4-NPM-FINDINGS.md +157 -0
- package/docs/DOGFOOD-V4-VSCODE-FINDINGS.md +135 -0
- package/docs/FIGMA-INTEGRATION.md +222 -0
- package/docs/MCP-INTEGRATION.md +243 -0
- package/docs/MIGRATION-v4.md +121 -0
- package/docs/PLUGIN-PACKAGING.md +240 -0
- package/docs/PRODUCT-READINESS.md +66 -0
- package/docs/QUICKSTART.ko.md +178 -0
- package/docs/QUICKSTART.md +179 -0
- package/docs/RELEASE-CHECKLIST.md +292 -0
- package/docs/ROADMAP.md +19495 -0
- package/docs/SESSION-LOG.md +940 -0
- package/docs/TOKEN-SYNC.md +237 -0
- package/docs/USING.ko.md +206 -0
- package/docs/USING.md +218 -0
- package/docs/WEBSITE-IMPROVEMENT.ko.md +75 -0
- package/docs/WEBSITE-IMPROVEMENT.md +89 -0
- package/docs/announcements/README.md +56 -0
- package/docs/announcements/dev-to-korea.md +206 -0
- package/docs/announcements/hashnode-post.ko.md +232 -0
- package/docs/announcements/okky-post.ko.md +158 -0
- package/docs/announcements/press-kit.md +101 -0
- package/docs/announcements/reddit-r-korea.md +196 -0
- package/docs/announcements/show-hn.md +114 -0
- package/docs/announcements/twitter-thread.md +255 -0
- package/docs/external-status.md +34 -0
- package/docs/integrations/aider-walkthrough.ko.md +275 -0
- package/docs/integrations/aider-walkthrough.md +274 -0
- package/docs/integrations/codex-walkthrough.ko.md +297 -0
- package/docs/integrations/codex-walkthrough.md +297 -0
- package/docs/integrations/cursor-walkthrough.ko.md +281 -0
- package/docs/integrations/cursor-walkthrough.md +284 -0
- package/docs/integrations/design-ai-mcp-server.md +169 -0
- package/docs/integrations/figma-mcp.md +149 -0
- package/docs/integrations/github-mcp.md +178 -0
- package/docs/integrations/linear-mcp.md +215 -0
- package/docs/integrations/notion-mcp.md +174 -0
- package/docs/integrations/sdk-walkthrough.ko.md +375 -0
- package/docs/integrations/sdk-walkthrough.md +375 -0
- package/docs/integrations/slack-mcp.md +208 -0
- package/docs/integrations/vscode-walkthrough.ko.md +202 -0
- package/docs/integrations/vscode-walkthrough.md +205 -0
- package/docs/requirements.txt +16 -0
- package/docs/site-overrides/extra.css +83 -0
- package/docs/site-overrides/favicon.svg +4 -0
- package/docs/site-overrides/logo.svg +10 -0
- package/docs/site-overrides/main.html +18 -0
- package/docs/website-console/app.js +2540 -0
- package/docs/website-console/index.html +24 -0
- package/docs/website-console/styles.css +975 -0
- package/examples/README.md +252 -0
- package/examples/cases/dogfood-v4-korean-hr-onboarding.md +356 -0
- package/examples/component-accordion-actions.md +153 -0
- package/examples/component-accordion-details.md +147 -0
- package/examples/component-accordion-summary.md +180 -0
- package/examples/component-accordion.md +229 -0
- package/examples/component-account-card.md +284 -0
- package/examples/component-address-input.md +260 -0
- package/examples/component-affix.md +190 -0
- package/examples/component-alert-dialog.md +210 -0
- package/examples/component-alert-title.md +77 -0
- package/examples/component-alert.md +192 -0
- package/examples/component-amount-input.md +278 -0
- package/examples/component-anchor.md +198 -0
- package/examples/component-app-bar.md +249 -0
- package/examples/component-aspect-ratio.md +156 -0
- package/examples/component-auto-complete.md +199 -0
- package/examples/component-avatar-group.md +170 -0
- package/examples/component-avatar.md +191 -0
- package/examples/component-back-top.md +123 -0
- package/examples/component-backdrop.md +148 -0
- package/examples/component-badge.md +181 -0
- package/examples/component-banner.md +237 -0
- package/examples/component-biometric-gate.md +281 -0
- package/examples/component-blockquote.md +153 -0
- package/examples/component-border-beam.md +207 -0
- package/examples/component-bottom-navigation.md +226 -0
- package/examples/component-box.md +112 -0
- package/examples/component-breadcrumb.md +222 -0
- package/examples/component-button-base.md +190 -0
- package/examples/component-button-group.md +117 -0
- package/examples/component-button.md +213 -0
- package/examples/component-calendar.md +280 -0
- package/examples/component-callout.md +131 -0
- package/examples/component-card-actions.md +101 -0
- package/examples/component-card-content.md +90 -0
- package/examples/component-card-header.md +122 -0
- package/examples/component-card-media.md +79 -0
- package/examples/component-card.md +233 -0
- package/examples/component-carousel.md +266 -0
- package/examples/component-cascader.md +135 -0
- package/examples/component-category-picker.md +271 -0
- package/examples/component-chart.md +237 -0
- package/examples/component-chat-interface.md +399 -0
- package/examples/component-checkbox.md +149 -0
- package/examples/component-click-away-listener.md +87 -0
- package/examples/component-code.md +213 -0
- package/examples/component-collapsible.md +219 -0
- package/examples/component-color-picker.md +110 -0
- package/examples/component-combobox.md +267 -0
- package/examples/component-command.md +299 -0
- package/examples/component-config-provider.md +190 -0
- package/examples/component-context-menu.md +179 -0
- package/examples/component-css-baseline.md +148 -0
- package/examples/component-date-picker.md +249 -0
- package/examples/component-descriptions.md +242 -0
- package/examples/component-dialog-actions.md +111 -0
- package/examples/component-dialog-content-text.md +76 -0
- package/examples/component-dialog-content.md +105 -0
- package/examples/component-dialog-title.md +104 -0
- package/examples/component-dialog.md +176 -0
- package/examples/component-divider.md +182 -0
- package/examples/component-doc-page.md +217 -0
- package/examples/component-drawer.md +257 -0
- package/examples/component-dropdown.md +220 -0
- package/examples/component-email-layout.md +253 -0
- package/examples/component-empty-state.md +269 -0
- package/examples/component-empty.md +172 -0
- package/examples/component-fade.md +87 -0
- package/examples/component-feature-grid.md +201 -0
- package/examples/component-field.md +266 -0
- package/examples/component-filled-input.md +114 -0
- package/examples/component-flex.md +117 -0
- package/examples/component-float-button.md +214 -0
- package/examples/component-form-control-label.md +134 -0
- package/examples/component-form-control.md +113 -0
- package/examples/component-form-controls.md +251 -0
- package/examples/component-form-group.md +86 -0
- package/examples/component-form-helper-text.md +95 -0
- package/examples/component-form-label.md +98 -0
- package/examples/component-form.md +291 -0
- package/examples/component-game-hud.md +362 -0
- package/examples/component-game-menu.md +327 -0
- package/examples/component-grid.md +140 -0
- package/examples/component-grow.md +79 -0
- package/examples/component-hero-block.md +252 -0
- package/examples/component-hover-card.md +211 -0
- package/examples/component-icon-button.md +142 -0
- package/examples/component-icon.md +102 -0
- package/examples/component-illustration.md +280 -0
- package/examples/component-image-list.md +107 -0
- package/examples/component-image.md +282 -0
- package/examples/component-input-adornment.md +101 -0
- package/examples/component-input-base.md +134 -0
- package/examples/component-input-number.md +141 -0
- package/examples/component-input-otp.md +271 -0
- package/examples/component-input.md +213 -0
- package/examples/component-item.md +243 -0
- package/examples/component-kbd.md +197 -0
- package/examples/component-krw-amount.md +219 -0
- package/examples/component-label.md +118 -0
- package/examples/component-layout.md +217 -0
- package/examples/component-link.md +223 -0
- package/examples/component-list-item-avatar.md +72 -0
- package/examples/component-list-item-button.md +139 -0
- package/examples/component-list-item-icon.md +82 -0
- package/examples/component-list-item-text.md +98 -0
- package/examples/component-list-item.md +116 -0
- package/examples/component-list-subheader.md +70 -0
- package/examples/component-list.md +198 -0
- package/examples/component-loading-button.md +125 -0
- package/examples/component-loading-sequence.md +254 -0
- package/examples/component-lottie-player.md +279 -0
- package/examples/component-masonry.md +191 -0
- package/examples/component-mentions.md +189 -0
- package/examples/component-menu-item.md +102 -0
- package/examples/component-menu-list.md +98 -0
- package/examples/component-menu.md +139 -0
- package/examples/component-menubar.md +259 -0
- package/examples/component-message.md +162 -0
- package/examples/component-mobile-stepper.md +155 -0
- package/examples/component-modal.md +220 -0
- package/examples/component-navigation-menu.md +295 -0
- package/examples/component-notification.md +166 -0
- package/examples/component-otp-countdown.md +245 -0
- package/examples/component-outlined-input.md +145 -0
- package/examples/component-page-transition.md +281 -0
- package/examples/component-pagination.md +226 -0
- package/examples/component-paper.md +199 -0
- package/examples/component-pass-auth.md +265 -0
- package/examples/component-payment-brand-button.md +253 -0
- package/examples/component-payment-method-selector.md +272 -0
- package/examples/component-payment-receipt.md +277 -0
- package/examples/component-popconfirm.md +144 -0
- package/examples/component-popover.md +239 -0
- package/examples/component-popper.md +129 -0
- package/examples/component-pricing-cards.md +247 -0
- package/examples/component-progress.md +195 -0
- package/examples/component-qr-code.md +201 -0
- package/examples/component-radio.md +167 -0
- package/examples/component-rate.md +202 -0
- package/examples/component-resizable.md +163 -0
- package/examples/component-result.md +270 -0
- package/examples/component-scroll-area.md +199 -0
- package/examples/component-scroll-reveal.md +320 -0
- package/examples/component-segmented.md +178 -0
- package/examples/component-select.md +258 -0
- package/examples/component-separator.md +177 -0
- package/examples/component-sheet.md +277 -0
- package/examples/component-sidebar.md +257 -0
- package/examples/component-skeleton.md +178 -0
- package/examples/component-slide.md +89 -0
- package/examples/component-slider.md +208 -0
- package/examples/component-snackbar-content.md +92 -0
- package/examples/component-snackbar.md +121 -0
- package/examples/component-sonner.md +165 -0
- package/examples/component-space.md +125 -0
- package/examples/component-spatial-locomotion.md +373 -0
- package/examples/component-spatial-panel.md +330 -0
- package/examples/component-speed-dial-action.md +78 -0
- package/examples/component-speed-dial.md +177 -0
- package/examples/component-spin.md +173 -0
- package/examples/component-spinner.md +204 -0
- package/examples/component-splitter.md +210 -0
- package/examples/component-stack.md +130 -0
- package/examples/component-statistic.md +282 -0
- package/examples/component-step-button.md +157 -0
- package/examples/component-step-connector.md +157 -0
- package/examples/component-step-content.md +121 -0
- package/examples/component-step-icon.md +115 -0
- package/examples/component-step-label.md +101 -0
- package/examples/component-step.md +84 -0
- package/examples/component-steps.md +264 -0
- package/examples/component-stock-chart.md +251 -0
- package/examples/component-swipeable-drawer.md +149 -0
- package/examples/component-switch.md +99 -0
- package/examples/component-tab-scroll-button.md +180 -0
- package/examples/component-tab.md +120 -0
- package/examples/component-table-body.md +82 -0
- package/examples/component-table-cell.md +118 -0
- package/examples/component-table-container.md +75 -0
- package/examples/component-table-footer.md +72 -0
- package/examples/component-table-head.md +78 -0
- package/examples/component-table-pagination.md +137 -0
- package/examples/component-table-row.md +113 -0
- package/examples/component-table-sort-label.md +109 -0
- package/examples/component-table.md +202 -0
- package/examples/component-tabs.md +184 -0
- package/examples/component-tag-badge.md +309 -0
- package/examples/component-tag.md +102 -0
- package/examples/component-testimonial-carousel.md +218 -0
- package/examples/component-textarea-autosize.md +114 -0
- package/examples/component-textarea.md +173 -0
- package/examples/component-time-picker.md +205 -0
- package/examples/component-timeline.md +170 -0
- package/examples/component-toast.md +224 -0
- package/examples/component-toggle-button.md +129 -0
- package/examples/component-toggle.md +220 -0
- package/examples/component-toolbar.md +104 -0
- package/examples/component-tooltip.md +178 -0
- package/examples/component-tour.md +176 -0
- package/examples/component-transaction-list-item.md +243 -0
- package/examples/component-transfer.md +156 -0
- package/examples/component-tree-select.md +202 -0
- package/examples/component-tree.md +297 -0
- package/examples/component-typography.md +215 -0
- package/examples/component-upload.md +295 -0
- package/examples/component-video-hero.md +409 -0
- package/examples/component-video-player.md +340 -0
- package/examples/component-voice-input.md +408 -0
- package/examples/component-watermark.md +217 -0
- package/examples/component-zoom.md +92 -0
- package/examples/doc-explanation-example.md +196 -0
- package/examples/doc-how-to-example.md +205 -0
- package/examples/doc-tutorial-example.md +162 -0
- package/examples/dogfood-korean-fintech-system.md +433 -0
- package/examples/email-transactional-example.md +259 -0
- package/examples/palette-saas-violet.md +235 -0
- package/examples/print-business-card-spec.md +205 -0
- package/examples/print-packaging-spec.md +285 -0
- package/examples/report-example.md +228 -0
- package/examples/slide-deck-example.md +237 -0
- package/examples/website-improvement-report.md +128 -0
- package/examples/website-improvement-workspace.json +126 -0
- package/install.sh +189 -0
- package/knowledge/COVERAGE.md +740 -0
- package/knowledge/PRINCIPLES.md +108 -0
- package/knowledge/a11y/contrast.md +70 -0
- package/knowledge/a11y/keyboard-and-focus.md +108 -0
- package/knowledge/colors/color-theory.md +90 -0
- package/knowledge/colors/mui-palette-structure.md +105 -0
- package/knowledge/colors/palettes-by-product-type.md +876 -0
- package/knowledge/components/INDEX.md +231 -0
- package/knowledge/components/index.json +1470 -0
- package/knowledge/components/shadcn-registry.md +159 -0
- package/knowledge/conversational/ai-chat-interfaces.md +323 -0
- package/knowledge/conversational/chatbot-design.md +312 -0
- package/knowledge/conversational/conversational-ui-fundamentals.md +299 -0
- package/knowledge/conversational/korean-voice-conventions.md +281 -0
- package/knowledge/conversational/voice-ui-patterns.md +297 -0
- package/knowledge/design-tokens/ant-design.md +124 -0
- package/knowledge/design-tokens/material-3.md +235 -0
- package/knowledge/design-tokens/polaris-and-carbon.md +231 -0
- package/knowledge/design-tokens/tailwind-v4.md +284 -0
- package/knowledge/game-ui/game-accessibility.md +317 -0
- package/knowledge/game-ui/game-ui-fundamentals.md +281 -0
- package/knowledge/game-ui/hud-design.md +324 -0
- package/knowledge/game-ui/korean-gaming-conventions.md +312 -0
- package/knowledge/game-ui/menu-systems.md +388 -0
- package/knowledge/i18n/korean-app-store-visual.md +223 -0
- package/knowledge/i18n/korean-document-style.md +301 -0
- package/knowledge/i18n/korean-payments.md +211 -0
- package/knowledge/i18n/korean-product-conventions.md +96 -0
- package/knowledge/i18n/korean-publishing.md +139 -0
- package/knowledge/i18n/korean-typography.md +123 -0
- package/knowledge/icons/curated-sets.md +225 -0
- package/knowledge/illustration/hero-illustrations.md +234 -0
- package/knowledge/illustration/illustration-systems.md +221 -0
- package/knowledge/illustration/mascot-design.md +208 -0
- package/knowledge/illustration/spot-illustrations.md +246 -0
- package/knowledge/illustration/svg-optimization.md +308 -0
- package/knowledge/layout/spacing-and-grid.md +119 -0
- package/knowledge/motion/app-loading-sequences.md +277 -0
- package/knowledge/motion/choreography-depth.md +297 -0
- package/knowledge/motion/marketing-motion.md +223 -0
- package/knowledge/motion/micro-interactions.md +266 -0
- package/knowledge/motion/motion-tools.md +281 -0
- package/knowledge/motion/principles.md +126 -0
- package/knowledge/patterns/auth-flow-design.md +316 -0
- package/knowledge/patterns/b2b-onboarding-flows.md +182 -0
- package/knowledge/patterns/brand-identity.md +238 -0
- package/knowledge/patterns/brand-references.md +97 -0
- package/knowledge/patterns/chart-color-encoding.md +269 -0
- package/knowledge/patterns/chart-types.md +344 -0
- package/knowledge/patterns/dashboard-composition.md +299 -0
- package/knowledge/patterns/design-system-qa.md +356 -0
- package/knowledge/patterns/document-typography.md +248 -0
- package/knowledge/patterns/email-design.md +338 -0
- package/knowledge/patterns/empty-states.md +263 -0
- package/knowledge/patterns/error-states.md +318 -0
- package/knowledge/patterns/form-design.md +237 -0
- package/knowledge/patterns/information-architecture.md +341 -0
- package/knowledge/patterns/landing-hero-design.md +283 -0
- package/knowledge/patterns/landing-page-patterns.md +681 -0
- package/knowledge/patterns/list-and-feed.md +371 -0
- package/knowledge/patterns/mobile-navigation.md +278 -0
- package/knowledge/patterns/money-and-amount.md +301 -0
- package/knowledge/patterns/onboarding.md +300 -0
- package/knowledge/patterns/pricing-page-design.md +261 -0
- package/knowledge/patterns/realtime-data.md +280 -0
- package/knowledge/patterns/report-design.md +330 -0
- package/knowledge/patterns/search-ux.md +373 -0
- package/knowledge/patterns/settings-page.md +325 -0
- package/knowledge/patterns/slide-deck-design.md +316 -0
- package/knowledge/patterns/styles-catalog.md +2599 -0
- package/knowledge/patterns/technical-writing.md +306 -0
- package/knowledge/patterns/ui-reasoning.md +1853 -0
- package/knowledge/patterns/ux-guidelines.md +1454 -0
- package/knowledge/platforms/react-native.md +395 -0
- package/knowledge/print/brochures-and-flyers.md +276 -0
- package/knowledge/print/korean-print-conventions.md +284 -0
- package/knowledge/print/packaging.md +321 -0
- package/knowledge/print/print-fundamentals.md +238 -0
- package/knowledge/print/signage-and-posters.md +235 -0
- package/knowledge/print/stationery.md +262 -0
- package/knowledge/spatial/ar-patterns.md +253 -0
- package/knowledge/spatial/comfort-and-accessibility.md +245 -0
- package/knowledge/spatial/spatial-design-fundamentals.md +346 -0
- package/knowledge/spatial/spatial-ui-elements.md +343 -0
- package/knowledge/spatial/vr-patterns.md +302 -0
- package/knowledge/typography/font-pairings.md +332 -0
- package/knowledge/typography/mui-type-scale.md +57 -0
- package/knowledge/typography/type-scale-fundamentals.md +105 -0
- package/knowledge/video/in-product-video.md +277 -0
- package/knowledge/video/korean-video-conventions.md +247 -0
- package/knowledge/video/marketing-video.md +258 -0
- package/knowledge/video/social-and-short-form.md +257 -0
- package/knowledge/video/video-fundamentals.md +296 -0
- package/package.json +106 -0
- package/skills/README.md +39 -0
- package/skills/color-palette/PLAYBOOK.md +175 -0
- package/skills/color-palette/SKILL.md +6 -0
- package/skills/color-palette/TEMPLATE.md +103 -0
- package/skills/component-spec-writer/PLAYBOOK.md +169 -0
- package/skills/component-spec-writer/SKILL.md +6 -0
- package/skills/component-spec-writer/TEMPLATE.md +115 -0
- package/skills/conversational-ui-designer/PLAYBOOK.md +231 -0
- package/skills/conversational-ui-designer/SKILL.md +6 -0
- package/skills/design-broadcast/PLAYBOOK.md +146 -0
- package/skills/design-broadcast/SKILL.md +6 -0
- package/skills/design-critique/PLAYBOOK.md +137 -0
- package/skills/design-critique/SKILL.md +6 -0
- package/skills/design-pr-review/PLAYBOOK.md +171 -0
- package/skills/design-pr-review/SKILL.md +6 -0
- package/skills/design-system-builder/PLAYBOOK.md +218 -0
- package/skills/design-system-builder/SKILL.md +6 -0
- package/skills/design-system-qa/PLAYBOOK.md +163 -0
- package/skills/design-system-qa/SKILL.md +6 -0
- package/skills/document-author/PLAYBOOK.md +167 -0
- package/skills/document-author/SKILL.md +6 -0
- package/skills/figma-token-sync/PLAYBOOK.md +149 -0
- package/skills/figma-token-sync/SKILL.md +6 -0
- package/skills/game-ui-designer/PLAYBOOK.md +209 -0
- package/skills/game-ui-designer/SKILL.md +6 -0
- package/skills/handoff-spec/PLAYBOOK.md +170 -0
- package/skills/handoff-spec/SKILL.md +6 -0
- package/skills/illustration-designer/PLAYBOOK.md +166 -0
- package/skills/illustration-designer/SKILL.md +6 -0
- package/skills/motion-designer/PLAYBOOK.md +223 -0
- package/skills/motion-designer/SKILL.md +6 -0
- package/skills/print-designer/PLAYBOOK.md +209 -0
- package/skills/print-designer/SKILL.md +6 -0
- package/skills/slide-deck-author/PLAYBOOK.md +198 -0
- package/skills/slide-deck-author/SKILL.md +6 -0
- package/skills/spatial-designer/PLAYBOOK.md +238 -0
- package/skills/spatial-designer/SKILL.md +6 -0
- package/skills/ux-audit/PLAYBOOK.md +142 -0
- package/skills/ux-audit/SKILL.md +6 -0
- package/skills/video-designer/PLAYBOOK.md +240 -0
- package/skills/video-designer/SKILL.md +6 -0
- package/skills/website-improvement/PLAYBOOK.md +118 -0
- package/skills/website-improvement/SKILL.md +6 -0
- package/skills/website-improvement/TEMPLATE.md +103 -0
- package/tools/audit/changelog-generate.py +176 -0
- package/tools/audit/check-coverage.py +483 -0
- package/tools/audit/doctor_assertions.py +256 -0
- package/tools/audit/example-qa.py +108 -0
- package/tools/audit/frontmatter-check.py +199 -0
- package/tools/audit/integration-check.py +95 -0
- package/tools/audit/korean-copy-check.py +161 -0
- package/tools/audit/link-check.py +146 -0
- package/tools/audit/local-ci.py +558 -0
- package/tools/audit/package-contents.py +723 -0
- package/tools/audit/package-smoke.py +22443 -0
- package/tools/audit/raw-hex-check.py +252 -0
- package/tools/audit/registry-smoke.py +8188 -0
- package/tools/audit/release-metadata.py +9832 -0
- package/tools/audit/run-all.py +351 -0
- package/tools/audit/smoke_assertions.py +12742 -0
- package/tools/audit/stability-review.py +332 -0
- package/tools/audit/stale-check.py +156 -0
- package/tools/migrations/add-version-frontmatter.py +132 -0
- package/tools/migrations/bump-last-updated.py +131 -0
- package/tools/migrations/promote-stability.py +172 -0
- package/tools/preview/README.md +58 -0
- package/tools/preview/render-tokens.py +454 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# `Transfer` (dual list) β spec
|
|
2
|
+
|
|
3
|
+
> Citing Ant Design `Transfer`, MUI (no built-in), shadcn-ui (no built-in)
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Two side-by-side lists with arrows to move items between them. Used for: permission editors (available roles β assigned roles), team assignment, tag selection (available tags β applied tags), feature flags (available features β enabled features).
|
|
8
|
+
|
|
9
|
+
## When Transfer vs alternatives
|
|
10
|
+
|
|
11
|
+
| Pattern | Use |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| **Transfer** | User explicitly moves items between TWO lists; both sides matter |
|
|
14
|
+
| **Multi-Select** | User picks from many; UI shows selected as tags only |
|
|
15
|
+
| **Checkbox list** | Simpler β just toggle each item |
|
|
16
|
+
| **Tree (with check)** | Hierarchical permissions; tree shape matters |
|
|
17
|
+
|
|
18
|
+
Transfer is a power-user pattern. Most consumer UIs should use Multi-Select instead.
|
|
19
|
+
|
|
20
|
+
## Anatomy
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
ββββββββββββββββββββ ββββββββββββββββββββ
|
|
24
|
+
β Available (12) β β Assigned (3) β
|
|
25
|
+
β β£ Search... β β β£ Search... β
|
|
26
|
+
ββββββββββββββββββββ€ ββββββββββββββββββββ€
|
|
27
|
+
β β Item A β [β ] β β Item D β
|
|
28
|
+
β β Item B β [ββ] β β Item E β
|
|
29
|
+
β β Item C β [β] [ββ] β β Item F β
|
|
30
|
+
β β Item D β β β
|
|
31
|
+
β ... β β β
|
|
32
|
+
ββββββββββββββββββββ ββββββββββββββββββββ
|
|
33
|
+
Select all (1) Remove all (0)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
| Slot | Required | Notes |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| Source list (left) | yes | Available items |
|
|
39
|
+
| Target list (right) | yes | Selected/assigned items |
|
|
40
|
+
| Movement arrows (center) | yes | Single + bulk move buttons |
|
|
41
|
+
| Search per side | optional | Filter within each list |
|
|
42
|
+
| Header per side | yes | Title + count + select-all |
|
|
43
|
+
| Item checkbox | yes | Multi-select before move |
|
|
44
|
+
|
|
45
|
+
## API
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
<Transfer
|
|
49
|
+
source={availableItems}
|
|
50
|
+
target={selectedItemKeys}
|
|
51
|
+
onChange={setSelectedItemKeys}
|
|
52
|
+
searchable
|
|
53
|
+
titles={["μ¬μ© κ°λ₯ν κΆν", "ν λΉλ κΆν"]}
|
|
54
|
+
itemRender={(item) => <PermissionItem item={item} />}
|
|
55
|
+
/>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
| Prop | Type | Default | Description |
|
|
59
|
+
| --- | --- | --- | --- |
|
|
60
|
+
| `source` | `Item[]` | β | All possible items |
|
|
61
|
+
| `target` | `string[]` | `[]` | Keys currently in the target side |
|
|
62
|
+
| `onChange` | `(targetKeys: string[]) => void` | β | |
|
|
63
|
+
| `titles` | `[string, string]` | `["Source", "Target"]` | Header labels per side |
|
|
64
|
+
| `searchable` | `boolean` | `false` | Search inputs |
|
|
65
|
+
| `itemRender` | `(item) => ReactNode` | default | Custom rendering |
|
|
66
|
+
| `disabled` | `boolean` | `false` | |
|
|
67
|
+
| `oneWay` | `boolean` | `false` | Items only move source β target (no return) |
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
type Item = {
|
|
71
|
+
key: string;
|
|
72
|
+
label: string;
|
|
73
|
+
description?: string;
|
|
74
|
+
disabled?: boolean;
|
|
75
|
+
data?: unknown;
|
|
76
|
+
};
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Behavior
|
|
80
|
+
|
|
81
|
+
### Movement
|
|
82
|
+
|
|
83
|
+
1. User checks items in source list.
|
|
84
|
+
2. Click `β` to move selected items to target.
|
|
85
|
+
3. Reverse with `β`.
|
|
86
|
+
4. Bulk: `ββ` (move all visible), `ββ` (return all).
|
|
87
|
+
|
|
88
|
+
### Search
|
|
89
|
+
|
|
90
|
+
Per-side search filters that side's visible items. Doesn't affect the other side. Combined search across both: typically not provided (different lists, different intent).
|
|
91
|
+
|
|
92
|
+
## States
|
|
93
|
+
|
|
94
|
+
| State | Visual |
|
|
95
|
+
| --- | --- |
|
|
96
|
+
| Default | Both lists rendered |
|
|
97
|
+
| Item checked (in source) | Move-right arrow enabled |
|
|
98
|
+
| Item checked (in target) | Move-left arrow enabled |
|
|
99
|
+
| Empty source side | "λͺ¨λ νλͺ©μ΄ ν λΉλμμ΅λλ€" |
|
|
100
|
+
| Empty target side | "ν λΉλ νλͺ©μ΄ μμ΅λλ€" |
|
|
101
|
+
| Disabled | Both lists muted |
|
|
102
|
+
|
|
103
|
+
## Accessibility
|
|
104
|
+
|
|
105
|
+
- Each side: `<section>` with `<h3>` heading.
|
|
106
|
+
- Lists: `role="listbox" aria-multiselectable="true"`.
|
|
107
|
+
- Items: `role="option"`, `aria-selected="true|false"`.
|
|
108
|
+
- Movement buttons: `<button>` with `aria-label`.
|
|
109
|
+
|
|
110
|
+
### Keyboard
|
|
111
|
+
|
|
112
|
+
| Key | Behavior |
|
|
113
|
+
| --- | --- |
|
|
114
|
+
| `Tab` | Reach search β list β arrows β other list (in order) |
|
|
115
|
+
| `β` / `β` | Move within list |
|
|
116
|
+
| `Space` | Toggle item selected |
|
|
117
|
+
| `Enter` (on arrow) | Apply movement |
|
|
118
|
+
|
|
119
|
+
## Mobile pattern
|
|
120
|
+
|
|
121
|
+
Transfer's two-side layout doesn't fit mobile. Switch to:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
[Single tab list with toggles]
|
|
125
|
+
"Available" tab "Assigned" tab
|
|
126
|
+
Item A [β Add] Item D [β]
|
|
127
|
+
Item B [β Add] Item E [β]
|
|
128
|
+
Item C [β Added] Item F [β]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Or a simpler "tap to toggle" pattern:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
β Item A (tap to add)
|
|
135
|
+
β Item B
|
|
136
|
+
β Item D (tap to remove)
|
|
137
|
+
β Item E
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Don't
|
|
141
|
+
|
|
142
|
+
- Don't use Transfer for < 10 items. Use Checkbox list β simpler.
|
|
143
|
+
- Don't use for non-symmetric "both sides matter" cases. If user only cares about one side, use Multi-Select.
|
|
144
|
+
- Don't omit per-side counts β users want to know how many they've selected.
|
|
145
|
+
- Don't disable items in source after moving β make it clear they're already in target by hiding or disabling consistently.
|
|
146
|
+
|
|
147
|
+
## References
|
|
148
|
+
|
|
149
|
+
- Ant Design: [`refs/ant-design/components/transfer/`](../refs/ant-design/components/transfer/) β `Transfer`. Most exhaustive; supports tree-like (`Transfer.TableTransfer`).
|
|
150
|
+
- MUI / shadcn-ui: no built-in.
|
|
151
|
+
|
|
152
|
+
## Cross-reference
|
|
153
|
+
|
|
154
|
+
- [`examples/component-form-controls.md`](component-form-controls.md) β Checkbox list alternative
|
|
155
|
+
- [`examples/component-select.md`](component-select.md) β Multi-Select alternative
|
|
156
|
+
- [`examples/component-tree.md`](component-tree.md) β for hierarchical permission pickers
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# `TreeSelect` β spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from Ant Design `TreeSelect`. A select-style dropdown that opens a tree view for hierarchical selection. Distinct from `Cascader` (level-by-level columns) and `Tree` (full-page).
|
|
4
|
+
|
|
5
|
+
## TreeSelect vs Cascader vs Tree
|
|
6
|
+
|
|
7
|
+
| | TreeSelect | Cascader | Tree |
|
|
8
|
+
| --- | --- | --- | --- |
|
|
9
|
+
| Trigger | Single dropdown | Single dropdown with column drilldown | Full-page or panel |
|
|
10
|
+
| Hierarchy | Whole tree visible (collapsible) | Level-at-a-time | Whole tree visible |
|
|
11
|
+
| Multi-select | Yes | Variable | Yes |
|
|
12
|
+
| Search | Yes | Yes | Yes |
|
|
13
|
+
| Use | Department / category picker (deep tree) | Region / address (consistent depth) | File browser / hierarchy management |
|
|
14
|
+
|
|
15
|
+
## Anatomy
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
[ Engineering / Frontend βΎ ] β trigger field with selected path
|
|
19
|
+
|
|
20
|
+
β open
|
|
21
|
+
ββββββββββββββββββββββββ
|
|
22
|
+
β β Search... β
|
|
23
|
+
β βββββββββββββββ β
|
|
24
|
+
β βΆ Engineering β
|
|
25
|
+
β βΌ Frontend β
|
|
26
|
+
β β React (selected) β
|
|
27
|
+
β β Vue β
|
|
28
|
+
β β Svelte β
|
|
29
|
+
β βΆ Backend β
|
|
30
|
+
β βΆ Design β
|
|
31
|
+
β βΆ Marketing β
|
|
32
|
+
ββββββββββββββββββββββββ
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## API
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
<TreeSelect
|
|
39
|
+
value={selectedKey}
|
|
40
|
+
onChange={setSelectedKey}
|
|
41
|
+
treeData={[
|
|
42
|
+
{
|
|
43
|
+
title: "Engineering",
|
|
44
|
+
key: "eng",
|
|
45
|
+
children: [
|
|
46
|
+
{
|
|
47
|
+
title: "Frontend",
|
|
48
|
+
key: "fe",
|
|
49
|
+
children: [
|
|
50
|
+
{ title: "React", key: "react" },
|
|
51
|
+
{ title: "Vue", key: "vue" },
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
{ title: "Backend", key: "be" },
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
{ title: "Design", key: "design" },
|
|
58
|
+
]}
|
|
59
|
+
treeDefaultExpandAll
|
|
60
|
+
showSearch
|
|
61
|
+
placeholder="λΆμ μ ν"
|
|
62
|
+
/>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
| Prop | Type | Default | Description |
|
|
66
|
+
| --- | --- | --- | --- |
|
|
67
|
+
| `value` | `string \| string[]` | controlled | Selected key(s) |
|
|
68
|
+
| `onChange` | `(value) => void` | β | Callback |
|
|
69
|
+
| `treeData` | `TreeNode[]` | β | Hierarchy |
|
|
70
|
+
| `multiple` | `boolean` | `false` | Multi-select |
|
|
71
|
+
| `treeCheckable` | `boolean` | `false` | Show checkbox per node (multi-select with parent β children sync) |
|
|
72
|
+
| `showSearch` | `boolean` | `false` | Filter input |
|
|
73
|
+
| `treeDefaultExpandAll` | `boolean` | `false` | Expand all on mount |
|
|
74
|
+
| `treeDefaultExpandedKeys` | `string[]` | `[]` | Initial expanded |
|
|
75
|
+
| `placeholder` | `string` | β | When no selection |
|
|
76
|
+
| `disabled` | `boolean` | `false` | β |
|
|
77
|
+
|
|
78
|
+
## Variants
|
|
79
|
+
|
|
80
|
+
### Single-select
|
|
81
|
+
|
|
82
|
+
One value, single click. No checkboxes.
|
|
83
|
+
|
|
84
|
+
### Multi-select with checkboxes (`treeCheckable`)
|
|
85
|
+
|
|
86
|
+
Click parent β all children checked.
|
|
87
|
+
Half-checked when some children selected.
|
|
88
|
+
Selected items shown as chips in trigger.
|
|
89
|
+
|
|
90
|
+
### Search
|
|
91
|
+
|
|
92
|
+
Type filters tree to matching nodes (and their ancestors so the path is visible).
|
|
93
|
+
|
|
94
|
+
## States
|
|
95
|
+
|
|
96
|
+
Same family as Combobox + Tree:
|
|
97
|
+
- Trigger states (default, focus, error, disabled).
|
|
98
|
+
- Open / closed.
|
|
99
|
+
- Hover / selected nodes.
|
|
100
|
+
- Expanded / collapsed branches.
|
|
101
|
+
|
|
102
|
+
## Tokens consumed
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
--tree-select-bg (panel)
|
|
106
|
+
--tree-select-bg-hover
|
|
107
|
+
--tree-select-bg-selected
|
|
108
|
+
--tree-select-checkbox-bg (multi-select)
|
|
109
|
+
--tree-select-line (tree connector lines, optional)
|
|
110
|
+
--tree-select-search-bg (filter input)
|
|
111
|
+
--space-xs, --space-sm
|
|
112
|
+
--font-size-sm
|
|
113
|
+
--motion-fast
|
|
114
|
+
--z-overlay
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Accessibility
|
|
118
|
+
|
|
119
|
+
- Trigger: `<button role="combobox" aria-haspopup="tree" aria-expanded>`.
|
|
120
|
+
- Tree: `role="tree"` with `<li role="treeitem" aria-expanded="true|false" aria-selected>` items.
|
|
121
|
+
- Keyboard:
|
|
122
|
+
- Tab into trigger; Enter opens.
|
|
123
|
+
- Arrow keys navigate within tree (Down/Up moves to next/prev visible node; Right expands; Left collapses).
|
|
124
|
+
- Enter selects.
|
|
125
|
+
- Esc closes.
|
|
126
|
+
- For multi-select with checkboxes: each checkbox is independent focusable.
|
|
127
|
+
- Touch target β₯ 36pt per node.
|
|
128
|
+
|
|
129
|
+
## Code example β KR organizational tree
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
function DepartmentSelect() {
|
|
133
|
+
return (
|
|
134
|
+
<Field>
|
|
135
|
+
<Label>λΆμ</Label>
|
|
136
|
+
<TreeSelect
|
|
137
|
+
value={department}
|
|
138
|
+
onChange={setDepartment}
|
|
139
|
+
showSearch
|
|
140
|
+
placeholder="λΆμλ₯Ό μ νν΄ μ£ΌμΈμ"
|
|
141
|
+
treeData={[
|
|
142
|
+
{
|
|
143
|
+
title: "μμ§λμ΄λ§",
|
|
144
|
+
key: "eng",
|
|
145
|
+
children: [
|
|
146
|
+
{ title: "νλ‘ νΈμλ", key: "fe" },
|
|
147
|
+
{ title: "λ°±μλ", key: "be" },
|
|
148
|
+
{ title: "λ°μ΄ν°", key: "data" },
|
|
149
|
+
{ title: "λ°λΈμ΅μ€", key: "ops" },
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
title: "λμμΈ",
|
|
154
|
+
key: "design",
|
|
155
|
+
children: [
|
|
156
|
+
{ title: "νλ‘λνΈ", key: "product-design" },
|
|
157
|
+
{ title: "λΈλλ", key: "brand" },
|
|
158
|
+
{ title: "리μμΉ", key: "research" },
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
title: "λ§μΌν
",
|
|
163
|
+
key: "marketing",
|
|
164
|
+
children: [
|
|
165
|
+
{ title: "κ·Έλ‘μ€", key: "growth" },
|
|
166
|
+
{ title: "μ½ν
μΈ ", key: "content" },
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
]}
|
|
170
|
+
/>
|
|
171
|
+
</Field>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Edge cases
|
|
177
|
+
|
|
178
|
+
- **Very deep tree (5+ levels)**: visual gets cramped. Consider Cascader instead.
|
|
179
|
+
- **Very wide tree at one level (50+ siblings)**: virtualize the visible nodes.
|
|
180
|
+
- **Async tree data**: load children on expand. Show loading state per node.
|
|
181
|
+
- **Search filters deeply**: ensure path-to-match is highlighted; expand intermediate ancestors.
|
|
182
|
+
- **Multi-select with checkbox + parent-child sync**: clicking parent checks all descendants. Half-check parent when some descendants checked.
|
|
183
|
+
- **Reduced motion**: skip expand/collapse animation.
|
|
184
|
+
|
|
185
|
+
## Don't
|
|
186
|
+
|
|
187
|
+
- Don't use TreeSelect when Cascader is appropriate (consistent depth, e.g., region selection).
|
|
188
|
+
- Don't show 1000+ flat nodes β that's a Combobox + virtualization.
|
|
189
|
+
- Don't auto-collapse user's manual expansions on re-open. Persist state.
|
|
190
|
+
- Don't omit search for trees > 20 nodes.
|
|
191
|
+
|
|
192
|
+
## References
|
|
193
|
+
|
|
194
|
+
- Ant: [`TreeSelect`](../refs/ant-design/components/tree-select)
|
|
195
|
+
- WAI-ARIA: [Tree pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/)
|
|
196
|
+
|
|
197
|
+
## Cross-reference
|
|
198
|
+
|
|
199
|
+
- [`examples/component-tree.md`](component-tree.md) β full-page tree
|
|
200
|
+
- [`examples/component-cascader.md`](component-cascader.md) β column-by-column
|
|
201
|
+
- [`examples/component-combobox.md`](component-combobox.md) β flat selectable
|
|
202
|
+
- [`examples/component-select.md`](component-select.md) β flat selectable variant
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# `Tree` (TreeView) β spec
|
|
2
|
+
|
|
3
|
+
> Citing Ant Design `Tree`, MUI `TreeView` (X package), shadcn-ui (no built-in)
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Hierarchical data with expandable nodes. Used for: file explorers, organization charts, category trees, taxonomy editors, navigation sidebars with nested sections.
|
|
8
|
+
|
|
9
|
+
## When Tree vs alternatives
|
|
10
|
+
|
|
11
|
+
| Pattern | Use |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| **Tree** | True parent-child hierarchy with arbitrary depth |
|
|
14
|
+
| **Accordion** | Two-level grouping where the inner items are flat |
|
|
15
|
+
| **Cascader / multi-level select** | Picking ONE leaf from a hierarchy |
|
|
16
|
+
| **Nested list** | Display-only hierarchy, no expand/collapse |
|
|
17
|
+
| **Sidebar nav** | Fixed structure (β€ 2 levels usually) |
|
|
18
|
+
|
|
19
|
+
Use Tree when nodes can be expanded/collapsed, possibly selected, possibly draggable.
|
|
20
|
+
|
|
21
|
+
## Anatomy
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
βΎ π Root
|
|
25
|
+
βΎ π Folder 1
|
|
26
|
+
π file-a.tsx
|
|
27
|
+
π file-b.tsx
|
|
28
|
+
βΈ π Folder 2
|
|
29
|
+
βΈ π Folder 3
|
|
30
|
+
βΈ π Archived
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
| Slot | Required | Notes |
|
|
34
|
+
| --- | --- | --- |
|
|
35
|
+
| Expand toggle | yes | Chevron `βΈ` / `βΎ` (rotates on expand) |
|
|
36
|
+
| Icon | optional | Folder / file / custom |
|
|
37
|
+
| Label | yes | Node display name |
|
|
38
|
+
| Trailing meta | optional | Count, badge, actions on hover |
|
|
39
|
+
| Indent | yes | Per depth level (typically 16β20px) |
|
|
40
|
+
|
|
41
|
+
## API
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
<Tree
|
|
45
|
+
data={treeData}
|
|
46
|
+
selectedKeys={selected}
|
|
47
|
+
onSelect={setSelected}
|
|
48
|
+
expandedKeys={expanded}
|
|
49
|
+
onExpand={setExpanded}
|
|
50
|
+
multiSelect={false}
|
|
51
|
+
draggable
|
|
52
|
+
/>
|
|
53
|
+
|
|
54
|
+
// where treeData is:
|
|
55
|
+
type TreeNode = {
|
|
56
|
+
key: string;
|
|
57
|
+
label: ReactNode;
|
|
58
|
+
icon?: ReactNode;
|
|
59
|
+
children?: TreeNode[];
|
|
60
|
+
disabled?: boolean;
|
|
61
|
+
isLeaf?: boolean; // override (children may exist but not visible β async load)
|
|
62
|
+
meta?: ReactNode;
|
|
63
|
+
};
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
| Prop | Type | Default | Description |
|
|
67
|
+
| --- | --- | --- | --- |
|
|
68
|
+
| `data` | `TreeNode[]` | β | Hierarchical data |
|
|
69
|
+
| `selectedKeys` | `string[]` | `[]` | Selected node keys |
|
|
70
|
+
| `onSelect` | `(keys, node) => void` | β | |
|
|
71
|
+
| `expandedKeys` | `string[]` | computed | Open nodes |
|
|
72
|
+
| `onExpand` | `(keys) => void` | β | |
|
|
73
|
+
| `defaultExpandedKeys` | `string[]` | `[]` | Initial open |
|
|
74
|
+
| `defaultExpandAll` | `boolean` | `false` | Expand everything on mount |
|
|
75
|
+
| `multiSelect` | `boolean` | `false` | Allow multiple selection (Ctrl/Shift modifiers) |
|
|
76
|
+
| `checkable` | `boolean` | `false` | Render checkboxes on each node |
|
|
77
|
+
| `checkedKeys` | `string[]` | `[]` | Checked items (with checkable) |
|
|
78
|
+
| `onCheck` | `(keys, info) => void` | β | |
|
|
79
|
+
| `searchable` | `boolean` | `false` | Render search input above; auto-expands matching paths |
|
|
80
|
+
| `searchValue` | `string` | β | Controlled search |
|
|
81
|
+
| `draggable` | `boolean` | `false` | Drag-and-drop reordering |
|
|
82
|
+
| `onDrop` | `(info) => void` | β | |
|
|
83
|
+
| `loadData` | `(node) => Promise<TreeNode[]>` | β | Async lazy-load children on expand |
|
|
84
|
+
| `density` | `"compact" \| "comfortable"` | `"comfortable"` | |
|
|
85
|
+
| `showLine` | `boolean` | `false` | Render guide lines connecting parent β children |
|
|
86
|
+
|
|
87
|
+
## Modes β selection vs check
|
|
88
|
+
|
|
89
|
+
| Mode | Use |
|
|
90
|
+
| --- | --- |
|
|
91
|
+
| **Selection** (`onSelect`) | Pick a single (or with multiSelect: multiple) node β file explorer "open this file" |
|
|
92
|
+
| **Check** (`checkable: true`) | Check sub-trees β permission editor "include these folders" |
|
|
93
|
+
|
|
94
|
+
You can combine β Tree with selectable nodes + checkboxes, but it's heavy. Pick one as primary.
|
|
95
|
+
|
|
96
|
+
### Check semantics
|
|
97
|
+
|
|
98
|
+
When `checkable`:
|
|
99
|
+
- Checking a parent checks all descendants.
|
|
100
|
+
- Unchecking a parent unchecks all descendants.
|
|
101
|
+
- Children with mixed states β parent shows **indeterminate** (β).
|
|
102
|
+
- "Strictly mode" (independent parent/child checks): set `checkStrictly={true}` for permission editors that need this.
|
|
103
|
+
|
|
104
|
+
## Behavior
|
|
105
|
+
|
|
106
|
+
### Expand / collapse
|
|
107
|
+
|
|
108
|
+
- Click chevron: toggle expand for that node.
|
|
109
|
+
- Click label: select (don't expand). Chevron handles expand.
|
|
110
|
+
- Some products: double-click label to expand. Convention.
|
|
111
|
+
|
|
112
|
+
### Single selection
|
|
113
|
+
|
|
114
|
+
- Click a node: select. Highlights row.
|
|
115
|
+
- Click again: deselect (or stays β depends on UX).
|
|
116
|
+
|
|
117
|
+
### Multi-selection
|
|
118
|
+
|
|
119
|
+
- `Ctrl+click` (or `Cmd`): toggle individual.
|
|
120
|
+
- `Shift+click`: select range from last selected to clicked.
|
|
121
|
+
- `Click` (no modifier): replace selection with single.
|
|
122
|
+
|
|
123
|
+
### Async lazy-load
|
|
124
|
+
|
|
125
|
+
When `loadData` is set, expanding a node fetches its children:
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
<Tree
|
|
129
|
+
data={treeData}
|
|
130
|
+
loadData={async (node) => {
|
|
131
|
+
const children = await api.fetchChildren(node.key);
|
|
132
|
+
return children;
|
|
133
|
+
}}
|
|
134
|
+
/>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Show spinner on the expanding node while fetching. Cache results β don't re-fetch on subsequent expands of the same node (unless explicitly invalidated).
|
|
138
|
+
|
|
139
|
+
### Search
|
|
140
|
+
|
|
141
|
+
Filter the tree by label. Auto-expand paths containing matches. Highlight matched substring.
|
|
142
|
+
|
|
143
|
+
When all matches in a subtree, that path is fully expanded. Other paths collapse.
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
search: "minji"
|
|
147
|
+
|
|
148
|
+
βΎ π Root
|
|
149
|
+
βΎ π Team
|
|
150
|
+
π€ κΉ**λ―Όμ§** (matched)
|
|
151
|
+
π Archived (collapsed β no matches inside)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## States β per node
|
|
155
|
+
|
|
156
|
+
| State | Visual |
|
|
157
|
+
| --- | --- |
|
|
158
|
+
| Default | Resting |
|
|
159
|
+
| Hover | Bg `--color-bg-subtle` |
|
|
160
|
+
| Selected | Bg `--color-primary-subtle-bg`, text `--color-primary-default` |
|
|
161
|
+
| Focus-visible | 2px ring on row |
|
|
162
|
+
| Loading (async) | Spinner replacing chevron |
|
|
163
|
+
| Disabled | Muted, no events |
|
|
164
|
+
| Drag-over (drop target) | Highlighted top/bottom border (insert above/below) or whole row (insert into) |
|
|
165
|
+
|
|
166
|
+
## Sizes / density
|
|
167
|
+
|
|
168
|
+
| Density | Row height | Indent per level |
|
|
169
|
+
| --- | --- | --- |
|
|
170
|
+
| `compact` | 24px | 16px |
|
|
171
|
+
| `comfortable` (default) | 32px | 20px |
|
|
172
|
+
|
|
173
|
+
For deep trees (10+ levels): `compact` is often the only readable choice. Render scrollable container.
|
|
174
|
+
|
|
175
|
+
## Tokens consumed
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
--color-bg-default
|
|
179
|
+
--color-bg-subtle (hover)
|
|
180
|
+
--color-primary-subtle-bg (selected)
|
|
181
|
+
--color-primary-default (selected text, indeterminate check)
|
|
182
|
+
--color-text-primary
|
|
183
|
+
--color-text-secondary (icon, secondary meta)
|
|
184
|
+
--color-text-tertiary (chevron when collapsed)
|
|
185
|
+
--color-border-default (drop indicator, guide lines)
|
|
186
|
+
--color-focus-ring
|
|
187
|
+
--space-xs, --space-sm
|
|
188
|
+
--font-size-sm, --font-size-base
|
|
189
|
+
--motion-fast (chevron rotate)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Accessibility β WAI-ARIA Tree pattern
|
|
193
|
+
|
|
194
|
+
This is one of the more complex a11y patterns. Use Radix/Headless or a battle-tested primitive.
|
|
195
|
+
|
|
196
|
+
### ARIA structure
|
|
197
|
+
|
|
198
|
+
- `role="tree"` on the container.
|
|
199
|
+
- Each node: `role="treeitem"`, `aria-expanded={true|false|undefined}` (undefined for leaves), `aria-level={n}`, `aria-setsize={count}`, `aria-posinset={index}`.
|
|
200
|
+
- Selected: `aria-selected="true"`.
|
|
201
|
+
- Children container: `role="group"`.
|
|
202
|
+
|
|
203
|
+
### Keyboard
|
|
204
|
+
|
|
205
|
+
| Key | Behavior |
|
|
206
|
+
| --- | --- |
|
|
207
|
+
| `Tab` | Reach the tree (single tab stop) |
|
|
208
|
+
| `β` / `β` | Move focus to next / previous visible node |
|
|
209
|
+
| `β` | Expand if collapsed; if expanded, move to first child |
|
|
210
|
+
| `β` | Collapse if expanded; if leaf, move to parent |
|
|
211
|
+
| `Home` / `End` | First / last visible node |
|
|
212
|
+
| `Enter` / `Space` | Select / toggle check |
|
|
213
|
+
| `*` (asterisk) | Expand all siblings of focused node |
|
|
214
|
+
| Type-ahead | Jump to first node starting with typed character |
|
|
215
|
+
|
|
216
|
+
This is **the** WAI-ARIA tree pattern. Don't reinvent. Implement exactly.
|
|
217
|
+
|
|
218
|
+
### Screen reader
|
|
219
|
+
|
|
220
|
+
Announce on movement:
|
|
221
|
+
- Position: "node 2 of 5"
|
|
222
|
+
- Level: "level 2"
|
|
223
|
+
- Expansion state: "expanded" / "collapsed"
|
|
224
|
+
- Selection: "selected"
|
|
225
|
+
|
|
226
|
+
## Code example
|
|
227
|
+
|
|
228
|
+
```tsx
|
|
229
|
+
// File explorer
|
|
230
|
+
<Tree
|
|
231
|
+
data={fileTree}
|
|
232
|
+
selectedKeys={openFile ? [openFile.key] : []}
|
|
233
|
+
onSelect={(keys, { node }) => setOpenFile(node.isLeaf ? node : null)}
|
|
234
|
+
defaultExpandedKeys={["root"]}
|
|
235
|
+
showLine
|
|
236
|
+
/>
|
|
237
|
+
|
|
238
|
+
// Permission editor with checkable
|
|
239
|
+
<Tree
|
|
240
|
+
data={permissionTree}
|
|
241
|
+
checkable
|
|
242
|
+
checkedKeys={selectedPermissions}
|
|
243
|
+
onCheck={setSelectedPermissions}
|
|
244
|
+
/>
|
|
245
|
+
|
|
246
|
+
// Async lazy-load
|
|
247
|
+
<Tree
|
|
248
|
+
data={initialTree}
|
|
249
|
+
loadData={async (node) => api.getChildren(node.key)}
|
|
250
|
+
/>
|
|
251
|
+
|
|
252
|
+
// Searchable team directory
|
|
253
|
+
<Tree
|
|
254
|
+
data={orgTree}
|
|
255
|
+
searchable
|
|
256
|
+
searchValue={query}
|
|
257
|
+
onSelect={(keys, { node }) => navigate(`/people/${node.key}`)}
|
|
258
|
+
/>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Edge cases
|
|
262
|
+
|
|
263
|
+
- **Very deep trees (20+ levels)**: indent overflow horizontally. Allow horizontal scroll OR use breadcrumbs at the top showing path.
|
|
264
|
+
- **Many siblings (1000+)**: virtualize. Standard Tree libraries (react-arborist, MUI X TreeView) support virtualization.
|
|
265
|
+
- **Async load fails**: show retry inline next to the node. Don't blow up the whole tree.
|
|
266
|
+
- **Loading parent that already has children**: re-fetch silently OR ignore (depends on whether children are stale).
|
|
267
|
+
- **Drag-and-drop**: provide visual cues (drop indicator), prevent dropping a node into its own descendant.
|
|
268
|
+
- **Mobile**: tree UIs are often broken on touch β small targets, no hover. Switch to a drill-in list pattern (each level is its own screen with breadcrumb).
|
|
269
|
+
- **Empty tree**: render an empty state (see [`empty-states.md`](../knowledge/patterns/empty-states.md)).
|
|
270
|
+
- **Korean tree labels**: usually short (3β10 chars per node). Hangul renders cleanly at compact density.
|
|
271
|
+
|
|
272
|
+
## Don't
|
|
273
|
+
|
|
274
|
+
- Don't render a tree with no expand/collapse if all data is always visible. Use a list.
|
|
275
|
+
- Don't use a tree for navigation if depth > 3. The user gets lost.
|
|
276
|
+
- Don't auto-expand-all on mount for large trees (perf + visual chaos).
|
|
277
|
+
- Don't combine selection + multiselect + check + drag in one tree without strong UX. Pick the modes.
|
|
278
|
+
- Don't forget keyboard nav. Tree without arrow keys is broken.
|
|
279
|
+
- Don't put long labels that wrap. Truncate with title attribute.
|
|
280
|
+
- Don't use trees on mobile without testing the drill-in alternative.
|
|
281
|
+
|
|
282
|
+
## References
|
|
283
|
+
|
|
284
|
+
- Ant Design: [`refs/ant-design/components/tree/`](../refs/ant-design/components/tree/) β `Tree` with `Tree.DirectoryTree` for file-style. Most exhaustive (drag-drop, async, search, virtual). Heavy.
|
|
285
|
+
- MUI: `@mui/x-tree-view` (separate package) β `RichTreeView` (declarative), `SimpleTreeView` (composition). Excellent a11y.
|
|
286
|
+
- shadcn-ui: no built-in. Compose from primitives + headless library (react-arborist or @aria-tree).
|
|
287
|
+
|
|
288
|
+
API choices made:
|
|
289
|
+
- **`data` driven prop** (not children composition): trees are usually data-driven from API; declarative API matches.
|
|
290
|
+
- **`selectedKeys` + `checkedKeys` separate**: select and check are different semantics (selection = "current pointer", check = "included in operation").
|
|
291
|
+
- **`loadData` for async**: matches Ant's convention; explicit promise return is clearer than callbacks.
|
|
292
|
+
|
|
293
|
+
## Cross-reference
|
|
294
|
+
|
|
295
|
+
- [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md) β tree keyboard contract
|
|
296
|
+
- [`knowledge/patterns/list-and-feed.md`](../knowledge/patterns/list-and-feed.md) β when flat list is enough
|
|
297
|
+
- [WAI-ARIA Tree Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/)
|