@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,162 @@
|
|
|
1
|
+
# `Message` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from Ant Design `Message`. A top-of-page transient notification — a thin strip / pill that appears at the top center for 1.5-3 seconds, then auto-dismisses. Distinct from `Toast` (corner-anchored) and `Notification` (richer, persistent corner).
|
|
4
|
+
|
|
5
|
+
## Message vs Toast vs Notification
|
|
6
|
+
|
|
7
|
+
| | Message | Toast | Notification |
|
|
8
|
+
| --- | --- | --- | --- |
|
|
9
|
+
| Position | Top center | Bottom-right (or corner) | Top-right (corner) |
|
|
10
|
+
| Size | Thin pill | Card-sized | Larger card |
|
|
11
|
+
| Duration | 1.5-3s | 3-5s | 4.5s default; can be persistent |
|
|
12
|
+
| Use | Result of action ("저장됨") | Action result + optional Undo | Notification with title + description |
|
|
13
|
+
| Title? | No (just one line) | Optional | Yes |
|
|
14
|
+
|
|
15
|
+
For **brief action confirmation** (저장됨, 복사됨): Message.
|
|
16
|
+
For **action confirmation with Undo**: Toast.
|
|
17
|
+
For **rich notifications with detail**: Notification.
|
|
18
|
+
|
|
19
|
+
## Anatomy
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
✓ 저장되었어요
|
|
23
|
+
↑ pill, top center, brief
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## API
|
|
27
|
+
|
|
28
|
+
Imperative API (Ant-style):
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { message } from "antd";
|
|
32
|
+
|
|
33
|
+
message.success("저장되었어요");
|
|
34
|
+
message.error("저장에 실패했어요");
|
|
35
|
+
message.info("새 버전이 있어요");
|
|
36
|
+
message.warning("연결이 불안정해요");
|
|
37
|
+
message.loading("처리 중...");
|
|
38
|
+
|
|
39
|
+
// With config
|
|
40
|
+
message.success({ content: "복사됨", duration: 1.5 });
|
|
41
|
+
|
|
42
|
+
// Custom dismiss
|
|
43
|
+
const hide = message.loading("Saving...", 0); // 0 = persistent
|
|
44
|
+
// later
|
|
45
|
+
hide();
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
| API | Description |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| `message.success(content, duration?)` | Green check |
|
|
51
|
+
| `message.error(content, duration?)` | Red X |
|
|
52
|
+
| `message.info(content, duration?)` | Blue info |
|
|
53
|
+
| `message.warning(content, duration?)` | Amber triangle |
|
|
54
|
+
| `message.loading(content, duration?)` | Spinner |
|
|
55
|
+
| `message.open(config)` | Full config object |
|
|
56
|
+
| `message.destroy()` | Clear all messages |
|
|
57
|
+
|
|
58
|
+
| Config field | Description |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| `content` | Text or ReactNode |
|
|
61
|
+
| `duration` | Seconds (default 3); 0 = persistent |
|
|
62
|
+
| `key` | Unique key (replace existing message with same key) |
|
|
63
|
+
| `onClose` | Callback when dismissed |
|
|
64
|
+
| `icon` | Custom icon override |
|
|
65
|
+
|
|
66
|
+
## States
|
|
67
|
+
|
|
68
|
+
| State | Visual |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| success | Green check icon + content |
|
|
71
|
+
| error | Red X icon + content |
|
|
72
|
+
| info | Blue info icon |
|
|
73
|
+
| warning | Amber triangle |
|
|
74
|
+
| loading | Spinner + content |
|
|
75
|
+
|
|
76
|
+
## Animation
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
Enter: slide down + fade in (200ms)
|
|
80
|
+
Hold: full opacity for `duration` seconds
|
|
81
|
+
Exit: slide up + fade out (200ms)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Reduced motion: skip slide; just fade.
|
|
85
|
+
|
|
86
|
+
## Tokens consumed
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
--message-bg (white / dark surface)
|
|
90
|
+
--message-fg
|
|
91
|
+
--message-success-icon (green)
|
|
92
|
+
--message-error-icon (red)
|
|
93
|
+
--message-warning-icon (amber)
|
|
94
|
+
--message-info-icon (blue)
|
|
95
|
+
--message-shadow
|
|
96
|
+
--radius-md
|
|
97
|
+
--space-sm, --space-md
|
|
98
|
+
--font-size-sm
|
|
99
|
+
--motion-medium (slide animation)
|
|
100
|
+
--ease-out
|
|
101
|
+
--z-message (above modals)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Accessibility
|
|
105
|
+
|
|
106
|
+
- Container: `role="status"` (info / success) or `role="alert"` (error / warning).
|
|
107
|
+
- `aria-live="polite"` for status; `assertive` for error.
|
|
108
|
+
- Don't use for accessibility-critical info that user must read at length — use a Modal or persistent Banner.
|
|
109
|
+
- For loading: pair with `aria-busy="true"` on the affected region.
|
|
110
|
+
|
|
111
|
+
## Korean conventions
|
|
112
|
+
|
|
113
|
+
| Action | Message |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| Save success | "저장되었어요" / "저장됐어요" |
|
|
116
|
+
| Copy | "복사되었어요" |
|
|
117
|
+
| Delete | "삭제됐어요" (often with Toast + Undo instead) |
|
|
118
|
+
| Error | "오류가 발생했어요" |
|
|
119
|
+
| Loading | "처리 중이에요..." |
|
|
120
|
+
| Network error | "네트워크가 불안정해요" |
|
|
121
|
+
|
|
122
|
+
해요체 default for casual brand voice.
|
|
123
|
+
|
|
124
|
+
## Code example
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
async function handleSave() {
|
|
128
|
+
const hide = message.loading("저장 중...");
|
|
129
|
+
try {
|
|
130
|
+
await api.save(data);
|
|
131
|
+
hide();
|
|
132
|
+
message.success("저장되었어요");
|
|
133
|
+
} catch (err) {
|
|
134
|
+
hide();
|
|
135
|
+
message.error("저장에 실패했어요. 다시 시도해 주세요.");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function handleCopy() {
|
|
140
|
+
await navigator.clipboard.writeText(text);
|
|
141
|
+
message.success({ content: "복사됨", duration: 1.5 });
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Don't
|
|
146
|
+
|
|
147
|
+
- Don't use Message for actions with Undo. Use Toast (anchor in corner; allow Undo button).
|
|
148
|
+
- Don't show 5 concurrent messages — they stack and confuse. Cap at 1-2 visible.
|
|
149
|
+
- Don't use Message for critical errors that block the user. Use Modal / AlertDialog.
|
|
150
|
+
- Don't make Message disappear in 500ms. Min 1.5s for users to read.
|
|
151
|
+
- Don't translate Message content from English word-for-word — adapt to Korean phrasing.
|
|
152
|
+
|
|
153
|
+
## References
|
|
154
|
+
|
|
155
|
+
- Ant: [`Message`](../refs/ant-design/components/message)
|
|
156
|
+
- Patterns: same family as iOS HUD, Material Snackbar (variant)
|
|
157
|
+
|
|
158
|
+
## Cross-reference
|
|
159
|
+
|
|
160
|
+
- [`examples/component-toast.md`](component-toast.md) — corner alternative with Undo
|
|
161
|
+
- [`examples/component-notification.md`](component-notification.md) — richer card variant
|
|
162
|
+
- [`examples/component-banner.md`](component-banner.md) — persistent strip variant
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# `MobileStepper` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from MUI `MobileStepper`. Compact step indicator for mobile-first flows — shows progress as dots, text, or a progress bar. Used in onboarding, image carousels, multi-step bottom sheets.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Mobile onboarding flow (3-7 steps).
|
|
8
|
+
- Carousel position indicator.
|
|
9
|
+
- Multi-step bottom sheet.
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- Desktop multi-step form → use `Stepper` (horizontal, labeled).
|
|
14
|
+
- Single-step → no indicator needed.
|
|
15
|
+
- Long flows (10+ steps) → use a percentage progress instead.
|
|
16
|
+
|
|
17
|
+
## Anatomy
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Variant = "dots":
|
|
21
|
+
┌──────────────────────────────────────────┐
|
|
22
|
+
│ [Back] ● ○ ○ ○ ○ [Next] │
|
|
23
|
+
└──────────────────────────────────────────┘
|
|
24
|
+
|
|
25
|
+
Variant = "progress":
|
|
26
|
+
┌──────────────────────────────────────────┐
|
|
27
|
+
│ [Back] ▓▓▓▓░░░░░░░░░░ [Next] │
|
|
28
|
+
└──────────────────────────────────────────┘
|
|
29
|
+
|
|
30
|
+
Variant = "text":
|
|
31
|
+
┌──────────────────────────────────────────┐
|
|
32
|
+
│ [Back] 3 / 7 [Next] │
|
|
33
|
+
└──────────────────────────────────────────┘
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## API
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<MobileStepper
|
|
40
|
+
variant="dots"
|
|
41
|
+
steps={5}
|
|
42
|
+
position="bottom"
|
|
43
|
+
activeStep={step}
|
|
44
|
+
nextButton={
|
|
45
|
+
<Button onClick={handleNext} disabled={step === 4}>
|
|
46
|
+
다음 <KeyboardArrowRight />
|
|
47
|
+
</Button>
|
|
48
|
+
}
|
|
49
|
+
backButton={
|
|
50
|
+
<Button onClick={handleBack} disabled={step === 0}>
|
|
51
|
+
<KeyboardArrowLeft /> 이전
|
|
52
|
+
</Button>
|
|
53
|
+
}
|
|
54
|
+
/>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
| Prop | Type | Default | Description |
|
|
58
|
+
| --- | --- | --- | --- |
|
|
59
|
+
| `variant` | `'dots' \| 'progress' \| 'text'` | `'dots'` | Indicator style |
|
|
60
|
+
| `steps` | `number` | required | Total steps |
|
|
61
|
+
| `activeStep` | `number` | `0` | Current step (0-indexed) |
|
|
62
|
+
| `position` | `'bottom' \| 'top' \| 'static'` | `'bottom'` | Sticky position |
|
|
63
|
+
| `nextButton` | `ReactNode` | required | Next button element |
|
|
64
|
+
| `backButton` | `ReactNode` | required | Back button element |
|
|
65
|
+
| `LinearProgressProps` | `LinearProgressProps` | — | Customize progress variant |
|
|
66
|
+
|
|
67
|
+
## States
|
|
68
|
+
|
|
69
|
+
| State | Visual |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| Step N active | Nth dot filled / progress bar at N/total / "N / total" text |
|
|
72
|
+
| First step | Back button disabled |
|
|
73
|
+
| Last step | Next button label often changes ("완료" / "Done") |
|
|
74
|
+
|
|
75
|
+
## Tokens consumed
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
--space-md /* horizontal padding */
|
|
79
|
+
--dot-size-8 /* dot diameter */
|
|
80
|
+
--dot-color-active /* brand */
|
|
81
|
+
--dot-color-inactive /* fg-subtle */
|
|
82
|
+
--mobile-stepper-height-48
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Accessibility
|
|
86
|
+
|
|
87
|
+
- The buttons own their accessible names. The stepper itself has no implicit role.
|
|
88
|
+
- For screen-reader announcement of progress, add live region: `aria-live="polite"` on the step text.
|
|
89
|
+
- Don't disable navigation buttons — MUI does it; but ensure focus moves elsewhere when disabled (e.g., to the form below).
|
|
90
|
+
|
|
91
|
+
## Edge cases
|
|
92
|
+
|
|
93
|
+
- **Too many steps** — 8+ dots become unreadable. Switch to `progress` or `text` variant.
|
|
94
|
+
- **Korean step labels** — use "다음" / "이전" / "완료" / "건너뛰기". Cite [`knowledge/i18n/korean-product-conventions.md`](../knowledge/i18n/korean-product-conventions.md).
|
|
95
|
+
- **Last-step Next button** — label change to "완료" + change `onClick` to submit. Pair with optimistic UI for snappy feel.
|
|
96
|
+
- **Position="static"** — embeds inline (good inside cards/sheets); `bottom` floats to viewport bottom.
|
|
97
|
+
|
|
98
|
+
## Code example
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
function OnboardingFlow() {
|
|
102
|
+
const [step, setStep] = useState(0);
|
|
103
|
+
const totalSteps = 4;
|
|
104
|
+
const isLast = step === totalSteps - 1;
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<Box sx={{ height: '100vh', display: 'flex', flexDirection: 'column' }}>
|
|
108
|
+
<Box sx={{ flex: 1, p: 2, overflowY: 'auto' }}>
|
|
109
|
+
{step === 0 && <WelcomeStep />}
|
|
110
|
+
{step === 1 && <ProfileStep />}
|
|
111
|
+
{step === 2 && <PreferencesStep />}
|
|
112
|
+
{step === 3 && <SummaryStep />}
|
|
113
|
+
</Box>
|
|
114
|
+
<MobileStepper
|
|
115
|
+
variant="dots"
|
|
116
|
+
steps={totalSteps}
|
|
117
|
+
position="static"
|
|
118
|
+
activeStep={step}
|
|
119
|
+
nextButton={
|
|
120
|
+
<Button
|
|
121
|
+
onClick={isLast ? handleSubmit : () => setStep(step + 1)}
|
|
122
|
+
variant={isLast ? 'contained' : 'text'}
|
|
123
|
+
>
|
|
124
|
+
{isLast ? '완료' : '다음'}
|
|
125
|
+
{!isLast && <KeyboardArrowRight />}
|
|
126
|
+
</Button>
|
|
127
|
+
}
|
|
128
|
+
backButton={
|
|
129
|
+
<Button onClick={() => setStep(step - 1)} disabled={step === 0}>
|
|
130
|
+
<KeyboardArrowLeft />
|
|
131
|
+
이전
|
|
132
|
+
</Button>
|
|
133
|
+
}
|
|
134
|
+
/>
|
|
135
|
+
</Box>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Don't
|
|
141
|
+
|
|
142
|
+
- Don't use without `nextButton` + `backButton` — required props.
|
|
143
|
+
- Don't use on desktop — too small / sparse for desktop scale; use `Stepper`.
|
|
144
|
+
- Don't change the indicator type mid-flow.
|
|
145
|
+
|
|
146
|
+
## References
|
|
147
|
+
|
|
148
|
+
- MUI: [`MobileStepper`](../refs/mui/packages/mui-material/src/MobileStepper/)
|
|
149
|
+
|
|
150
|
+
## Cross-reference
|
|
151
|
+
|
|
152
|
+
- [`component-step.md`](component-step.md) — desktop equivalent
|
|
153
|
+
- [`component-step.md`](component-step.md)
|
|
154
|
+
- [`knowledge/patterns/onboarding.md`](../knowledge/patterns/onboarding.md)
|
|
155
|
+
- [`knowledge/patterns/b2b-onboarding-flows.md`](../knowledge/patterns/b2b-onboarding-flows.md)
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# `Modal` (Dialog) — spec
|
|
2
|
+
|
|
3
|
+
> Status: example artifact for `component-spec-writer` skill
|
|
4
|
+
> Generated by: `skills/component-spec-writer`, citing Ant Design `Modal`, MUI `Dialog`, shadcn-ui `dialog`/`alert-dialog`/`sheet`
|
|
5
|
+
|
|
6
|
+
## Purpose
|
|
7
|
+
|
|
8
|
+
A modal interrupts the user to capture a decision or focused interaction. It blocks page interaction until dismissed. Use sparingly — every modal is a small attention tax.
|
|
9
|
+
|
|
10
|
+
This spec covers **dialog** (centered, decision/form), **alert-dialog** (destructive confirm), and **sheet** (edge-anchored, browse/edit) as variants of one component.
|
|
11
|
+
|
|
12
|
+
## When to use which variant
|
|
13
|
+
|
|
14
|
+
| Variant | Use when | Reference |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| `dialog` | Decision or focused form that interrupts the current page | shadcn `dialog`, MUI `Dialog`, Ant `Modal` |
|
|
17
|
+
| `alert-dialog` | Destructive confirm or important alert; requires explicit acknowledgement | shadcn `alert-dialog`, Ant `Modal.confirm` |
|
|
18
|
+
| `sheet` | Browse or edit content too long for centered modal; mobile-native pattern | shadcn `sheet`, MUI `Drawer` |
|
|
19
|
+
| `popover` (not modal) | Lightweight, non-blocking | use `Popover` instead |
|
|
20
|
+
| `toast` (not modal) | Transient feedback | use `Toast` instead |
|
|
21
|
+
|
|
22
|
+
## Anatomy
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Modal (root, portal-mounted)
|
|
26
|
+
├── Backdrop (click-dismiss + visual scrim)
|
|
27
|
+
└── Surface (the box)
|
|
28
|
+
├── Header
|
|
29
|
+
│ ├── Title
|
|
30
|
+
│ ├── [Description?]
|
|
31
|
+
│ └── [CloseButton?]
|
|
32
|
+
├── Body (scrollable if content overflows)
|
|
33
|
+
└── Footer (action buttons, right-aligned LTR)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
| Part | Required | Notes |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| Backdrop | yes | semi-opaque overlay; click dismisses (configurable) |
|
|
39
|
+
| Title | yes | accessible name source — `aria-labelledby` points here |
|
|
40
|
+
| Description | optional | `aria-describedby` if present |
|
|
41
|
+
| CloseButton | yes (`dialog`), optional (`alert-dialog`) | top-right ✕ |
|
|
42
|
+
| Body | yes | content; scrollable if tall |
|
|
43
|
+
| Footer | usual | right-aligned action buttons; primary on the right (LTR) |
|
|
44
|
+
|
|
45
|
+
## API
|
|
46
|
+
|
|
47
|
+
| Prop | Type | Default | Description |
|
|
48
|
+
| --- | --- | --- | --- |
|
|
49
|
+
| `open` | `boolean` | — | Controlled open state. |
|
|
50
|
+
| `onOpenChange` | `(open: boolean) => void` | — | Fires on open/close (backdrop click, escape, button click). |
|
|
51
|
+
| `title` | `string \| ReactNode` | — | Accessible name. **Required**. |
|
|
52
|
+
| `description` | `string \| ReactNode` | — | Subtitle, sets `aria-describedby`. |
|
|
53
|
+
| `size` | `"sm" \| "md" \| "lg" \| "xl" \| "full"` | `"md"` | Max-width tier. |
|
|
54
|
+
| `dismissible` | `boolean` | `true` for `dialog` / `false` for `alert-dialog` | If false, backdrop click and Escape do not close. |
|
|
55
|
+
| `showCloseButton` | `boolean` | `true` | Renders top-right ✕. |
|
|
56
|
+
| `initialFocus` | `RefObject<HTMLElement>` | first focusable inside | Element to focus on open. |
|
|
57
|
+
| `restoreFocus` | `boolean` | `true` | Return focus to opener on close. |
|
|
58
|
+
| `position` | `"center" \| "top"` (dialog) / `"top" \| "right" \| "bottom" \| "left"` (sheet) | `"center"` / `"right"` | Edge for sheet variant. |
|
|
59
|
+
| `children` | `ReactNode` | — | Body content. |
|
|
60
|
+
| `footer` | `ReactNode` | — | Footer slot for actions. |
|
|
61
|
+
| `loading` | `boolean` | `false` | Disables footer actions, shows spinner. |
|
|
62
|
+
|
|
63
|
+
For composition-style API (shadcn pattern):
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
<Modal open={open} onOpenChange={setOpen}>
|
|
67
|
+
<Modal.Header>
|
|
68
|
+
<Modal.Title>...</Modal.Title>
|
|
69
|
+
<Modal.Description>...</Modal.Description>
|
|
70
|
+
</Modal.Header>
|
|
71
|
+
<Modal.Body>...</Modal.Body>
|
|
72
|
+
<Modal.Footer>...</Modal.Footer>
|
|
73
|
+
</Modal>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## States
|
|
77
|
+
|
|
78
|
+
| State | Trigger | Behavior |
|
|
79
|
+
| --- | --- | --- |
|
|
80
|
+
| Closed | `open={false}` | Unmounted from DOM (or kept with `display:none` for performance). |
|
|
81
|
+
| Opening | transition 200ms | Backdrop fade-in 0→0.5; surface fade+scale 0.96→1 with translateY(8px)→0. |
|
|
82
|
+
| Open | settled | Focus inside surface, page scroll locked, page inert. |
|
|
83
|
+
| Closing | transition 150ms | Reverse of opening. |
|
|
84
|
+
|
|
85
|
+
Animation timing references: [knowledge/motion/principles.md](../knowledge/motion/principles.md) — modal fade-in is the canonical 200ms `ease-out` pattern.
|
|
86
|
+
|
|
87
|
+
## Sizes
|
|
88
|
+
|
|
89
|
+
| Size | Max-width | Use |
|
|
90
|
+
| --- | --- | --- |
|
|
91
|
+
| `sm` | 400px | confirmation, simple input |
|
|
92
|
+
| `md` | 560px | default; form, info |
|
|
93
|
+
| `lg` | 720px | content-heavy; multi-step |
|
|
94
|
+
| `xl` | 960px | data table, complex form |
|
|
95
|
+
| `full` | viewport-100% with margin | mobile, image gallery |
|
|
96
|
+
|
|
97
|
+
On mobile, all sizes collapse to `width: 100% - 32px margin` regardless of size prop.
|
|
98
|
+
|
|
99
|
+
## Tokens consumed
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
--color-bg-elevated (surface)
|
|
103
|
+
--color-bg-overlay (backdrop, often rgba(0,0,0,0.5))
|
|
104
|
+
--color-border-default
|
|
105
|
+
--color-text-primary
|
|
106
|
+
--color-text-secondary
|
|
107
|
+
--space-md
|
|
108
|
+
--space-lg
|
|
109
|
+
--space-xl
|
|
110
|
+
--radius-lg
|
|
111
|
+
--shadow-3 (elevation)
|
|
112
|
+
--motion-default (200ms)
|
|
113
|
+
--easing-out
|
|
114
|
+
--z-modal (typically 1000+)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Accessibility — required behaviors
|
|
118
|
+
|
|
119
|
+
This is the most a11y-sensitive component in the system. Get the WAI-ARIA dialog pattern exactly right.
|
|
120
|
+
|
|
121
|
+
- **Role**: `role="dialog"` (or `role="alertdialog"` for destructive confirm).
|
|
122
|
+
- **`aria-modal="true"`** to indicate the rest of the page is inert.
|
|
123
|
+
- **`aria-labelledby={titleId}`** pointing at the Title element.
|
|
124
|
+
- **`aria-describedby={descId}`** if Description is present.
|
|
125
|
+
- **Focus trap**: while open, `Tab` and `Shift+Tab` cycle within the modal. The last element loops back to the first.
|
|
126
|
+
- **Initial focus**: on open, focus moves into the modal. Default to first focusable element (or the close button if no focusable content). For destructive `alert-dialog`, focus the **non-destructive** action by default ("Cancel"), not the destructive one.
|
|
127
|
+
- **Restore focus**: on close, focus returns to the element that opened the modal.
|
|
128
|
+
- **Escape closes** (unless `dismissible={false}`).
|
|
129
|
+
- **Backdrop click closes** (unless `dismissible={false}`).
|
|
130
|
+
- **Page scroll lock**: prevent body scroll while open. iOS needs `position: fixed; top: -<scrollY>px`. CSS `overflow: hidden` on body alone breaks iOS.
|
|
131
|
+
- **Page inert**: set `inert` attribute on the root app container while modal is open (modern browsers 2023+). Or use `aria-hidden="true"` on background and trap focus within modal (older approach).
|
|
132
|
+
- **Announce on open**: the title is read because focus moves to / inside the labeled dialog. Don't add extra announcements — that double-announces.
|
|
133
|
+
- **Z-index**: above everything except notifications/toasts. Stacking multiple modals: prefer to refactor; if necessary, each higher modal needs +1 z-index and its own backdrop.
|
|
134
|
+
|
|
135
|
+
## Code example
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
// Standard form dialog
|
|
139
|
+
const [open, setOpen] = useState(false);
|
|
140
|
+
|
|
141
|
+
<Modal open={open} onOpenChange={setOpen} title="Invite member">
|
|
142
|
+
<Modal.Body>
|
|
143
|
+
<Input label="Email" type="email" value={email} onChange={setEmail} />
|
|
144
|
+
<Input label="Role" type="text" value={role} onChange={setRole} />
|
|
145
|
+
</Modal.Body>
|
|
146
|
+
<Modal.Footer>
|
|
147
|
+
<Button variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
|
|
148
|
+
<Button onClick={handleInvite} loading={isPending}>Send invite</Button>
|
|
149
|
+
</Modal.Footer>
|
|
150
|
+
</Modal>
|
|
151
|
+
|
|
152
|
+
// Destructive confirm
|
|
153
|
+
<AlertModal
|
|
154
|
+
open={confirmOpen}
|
|
155
|
+
onOpenChange={setConfirmOpen}
|
|
156
|
+
title="Delete project?"
|
|
157
|
+
description="This permanently deletes the project and all its data. This cannot be undone."
|
|
158
|
+
>
|
|
159
|
+
<AlertModal.Footer>
|
|
160
|
+
<Button variant="outline" onClick={() => setConfirmOpen(false)}>Cancel</Button>
|
|
161
|
+
<Button intent="danger" onClick={handleDelete}>Delete project</Button>
|
|
162
|
+
</AlertModal.Footer>
|
|
163
|
+
</AlertModal>
|
|
164
|
+
|
|
165
|
+
// Sheet (mobile-friendly edit panel)
|
|
166
|
+
<Sheet open={editOpen} onOpenChange={setEditOpen} position="right" size="md">
|
|
167
|
+
<Sheet.Header>
|
|
168
|
+
<Sheet.Title>Edit profile</Sheet.Title>
|
|
169
|
+
</Sheet.Header>
|
|
170
|
+
<Sheet.Body>
|
|
171
|
+
<ProfileForm />
|
|
172
|
+
</Sheet.Body>
|
|
173
|
+
<Sheet.Footer>
|
|
174
|
+
<Button variant="outline" onClick={() => setEditOpen(false)}>Cancel</Button>
|
|
175
|
+
<Button onClick={handleSave}>Save</Button>
|
|
176
|
+
</Sheet.Footer>
|
|
177
|
+
</Sheet>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Edge cases
|
|
181
|
+
|
|
182
|
+
- **Long content**: body scrolls; header and footer stay fixed.
|
|
183
|
+
- **Nested modal**: avoid. Refactor into wizard or pass-through navigation. If unavoidable, the inner modal's backdrop is fully opaque or significantly darker.
|
|
184
|
+
- **Keyboard user lands on close button as first focus**: jarring. Default to first interactive content; `aria-label="Close"` makes the ✕ usable but not the focus target.
|
|
185
|
+
- **Mobile: keyboard appears, modal jumps**: use `viewport-fit=cover` and `100dvh` for height. Avoid `100vh` on iOS Safari.
|
|
186
|
+
- **Form inside modal, Enter key submits**: that's correct. Make sure the primary footer button is `type="submit"` or wire `onKeyDown` for Enter.
|
|
187
|
+
- **Animations + reduced motion**: respect `prefers-reduced-motion`. Replace fade+scale with opacity-only.
|
|
188
|
+
- **RTL**: `sheet position="right"` becomes left in RTL automatically with logical CSS.
|
|
189
|
+
- **Print**: hide all modals (`@media print { .modal { display: none; } }`).
|
|
190
|
+
|
|
191
|
+
## Don't
|
|
192
|
+
|
|
193
|
+
- **Don't** put critical content only in modals — search engines can't index, browser back doesn't work intuitively.
|
|
194
|
+
- **Don't** disable the backdrop click + Escape **and** hide the close button. Always provide at least one dismiss path (unless it's a wizard with required steps — then a clear "Save & Close" or progress indicator).
|
|
195
|
+
- **Don't** open modals on page load without user action. Auto-open is hostile.
|
|
196
|
+
- **Don't** chain modals (modal opens another modal). Refactor.
|
|
197
|
+
- **Don't** put primary actions in the header — footer is the convention. Top-right is for close.
|
|
198
|
+
- **Don't** show the close button AND a "Cancel" button — they do the same thing. Pick one.
|
|
199
|
+
- **Don't** use modal for transient feedback (success message, info). Use a toast.
|
|
200
|
+
|
|
201
|
+
## References
|
|
202
|
+
|
|
203
|
+
- Ant Design: [`refs/ant-design/components/modal/`](../refs/ant-design/components/modal/) — exhaustive: `Modal`, `Modal.confirm`, `Modal.info`, `Modal.success`, `Modal.error`, `Modal.warning`. Imperative API via `Modal.confirm({...})` is convenient but harder to test. The static methods are an Ant idiom worth knowing about.
|
|
204
|
+
- MUI: [`refs/mui/packages/mui-material/src/Dialog/Dialog.tsx`](../refs/mui/packages/mui-material/src/Dialog/) — composition-first: `<Dialog>`, `<DialogTitle>`, `<DialogContent>`, `<DialogActions>`. Cleanest base API.
|
|
205
|
+
- shadcn-ui:
|
|
206
|
+
- [`refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/dialog.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/dialog.tsx) — Radix Dialog primitive, all a11y handled upstream.
|
|
207
|
+
- [`refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/alert-dialog.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/alert-dialog.tsx) — separate primitive for confirms; difference is `role="alertdialog"` and modal cannot be dismissed via Escape/backdrop unless code-driven.
|
|
208
|
+
- [`refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/sheet.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/sheet.tsx) — edge-anchored variant.
|
|
209
|
+
|
|
210
|
+
API choices made:
|
|
211
|
+
- **Three variants in one spec** (`dialog`/`alert-dialog`/`sheet`) — same focus-management contract, same a11y pattern, same composition. Fewer concepts to learn than three separate components with overlapping concerns.
|
|
212
|
+
- **Composition over imperative**: prefer `<Modal>...</Modal>` to Ant's `Modal.confirm({...})`. Imperative is fine as a wrapper for one-off confirms; composition is the foundation.
|
|
213
|
+
- **`title` prop required + `<Modal.Title>` slot supported**: prop is the 80% case (consistent a11y), slot for layouts that need custom title rendering.
|
|
214
|
+
|
|
215
|
+
## Cross-reference
|
|
216
|
+
|
|
217
|
+
- [knowledge/a11y/keyboard-and-focus.md](../knowledge/a11y/keyboard-and-focus.md) — focus trap rules
|
|
218
|
+
- [knowledge/motion/principles.md](../knowledge/motion/principles.md) — modal animation timing
|
|
219
|
+
- [WAI-ARIA Dialog Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/)
|
|
220
|
+
- [WAI-ARIA Alert Dialog Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/)
|