@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,217 @@
|
|
|
1
|
+
# `DocPage` (full doc page layout) — spec
|
|
2
|
+
|
|
3
|
+
> The canonical layout for a single documentation page. Header + sidebar + body + right TOC + footer. Shipped by most doc-site frameworks (Docusaurus, Nextra, Mintlify, GitBook).
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Standard layout for documentation sites. Differs from product app `Layout` ([`component-layout.md`](component-layout.md)) — DocPage is optimized for reading prose.
|
|
8
|
+
|
|
9
|
+
## Anatomy
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌────────────────────────────────────────────────────────────────────┐
|
|
13
|
+
│ [Brand] [Search Cmd+K] [Versions] [GitHub] [Theme] │ ← top bar
|
|
14
|
+
├──────────────┬─────────────────────────────────────────┬───────────┤
|
|
15
|
+
│ │ Breadcrumb · Updated 2026-05-08 │ │
|
|
16
|
+
│ Sidebar nav │ │ TOC │
|
|
17
|
+
│ │ # Title │ │
|
|
18
|
+
│ ▸ Section A │ │ ▸ Anatomy │
|
|
19
|
+
│ ▸ Page 1 │ Lede paragraph (2 sentences). │ ▸ API │
|
|
20
|
+
│ ● Page 2 │ │ ▸ States │
|
|
21
|
+
│ ▸ Section B │ ## Anatomy │ ▸ Examples│
|
|
22
|
+
│ │ ... │ │
|
|
23
|
+
│ │ │ │
|
|
24
|
+
│ │ ## API │ │
|
|
25
|
+
│ │ ... │ │
|
|
26
|
+
│ │ │ │
|
|
27
|
+
│ │ ── Prev / Next ───────────────────────── │ │
|
|
28
|
+
│ │ "Edit this page on GitHub" │ │
|
|
29
|
+
└──────────────┴─────────────────────────────────────────┴───────────┘
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
| Region | Width | Sticky? |
|
|
33
|
+
| --- | --- | --- |
|
|
34
|
+
| Top bar | full | yes |
|
|
35
|
+
| Sidebar (left) | 240–280px | yes |
|
|
36
|
+
| Main body | 720–800px | no |
|
|
37
|
+
| TOC (right) | 200–240px | yes |
|
|
38
|
+
| Footer / prev-next | matches body | no |
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
<DocPage
|
|
44
|
+
meta={{
|
|
45
|
+
title: "Button",
|
|
46
|
+
description: "The most-used UI control.",
|
|
47
|
+
lastUpdated: "2026-05-08",
|
|
48
|
+
editUrl: "https://github.com/.../button.mdx",
|
|
49
|
+
}}
|
|
50
|
+
sidebar={navTree}
|
|
51
|
+
prevPage={{ title: "Avatar", href: "../avatar" }}
|
|
52
|
+
nextPage={{ title: "Card", href: "../card" }}
|
|
53
|
+
>
|
|
54
|
+
{/* MDX content */}
|
|
55
|
+
</DocPage>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
| Prop | Type | Default | Description |
|
|
59
|
+
| --- | --- | --- | --- |
|
|
60
|
+
| `meta` | `{ title, description?, lastUpdated?, editUrl? }` | — | Page metadata |
|
|
61
|
+
| `sidebar` | `NavNode[]` | — | Left nav tree |
|
|
62
|
+
| `tocItems` | `{ id, level, text }[]` | derived from headings | Right TOC |
|
|
63
|
+
| `prevPage` / `nextPage` | `{ title, href }` | — | Footer pagination |
|
|
64
|
+
| `breadcrumb` | `BreadcrumbNode[]` | derived from URL | |
|
|
65
|
+
| `children` | `ReactNode` | — | Page MDX content |
|
|
66
|
+
|
|
67
|
+
## Sidebar nav
|
|
68
|
+
|
|
69
|
+
The left column. Lists site sections + pages within. Cite [`knowledge/patterns/information-architecture.md`](../knowledge/patterns/information-architecture.md):
|
|
70
|
+
|
|
71
|
+
- Max 3 levels deep.
|
|
72
|
+
- Active page highlighted (filled bg, primary text color).
|
|
73
|
+
- Active section auto-expanded.
|
|
74
|
+
- Collapsible on mobile.
|
|
75
|
+
- Sticky on desktop.
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
const sidebar = [
|
|
79
|
+
{
|
|
80
|
+
title: "Getting started",
|
|
81
|
+
children: [
|
|
82
|
+
{ title: "Installation", href: "/install" },
|
|
83
|
+
{ title: "Quick start", href: "/quickstart" },
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
title: "Components",
|
|
88
|
+
children: [
|
|
89
|
+
{ title: "Button", href: "/components/button" },
|
|
90
|
+
{ title: "Card", href: "/components/card" },
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Right TOC (in-page)
|
|
97
|
+
|
|
98
|
+
Shows headings on the current page. Active section highlighted as user scrolls.
|
|
99
|
+
|
|
100
|
+
Cite [`examples/component-anchor.md`](component-anchor.md) — Anchor pattern. Default: show h2 + h3 only (h4+ creates noise).
|
|
101
|
+
|
|
102
|
+
## Body content
|
|
103
|
+
|
|
104
|
+
Cite [`knowledge/patterns/document-typography.md`](../knowledge/patterns/document-typography.md):
|
|
105
|
+
|
|
106
|
+
- Body 18px, line-height 1.6.
|
|
107
|
+
- Max-width ~720px.
|
|
108
|
+
- Headings with consistent vertical rhythm.
|
|
109
|
+
- Code blocks with copy button.
|
|
110
|
+
- Callouts where appropriate.
|
|
111
|
+
|
|
112
|
+
## Footer pagination
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
┌─────────────────────────────────────────────┐
|
|
116
|
+
│ ← Avatar Card → │
|
|
117
|
+
└─────────────────────────────────────────────┘
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Linear nav for sequential learners. Each link shows title; arrow direction indicates flow.
|
|
121
|
+
|
|
122
|
+
## "Edit on GitHub"
|
|
123
|
+
|
|
124
|
+
Link below the body or in a metadata strip. Open the source MDX for editing on GitHub.
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
<a href={meta.editUrl}>Edit this page on GitHub</a>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
For community contribution: this link is high-leverage.
|
|
131
|
+
|
|
132
|
+
## Search
|
|
133
|
+
|
|
134
|
+
Cmd+K → opens search overlay. See [`knowledge/patterns/search-ux.md`](../knowledge/patterns/search-ux.md).
|
|
135
|
+
|
|
136
|
+
For doc sites: integrate Algolia DocSearch (free for OSS), MeiliSearch, or Pagefind (no-server static search).
|
|
137
|
+
|
|
138
|
+
## Mobile patterns
|
|
139
|
+
|
|
140
|
+
Below `md` breakpoint:
|
|
141
|
+
- Sidebar collapses to drawer (`☰` opens).
|
|
142
|
+
- TOC hidden (replaced by floating "Sections" button OR inline at top of page).
|
|
143
|
+
- Body full-width minus margin.
|
|
144
|
+
|
|
145
|
+
## Theme toggle
|
|
146
|
+
|
|
147
|
+
Light / dark / system. Toggle in top-right.
|
|
148
|
+
|
|
149
|
+
For docs: dark mode is essential — many devs read docs at night, or prefer dark editors.
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
<ThemeToggle current={theme} onChange={setTheme} />
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Tokens consumed
|
|
156
|
+
|
|
157
|
+
Inherits from the broader design system. Doc-specific:
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
--color-bg-default
|
|
161
|
+
--color-bg-elevated (sidebar bg, slightly different from body)
|
|
162
|
+
--color-bg-subtle (hover states)
|
|
163
|
+
--color-text-primary, --color-text-secondary, --color-text-tertiary
|
|
164
|
+
--color-primary-default (active sidebar item)
|
|
165
|
+
--color-border-default (between regions)
|
|
166
|
+
--space-* full scale
|
|
167
|
+
--font-* full scale (body 18px)
|
|
168
|
+
--shadow-card (mobile drawer)
|
|
169
|
+
--motion-default
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Accessibility
|
|
173
|
+
|
|
174
|
+
- Top bar: `<header>` with `<nav aria-label="Site">`.
|
|
175
|
+
- Sidebar: `<aside>` or `<nav aria-label="Documentation">`.
|
|
176
|
+
- Body: `<main id="main-content">`.
|
|
177
|
+
- TOC: `<aside aria-label="On this page">`.
|
|
178
|
+
- Footer: `<footer>`.
|
|
179
|
+
- Skip link: "Skip to main content" before sidebar (keyboard users skip nav).
|
|
180
|
+
|
|
181
|
+
## Versioning UI
|
|
182
|
+
|
|
183
|
+
For docs with multiple versions:
|
|
184
|
+
- Version selector in top bar (dropdown).
|
|
185
|
+
- Banner on older-version pages: "You're viewing v1. The latest is v2 → [link]."
|
|
186
|
+
- 301 redirects from old URLs.
|
|
187
|
+
|
|
188
|
+
## Frameworks
|
|
189
|
+
|
|
190
|
+
| Framework | Best for |
|
|
191
|
+
| --- | --- |
|
|
192
|
+
| **Docusaurus** | OSS docs, MDX, well-maintained |
|
|
193
|
+
| **Nextra** | Next.js apps, MDX, modern |
|
|
194
|
+
| **Mintlify** | Hosted, paid, polished |
|
|
195
|
+
| **GitBook** | Hosted, non-engineer-friendly |
|
|
196
|
+
| **VitePress** | Vue ecosystem, fast |
|
|
197
|
+
| **Starlight** | Astro ecosystem |
|
|
198
|
+
|
|
199
|
+
For design-ai's docs: any of these works. Pick one.
|
|
200
|
+
|
|
201
|
+
## Don't
|
|
202
|
+
|
|
203
|
+
- Don't ship without search. Doc sites without search are unusable past 30 pages.
|
|
204
|
+
- Don't omit "Edit on GitHub" — drives community contributions.
|
|
205
|
+
- Don't break URLs on doc reorgs (301 redirect).
|
|
206
|
+
- Don't use full-width body for prose. Cap at ~720px.
|
|
207
|
+
- Don't omit dark mode.
|
|
208
|
+
- Don't have 4+ sidebar levels.
|
|
209
|
+
|
|
210
|
+
## Cross-reference
|
|
211
|
+
|
|
212
|
+
- [`knowledge/patterns/information-architecture.md`](../knowledge/patterns/information-architecture.md) — IA + nav
|
|
213
|
+
- [`knowledge/patterns/document-typography.md`](../knowledge/patterns/document-typography.md) — body text rules
|
|
214
|
+
- [`knowledge/patterns/search-ux.md`](../knowledge/patterns/search-ux.md) — search input
|
|
215
|
+
- [`examples/component-anchor.md`](component-anchor.md) — TOC pattern
|
|
216
|
+
- [`examples/component-breadcrumb.md`](component-breadcrumb.md) — breadcrumb
|
|
217
|
+
- [`examples/component-layout.md`](component-layout.md) — product app layout (different)
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# `Drawer` — spec
|
|
2
|
+
|
|
3
|
+
> Citing Ant Design `Drawer`, MUI `Drawer`, shadcn-ui `sheet` (which the Modal spec covers as Sheet variant)
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
A panel that slides in from a screen edge, covering part of the page. Used for navigation menus, edit panels, filters, and detail-without-leaving-context.
|
|
8
|
+
|
|
9
|
+
This is **different from Modal** — a modal centers and blocks; a drawer slides from an edge and can be dismissed by clicking outside or swiping.
|
|
10
|
+
|
|
11
|
+
In shadcn-ui, this primitive is called "Sheet" — see [`examples/component-modal.md`](component-modal.md) which treats Sheet as a variant of Modal. This spec covers the **navigation drawer** specifically: persistent or persistent-in-context navigation panels, distinct from one-shot edit sheets.
|
|
12
|
+
|
|
13
|
+
## When Drawer vs Modal vs Sheet
|
|
14
|
+
|
|
15
|
+
| Pattern | Use |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| **Drawer** (this spec) | Persistent or repeatedly-accessed navigation panel. Slides from screen edge. May be persistent (visible always above tablet width). |
|
|
18
|
+
| **Sheet / Modal** (see modal spec) | One-shot edit / form / decision. Slides in for one task, dismisses. |
|
|
19
|
+
| **Popover** | Small, attached to a trigger element. |
|
|
20
|
+
|
|
21
|
+
The line: a Drawer often holds the app's secondary navigation (sidebar). A Sheet holds a one-time interaction.
|
|
22
|
+
|
|
23
|
+
## Anatomy
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
┌─────────┬──────────────────────────────────────┐
|
|
27
|
+
│ Drawer │ │
|
|
28
|
+
│ │ │
|
|
29
|
+
│ ── │ Main content │
|
|
30
|
+
│ Nav 1 │ │
|
|
31
|
+
│ Nav 2 │ │
|
|
32
|
+
│ Nav 3 │ │
|
|
33
|
+
│ │ │
|
|
34
|
+
│ │ │
|
|
35
|
+
│ Footer │ │
|
|
36
|
+
└─────────┴──────────────────────────────────────┘
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
| Slot | Required | Notes |
|
|
40
|
+
| --- | --- | --- |
|
|
41
|
+
| Header | optional | Title + close button OR account info (in nav drawers) |
|
|
42
|
+
| Body | yes | Scrollable content (nav links, list, etc.) |
|
|
43
|
+
| Footer | optional | Pinned to bottom — settings, logout, version |
|
|
44
|
+
|
|
45
|
+
## API
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
<Drawer
|
|
49
|
+
open={open}
|
|
50
|
+
onOpenChange={setOpen}
|
|
51
|
+
side="left"
|
|
52
|
+
size="md"
|
|
53
|
+
modal={true}
|
|
54
|
+
persistent={false}
|
|
55
|
+
>
|
|
56
|
+
<Drawer.Header>
|
|
57
|
+
<Drawer.Title>Menu</Drawer.Title>
|
|
58
|
+
<Drawer.Close />
|
|
59
|
+
</Drawer.Header>
|
|
60
|
+
<Drawer.Body>
|
|
61
|
+
<NavList />
|
|
62
|
+
</Drawer.Body>
|
|
63
|
+
<Drawer.Footer>
|
|
64
|
+
<UserCard />
|
|
65
|
+
</Drawer.Footer>
|
|
66
|
+
</Drawer>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
| Prop | Type | Default | Description |
|
|
70
|
+
| --- | --- | --- | --- |
|
|
71
|
+
| `open` / `defaultOpen` | `boolean` | — | |
|
|
72
|
+
| `onOpenChange` | `(open: boolean) => void` | — | |
|
|
73
|
+
| `side` | `"left" \| "right" \| "top" \| "bottom"` | `"left"` | Edge to anchor |
|
|
74
|
+
| `size` | `"sm" \| "md" \| "lg" \| "xl"` or width/height | `"md"` | |
|
|
75
|
+
| `modal` | `boolean` | `true` | If true, backdrop + scroll lock + focus trap. If false, persistent / inline drawer. |
|
|
76
|
+
| `persistent` | `boolean` | `false` | When true on tablet+ widths, drawer is always visible (no slide-in/out). |
|
|
77
|
+
| `dismissOnOutsideClick` | `boolean` | `true` (when modal) | |
|
|
78
|
+
| `swipeToDismiss` | `boolean` | `true` on mobile | iOS-native swipe-to-close gesture |
|
|
79
|
+
|
|
80
|
+
## Sizes
|
|
81
|
+
|
|
82
|
+
| Side: left/right | Width |
|
|
83
|
+
| --- | --- |
|
|
84
|
+
| `sm` | 240px |
|
|
85
|
+
| `md` (default) | 320px |
|
|
86
|
+
| `lg` | 400px |
|
|
87
|
+
| `xl` | 480px |
|
|
88
|
+
|
|
89
|
+
| Side: top/bottom | Height |
|
|
90
|
+
| --- | --- |
|
|
91
|
+
| `sm` | 25% viewport |
|
|
92
|
+
| `md` | 50% |
|
|
93
|
+
| `lg` | 75% |
|
|
94
|
+
| `xl` | 90% |
|
|
95
|
+
|
|
96
|
+
For mobile bottom drawers (sheets): `md` with detents (drag handle, snap to multiple sizes).
|
|
97
|
+
|
|
98
|
+
## Persistent vs modal mode
|
|
99
|
+
|
|
100
|
+
### Modal drawer (default)
|
|
101
|
+
|
|
102
|
+
- Backdrop behind drawer (50% black scrim)
|
|
103
|
+
- Closes on backdrop click, Escape, swipe (mobile)
|
|
104
|
+
- Body scroll locked while open
|
|
105
|
+
- Focus trap inside drawer
|
|
106
|
+
|
|
107
|
+
### Persistent drawer
|
|
108
|
+
|
|
109
|
+
For desktop apps where the sidebar is always visible above tablet width:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
< sm: hidden, opens via menu button (modal mode)
|
|
113
|
+
≥ md: persistent, always visible
|
|
114
|
+
|
|
115
|
+
@media (min-width: 768px) {
|
|
116
|
+
.drawer { transform: translateX(0); position: relative; }
|
|
117
|
+
.main-content { margin-left: 320px; }
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The drawer collapses to modal mode below the breakpoint. **Don't show both modal toggle and persistent at the same width** — use media queries to switch behavior.
|
|
122
|
+
|
|
123
|
+
## States
|
|
124
|
+
|
|
125
|
+
| State | Visual |
|
|
126
|
+
| --- | --- |
|
|
127
|
+
| Closed (modal) | Translated off-screen (-100% on side axis) |
|
|
128
|
+
| Opening | 250–300ms slide-in with ease-out |
|
|
129
|
+
| Open | Settled, focus inside, scroll locked |
|
|
130
|
+
| Closing | 200ms slide-out with ease-in |
|
|
131
|
+
| Persistent | Always visible, no slide animation needed |
|
|
132
|
+
|
|
133
|
+
For mobile bottom drawer with detents: also have intermediate "snap" states (50%, 90%).
|
|
134
|
+
|
|
135
|
+
## Tokens consumed
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
--color-bg-elevated (drawer surface)
|
|
139
|
+
--color-bg-overlay (backdrop, ~rgba(0,0,0,0.5))
|
|
140
|
+
--color-border-default
|
|
141
|
+
--color-text-primary
|
|
142
|
+
--space-md, --space-lg
|
|
143
|
+
--radius-lg (top corners on bottom drawer; left/right edges on side drawers usually 0)
|
|
144
|
+
--shadow-modal (drawer's elevation)
|
|
145
|
+
--motion-default (250ms slide)
|
|
146
|
+
--easing-out
|
|
147
|
+
--z-modal
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Accessibility — same as Modal
|
|
151
|
+
|
|
152
|
+
This is the WAI-ARIA dialog pattern when `modal={true}`:
|
|
153
|
+
- `role="dialog"`, `aria-modal="true"`, `aria-labelledby={titleId}`
|
|
154
|
+
- Focus trap on open
|
|
155
|
+
- Restore focus to opener on close
|
|
156
|
+
- Escape closes (unless dismissible disabled)
|
|
157
|
+
|
|
158
|
+
For persistent drawers (when not modal):
|
|
159
|
+
- `<nav>` element, not dialog role
|
|
160
|
+
- Focus is not trapped — user can tab out into main content
|
|
161
|
+
- No backdrop, no scroll lock
|
|
162
|
+
- Escape doesn't close (it's not modal)
|
|
163
|
+
|
|
164
|
+
### Keyboard
|
|
165
|
+
|
|
166
|
+
| Key | Modal drawer | Persistent drawer |
|
|
167
|
+
| --- | --- | --- |
|
|
168
|
+
| `Tab` | Cycle within drawer | Move through drawer content; eventually exits to main |
|
|
169
|
+
| `Esc` | Close | No-op |
|
|
170
|
+
| `Enter`/`Space` | Activate focused item | Same |
|
|
171
|
+
|
|
172
|
+
## Mobile-specific behaviors
|
|
173
|
+
|
|
174
|
+
### Swipe to dismiss
|
|
175
|
+
|
|
176
|
+
- Side drawer (left): swipe right-to-left dismisses (or left-to-right depending on side).
|
|
177
|
+
- Bottom drawer (sheet): swipe down dismisses.
|
|
178
|
+
- Drag handle (3px high pill) at the swipeable edge as a visual hint.
|
|
179
|
+
|
|
180
|
+
### Detents (multi-size)
|
|
181
|
+
|
|
182
|
+
iOS sheets support detents — the user can drag to snap to multiple sizes (small, medium, full):
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
<Drawer side="bottom" detents={[0.25, 0.5, 0.9]}>
|
|
186
|
+
...
|
|
187
|
+
</Drawer>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Code example
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
// Mobile menu drawer
|
|
194
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
195
|
+
|
|
196
|
+
<Drawer open={menuOpen} onOpenChange={setMenuOpen} side="left" size="md">
|
|
197
|
+
<Drawer.Header>
|
|
198
|
+
<UserCard user={user} />
|
|
199
|
+
</Drawer.Header>
|
|
200
|
+
<Drawer.Body>
|
|
201
|
+
<NavLink to="/dashboard">대시보드</NavLink>
|
|
202
|
+
<NavLink to="/transactions">거래 내역</NavLink>
|
|
203
|
+
<NavLink to="/settings">설정</NavLink>
|
|
204
|
+
</Drawer.Body>
|
|
205
|
+
<Drawer.Footer>
|
|
206
|
+
<Button onClick={signOut}>로그아웃</Button>
|
|
207
|
+
</Drawer.Footer>
|
|
208
|
+
</Drawer>
|
|
209
|
+
|
|
210
|
+
// Filter drawer (right side)
|
|
211
|
+
<Drawer open={filterOpen} onOpenChange={setFilterOpen} side="right" size="md">
|
|
212
|
+
<Drawer.Header>
|
|
213
|
+
<Drawer.Title>필터</Drawer.Title>
|
|
214
|
+
<Button variant="link" onClick={resetFilters}>초기화</Button>
|
|
215
|
+
</Drawer.Header>
|
|
216
|
+
<Drawer.Body>
|
|
217
|
+
<FilterForm />
|
|
218
|
+
</Drawer.Body>
|
|
219
|
+
<Drawer.Footer>
|
|
220
|
+
<Button fullWidth onClick={applyFilters}>적용</Button>
|
|
221
|
+
</Drawer.Footer>
|
|
222
|
+
</Drawer>
|
|
223
|
+
|
|
224
|
+
// Persistent sidebar on desktop
|
|
225
|
+
<Drawer side="left" size="md" persistent open={true}>
|
|
226
|
+
<Sidebar />
|
|
227
|
+
</Drawer>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Edge cases
|
|
231
|
+
|
|
232
|
+
- **Drawer overflows on small phones**: cap at `100vw - 16px` (always show some main content peeking) so user knows there's a way back.
|
|
233
|
+
- **Long content scrolls inside body**: header and footer stay fixed, body scrolls.
|
|
234
|
+
- **Drawer above another drawer**: avoid. Refactor.
|
|
235
|
+
- **Drawer + on-screen keyboard (mobile)**: keyboard pushes drawer content up, but doesn't affect drawer chrome. Test on iOS Safari.
|
|
236
|
+
- **RTL**: `side="left"` becomes physical right. Use logical `side="start"`/`"end"` if your library supports it; else handle in CSS.
|
|
237
|
+
- **Persistent on small viewport**: collapse to modal below breakpoint. Don't show both styles competing.
|
|
238
|
+
|
|
239
|
+
## Don't
|
|
240
|
+
|
|
241
|
+
- Don't use Drawer for simple confirmation. Use a Modal or AlertDialog.
|
|
242
|
+
- Don't make a Drawer's content depend on the parent page's data without a way to refresh — context can become stale.
|
|
243
|
+
- Don't put primary destructive actions in a drawer's footer without confirmation.
|
|
244
|
+
- Don't autoplay videos / animations in a drawer that's not currently open (waste of CPU).
|
|
245
|
+
- Don't combine modal + persistent at the same viewport size.
|
|
246
|
+
|
|
247
|
+
## References
|
|
248
|
+
|
|
249
|
+
- Ant Design: [`refs/ant-design/components/drawer/`](../refs/ant-design/components/drawer/) — `Drawer`. Supports `placement`, `size`, `mask`, `closable`. Mature.
|
|
250
|
+
- MUI: [`refs/mui/packages/mui-material/src/Drawer/`](../refs/mui/packages/mui-material/src/Drawer/) — `Drawer` with `variant="permanent" | "persistent" | "temporary"`. Best persistent-mode handling.
|
|
251
|
+
- shadcn-ui: [`refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/sheet.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/sheet.tsx) — Radix Dialog primitive used as a side panel. Modal-only by default; persistent requires composition.
|
|
252
|
+
|
|
253
|
+
## Cross-reference
|
|
254
|
+
|
|
255
|
+
- [`examples/component-modal.md`](component-modal.md) — Sheet variant, focus management
|
|
256
|
+
- [`knowledge/patterns/mobile-navigation.md`](../knowledge/patterns/mobile-navigation.md) — when drawer vs bottom-tab-bar
|
|
257
|
+
- [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md) — focus trap rules
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# `DropdownMenu` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from Ant Design `Dropdown`, MUI `Menu`, shadcn-ui `dropdown-menu` (Radix). Triggered overlay menu of actions; the canonical "more options" / overflow menu, profile menu, action menu.
|
|
4
|
+
|
|
5
|
+
## Anatomy
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌────────────────────┐
|
|
9
|
+
│ [trigger button] │ ← user clicks
|
|
10
|
+
└────────────────────┘
|
|
11
|
+
↓ opens
|
|
12
|
+
┌────────────────────┐
|
|
13
|
+
│ ⌃ caret pointing up│
|
|
14
|
+
│ ────────────────── │
|
|
15
|
+
│ Profile ⌘P│
|
|
16
|
+
│ Settings ⌘,│
|
|
17
|
+
│ ────────────────── │
|
|
18
|
+
│ ▶ Workspace │ ← submenu trigger
|
|
19
|
+
│ ──── │
|
|
20
|
+
│ Sign out │
|
|
21
|
+
└────────────────────┘
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## API
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
<DropdownMenu>
|
|
28
|
+
<DropdownMenu.Trigger asChild>
|
|
29
|
+
<Button variant="ghost">More ▾</Button>
|
|
30
|
+
</DropdownMenu.Trigger>
|
|
31
|
+
<DropdownMenu.Content align="end">
|
|
32
|
+
<DropdownMenu.Item onSelect={handleProfile}>
|
|
33
|
+
Profile
|
|
34
|
+
<DropdownMenu.Shortcut>⌘P</DropdownMenu.Shortcut>
|
|
35
|
+
</DropdownMenu.Item>
|
|
36
|
+
<DropdownMenu.Item onSelect={handleSettings}>Settings</DropdownMenu.Item>
|
|
37
|
+
<DropdownMenu.Separator />
|
|
38
|
+
<DropdownMenu.Sub>
|
|
39
|
+
<DropdownMenu.SubTrigger>Workspace</DropdownMenu.SubTrigger>
|
|
40
|
+
<DropdownMenu.SubContent>
|
|
41
|
+
<DropdownMenu.Item>Switch workspace</DropdownMenu.Item>
|
|
42
|
+
<DropdownMenu.Item>Invite members</DropdownMenu.Item>
|
|
43
|
+
</DropdownMenu.SubContent>
|
|
44
|
+
</DropdownMenu.Sub>
|
|
45
|
+
<DropdownMenu.Separator />
|
|
46
|
+
<DropdownMenu.Item destructive onSelect={handleSignOut}>Sign out</DropdownMenu.Item>
|
|
47
|
+
</DropdownMenu.Content>
|
|
48
|
+
</DropdownMenu>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Composition
|
|
52
|
+
|
|
53
|
+
| Part | Purpose |
|
|
54
|
+
| --- | --- |
|
|
55
|
+
| `Trigger` | Element that opens the menu (Button, IconButton, etc) |
|
|
56
|
+
| `Content` | Menu surface; positioned via floating-ui |
|
|
57
|
+
| `Item` | Individual action |
|
|
58
|
+
| `CheckboxItem` | Toggleable item with check state |
|
|
59
|
+
| `RadioGroup` + `RadioItem` | Mutually exclusive items |
|
|
60
|
+
| `Sub` + `SubTrigger` + `SubContent` | Nested submenu |
|
|
61
|
+
| `Label` | Section heading (non-interactive) |
|
|
62
|
+
| `Separator` | Visual divider |
|
|
63
|
+
| `Group` | Logical grouping for screen readers |
|
|
64
|
+
| `Shortcut` | Keyboard shortcut hint (visual only; doesn't bind) |
|
|
65
|
+
|
|
66
|
+
## Item types
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
<DropdownMenu.Item>Standard action</DropdownMenu.Item>
|
|
70
|
+
|
|
71
|
+
<DropdownMenu.CheckboxItem
|
|
72
|
+
checked={notificationsOn}
|
|
73
|
+
onCheckedChange={setNotificationsOn}
|
|
74
|
+
>
|
|
75
|
+
Email notifications
|
|
76
|
+
</DropdownMenu.CheckboxItem>
|
|
77
|
+
|
|
78
|
+
<DropdownMenu.RadioGroup value={theme} onValueChange={setTheme}>
|
|
79
|
+
<DropdownMenu.RadioItem value="light">Light</DropdownMenu.RadioItem>
|
|
80
|
+
<DropdownMenu.RadioItem value="dark">Dark</DropdownMenu.RadioItem>
|
|
81
|
+
<DropdownMenu.RadioItem value="system">System</DropdownMenu.RadioItem>
|
|
82
|
+
</DropdownMenu.RadioGroup>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## States
|
|
86
|
+
|
|
87
|
+
| State | Visual |
|
|
88
|
+
| --- | --- |
|
|
89
|
+
| Closed | Trigger only; menu hidden |
|
|
90
|
+
| Opening | Menu fades + scales in (200ms) |
|
|
91
|
+
| Open | Menu visible; first item focused |
|
|
92
|
+
| Item hover | Bg highlight |
|
|
93
|
+
| Item focus (keyboard) | Bg highlight + visible focus ring |
|
|
94
|
+
| Item disabled | Reduced opacity, no events, `aria-disabled="true"` |
|
|
95
|
+
| Item destructive | Red text + hover |
|
|
96
|
+
| Submenu opening | Right-side adjacent panel slides in |
|
|
97
|
+
| Closing | Reverse 150ms |
|
|
98
|
+
|
|
99
|
+
## Positioning
|
|
100
|
+
|
|
101
|
+
- Default: `bottom-start` (below trigger, left-aligned).
|
|
102
|
+
- `align="end"`: right-aligned (common for header avatar menus).
|
|
103
|
+
- `side="top"`: above trigger (when near bottom of viewport).
|
|
104
|
+
- **Auto-flip**: floating-ui adjusts side / align based on available space.
|
|
105
|
+
- **Collision padding**: 8px from viewport edges.
|
|
106
|
+
- **Sub-menus**: open to the right by default; flip to left if collision.
|
|
107
|
+
|
|
108
|
+
## Keyboard contract (WAI-ARIA Menu pattern)
|
|
109
|
+
|
|
110
|
+
| Key | Action |
|
|
111
|
+
| --- | --- |
|
|
112
|
+
| `Enter` / `Space` (on trigger) | Open menu, focus first item |
|
|
113
|
+
| `↓` / `↑` | Move between items |
|
|
114
|
+
| `Home` / `End` | Jump to first / last item |
|
|
115
|
+
| `Enter` / `Space` (on item) | Activate; close menu |
|
|
116
|
+
| `Esc` | Close; return focus to trigger |
|
|
117
|
+
| `Tab` | Close; move to next focusable in document |
|
|
118
|
+
| `→` (on submenu trigger) | Open submenu |
|
|
119
|
+
| `←` (in submenu) | Close submenu, focus parent item |
|
|
120
|
+
| typeahead (letter keys) | Jump to item starting with letter |
|
|
121
|
+
|
|
122
|
+
## Tokens consumed
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
--color-bg-overlay (menu bg)
|
|
126
|
+
--color-fg-on-overlay (item text)
|
|
127
|
+
--color-bg-overlay-hover (item hover bg)
|
|
128
|
+
--color-fg-emphasis (selected item)
|
|
129
|
+
--color-error-default (destructive item)
|
|
130
|
+
--color-border-overlay
|
|
131
|
+
--color-fg-muted (Shortcut, Label)
|
|
132
|
+
--radius-md
|
|
133
|
+
--shadow-overlay (drop shadow)
|
|
134
|
+
--space-xs, --space-sm, --space-md
|
|
135
|
+
--font-size-sm
|
|
136
|
+
--motion-fast (open/close)
|
|
137
|
+
--ease-out
|
|
138
|
+
--z-overlay
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Accessibility
|
|
142
|
+
|
|
143
|
+
- Trigger: `<button>` with `aria-haspopup="menu" aria-expanded="true|false"`.
|
|
144
|
+
- Content: `role="menu"`; auto-focuses first item on open.
|
|
145
|
+
- Items: `role="menuitem"`; `tabindex="-1"` (managed by parent `roving tabindex`).
|
|
146
|
+
- CheckboxItem: `role="menuitemcheckbox"` + `aria-checked`.
|
|
147
|
+
- RadioItem: `role="menuitemradio"` + `aria-checked`.
|
|
148
|
+
- Separator: `role="separator"`.
|
|
149
|
+
- Label: `role="presentation"` (just visual).
|
|
150
|
+
- Submenu trigger: `aria-haspopup="menu" aria-expanded`.
|
|
151
|
+
- Touch target: each item ≥ 36px tall.
|
|
152
|
+
- Don't disable focus outline; brand the ring color but keep visible.
|
|
153
|
+
|
|
154
|
+
## Tokens for Korean
|
|
155
|
+
|
|
156
|
+
For Korean menus:
|
|
157
|
+
- Menu items in Korean text — Pretendard / NanumSquare; line-height 1.6 for legibility.
|
|
158
|
+
- Shortcut display: 한글 keyboards have different keys; show "Cmd / Ctrl" + Latin letter (typing layouts mostly Latin).
|
|
159
|
+
|
|
160
|
+
## Code example
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
function UserMenu({ user, onSignOut }: Props) {
|
|
164
|
+
return (
|
|
165
|
+
<DropdownMenu>
|
|
166
|
+
<DropdownMenu.Trigger asChild>
|
|
167
|
+
<button className="user-menu-trigger" aria-label="사용자 메뉴">
|
|
168
|
+
<Avatar src={user.avatar} />
|
|
169
|
+
</button>
|
|
170
|
+
</DropdownMenu.Trigger>
|
|
171
|
+
<DropdownMenu.Content align="end">
|
|
172
|
+
<DropdownMenu.Label>{user.name}</DropdownMenu.Label>
|
|
173
|
+
<DropdownMenu.Item onSelect={() => navigate("/profile")}>
|
|
174
|
+
프로필
|
|
175
|
+
</DropdownMenu.Item>
|
|
176
|
+
<DropdownMenu.Item onSelect={() => navigate("/settings")}>
|
|
177
|
+
설정
|
|
178
|
+
</DropdownMenu.Item>
|
|
179
|
+
<DropdownMenu.Separator />
|
|
180
|
+
<DropdownMenu.Item destructive onSelect={onSignOut}>
|
|
181
|
+
로그아웃
|
|
182
|
+
</DropdownMenu.Item>
|
|
183
|
+
</DropdownMenu.Content>
|
|
184
|
+
</DropdownMenu>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Edge cases
|
|
190
|
+
|
|
191
|
+
- **Long item list**: scroll inside menu; cap at ~60% of viewport height.
|
|
192
|
+
- **Item label too long**: truncate with ellipsis OR wrap (pick a system-wide rule).
|
|
193
|
+
- **Menu opens off-screen on small viewport**: floating-ui auto-flips. Test on mobile.
|
|
194
|
+
- **Closing while submenu open**: closes both at once; focus returns to trigger.
|
|
195
|
+
- **Disabled state with destructive variant**: still grayed but red tint preserved.
|
|
196
|
+
- **Async action inside Item**: don't close menu before action completes; show inline spinner.
|
|
197
|
+
- **Right-click context menu**: use `ContextMenu` component, not DropdownMenu.
|
|
198
|
+
|
|
199
|
+
## Don't
|
|
200
|
+
|
|
201
|
+
- Don't use DropdownMenu for navigation links — use NavigationMenu.
|
|
202
|
+
- Don't pack > 10 items in one menu. Use sections / groups, or move some to a settings page.
|
|
203
|
+
- Don't open menu on hover (except submenus). Click-only.
|
|
204
|
+
- Don't put inputs inside DropdownMenu (use `Popover` for that — different keyboard model).
|
|
205
|
+
- Don't omit `aria-label` on icon-only triggers.
|
|
206
|
+
- Don't disable Esc closing — accessibility foundation.
|
|
207
|
+
|
|
208
|
+
## References
|
|
209
|
+
|
|
210
|
+
- Ant: [`Dropdown`](../refs/ant-design/components/dropdown)
|
|
211
|
+
- MUI: [`Menu`](../refs/mui/packages/mui-material/src/Menu)
|
|
212
|
+
- shadcn-ui: [`dropdown-menu`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/dropdown-menu.tsx) (Radix-based)
|
|
213
|
+
- WAI-ARIA: [Menu pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menu/)
|
|
214
|
+
|
|
215
|
+
## Cross-reference
|
|
216
|
+
|
|
217
|
+
- [`examples/component-context-menu.md`](component-context-menu.md) — right-click variant
|
|
218
|
+
- [`examples/component-popover.md`](component-popover.md) — for non-menu floating content
|
|
219
|
+
- [`examples/component-command.md`](component-command.md) — for searchable menus
|
|
220
|
+
- [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md)
|