@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,282 @@
|
|
|
1
|
+
# `Image` — spec
|
|
2
|
+
|
|
3
|
+
> Citing Ant Design `Image`, MUI (composition), shadcn-ui (composition with native `<img>`)
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
A wrapper around `<img>` that adds: lazy loading, fallback for broken images, lightbox preview, aspect ratio enforcement, optional zoom + skeleton. Use for any non-trivial image display in product UIs.
|
|
8
|
+
|
|
9
|
+
For pure `<img>` (decorative icons, avatars): use the native element OR `Avatar` component.
|
|
10
|
+
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Default: With preview enabled (click to expand):
|
|
15
|
+
┌──────────────────────┐ ┌──────────────────────┐
|
|
16
|
+
│ │ │ │
|
|
17
|
+
│ [image] │ │ [image] 🔍 │ ← magnifier overlay
|
|
18
|
+
│ │ │ │
|
|
19
|
+
└──────────────────────┘ └──────────────────────┘
|
|
20
|
+
|
|
21
|
+
In lightbox (after click):
|
|
22
|
+
┌───────────────────────────────────────────┐
|
|
23
|
+
│ [image at full resolution, zoom enabled] │ ← modal-style overlay
|
|
24
|
+
│ │
|
|
25
|
+
│ [previous] [next] [close ✕] │
|
|
26
|
+
└───────────────────────────────────────────┘
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
<Image
|
|
33
|
+
src="/photo.jpg"
|
|
34
|
+
alt="Product photo"
|
|
35
|
+
aspectRatio="1/1"
|
|
36
|
+
preview
|
|
37
|
+
fallback="/placeholder.png"
|
|
38
|
+
loading="lazy"
|
|
39
|
+
/>
|
|
40
|
+
|
|
41
|
+
<Image.Group>
|
|
42
|
+
<Image src="/p1.jpg" alt="..." />
|
|
43
|
+
<Image src="/p2.jpg" alt="..." />
|
|
44
|
+
<Image src="/p3.jpg" alt="..." />
|
|
45
|
+
</Image.Group>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
| Prop | Type | Default | Description |
|
|
49
|
+
| --- | --- | --- | --- |
|
|
50
|
+
| `src` | `string` | — | Required. Image URL. |
|
|
51
|
+
| `alt` | `string` | — | Required. Alt text — describe meaning, or `""` for decorative. |
|
|
52
|
+
| `width` / `height` | `number \| string` | — | |
|
|
53
|
+
| `aspectRatio` | `string` | — | `"16/9"`, `"1/1"`, `"4/3"`. Cleaner than width+height. |
|
|
54
|
+
| `fit` | `"cover" \| "contain" \| "fill" \| "scale-down" \| "none"` | `"cover"` | CSS object-fit |
|
|
55
|
+
| `position` | CSS object-position | `"center"` | |
|
|
56
|
+
| `preview` | `boolean` | `false` | Click opens lightbox |
|
|
57
|
+
| `fallback` | `string \| ReactNode` | default broken-image icon | What to render on load error |
|
|
58
|
+
| `placeholder` | `ReactNode` | skeleton | What to render while loading |
|
|
59
|
+
| `loading` | `"lazy" \| "eager"` | `"lazy"` | Native lazy-load attribute |
|
|
60
|
+
| `srcset` | `string` | — | Responsive sources |
|
|
61
|
+
| `sizes` | `string` | — | Hints for srcset selection |
|
|
62
|
+
| `priority` | `boolean` | `false` | If true, sets `loading="eager"` and `fetchpriority="high"` (above-fold images) |
|
|
63
|
+
| `radius` | `"none" \| "sm" \| "md" \| "lg" \| "full"` | `"none"` | Corner radius |
|
|
64
|
+
|
|
65
|
+
### Image.Group (lightbox sequence)
|
|
66
|
+
|
|
67
|
+
When grouped, clicking any image opens the lightbox with previous/next navigation:
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
<Image.Group>
|
|
71
|
+
<Image src="/p1.jpg" alt="..." />
|
|
72
|
+
<Image src="/p2.jpg" alt="..." />
|
|
73
|
+
<Image src="/p3.jpg" alt="..." />
|
|
74
|
+
</Image.Group>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The lightbox shows previous/next arrows + counter "1 / 3".
|
|
78
|
+
|
|
79
|
+
## Behavior
|
|
80
|
+
|
|
81
|
+
### Loading sequence
|
|
82
|
+
|
|
83
|
+
1. Render skeleton (`placeholder` or default).
|
|
84
|
+
2. Browser fetches image.
|
|
85
|
+
3. On load: replace skeleton with image.
|
|
86
|
+
4. On error: render fallback.
|
|
87
|
+
|
|
88
|
+
### Aspect ratio
|
|
89
|
+
|
|
90
|
+
Use `aspectRatio` to prevent layout shift (CLS):
|
|
91
|
+
|
|
92
|
+
```css
|
|
93
|
+
.image-wrapper {
|
|
94
|
+
aspect-ratio: 16 / 9;
|
|
95
|
+
width: 100%;
|
|
96
|
+
}
|
|
97
|
+
img {
|
|
98
|
+
width: 100%;
|
|
99
|
+
height: 100%;
|
|
100
|
+
object-fit: cover;
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The wrapper takes its full width; height is computed from aspect ratio. Image fills the wrapper with object-fit cover.
|
|
105
|
+
|
|
106
|
+
### Fallback
|
|
107
|
+
|
|
108
|
+
When the image fails to load (404, CORS, network):
|
|
109
|
+
- Default: small icon (broken image symbol) + "이미지를 불러올 수 없습니다."
|
|
110
|
+
- Custom: pass `fallback` (URL or React node).
|
|
111
|
+
|
|
112
|
+
### Lightbox
|
|
113
|
+
|
|
114
|
+
When `preview: true`:
|
|
115
|
+
- Click image → opens modal-style overlay with the image at full resolution.
|
|
116
|
+
- Lightbox features: zoom (mouse wheel / pinch), pan, close on Escape, close on backdrop click.
|
|
117
|
+
- For Image.Group: keyboard arrows navigate between images; click outside closes.
|
|
118
|
+
|
|
119
|
+
### Lazy loading
|
|
120
|
+
|
|
121
|
+
Default `loading="lazy"` defers image fetch until near viewport. Saves bandwidth on long pages.
|
|
122
|
+
|
|
123
|
+
For above-fold (hero) images: set `priority` to load eagerly.
|
|
124
|
+
|
|
125
|
+
## Sizes / aspect ratios
|
|
126
|
+
|
|
127
|
+
Common ratios:
|
|
128
|
+
|
|
129
|
+
| Ratio | Use |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `1/1` | Avatars, product cards (square), Instagram-style |
|
|
132
|
+
| `4/3` | Standard photo |
|
|
133
|
+
| `16/9` | Video thumbnails, hero banners |
|
|
134
|
+
| `21/9` | Cinematic banners |
|
|
135
|
+
| `2/3` | Portrait product photos |
|
|
136
|
+
| `9/16` | Story / vertical mobile content |
|
|
137
|
+
|
|
138
|
+
Always set an aspect ratio — this prevents the browser-jumping layout shift when images load.
|
|
139
|
+
|
|
140
|
+
## States
|
|
141
|
+
|
|
142
|
+
| State | Visual |
|
|
143
|
+
| --- | --- |
|
|
144
|
+
| Loading | Skeleton (or `placeholder`) at the aspect ratio |
|
|
145
|
+
| Loaded | Image visible |
|
|
146
|
+
| Error | Fallback icon + text |
|
|
147
|
+
| Lightbox open | Modal overlay; underlying page locked |
|
|
148
|
+
| Lightbox zooming | Cursor changes to zoom-in/out; image scales |
|
|
149
|
+
|
|
150
|
+
## Tokens consumed
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
--color-bg-subtle (skeleton bg)
|
|
154
|
+
--color-text-tertiary (fallback icon)
|
|
155
|
+
--color-text-secondary (fallback caption)
|
|
156
|
+
--color-bg-overlay (lightbox backdrop, ~rgba(0,0,0,0.85))
|
|
157
|
+
--color-on-overlay (lightbox text/icons — typically white)
|
|
158
|
+
--space-md
|
|
159
|
+
--radius-md, --radius-lg, --radius-full
|
|
160
|
+
--motion-default (lightbox open/close)
|
|
161
|
+
--easing-out
|
|
162
|
+
--shadow-modal (lightbox surface)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Accessibility
|
|
166
|
+
|
|
167
|
+
### Alt text rules
|
|
168
|
+
|
|
169
|
+
- **Decorative** (alt=""): screen readers skip. Use for purely visual flourishes.
|
|
170
|
+
- **Functional** (icon-button image): `alt` describes the action.
|
|
171
|
+
- **Informational**: `alt` describes what the image shows. Don't say "image of" — screen readers announce it's an image already.
|
|
172
|
+
|
|
173
|
+
```html
|
|
174
|
+
<!-- Decorative -->
|
|
175
|
+
<img src="/decorative-blob.svg" alt="" />
|
|
176
|
+
|
|
177
|
+
<!-- Functional -->
|
|
178
|
+
<button>
|
|
179
|
+
<img src="/print-icon.svg" alt="Print this page" />
|
|
180
|
+
</button>
|
|
181
|
+
|
|
182
|
+
<!-- Informational -->
|
|
183
|
+
<img src="/team-photo.jpg" alt="Three engineers in front of a whiteboard during a sprint planning session" />
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Lightbox accessibility
|
|
187
|
+
|
|
188
|
+
- Modal pattern: focus trap, restore focus on close. See [`examples/component-modal.md`](component-modal.md).
|
|
189
|
+
- Image in lightbox: `role="img" aria-label={alt}` on the wrapper if multiple are stacked.
|
|
190
|
+
- Counter "N / M" announced on slide change via `aria-live="polite"`.
|
|
191
|
+
- Zoom: keyboard `+` / `-` for zoom in / out, `0` to reset. (Optional but nice.)
|
|
192
|
+
|
|
193
|
+
## Korean considerations
|
|
194
|
+
|
|
195
|
+
- Alt text in Korean for KR-primary apps.
|
|
196
|
+
- For e-commerce / fashion: include garment color + style in alt (helps blind users compare).
|
|
197
|
+
- For receipts / 영수증: never replace text content with screenshots without an accessible alternative.
|
|
198
|
+
|
|
199
|
+
## Code example
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
// Standard product card image
|
|
203
|
+
<Image
|
|
204
|
+
src={product.imageUrl}
|
|
205
|
+
alt={product.name}
|
|
206
|
+
aspectRatio="1/1"
|
|
207
|
+
fit="cover"
|
|
208
|
+
radius="md"
|
|
209
|
+
loading="lazy"
|
|
210
|
+
/>
|
|
211
|
+
|
|
212
|
+
// Hero image (above fold)
|
|
213
|
+
<Image
|
|
214
|
+
src="/hero.jpg"
|
|
215
|
+
alt="Workspace with laptop and coffee"
|
|
216
|
+
aspectRatio="16/9"
|
|
217
|
+
priority
|
|
218
|
+
/>
|
|
219
|
+
|
|
220
|
+
// Image gallery with lightbox
|
|
221
|
+
<Image.Group>
|
|
222
|
+
{product.images.map(img => (
|
|
223
|
+
<Image
|
|
224
|
+
key={img.id}
|
|
225
|
+
src={img.thumbnailUrl}
|
|
226
|
+
srcset={`${img.thumbnailUrl} 400w, ${img.fullUrl} 1200w`}
|
|
227
|
+
sizes="(max-width: 768px) 100vw, 400px"
|
|
228
|
+
alt={`${product.name} 사진 ${img.index}`}
|
|
229
|
+
aspectRatio="1/1"
|
|
230
|
+
preview
|
|
231
|
+
/>
|
|
232
|
+
))}
|
|
233
|
+
</Image.Group>
|
|
234
|
+
|
|
235
|
+
// Avatar-style with full radius
|
|
236
|
+
<Image
|
|
237
|
+
src={user.photoUrl}
|
|
238
|
+
alt={user.name}
|
|
239
|
+
aspectRatio="1/1"
|
|
240
|
+
radius="full"
|
|
241
|
+
fallback="/default-avatar.png"
|
|
242
|
+
/>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Edge cases
|
|
246
|
+
|
|
247
|
+
- **Image takes >5s to load**: still show skeleton; don't fall back to error prematurely. Errors are for actual failures (404, CORS).
|
|
248
|
+
- **Very large image** (10MB+): forces user to wait. Always serve resized versions via `srcset`.
|
|
249
|
+
- **Hi-DPI / retina**: serve 2x resolution for retina screens via `srcset` `2x` descriptor.
|
|
250
|
+
- **CORS-blocked image**: counts as load error, fallback renders. Inform user if it's a recurring issue.
|
|
251
|
+
- **Image with broken `src` URL**: fallback renders. Log the error for debugging (don't silently hide).
|
|
252
|
+
- **Zoomed image larger than viewport** (lightbox): allow pan; clamp at edges.
|
|
253
|
+
- **Reduced motion**: lightbox open/close animations are minimal; respect `prefers-reduced-motion`.
|
|
254
|
+
- **Print**: images print by default. For receipts/invoices: ensure print stylesheet renders them at appropriate sizes.
|
|
255
|
+
|
|
256
|
+
## Don't
|
|
257
|
+
|
|
258
|
+
- Don't omit `alt`. Even decorative images need `alt=""` (empty, but present).
|
|
259
|
+
- Don't lazy-load above-fold images. Use `priority` or `loading="eager"`.
|
|
260
|
+
- Don't render images at unspecified aspect ratio — causes layout shift.
|
|
261
|
+
- Don't put critical info only in images. Provide text alternative.
|
|
262
|
+
- Don't auto-zoom without user input. The user should drive zoom.
|
|
263
|
+
- Don't use `Image` for icons. Use `Icon` component or inline SVG.
|
|
264
|
+
- Don't ship images without responsive sources (`srcset`/`sizes`) for content-heavy pages.
|
|
265
|
+
|
|
266
|
+
## References
|
|
267
|
+
|
|
268
|
+
- Ant Design: [`refs/ant-design/components/image/`](../refs/ant-design/components/image/) — `Image` + `Image.PreviewGroup` for lightbox. Has `placeholder`, `fallback`, `preview` config. Solid impl.
|
|
269
|
+
- MUI: no dedicated component. Compose with native `<img>`.
|
|
270
|
+
- shadcn-ui: no built-in. Compose `<img>` + Tailwind. For lightbox: `react-photo-view` or `yet-another-react-lightbox`.
|
|
271
|
+
|
|
272
|
+
API choices made:
|
|
273
|
+
- **`aspectRatio` as first-class prop**: prevents layout shift; cleaner than separate width+height.
|
|
274
|
+
- **`preview` opt-in**: most images don't need lightbox; opting in is the right friction.
|
|
275
|
+
- **`Image.Group` for sequence**: mirrors Ant's pattern; lightbox navigates within group.
|
|
276
|
+
- **`priority` boolean**: simpler than passing `loading="eager"` + `fetchpriority="high"` separately for the common above-fold case.
|
|
277
|
+
|
|
278
|
+
## Cross-reference
|
|
279
|
+
|
|
280
|
+
- [`examples/component-avatar.md`](component-avatar.md) — for user/profile images (different fallback semantics)
|
|
281
|
+
- [`examples/component-modal.md`](component-modal.md) — lightbox uses modal a11y pattern
|
|
282
|
+
- [`knowledge/a11y/contrast.md`](../knowledge/a11y/contrast.md) — text on image overlays
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# `InputAdornment` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from MUI `InputAdornment`. Leading or trailing content slot for an input — icons (search, calendar, currency), text prefixes/suffixes (`₩`, `@`), or interactive controls (clear button, password toggle).
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Search input → leading magnifying glass.
|
|
8
|
+
- Currency input → leading `₩` or `$`.
|
|
9
|
+
- Password input → trailing show/hide toggle.
|
|
10
|
+
- Email input → trailing domain hint.
|
|
11
|
+
|
|
12
|
+
## API
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
<OutlinedInput
|
|
16
|
+
startAdornment={
|
|
17
|
+
<InputAdornment position="start">
|
|
18
|
+
<SearchIcon />
|
|
19
|
+
</InputAdornment>
|
|
20
|
+
}
|
|
21
|
+
endAdornment={
|
|
22
|
+
<InputAdornment position="end">
|
|
23
|
+
<IconButton aria-label="지우기" size="small">
|
|
24
|
+
<CloseIcon />
|
|
25
|
+
</IconButton>
|
|
26
|
+
</InputAdornment>
|
|
27
|
+
}
|
|
28
|
+
/>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| Prop | Type | Default | Description |
|
|
32
|
+
| --- | --- | --- | --- |
|
|
33
|
+
| `position` | `'start' \| 'end'` | required | Which side |
|
|
34
|
+
| `children` | `ReactNode` | — | The content |
|
|
35
|
+
| `disablePointerEvents` | `boolean` | `false` | When the adornment is decorative-only (icon, prefix text), this lets clicks pass through to the input |
|
|
36
|
+
| `disableTypography` | `boolean` | `false` | Skip default Typography wrapping (for non-text adornments) |
|
|
37
|
+
|
|
38
|
+
## Tokens consumed
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
--space-sm /* gap between adornment and input value */
|
|
42
|
+
--icon-size-md /* default 24px */
|
|
43
|
+
--color-fg-muted /* default adornment color */
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Accessibility
|
|
47
|
+
|
|
48
|
+
- **Decorative icons**: set `aria-hidden="true"` on the icon + `disablePointerEvents={true}` on the adornment.
|
|
49
|
+
- **Interactive adornments** (clear button, password toggle): use `IconButton` inside with explicit `aria-label`. Set `edge="start"` or `edge="end"` on the IconButton for proper alignment.
|
|
50
|
+
- **Text prefixes** like `₩` are decorative — wrap in `<Typography>` and `aria-hidden="true"`. The input's `inputMode="decimal"` + numeric value handle the actual semantics.
|
|
51
|
+
|
|
52
|
+
## Edge cases
|
|
53
|
+
|
|
54
|
+
- **Adornment focus tab order** — interactive adornments are part of the tab order BEFORE/AFTER the input, depending on `position`. End-adornments tab AFTER the input — usually correct (clear button after typing).
|
|
55
|
+
- **Korean prefix labels** — for "원" suffix, use `position="end"`. Don't put it inside the input as text — the input's value should stay numeric.
|
|
56
|
+
- **Combining start + end** — fine, but watch for narrow widths; long text in both can squeeze the input.
|
|
57
|
+
|
|
58
|
+
## Code example
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
function PriceInput({ value, onChange }) {
|
|
62
|
+
return (
|
|
63
|
+
<FormControl fullWidth>
|
|
64
|
+
<FormLabel htmlFor="price">가격</FormLabel>
|
|
65
|
+
<OutlinedInput
|
|
66
|
+
id="price"
|
|
67
|
+
type="number"
|
|
68
|
+
inputMode="decimal"
|
|
69
|
+
value={value}
|
|
70
|
+
onChange={(e) => onChange(Number(e.target.value))}
|
|
71
|
+
startAdornment={
|
|
72
|
+
<InputAdornment position="start" disablePointerEvents>
|
|
73
|
+
<Typography aria-hidden>₩</Typography>
|
|
74
|
+
</InputAdornment>
|
|
75
|
+
}
|
|
76
|
+
endAdornment={
|
|
77
|
+
<InputAdornment position="end" disablePointerEvents>
|
|
78
|
+
<Typography color="text.secondary" aria-hidden>원</Typography>
|
|
79
|
+
</InputAdornment>
|
|
80
|
+
}
|
|
81
|
+
/>
|
|
82
|
+
</FormControl>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Don't
|
|
88
|
+
|
|
89
|
+
- Don't put non-trivial UI in adornments (whole forms, multi-line text) — they collapse oddly.
|
|
90
|
+
- Don't omit `aria-label` on interactive adornments.
|
|
91
|
+
- Don't set `disablePointerEvents` on interactive adornments — it breaks them.
|
|
92
|
+
|
|
93
|
+
## References
|
|
94
|
+
|
|
95
|
+
- MUI: [`InputAdornment`](../refs/mui/packages/mui-material/src/InputAdornment/)
|
|
96
|
+
|
|
97
|
+
## Cross-reference
|
|
98
|
+
|
|
99
|
+
- [`component-input-base.md`](component-input-base.md)
|
|
100
|
+
- [`component-outlined-input.md`](component-outlined-input.md)
|
|
101
|
+
- [`component-amount-input.md`](component-amount-input.md) — currency-specific composition
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# `InputBase` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from MUI `InputBase`. The unstyled foundation of every MUI input variant (`OutlinedInput`, `FilledInput`, `Input`, `TextField`'s internals). Use directly when you need a fully custom-styled input that still gets MUI's accessibility + IME + adornment behavior.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Building a custom-styled input that doesn't fit `OutlinedInput`/`FilledInput`.
|
|
8
|
+
- Composition primitive for design-system-specific input variants.
|
|
9
|
+
- For 99% of cases, prefer `OutlinedInput` (default styling + label notch).
|
|
10
|
+
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
┌─[start adornment]─[input element]─[end adornment]─┐
|
|
15
|
+
│ │
|
|
16
|
+
└────────────────────────────────────────────────────┘
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## API
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
<InputBase
|
|
23
|
+
inputProps={{ "aria-label": "search" }}
|
|
24
|
+
startAdornment={<SearchIcon />}
|
|
25
|
+
placeholder="검색..."
|
|
26
|
+
sx={{ /* full custom styling */ }}
|
|
27
|
+
/>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
39 props (full surface). Most-used:
|
|
31
|
+
|
|
32
|
+
| Prop | Type | Default | Description |
|
|
33
|
+
| --- | --- | --- | --- |
|
|
34
|
+
| `value` / `defaultValue` | `unknown` | — | Controlled / uncontrolled value |
|
|
35
|
+
| `onChange` | `(e) => void` | — | Change handler |
|
|
36
|
+
| `type` | `string` | `'text'` | HTML input type |
|
|
37
|
+
| `multiline` | `boolean` | `false` | Render as `<textarea>` |
|
|
38
|
+
| `rows` / `minRows` / `maxRows` | `number` | — | Multi-line height |
|
|
39
|
+
| `placeholder` | `string` | — | Placeholder text |
|
|
40
|
+
| `startAdornment` / `endAdornment` | `ReactNode` | — | Leading/trailing content |
|
|
41
|
+
| `disabled` | `boolean` | `false` | |
|
|
42
|
+
| `readOnly` | `boolean` | `false` | Caret disabled, no editing |
|
|
43
|
+
| `error` | `boolean` | `false` | Error state |
|
|
44
|
+
| `fullWidth` | `boolean` | `false` | |
|
|
45
|
+
| `autoFocus` | `boolean` | `false` | Focus on mount |
|
|
46
|
+
| `inputProps` | `InputHTMLAttributes` | — | Pass-through to native input (autoComplete, inputMode, pattern, maxLength, etc.) |
|
|
47
|
+
| `inputRef` | `Ref` | — | Ref to native input |
|
|
48
|
+
| `inputComponent` | `ElementType` | `'input'` | Override the inner element (e.g., for masked input libraries) |
|
|
49
|
+
| `name` | `string` | — | Form name |
|
|
50
|
+
| `required` | `boolean` | `false` | |
|
|
51
|
+
| `slots` / `slotProps` | `object` | — | MUI v5+ component override pattern |
|
|
52
|
+
| `sx` | `SxProps` | — | Style override |
|
|
53
|
+
|
|
54
|
+
## States
|
|
55
|
+
|
|
56
|
+
| State | Visual |
|
|
57
|
+
| --- | --- |
|
|
58
|
+
| Default | inherits parent FormControl styling |
|
|
59
|
+
| Focus | inherits FormControl focus styling |
|
|
60
|
+
| Disabled | reduced opacity, no caret |
|
|
61
|
+
| Error | inherits FormControl error styling |
|
|
62
|
+
| Read-only | no caret, but still focusable + selectable |
|
|
63
|
+
|
|
64
|
+
## Tokens consumed
|
|
65
|
+
|
|
66
|
+
InputBase has no built-in tokens — it inherits from the parent FormControl + your custom `sx` styles. Token cascade comes from the variant wrapper (`OutlinedInput`, `FilledInput`).
|
|
67
|
+
|
|
68
|
+
## Accessibility
|
|
69
|
+
|
|
70
|
+
- `inputProps` is the right place for native semantics: `autoComplete`, `inputMode`, `pattern`, `maxLength`, `aria-*`.
|
|
71
|
+
- For required: pair `required` with `aria-required="true"` (for older AT compatibility).
|
|
72
|
+
- `inputComponent` is the seam for masked-input libraries (react-imask, react-text-mask) — they need to forward refs correctly; check the library docs.
|
|
73
|
+
- Cite [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md).
|
|
74
|
+
|
|
75
|
+
## Edge cases
|
|
76
|
+
|
|
77
|
+
- **Korean IME composition** — `onChange` fires per keystroke including IME composition. For "search-as-you-type" patterns, use `onCompositionEnd` instead. Cite [`knowledge/i18n/korean-typography.md`](../knowledge/i18n/korean-typography.md).
|
|
78
|
+
- **`inputComponent` swap** — when using a masked-input lib, the component must implement `forwardRef` correctly. Common gotcha: cursor jumps on every keystroke if the implementation doesn't preserve selection.
|
|
79
|
+
- **`multiline=true` + `maxRows`** — the textarea grows up to `maxRows` then becomes scrollable. Don't set both `rows` and `maxRows` — pick auto-grow or fixed.
|
|
80
|
+
- **`type="search"`** — adds an "X" clear button in some browsers (Safari, Chrome on macOS). For consistent UX, render your own end-adornment with a clear icon.
|
|
81
|
+
|
|
82
|
+
## Code example
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
// Custom search field with clear + icon
|
|
86
|
+
function SearchField({ value, onChange, onClear }) {
|
|
87
|
+
return (
|
|
88
|
+
<InputBase
|
|
89
|
+
value={value}
|
|
90
|
+
onChange={(e) => onChange(e.target.value)}
|
|
91
|
+
placeholder="검색..."
|
|
92
|
+
sx={{
|
|
93
|
+
bgcolor: 'background.paper',
|
|
94
|
+
border: 1,
|
|
95
|
+
borderColor: 'divider',
|
|
96
|
+
borderRadius: 1,
|
|
97
|
+
px: 2,
|
|
98
|
+
py: 1,
|
|
99
|
+
'&:focus-within': { borderColor: 'primary.main' },
|
|
100
|
+
}}
|
|
101
|
+
startAdornment={
|
|
102
|
+
<SearchIcon sx={{ color: 'text.secondary', mr: 1 }} aria-hidden />
|
|
103
|
+
}
|
|
104
|
+
endAdornment={
|
|
105
|
+
value && (
|
|
106
|
+
<IconButton size="small" onClick={onClear} aria-label="검색어 지우기">
|
|
107
|
+
<CloseIcon fontSize="small" />
|
|
108
|
+
</IconButton>
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
inputProps={{ "aria-label": "검색", autoComplete: "off" }}
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Don't
|
|
118
|
+
|
|
119
|
+
- Don't use directly when an existing variant (`OutlinedInput`, `FilledInput`, `TextField`) fits — you'll re-implement focus styling, label association, and helper-text wiring.
|
|
120
|
+
- Don't omit `inputProps={{ "aria-label": ... }}` if there's no associated `<label>` — the input has no accessible name otherwise.
|
|
121
|
+
- Don't pass styling via `style` prop — use `sx` for theme integration.
|
|
122
|
+
|
|
123
|
+
## References
|
|
124
|
+
|
|
125
|
+
- MUI: [`InputBase`](../refs/mui/packages/mui-material/src/InputBase/)
|
|
126
|
+
|
|
127
|
+
## Cross-reference
|
|
128
|
+
|
|
129
|
+
- [`component-outlined-input.md`](component-outlined-input.md) — outlined variant (default)
|
|
130
|
+
- [`component-filled-input.md`](component-filled-input.md) — filled variant
|
|
131
|
+
- [`component-input.md`](component-input.md) — standard variant
|
|
132
|
+
- [`component-input-adornment.md`](component-input-adornment.md)
|
|
133
|
+
- [`component-form-control.md`](component-form-control.md)
|
|
134
|
+
- [`knowledge/i18n/korean-typography.md`](../knowledge/i18n/korean-typography.md) — IME notes
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# `InputNumber` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from Ant Design `InputNumber`. Numeric input with up/down stepper buttons, formatting, and min/max constraints. shadcn / MUI ship a generic `<TextField type="number">` instead — Ant's specialized component handles formatting (commas, decimals), parsing, and IME edge cases that the generic falls down on.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Quantities (수량, 인원, 횟수).
|
|
8
|
+
- Prices / amounts where commas matter.
|
|
9
|
+
- Bounded inputs (rating 1-5, percentage 0-100).
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- Currency input with extensive formatting → use a specialized `AmountInput` per [`knowledge/patterns/money-and-amount.md`](../knowledge/patterns/money-and-amount.md).
|
|
14
|
+
- Phone numbers → text input with masking, not numeric.
|
|
15
|
+
|
|
16
|
+
## Anatomy
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
┌────────────────┐
|
|
20
|
+
│ 12,345 ▲▼ │ ← stepper buttons (up/down)
|
|
21
|
+
└────────────────┘
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## API
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
<InputNumber
|
|
28
|
+
min={0}
|
|
29
|
+
max={100}
|
|
30
|
+
step={1}
|
|
31
|
+
value={qty}
|
|
32
|
+
onChange={setQty}
|
|
33
|
+
formatter={(v) => `${v}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
|
|
34
|
+
parser={(v) => v.replace(/,/g, '')}
|
|
35
|
+
addonAfter="개"
|
|
36
|
+
/>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
| Prop | Type | Default | Description |
|
|
40
|
+
| --- | --- | --- | --- |
|
|
41
|
+
| `value` / `defaultValue` | `number` | — | Controlled / uncontrolled value |
|
|
42
|
+
| `onChange` | `(value) => void` | — | Fires on commit (blur, Enter, stepper) |
|
|
43
|
+
| `min` / `max` | `number` | `-Infinity` / `Infinity` | Bounds |
|
|
44
|
+
| `step` | `number` | `1` | Stepper increment |
|
|
45
|
+
| `precision` | `number` | — | Decimal places |
|
|
46
|
+
| `formatter` | `(value) => string` | — | Display transform (e.g., add commas) |
|
|
47
|
+
| `parser` | `(displayValue) => number` | — | Reverse the formatter on input |
|
|
48
|
+
| `controls` | `boolean \| { upIcon, downIcon }` | `true` | Show stepper buttons |
|
|
49
|
+
| `prefix` / `addonBefore` | `ReactNode` | — | Leading content (icon / unit) |
|
|
50
|
+
| `suffix` / `addonAfter` | `ReactNode` | — | Trailing content (unit / "원") |
|
|
51
|
+
| `disabled` | `boolean` | `false` | |
|
|
52
|
+
| `size` | `'small' \| 'middle' \| 'large'` | `'middle'` | |
|
|
53
|
+
| `keyboard` | `boolean` | `true` | Enable arrow keys to step |
|
|
54
|
+
| `stringMode` | `boolean` | `false` | Use string for big-int values (decimals beyond JS number precision) |
|
|
55
|
+
| `status` | `'error' \| 'warning'` | — | Validation state |
|
|
56
|
+
|
|
57
|
+
## States
|
|
58
|
+
|
|
59
|
+
| State | Visual |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| Default | Border, fg-default |
|
|
62
|
+
| Focus | Brand border + ring |
|
|
63
|
+
| Hover | Stepper buttons reveal (or always visible per design system) |
|
|
64
|
+
| Error | Red border + helper |
|
|
65
|
+
| Disabled | Muted, stepper hidden |
|
|
66
|
+
|
|
67
|
+
## Tokens consumed
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
--input-bg
|
|
71
|
+
--input-border
|
|
72
|
+
--input-border-focus
|
|
73
|
+
--input-border-error
|
|
74
|
+
--input-min-height-32
|
|
75
|
+
--input-min-height-40
|
|
76
|
+
--input-padding-x
|
|
77
|
+
--font-family-mono /* tabular numerals for clean alignment */
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Accessibility
|
|
81
|
+
|
|
82
|
+
- Renders as `<input type="text" inputmode="decimal">` (NOT `type="number"` — that breaks `formatter`).
|
|
83
|
+
- Stepper buttons need `aria-label="증가"` / `aria-label="감소"`.
|
|
84
|
+
- Arrow Up/Down keys step through values when focused.
|
|
85
|
+
- For min/max bounds, surface invalid attempts via `aria-invalid` + helper text rather than silently clamping.
|
|
86
|
+
- Cite [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md).
|
|
87
|
+
|
|
88
|
+
## Edge cases
|
|
89
|
+
|
|
90
|
+
- **Korean IME entering numbers** — IME shouldn't intercept; `inputmode="decimal"` brings up numeric keyboard on mobile. Test on a real device — desktop testing misses IME edge cases per [`knowledge/i18n/korean-typography.md`](../knowledge/i18n/korean-typography.md).
|
|
91
|
+
- **Paste with formatting** — "12,345원" pasted should parse to 12345 via `parser`. Don't reject — clean it.
|
|
92
|
+
- **Decimal precision overflow** — JS `0.1 + 0.2 = 0.30000000000000004`. Use `precision={2}` + display rounding, or `stringMode` for invoices/finance.
|
|
93
|
+
- **Negative values** — explicit `min={0}` if not allowed; otherwise minus sign is accepted.
|
|
94
|
+
- **Empty value** — `value=null` vs `value=undefined` vs `value=0` are distinct. Decide your convention; document it.
|
|
95
|
+
- **Big numbers (> Number.MAX_SAFE_INTEGER)** — use `stringMode={true}` to keep precision.
|
|
96
|
+
|
|
97
|
+
## Code example
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
// Quantity picker
|
|
101
|
+
<InputNumber
|
|
102
|
+
min={1}
|
|
103
|
+
max={99}
|
|
104
|
+
defaultValue={1}
|
|
105
|
+
onChange={(qty) => setQty(qty ?? 1)}
|
|
106
|
+
addonAfter="개"
|
|
107
|
+
size="middle"
|
|
108
|
+
aria-label="수량"
|
|
109
|
+
/>
|
|
110
|
+
|
|
111
|
+
// Price input with comma formatting
|
|
112
|
+
<InputNumber
|
|
113
|
+
min={0}
|
|
114
|
+
step={100}
|
|
115
|
+
precision={0}
|
|
116
|
+
value={price}
|
|
117
|
+
onChange={setPrice}
|
|
118
|
+
addonBefore="₩"
|
|
119
|
+
formatter={(v) => `${v}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
|
|
120
|
+
parser={(v) => Number(v?.replace(/,/g, '') ?? 0)}
|
|
121
|
+
style={{ width: '100%' }}
|
|
122
|
+
/>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Don't
|
|
126
|
+
|
|
127
|
+
- Don't use `<input type="number">` for prices — formatting/IME break.
|
|
128
|
+
- Don't silently clamp to bounds without a message — user wonders why their input changed.
|
|
129
|
+
- Don't omit unit suffix for ambiguous numbers (12 what?).
|
|
130
|
+
- Don't use without `inputmode="decimal"` on mobile.
|
|
131
|
+
|
|
132
|
+
## References
|
|
133
|
+
|
|
134
|
+
- Ant Design: [`InputNumber`](../refs/ant-design/components/input-number/)
|
|
135
|
+
|
|
136
|
+
## Cross-reference
|
|
137
|
+
|
|
138
|
+
- [`knowledge/patterns/money-and-amount.md`](../knowledge/patterns/money-and-amount.md)
|
|
139
|
+
- [`knowledge/i18n/korean-typography.md`](../knowledge/i18n/korean-typography.md)
|
|
140
|
+
- [`component-input.md`](component-input.md)
|
|
141
|
+
- [`component-amount-input.md`](component-amount-input.md)
|