@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,117 @@
|
|
|
1
|
+
# `Flex` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from Ant Design `Flex`. A `<div>` with `display: flex` and shorthand props for direction / gap / align / justify. Sibling to `Stack` (MUI) and `HStack`/`VStack` patterns.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Horizontal or vertical row of items with consistent gap.
|
|
8
|
+
- Header layouts (logo + nav + actions).
|
|
9
|
+
- Toolbar / button groups.
|
|
10
|
+
|
|
11
|
+
When NOT to use:
|
|
12
|
+
- Multi-row wrapping with column constraints — use `Grid`.
|
|
13
|
+
- Single-row with text wrapping — use raw CSS.
|
|
14
|
+
|
|
15
|
+
## API
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
<Flex gap={2}>
|
|
19
|
+
<Avatar />
|
|
20
|
+
<Text>Name</Text>
|
|
21
|
+
</Flex>
|
|
22
|
+
|
|
23
|
+
<Flex direction="column" gap={4} align="start">
|
|
24
|
+
<Heading>Title</Heading>
|
|
25
|
+
<Text>Body</Text>
|
|
26
|
+
</Flex>
|
|
27
|
+
|
|
28
|
+
<Flex justify="space-between" align="center">
|
|
29
|
+
<Logo />
|
|
30
|
+
<Nav />
|
|
31
|
+
<Actions />
|
|
32
|
+
</Flex>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
| Prop | Type | Default | Description |
|
|
36
|
+
| --- | --- | --- | --- |
|
|
37
|
+
| `direction` | `"row" \| "column" \| "row-reverse" \| "column-reverse"` | `"row"` | Flex direction |
|
|
38
|
+
| `gap` | spacing-token | `0` | Gap between children |
|
|
39
|
+
| `align` | `"start" \| "center" \| "end" \| "stretch" \| "baseline"` | `"stretch"` | align-items |
|
|
40
|
+
| `justify` | `"start" \| "center" \| "end" \| "space-between" \| "space-around" \| "space-evenly"` | `"start"` | justify-content |
|
|
41
|
+
| `wrap` | `boolean` | `false` | Allow wrapping |
|
|
42
|
+
| `inline` | `boolean` | `false` | inline-flex instead of flex |
|
|
43
|
+
| `as` | element | `"div"` | Render element |
|
|
44
|
+
|
|
45
|
+
## Common patterns
|
|
46
|
+
|
|
47
|
+
### Toolbar (justify-between)
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
<Flex justify="space-between" align="center">
|
|
51
|
+
<Heading>Title</Heading>
|
|
52
|
+
<Flex gap={2}>
|
|
53
|
+
<Button variant="ghost">Cancel</Button>
|
|
54
|
+
<Button>Save</Button>
|
|
55
|
+
</Flex>
|
|
56
|
+
</Flex>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Stack (column with gap)
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
<Flex direction="column" gap={4}>
|
|
63
|
+
<Card>...</Card>
|
|
64
|
+
<Card>...</Card>
|
|
65
|
+
</Flex>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Centered
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
<Flex justify="center" align="center" minHeight="100vh">
|
|
72
|
+
<Card>Centered</Card>
|
|
73
|
+
</Flex>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Wrapping tag list
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
<Flex wrap gap={1}>
|
|
80
|
+
{tags.map(tag => <Tag key={tag}>{tag}</Tag>)}
|
|
81
|
+
</Flex>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## States
|
|
85
|
+
|
|
86
|
+
Stateless.
|
|
87
|
+
|
|
88
|
+
## Tokens consumed
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
--space-{0..n} (gap)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Accessibility
|
|
95
|
+
|
|
96
|
+
- Flex is presentational. Use `as` for semantic elements (`as="nav"` for nav).
|
|
97
|
+
- For toolbars: wrap with `<div role="toolbar">` if interactive controls.
|
|
98
|
+
- Source order = reading order. Flex visual order can differ via `order` prop, but DOM order is what screen readers read. Avoid `order` for content layout.
|
|
99
|
+
|
|
100
|
+
## Don't
|
|
101
|
+
|
|
102
|
+
- Don't use Flex where Stack (MUI) or VStack/HStack (Chakra) is the team convention. Pick one primitive name and stick with it.
|
|
103
|
+
- Don't nest Flex 5+ levels deep. If layout is that complex, use Grid.
|
|
104
|
+
- Don't use Flex with `direction="column"` AND `gap={N}` for content reading flow when a semantic element exists. Use `<article>`, `<section>`, etc.
|
|
105
|
+
|
|
106
|
+
## References
|
|
107
|
+
|
|
108
|
+
- Ant: [`Flex`](../refs/ant-design/components/flex)
|
|
109
|
+
- MUI: `Stack` (sibling primitive)
|
|
110
|
+
- Chakra UI: `HStack`, `VStack`, `Flex`
|
|
111
|
+
|
|
112
|
+
## Cross-reference
|
|
113
|
+
|
|
114
|
+
- [`examples/component-stack.md`](component-stack.md) — N/A (Stack rendered via similar primitive in some libs)
|
|
115
|
+
- [`examples/component-grid.md`](component-grid.md) — for 2D layout
|
|
116
|
+
- [`examples/component-box.md`](component-box.md) — generic styled wrapper
|
|
117
|
+
- [`knowledge/layout/spacing-and-grid.md`](../knowledge/layout/spacing-and-grid.md)
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# `FloatButton` (FAB — Floating Action Button) — spec
|
|
2
|
+
|
|
3
|
+
> Citing Ant Design `FloatButton`, MUI `Fab`, shadcn-ui (composition)
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
A round floating button anchored to the screen edge (typically bottom-right). Used for the **single most important action** on the screen — compose new message, add new item, scroll-to-top.
|
|
8
|
+
|
|
9
|
+
## When FAB vs alternatives
|
|
10
|
+
|
|
11
|
+
| Pattern | Use |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| **FAB** | One primary action, mobile-primary product |
|
|
14
|
+
| **Bottom CTA** (full-width footer button) | Form submit, "Pay" — context-specific |
|
|
15
|
+
| **Header action button** | When the action is contextual to the page header |
|
|
16
|
+
| **Inline button in list** | Per-item actions |
|
|
17
|
+
|
|
18
|
+
A FAB **must be the single most important action**. Don't use it for navigation. Don't have multiple FABs at the same time.
|
|
19
|
+
|
|
20
|
+
## Anatomy
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
[viewport]
|
|
24
|
+
┌─────┐
|
|
25
|
+
│ + │ ← FAB
|
|
26
|
+
└─────┘
|
|
27
|
+
▼ tap
|
|
28
|
+
|
|
29
|
+
With expand menu:
|
|
30
|
+
┌────┐
|
|
31
|
+
│ 📷 │ ← child action
|
|
32
|
+
└────┘
|
|
33
|
+
┌────┐
|
|
34
|
+
│ 📝 │
|
|
35
|
+
└────┘
|
|
36
|
+
┌─────┐
|
|
37
|
+
│ ✕ │ ← rotated FAB (close)
|
|
38
|
+
└─────┘
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
| Slot | Required | Notes |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| Icon | yes | Single, recognizable (+, 📝, 📷, ↑) |
|
|
44
|
+
| Label | optional | "Extended FAB" — text alongside icon |
|
|
45
|
+
| Child actions | optional | Speed-dial menu when tapped |
|
|
46
|
+
|
|
47
|
+
## API
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
<FloatButton
|
|
51
|
+
icon={<PlusIcon />}
|
|
52
|
+
onClick={openAddModal}
|
|
53
|
+
position="bottom-right"
|
|
54
|
+
label="Add"
|
|
55
|
+
/>
|
|
56
|
+
|
|
57
|
+
// With expand menu (Speed Dial)
|
|
58
|
+
<FloatButton.Group icon={<PlusIcon />} position="bottom-right">
|
|
59
|
+
<FloatButton.Item icon={<CameraIcon />} label="사진" onClick={takePhoto} />
|
|
60
|
+
<FloatButton.Item icon={<PenIcon />} label="메모" onClick={addNote} />
|
|
61
|
+
<FloatButton.Item icon={<MicIcon />} label="음성" onClick={recordVoice} />
|
|
62
|
+
</FloatButton.Group>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
| Prop | Type | Default | Description |
|
|
66
|
+
| --- | --- | --- | --- |
|
|
67
|
+
| `icon` | `ReactNode` | — | Required |
|
|
68
|
+
| `label` | `string` | — | Extended-FAB label |
|
|
69
|
+
| `onClick` | `() => void` | — | |
|
|
70
|
+
| `position` | `"bottom-right" \| "bottom-left" \| "bottom-center"` | `"bottom-right"` | Screen-edge anchor |
|
|
71
|
+
| `offset` | `[number, number]` | `[16, 16]` (mobile) / `[24, 24]` (desktop) | px from edge |
|
|
72
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | |
|
|
73
|
+
| `variant` | `"primary" \| "secondary" \| "tonal"` | `"primary"` | |
|
|
74
|
+
| `disabled` | `boolean` | `false` | |
|
|
75
|
+
| `tooltip` | `string` | — | Optional hover hint (desktop) |
|
|
76
|
+
|
|
77
|
+
## Sizes
|
|
78
|
+
|
|
79
|
+
| Size | Diameter | Icon | Use |
|
|
80
|
+
| --- | --- | --- | --- |
|
|
81
|
+
| `sm` | 40px | 20px | Inline / dense |
|
|
82
|
+
| `md` (default) | 56px | 24px | Standard mobile FAB |
|
|
83
|
+
| `lg` | 64px | 28px | Tablet / hero |
|
|
84
|
+
|
|
85
|
+
Material 3's "extended FAB" with label: ~48px height + label text padding.
|
|
86
|
+
|
|
87
|
+
## States
|
|
88
|
+
|
|
89
|
+
| State | Visual |
|
|
90
|
+
| --- | --- |
|
|
91
|
+
| Default | Resting; raised shadow |
|
|
92
|
+
| Hover | Slight scale up + shadow deepen |
|
|
93
|
+
| Pressed | Scale 0.96 |
|
|
94
|
+
| Focus-visible | 2px ring around |
|
|
95
|
+
| Expanded (Speed Dial open) | Backdrop dim, child actions visible above, FAB rotates to ✕ |
|
|
96
|
+
|
|
97
|
+
## Tokens consumed
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
--color-primary-default (default FAB bg)
|
|
101
|
+
--color-on-primary (icon)
|
|
102
|
+
--color-bg-elevated (tonal variant)
|
|
103
|
+
--color-text-primary
|
|
104
|
+
--color-focus-ring
|
|
105
|
+
--space-md, --space-base
|
|
106
|
+
--radius-full (circular)
|
|
107
|
+
--radius-lg (extended FAB)
|
|
108
|
+
--shadow-3 (elevation when raised)
|
|
109
|
+
--shadow-4 (elevation when expanded)
|
|
110
|
+
--motion-fast, --easing-out
|
|
111
|
+
--z-fab (above content, below modals)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Safe area on mobile
|
|
115
|
+
|
|
116
|
+
iOS / Android devices have safe-area insets (home bar, notches). FAB position must respect them:
|
|
117
|
+
|
|
118
|
+
```css
|
|
119
|
+
.fab {
|
|
120
|
+
position: fixed;
|
|
121
|
+
bottom: max(16px, calc(16px + env(safe-area-inset-bottom)));
|
|
122
|
+
right: max(16px, calc(16px + env(safe-area-inset-right)));
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
In RN: use `useSafeAreaInsets()` hook.
|
|
127
|
+
|
|
128
|
+
## Bottom navigation interplay
|
|
129
|
+
|
|
130
|
+
If your app has a bottom-tab-bar (per [`knowledge/patterns/mobile-navigation.md`](../knowledge/patterns/mobile-navigation.md)), the FAB sits **above the tab bar** with `bottom: tabBarHeight + 16`.
|
|
131
|
+
|
|
132
|
+
For the "center action" tab (elevated tab in middle of tab bar): that's a different pattern — not a FAB, integrated into nav.
|
|
133
|
+
|
|
134
|
+
## Accessibility
|
|
135
|
+
|
|
136
|
+
- Render as `<button>` with `aria-label` (icon-only).
|
|
137
|
+
- For Speed Dial: parent button has `aria-haspopup="menu" aria-expanded`. Children are `role="menuitem"`.
|
|
138
|
+
- Focus order: FAB is reachable via Tab.
|
|
139
|
+
- High contrast mode: ensure icon visible against bg color.
|
|
140
|
+
|
|
141
|
+
### Keyboard
|
|
142
|
+
|
|
143
|
+
- `Tab` reaches FAB.
|
|
144
|
+
- `Enter` / `Space` activates.
|
|
145
|
+
- For Speed Dial: arrow keys move through children, `Esc` closes.
|
|
146
|
+
|
|
147
|
+
## Variants
|
|
148
|
+
|
|
149
|
+
### `primary` (default)
|
|
150
|
+
|
|
151
|
+
Filled with `--color-primary-default`, on-primary icon. Highest emphasis.
|
|
152
|
+
|
|
153
|
+
### `secondary`
|
|
154
|
+
|
|
155
|
+
Filled with secondary brand or neutral elevated. Use when there's a more important primary CTA elsewhere on the page.
|
|
156
|
+
|
|
157
|
+
### `tonal` (Material 3)
|
|
158
|
+
|
|
159
|
+
Subtle bg (`--color-primary-subtle-bg`), primary icon. Less emphasis but still elevated.
|
|
160
|
+
|
|
161
|
+
## Code example
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
// Standard FAB — add new
|
|
165
|
+
<FloatButton
|
|
166
|
+
icon={<PlusIcon />}
|
|
167
|
+
aria-label="새 거래 추가"
|
|
168
|
+
onClick={openAddTransaction}
|
|
169
|
+
/>
|
|
170
|
+
|
|
171
|
+
// Extended (label visible)
|
|
172
|
+
<FloatButton
|
|
173
|
+
icon={<PenIcon />}
|
|
174
|
+
label="작성"
|
|
175
|
+
onClick={openCompose}
|
|
176
|
+
/>
|
|
177
|
+
|
|
178
|
+
// Scroll to top variant
|
|
179
|
+
<FloatButton
|
|
180
|
+
icon={<ArrowUpIcon />}
|
|
181
|
+
aria-label="맨 위로"
|
|
182
|
+
onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}
|
|
183
|
+
hidden={scrollY < 200} // only show when scrolled
|
|
184
|
+
/>
|
|
185
|
+
|
|
186
|
+
// Speed dial
|
|
187
|
+
<FloatButton.Group icon={<PlusIcon />}>
|
|
188
|
+
<FloatButton.Item icon={<CameraIcon />} label="사진 촬영" onClick={takePhoto} />
|
|
189
|
+
<FloatButton.Item icon={<NoteIcon />} label="메모 작성" onClick={addNote} />
|
|
190
|
+
<FloatButton.Item icon={<MicIcon />} label="음성 녹음" onClick={recordVoice} />
|
|
191
|
+
</FloatButton.Group>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Don't
|
|
195
|
+
|
|
196
|
+
- Don't have multiple FABs visible at once.
|
|
197
|
+
- Don't use FAB for navigation — that's a tab.
|
|
198
|
+
- Don't use for destructive actions — too easy to tap accidentally.
|
|
199
|
+
- Don't use FAB on screens where its action wouldn't make sense (settings page, etc.). Show only where the action is contextual.
|
|
200
|
+
- Don't omit `aria-label` for icon-only.
|
|
201
|
+
- Don't ignore safe-area-inset on mobile.
|
|
202
|
+
- Don't put FAB so close to bottom-tab-bar that taps overlap.
|
|
203
|
+
|
|
204
|
+
## References
|
|
205
|
+
|
|
206
|
+
- Ant Design: [`refs/ant-design/components/float-button/`](../refs/ant-design/components/float-button/) — `FloatButton`, `FloatButton.Group` (speed dial), `FloatButton.BackTop`. Most flexible.
|
|
207
|
+
- MUI: [`refs/mui/packages/mui-material/src/Fab/`](../refs/mui/packages/mui-material/src/Fab/) — `Fab` with `variant="circular" | "extended"`, color, size. Material-aligned.
|
|
208
|
+
- shadcn-ui: no built-in. Compose with `Button` + Tailwind `fixed bottom-4 right-4 rounded-full`.
|
|
209
|
+
|
|
210
|
+
## Cross-reference
|
|
211
|
+
|
|
212
|
+
- [`knowledge/patterns/mobile-navigation.md`](../knowledge/patterns/mobile-navigation.md) — center-tab variant
|
|
213
|
+
- [`examples/component-button.md`](component-button.md) — for non-FAB buttons
|
|
214
|
+
- [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md) — touch target sizing
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# `FormControlLabel` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from MUI `FormControlLabel`. The label-wraps-control pattern for `Checkbox` / `Radio` / `Switch` — the entire label area becomes the click target. Without it, users have to click the tiny check/radio circle directly (poor touch UX).
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Any standalone `Checkbox` / `Radio` / `Switch` with a visible label.
|
|
8
|
+
- Inside `FormGroup` for grouped checkboxes.
|
|
9
|
+
- Inside `RadioGroup` for radio sets (RadioGroup wires up `name` automatically).
|
|
10
|
+
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
[control] Label text
|
|
15
|
+
└─────── click target spans both ────────┘
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## API
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
<FormControlLabel
|
|
22
|
+
control={<Checkbox checked={agreed} onChange={(e) => setAgreed(e.target.checked)} />}
|
|
23
|
+
label="개인정보 수집 및 이용에 동의해요"
|
|
24
|
+
/>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| Prop | Type | Default | Description |
|
|
28
|
+
| --- | --- | --- | --- |
|
|
29
|
+
| `control` | `ReactElement` | required | The Checkbox/Radio/Switch |
|
|
30
|
+
| `label` | `ReactNode` | — | Label text or component |
|
|
31
|
+
| `labelPlacement` | `'start' \| 'end' \| 'top' \| 'bottom'` | `'end'` | Label position relative to control |
|
|
32
|
+
| `disabled` | `boolean` | inherited | Disable the entire label+control |
|
|
33
|
+
| `required` | `boolean` | `false` | Visual asterisk (label only) |
|
|
34
|
+
| `value` | `any` | — | When inside RadioGroup |
|
|
35
|
+
| `componentsProps` | `{ typography?: TypographyProps }` | — | Customize label typography |
|
|
36
|
+
|
|
37
|
+
## States
|
|
38
|
+
|
|
39
|
+
| State | Visual |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| Default | Control + label fg-default |
|
|
42
|
+
| Hover | Subtle bg ripple from control |
|
|
43
|
+
| Focus | Control's focus ring; label color unchanged |
|
|
44
|
+
| Disabled | Both control + label muted |
|
|
45
|
+
| Checked / unchecked | Driven by inner control |
|
|
46
|
+
|
|
47
|
+
## Tokens consumed
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
--font-size-body
|
|
51
|
+
--color-fg-default
|
|
52
|
+
--color-fg-muted /* disabled */
|
|
53
|
+
--space-sm /* gap between control and label */
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Accessibility
|
|
57
|
+
|
|
58
|
+
- Label is implicitly associated via the wrapping `<label>` element — no explicit `htmlFor` needed when `control` is a child.
|
|
59
|
+
- For long labels with HTML inside (links, **bold**), screen readers read the entire label as the control's name.
|
|
60
|
+
- Don't put interactive elements (other buttons/links) inside the label — they conflict with the click target.
|
|
61
|
+
- For consent checkboxes with required-acceptance, also set `aria-required="true"` on the inner Checkbox.
|
|
62
|
+
|
|
63
|
+
## Edge cases
|
|
64
|
+
|
|
65
|
+
- **Long label wrapping** — wraps cleanly; the click target stays aligned with the control on the first line.
|
|
66
|
+
- **Korean labels with embedded link** — "이용약관에 동의해요" with link on "이용약관". Use `<Link onClick={(e) => e.stopPropagation()}>` to prevent toggling the checkbox when the link is clicked.
|
|
67
|
+
- **labelPlacement="start"** — useful for settings rows where the label is the question and the Switch is the answer.
|
|
68
|
+
- **Inside Stack with multiple labels** — `Stack gap={0}` — don't add extra gap; FormControlLabel has its own.
|
|
69
|
+
|
|
70
|
+
## Code example
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
function ConsentCheckboxes() {
|
|
74
|
+
const [consents, setConsents] = useState({
|
|
75
|
+
terms: false,
|
|
76
|
+
privacy: false,
|
|
77
|
+
marketing: false,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<FormGroup>
|
|
82
|
+
<FormControlLabel
|
|
83
|
+
control={
|
|
84
|
+
<Checkbox
|
|
85
|
+
checked={consents.terms}
|
|
86
|
+
onChange={(e) => setConsents({ ...consents, terms: e.target.checked })}
|
|
87
|
+
/>
|
|
88
|
+
}
|
|
89
|
+
label={
|
|
90
|
+
<>
|
|
91
|
+
<Link
|
|
92
|
+
href="/terms"
|
|
93
|
+
target="_blank"
|
|
94
|
+
onClick={(e) => e.stopPropagation()}
|
|
95
|
+
>
|
|
96
|
+
이용약관
|
|
97
|
+
</Link>
|
|
98
|
+
에 동의해요 <span style={{ color: 'red' }}>*</span>
|
|
99
|
+
</>
|
|
100
|
+
}
|
|
101
|
+
required
|
|
102
|
+
/>
|
|
103
|
+
<FormControlLabel
|
|
104
|
+
control={<Checkbox checked={consents.privacy} onChange={...} />}
|
|
105
|
+
label="개인정보 수집 동의"
|
|
106
|
+
required
|
|
107
|
+
/>
|
|
108
|
+
<FormControlLabel
|
|
109
|
+
control={<Checkbox checked={consents.marketing} onChange={...} />}
|
|
110
|
+
label="마케팅 수신 동의 (선택)"
|
|
111
|
+
/>
|
|
112
|
+
</FormGroup>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Don't
|
|
118
|
+
|
|
119
|
+
- Don't put a button inside `label` — clicking the button toggles the control, confusing users.
|
|
120
|
+
- Don't use it without a visible label — for icon-only toggles, use `IconButton` with `aria-label`.
|
|
121
|
+
- Don't place the control too far from the label visually (`labelPlacement="bottom"` with extra gap) — the connection becomes unclear.
|
|
122
|
+
|
|
123
|
+
## References
|
|
124
|
+
|
|
125
|
+
- MUI: [`FormControlLabel`](../refs/mui/packages/mui-material/src/FormControlLabel/)
|
|
126
|
+
|
|
127
|
+
## Cross-reference
|
|
128
|
+
|
|
129
|
+
- [`component-form-control.md`](component-form-control.md)
|
|
130
|
+
- [`component-form-group.md`](component-form-group.md)
|
|
131
|
+
- [`component-checkbox.md`](component-checkbox.md)
|
|
132
|
+
- [`component-radio.md`](component-radio.md)
|
|
133
|
+
- [`component-switch.md`](component-switch.md)
|
|
134
|
+
- [`knowledge/patterns/form-design.md`](../knowledge/patterns/form-design.md)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# `FormControl` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from MUI `FormControl`. The wrapper that groups a label + input + helper-text + error message together, so they share state (focused, error, disabled, required).
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Around every form input that has a label or helper text. Skip when wrapping a single uncontrolled `TextField` (which already provides its own FormControl internally).
|
|
8
|
+
- Around custom composed inputs where you want consistent error/required state propagation.
|
|
9
|
+
|
|
10
|
+
## Anatomy
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
┌──────────────────────────────────────┐
|
|
14
|
+
│ Label * │ ← FormLabel
|
|
15
|
+
│ ┌──────────────────────────────────┐ │
|
|
16
|
+
│ │ Input │ │ ← OutlinedInput / Select / etc.
|
|
17
|
+
│ └──────────────────────────────────┘ │
|
|
18
|
+
│ Helper text or error │ ← FormHelperText
|
|
19
|
+
└──────────────────────────────────────┘
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The visual gap between input and helper text is part of the FormControl's owned spacing.
|
|
23
|
+
|
|
24
|
+
## API
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
<FormControl error={hasError} required disabled={!editable}>
|
|
28
|
+
<FormLabel htmlFor="email">이메일</FormLabel>
|
|
29
|
+
<OutlinedInput id="email" value={email} onChange={...} />
|
|
30
|
+
<FormHelperText>{hasError ? errorMsg : '회사 이메일을 입력해 주세요'}</FormHelperText>
|
|
31
|
+
</FormControl>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
| Prop | Type | Default | Description |
|
|
35
|
+
| --- | --- | --- | --- |
|
|
36
|
+
| `children` | `ReactNode` | — | Label + input + helper |
|
|
37
|
+
| `error` | `boolean` | `false` | Propagates error styling to label, input, and helper |
|
|
38
|
+
| `disabled` | `boolean` | `false` | Propagates disabled to all children |
|
|
39
|
+
| `required` | `boolean` | `false` | Propagates required (visual asterisk on label) |
|
|
40
|
+
| `fullWidth` | `boolean` | `false` | 100% width |
|
|
41
|
+
| `variant` | `'outlined' \| 'filled' \| 'standard'` | `'outlined'` | Inherited by child input |
|
|
42
|
+
| `size` | `'small' \| 'medium'` | `'medium'` | Inherited by child input |
|
|
43
|
+
| `focused` | `boolean` | — | Force-focused styling (rarely needed; auto from input focus) |
|
|
44
|
+
| `margin` | `'dense' \| 'normal' \| 'none'` | `'none'` | Vertical margin |
|
|
45
|
+
|
|
46
|
+
## States
|
|
47
|
+
|
|
48
|
+
| State | Visual (cascades to children) |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| Default | Standard label + input |
|
|
51
|
+
| Focused | Label color = primary; input border = primary |
|
|
52
|
+
| Error | Label color = error; input border = error; helper text = error |
|
|
53
|
+
| Disabled | All elements muted; no hover effects |
|
|
54
|
+
|
|
55
|
+
## Tokens consumed
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
--color-fg-default
|
|
59
|
+
--color-fg-error
|
|
60
|
+
--color-fg-primary
|
|
61
|
+
--space-sm /* helper-text margin-top */
|
|
62
|
+
--space-md
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Accessibility
|
|
66
|
+
|
|
67
|
+
- The `FormLabel`'s `htmlFor` MUST match the input's `id` — without it, label clicks don't focus the input AND screen readers don't read the label.
|
|
68
|
+
- For required fields, the visual `*` is decorative; pair with `aria-required="true"` on the input itself.
|
|
69
|
+
- For error state: `aria-invalid="true"` on the input, and the FormHelperText's `id` should match `aria-describedby` so screen readers announce the error.
|
|
70
|
+
- Cite [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md) and [`knowledge/patterns/form-design.md`](../knowledge/patterns/form-design.md).
|
|
71
|
+
|
|
72
|
+
## Edge cases
|
|
73
|
+
|
|
74
|
+
- **Multiple FormControls in a row** — group them with `Stack` or `Grid`; don't try to nest one FormControl with multiple labels.
|
|
75
|
+
- **Validation message switching** — when toggling between helper text and error message, animate the color change but not the text swap (no flicker).
|
|
76
|
+
- **Korean field labels** — keep labels short (1-3 words) plus optional helper text. "이메일" not "이메일 주소를 입력해 주세요" as the label.
|
|
77
|
+
|
|
78
|
+
## Code example
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
<FormControl error={!!errors.email} required disabled={isSubmitting} fullWidth>
|
|
82
|
+
<FormLabel htmlFor="email">이메일</FormLabel>
|
|
83
|
+
<OutlinedInput
|
|
84
|
+
id="email"
|
|
85
|
+
type="email"
|
|
86
|
+
value={values.email}
|
|
87
|
+
onChange={handleChange}
|
|
88
|
+
aria-invalid={!!errors.email}
|
|
89
|
+
aria-describedby={errors.email ? "email-error" : "email-help"}
|
|
90
|
+
/>
|
|
91
|
+
<FormHelperText id={errors.email ? "email-error" : "email-help"}>
|
|
92
|
+
{errors.email ?? '회사 이메일을 입력해 주세요'}
|
|
93
|
+
</FormHelperText>
|
|
94
|
+
</FormControl>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Don't
|
|
98
|
+
|
|
99
|
+
- Don't omit `FormLabel` for a labeled field — visual placeholder text isn't a substitute (placeholders disappear on focus).
|
|
100
|
+
- Don't put the helper text in a separate paragraph outside `FormControl` — error state won't propagate.
|
|
101
|
+
- Don't toggle `required` based on user input — set it once based on schema.
|
|
102
|
+
|
|
103
|
+
## References
|
|
104
|
+
|
|
105
|
+
- MUI: [`FormControl.d.ts`](../refs/mui/packages/mui-material/src/FormControl/FormControl.d.ts)
|
|
106
|
+
|
|
107
|
+
## Cross-reference
|
|
108
|
+
|
|
109
|
+
- [`knowledge/components/INDEX.md`](../knowledge/components/INDEX.md)
|
|
110
|
+
- [`component-form-label.md`](component-form-label.md)
|
|
111
|
+
- [`component-form-helper-text.md`](component-form-helper-text.md)
|
|
112
|
+
- [`component-form-control-label.md`](component-form-control-label.md)
|
|
113
|
+
- [`knowledge/patterns/form-design.md`](../knowledge/patterns/form-design.md)
|