@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,99 @@
|
|
|
1
|
+
# `Switch` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from Ant Design `Switch`, MUI `Switch`, shadcn-ui `switch`. iOS-style toggle for binary on/off settings. See [`component-form-controls.md`](component-form-controls.md) for Switch + Checkbox + Radio comparison.
|
|
4
|
+
|
|
5
|
+
## Switch vs Checkbox
|
|
6
|
+
|
|
7
|
+
> **Switch = immediate effect setting. Checkbox = form input.**
|
|
8
|
+
|
|
9
|
+
- Settings page: `Switch` ("Enable notifications" — toggles immediately).
|
|
10
|
+
- Signup form: `Checkbox` ("I agree to terms" — submitted with form).
|
|
11
|
+
|
|
12
|
+
## Anatomy
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
Off: ◯━━ ━━━━━ On: ━━━━━ ━━●
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Track + thumb. Thumb slides from left to right when toggled.
|
|
19
|
+
|
|
20
|
+
## API
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
<Switch
|
|
24
|
+
checked={enabled}
|
|
25
|
+
onCheckedChange={setEnabled}
|
|
26
|
+
id="notifications"
|
|
27
|
+
/>
|
|
28
|
+
|
|
29
|
+
<Switch checked={loading ? enabled : ...} disabled={loading} />
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
| Prop | Type | Default | Description |
|
|
33
|
+
| --- | --- | --- | --- |
|
|
34
|
+
| `checked` | `boolean` | controlled | State |
|
|
35
|
+
| `defaultChecked` | `boolean` | `false` | Uncontrolled initial |
|
|
36
|
+
| `onCheckedChange` | `(checked: boolean) => void` | — | Callback |
|
|
37
|
+
| `disabled` | `boolean` | `false` | — |
|
|
38
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | — |
|
|
39
|
+
| `name` / `value` | `string` | — | Form attributes |
|
|
40
|
+
|
|
41
|
+
## Sizes
|
|
42
|
+
|
|
43
|
+
| Size | Track w×h | Thumb |
|
|
44
|
+
| --- | --- | --- |
|
|
45
|
+
| sm | 28×16 | 12 |
|
|
46
|
+
| md (default) | 44×24 | 20 |
|
|
47
|
+
| lg | 56×32 | 28 |
|
|
48
|
+
|
|
49
|
+
Touch target ≥ 44pt regardless via padding.
|
|
50
|
+
|
|
51
|
+
## States
|
|
52
|
+
|
|
53
|
+
| State | Visual |
|
|
54
|
+
| --- | --- |
|
|
55
|
+
| Off | Track: muted gray; thumb left |
|
|
56
|
+
| On | Track: brand color; thumb right |
|
|
57
|
+
| Hover | Subtle track color shift |
|
|
58
|
+
| Focus-visible | Ring around track |
|
|
59
|
+
| Disabled | Reduced opacity |
|
|
60
|
+
| Loading (optional) | Spinner replaces thumb |
|
|
61
|
+
|
|
62
|
+
## Tokens consumed
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
--switch-track-off
|
|
66
|
+
--switch-track-on (brand)
|
|
67
|
+
--switch-thumb
|
|
68
|
+
--switch-thumb-disabled
|
|
69
|
+
--motion-fast (200ms slide)
|
|
70
|
+
--ease-out
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Accessibility
|
|
74
|
+
|
|
75
|
+
- `<button role="switch" aria-checked="true|false">`.
|
|
76
|
+
- `aria-label` if no visible label.
|
|
77
|
+
- Keyboard: Space toggles; Enter doesn't (per WAI-ARIA Switch).
|
|
78
|
+
|
|
79
|
+
## Korean conventions
|
|
80
|
+
|
|
81
|
+
- 알림 받기, 다크 모드, 자동 저장 — typical settings labels (해요체).
|
|
82
|
+
- For 마케팅 정보 수신: use Checkbox (form), not Switch (immediate effect).
|
|
83
|
+
|
|
84
|
+
## Don't
|
|
85
|
+
|
|
86
|
+
- Don't use Switch in forms with Submit. That's Checkbox.
|
|
87
|
+
- Don't make Switch < 28px wide. Touch / readability.
|
|
88
|
+
- Don't lazy-render label state ("On" / "Off") — let the visual track show state.
|
|
89
|
+
|
|
90
|
+
## References
|
|
91
|
+
|
|
92
|
+
- Ant: [`Switch`](../refs/ant-design/components/switch)
|
|
93
|
+
- MUI: [`Switch`](../refs/mui/packages/mui-material/src/Switch)
|
|
94
|
+
- shadcn-ui: [`switch`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/switch.tsx)
|
|
95
|
+
|
|
96
|
+
## Cross-reference
|
|
97
|
+
|
|
98
|
+
- [`examples/component-form-controls.md`](component-form-controls.md)
|
|
99
|
+
- [`examples/component-checkbox.md`](component-checkbox.md)
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# `TabScrollButton` - spec
|
|
2
|
+
|
|
3
|
+
> Direct upstream component: MUI `TabScrollButton`. Parent pattern references: Ant Design `Tabs`, MUI `Tabs`, shadcn-ui `tabs`.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
`TabScrollButton` is the overflow affordance used by scrollable tab lists. It moves the tab strip left/right or up/down when there are more tabs than fit in the available space.
|
|
8
|
+
|
|
9
|
+
It is a supporting control for `Tabs`, not a tab and not page navigation.
|
|
10
|
+
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Tabs
|
|
15
|
+
├── Start TabScrollButton optional; appears when content can scroll backward
|
|
16
|
+
├── TabList
|
|
17
|
+
│ ├── Tab
|
|
18
|
+
│ ├── Tab
|
|
19
|
+
│ └── Tab
|
|
20
|
+
└── End TabScrollButton optional; appears when content can scroll forward
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
| Part | Required | Purpose |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| Root | yes | Scroll command container. |
|
|
26
|
+
| Direction icon | yes | Communicates scroll direction. |
|
|
27
|
+
| Start/end slot | optional | Allows custom icons while preserving behavior. |
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
<TabScrollButton
|
|
33
|
+
direction="right"
|
|
34
|
+
orientation="horizontal"
|
|
35
|
+
disabled={!canScrollForward}
|
|
36
|
+
aria-label="다음 탭 보기"
|
|
37
|
+
/>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
| Prop | Type | Default | Description |
|
|
41
|
+
| --- | --- | --- | --- |
|
|
42
|
+
| `children` | `ReactNode` | - | Optional custom content. Usually omit and use icon slots. |
|
|
43
|
+
| `classes` | `Partial<TabScrollButtonClasses>` | - | Style override hooks for MUI-style implementations. |
|
|
44
|
+
| `direction` | `"left" \| "right"` | required | Visual/behavioral scroll direction. |
|
|
45
|
+
| `disabled` | `boolean` | `false` | Disabled when the tab strip cannot scroll further in that direction. |
|
|
46
|
+
| `orientation` | `"horizontal" \| "vertical"` | required | Tab list orientation. |
|
|
47
|
+
| `slots` | `{ StartScrollButtonIcon?, EndScrollButtonIcon? }` | `{}` | Custom start/end icon components. |
|
|
48
|
+
| `slotProps` | `{ startScrollButtonIcon?, endScrollButtonIcon? }` | `{}` | Props forwarded to icon slots. |
|
|
49
|
+
| `sx` | `SxProps<Theme>` | - | MUI system override. Prefer tokens for shared design-system code. |
|
|
50
|
+
|
|
51
|
+
Inherits most `ButtonBase` props in MUI, except native button behavior is intentionally customized.
|
|
52
|
+
|
|
53
|
+
## API choices made
|
|
54
|
+
|
|
55
|
+
- Keep `direction` and `orientation` required because icon rotation and scroll behavior depend on both.
|
|
56
|
+
- Keep `disabled` explicit so first/last scroll limits are represented in DOM and visuals.
|
|
57
|
+
- Do not expose `onScrollTabs` in this spec; the parent `Tabs` component should own scroll position and click handlers.
|
|
58
|
+
- Do not treat `TabScrollButton` as a `Tabs.Trigger`. It must stay outside the tab roving-focus model.
|
|
59
|
+
|
|
60
|
+
## States
|
|
61
|
+
|
|
62
|
+
| State | Trigger | Visual rule |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| Hidden | No overflow in that direction | Do not render, or render with zero interaction and no layout jump depending on parent Tabs strategy. |
|
|
65
|
+
| Default | Overflow available | Icon uses secondary text color; fixed control width/height. |
|
|
66
|
+
| Hover | Pointer over enabled control | Subtle background. |
|
|
67
|
+
| Focus-visible | Keyboard focus if implemented as a real button | 2px focus ring with at least 3:1 contrast. |
|
|
68
|
+
| Active | Press | Pressed background; scroll distance remains deterministic. |
|
|
69
|
+
| Disabled | At scroll limit | Muted or transparent; no activation. |
|
|
70
|
+
| Vertical | `orientation="vertical"` | Icon rotates to indicate up/down movement. |
|
|
71
|
+
| RTL | Directional context | Horizontal start/end behavior mirrors with text direction. |
|
|
72
|
+
|
|
73
|
+
## Tokens consumed
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
--color-bg-default
|
|
77
|
+
--color-bg-subtle
|
|
78
|
+
--color-text-secondary
|
|
79
|
+
--color-text-disabled
|
|
80
|
+
--color-focus-ring
|
|
81
|
+
--space-xs
|
|
82
|
+
--space-sm
|
|
83
|
+
--tabs-scroll-button-size
|
|
84
|
+
--icon-size-sm
|
|
85
|
+
--radius-sm
|
|
86
|
+
--motion-fast
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
If `--tabs-scroll-button-size` does not exist, map it to the tab trigger height for the current size.
|
|
90
|
+
|
|
91
|
+
## Accessibility
|
|
92
|
+
|
|
93
|
+
- The control must not be part of the `role="tablist"` roving focus sequence.
|
|
94
|
+
- If your implementation makes it user-clickable, render a real `<button type="button">` with labels such as `aria-label="이전 탭 보기"` and `aria-label="다음 탭 보기"`.
|
|
95
|
+
- If matching MUI's internal presentational pattern, ensure the same scroll action is available through pointer drag/trackpad scroll and tab-list arrow-key navigation.
|
|
96
|
+
- Disabled controls need native `disabled` or `aria-disabled="true"` plus suppressed activation.
|
|
97
|
+
- Touch target must be at least 44x44 on mobile.
|
|
98
|
+
- Icons are decorative when the button has an accessible label; set icon `aria-hidden="true"`.
|
|
99
|
+
|
|
100
|
+
### Keyboard
|
|
101
|
+
|
|
102
|
+
| Key | Behavior |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| `Tab` | Enters active tab, not every tab and not hidden scroll controls, unless scroll controls are implemented as visible buttons. |
|
|
105
|
+
| `Enter` / `Space` | Activates the scroll button only when it is a focusable real button. |
|
|
106
|
+
| Arrow keys | Move between tabs through the parent Tabs pattern. |
|
|
107
|
+
|
|
108
|
+
## Layout rules
|
|
109
|
+
|
|
110
|
+
| Rule | Value |
|
|
111
|
+
| --- | --- |
|
|
112
|
+
| Horizontal size | Fixed inline size matching the parent density; commonly 40px equivalent. |
|
|
113
|
+
| Vertical size | Full tab-list width with fixed block size. |
|
|
114
|
+
| Position | At the start/end edge of the scroll container. |
|
|
115
|
+
| Overlay | Avoid covering tab labels; reserve space or use gradient mask plus button. |
|
|
116
|
+
| Motion | Smooth scroll is allowed, but disable it for `prefers-reduced-motion`. |
|
|
117
|
+
|
|
118
|
+
## Code example
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
function ScrollableTabsHeader({ tabs, value, onValueChange }: Props) {
|
|
122
|
+
return (
|
|
123
|
+
<Tabs value={value} onValueChange={onValueChange} variant="underline">
|
|
124
|
+
<TabScrollButton
|
|
125
|
+
direction="left"
|
|
126
|
+
orientation="horizontal"
|
|
127
|
+
disabled={!canScrollBack}
|
|
128
|
+
aria-label="이전 탭 보기"
|
|
129
|
+
onClick={scrollBack}
|
|
130
|
+
/>
|
|
131
|
+
<Tabs.List>
|
|
132
|
+
{tabs.map((tab) => (
|
|
133
|
+
<Tabs.Trigger key={tab.value} value={tab.value}>
|
|
134
|
+
{tab.label}
|
|
135
|
+
</Tabs.Trigger>
|
|
136
|
+
))}
|
|
137
|
+
</Tabs.List>
|
|
138
|
+
<TabScrollButton
|
|
139
|
+
direction="right"
|
|
140
|
+
orientation="horizontal"
|
|
141
|
+
disabled={!canScrollForward}
|
|
142
|
+
aria-label="다음 탭 보기"
|
|
143
|
+
onClick={scrollForward}
|
|
144
|
+
/>
|
|
145
|
+
</Tabs>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Edge cases
|
|
151
|
+
|
|
152
|
+
- **No overflow**: hide both controls or keep reserved space consistently. Do not show disabled arrows forever in compact mobile UIs.
|
|
153
|
+
- **RTL**: visual arrows and scroll math must be tested together; browser `scrollLeft` behavior differs by engine.
|
|
154
|
+
- **Vertical tabs**: rotate or swap icons so the control reads as up/down, not left/right.
|
|
155
|
+
- **Touch devices**: horizontal swipe/drag should work even when scroll buttons are hidden.
|
|
156
|
+
- **Many tabs**: keep arrow-key navigation functional for all tabs, including off-screen tabs.
|
|
157
|
+
- **Reduced motion**: use instant scroll instead of smooth scrolling.
|
|
158
|
+
- **High contrast mode**: do not rely on opacity alone for disabled state; pair with `disabled` semantics.
|
|
159
|
+
|
|
160
|
+
## Don't
|
|
161
|
+
|
|
162
|
+
- Don't render scroll buttons as tabs.
|
|
163
|
+
- Don't include scroll buttons in the tab count announced to screen readers.
|
|
164
|
+
- Don't use a "More" dropdown as the first solution for overflowed tabs.
|
|
165
|
+
- Don't hide off-screen tabs from the accessibility tree if they are still part of the tab set.
|
|
166
|
+
|
|
167
|
+
## References
|
|
168
|
+
|
|
169
|
+
- MUI direct source: [`refs/mui/packages/mui-material/src/TabScrollButton/TabScrollButton.d.ts`](../refs/mui/packages/mui-material/src/TabScrollButton/TabScrollButton.d.ts)
|
|
170
|
+
- MUI implementation: [`refs/mui/packages/mui-material/src/TabScrollButton/TabScrollButton.js`](../refs/mui/packages/mui-material/src/TabScrollButton/TabScrollButton.js)
|
|
171
|
+
- MUI tabs source: [`refs/mui/packages/mui-material/src/Tabs/`](../refs/mui/packages/mui-material/src/Tabs/)
|
|
172
|
+
- Ant Design parent pattern: [`refs/ant-design/components/tabs/`](../refs/ant-design/components/tabs/)
|
|
173
|
+
- shadcn-ui parent pattern: [`refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/tabs.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/tabs.tsx)
|
|
174
|
+
- Accessibility baseline: [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md)
|
|
175
|
+
|
|
176
|
+
## Cross-reference
|
|
177
|
+
|
|
178
|
+
- [examples/component-tabs.md](component-tabs.md)
|
|
179
|
+
- [examples/component-tab.md](component-tab.md)
|
|
180
|
+
- [WAI-ARIA Tabs Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# `Tab` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from MUI `Tab`. A single tab inside a `Tabs` set. Used for top-level navigation within a section ("개요 / 활동 / 멤버") and for bottom navigation patterns.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Mutually exclusive views of the same context (account → profile / security / billing).
|
|
8
|
+
- Switching between datasets in a dashboard.
|
|
9
|
+
- For top-level app navigation, prefer dedicated nav (drawer, top bar) — Tabs are within-page.
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- 2 options → use `ToggleButtonGroup` or `Radio`.
|
|
14
|
+
- 7+ options → switch to a dropdown or a sidebar.
|
|
15
|
+
|
|
16
|
+
## Anatomy
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
[Tab1] [Tab2] [Tab3]
|
|
20
|
+
───── ───── ─────
|
|
21
|
+
▔▔▔ ← indicator under selected
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## API
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
<Tabs value={tab} onChange={(_, v) => setTab(v)} aria-label="account sections">
|
|
28
|
+
<Tab label="프로필" value="profile" />
|
|
29
|
+
<Tab label="보안" value="security" />
|
|
30
|
+
<Tab label="결제" value="billing" disabled />
|
|
31
|
+
</Tabs>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
| Prop | Type | Default | Description |
|
|
35
|
+
| --- | --- | --- | --- |
|
|
36
|
+
| `label` | `ReactNode` | — | Tab label |
|
|
37
|
+
| `value` | `any` | — | Identifies tab; matched against parent `Tabs.value` |
|
|
38
|
+
| `icon` | `ReactNode` | — | Leading icon (above label by default) |
|
|
39
|
+
| `iconPosition` | `'top' \| 'bottom' \| 'start' \| 'end'` | `'top'` | Icon placement |
|
|
40
|
+
| `disabled` | `boolean` | `false` | Non-interactive |
|
|
41
|
+
| `wrapped` | `boolean` | `false` | Allow text to wrap to 2 lines |
|
|
42
|
+
| `href` | `string` | — | Render as link (use for tabs that map to routes) |
|
|
43
|
+
|
|
44
|
+
## States
|
|
45
|
+
|
|
46
|
+
| State | Visual |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| Default | fg-muted, no underline |
|
|
49
|
+
| Hover | fg-default |
|
|
50
|
+
| Focus-visible | fg-default + ring |
|
|
51
|
+
| Selected | fg-primary, underline indicator |
|
|
52
|
+
| Disabled | reduced opacity |
|
|
53
|
+
|
|
54
|
+
## Tokens consumed
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
--tab-fg-default /* fg-muted */
|
|
58
|
+
--tab-fg-selected /* fg-primary OR fg-default — design-system choice */
|
|
59
|
+
--tab-indicator-color /* brand */
|
|
60
|
+
--tab-indicator-height /* 2px */
|
|
61
|
+
--tab-min-width-72 /* default min */
|
|
62
|
+
--tab-min-height-48 /* touch */
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Accessibility
|
|
66
|
+
|
|
67
|
+
- Renders `role="tab"` inside `role="tablist"`. Selected = `aria-selected="true"`.
|
|
68
|
+
- Keyboard: ArrowLeft/Right cycle between tabs. Home/End jump.
|
|
69
|
+
- For tabs with associated panels: `aria-controls="panel-id"` + matching `role="tabpanel"` + `aria-labelledby="tab-id"`.
|
|
70
|
+
- Disabled tabs are skipped in keyboard nav by default.
|
|
71
|
+
|
|
72
|
+
## Edge cases
|
|
73
|
+
|
|
74
|
+
- **Long labels in Korean** — Hangul is wider; expect tabs to overflow. Use `<Tabs variant="scrollable">` for horizontal scroll on overflow.
|
|
75
|
+
- **Mobile narrow viewport** — `variant="fullWidth"` distributes tabs evenly; OK for ≤ 4 tabs. For 5+, switch to scrollable.
|
|
76
|
+
- **Icon + label** — label first then icon-only on narrow → use `useMediaQuery` to switch `iconPosition`.
|
|
77
|
+
- **Nested tabs** — discouraged but possible. Aria gets confusing; consider a sub-nav pattern instead.
|
|
78
|
+
|
|
79
|
+
## Code example
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
function AccountTabs() {
|
|
83
|
+
const [tab, setTab] = useState('profile');
|
|
84
|
+
const navigate = useNavigate();
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
|
88
|
+
<Tabs
|
|
89
|
+
value={tab}
|
|
90
|
+
onChange={(_, v) => { setTab(v); navigate(`/account/${v}`); }}
|
|
91
|
+
aria-label="계정 설정"
|
|
92
|
+
variant="scrollable"
|
|
93
|
+
scrollButtons="auto"
|
|
94
|
+
>
|
|
95
|
+
<Tab label="프로필" value="profile" />
|
|
96
|
+
<Tab label="보안" value="security" />
|
|
97
|
+
<Tab label="결제" value="billing" />
|
|
98
|
+
<Tab label="알림" value="notifications" />
|
|
99
|
+
<Tab label="개인정보" value="privacy" />
|
|
100
|
+
</Tabs>
|
|
101
|
+
</Box>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Don't
|
|
107
|
+
|
|
108
|
+
- Don't use Tabs for binary on/off — use `Switch` or `ToggleButton`.
|
|
109
|
+
- Don't put 2 separate Tabs sets on the same screen — confuses keyboard navigation.
|
|
110
|
+
- Don't use Tab text as the page heading — they have separate semantics.
|
|
111
|
+
|
|
112
|
+
## References
|
|
113
|
+
|
|
114
|
+
- MUI: [`Tab`](../refs/mui/packages/mui-material/src/Tab/) + [`Tabs`](../refs/mui/packages/mui-material/src/Tabs/)
|
|
115
|
+
|
|
116
|
+
## Cross-reference
|
|
117
|
+
|
|
118
|
+
- [`component-tabs.md`](component-tabs.md)
|
|
119
|
+
- [`component-bottom-navigation.md`](component-bottom-navigation.md)
|
|
120
|
+
- [`knowledge/patterns/mobile-navigation.md`](../knowledge/patterns/mobile-navigation.md)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# `TableBody` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from MUI `TableBody`. The container for data rows in a `Table`. Equivalent to `<tbody>` with consistent styling defaults.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Inside every `Table` that displays data rows.
|
|
8
|
+
- For tables with no body (header-only summary), omit.
|
|
9
|
+
|
|
10
|
+
## API
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
<Table>
|
|
14
|
+
<TableHead>...</TableHead>
|
|
15
|
+
<TableBody>
|
|
16
|
+
{rows.map((row) => (
|
|
17
|
+
<TableRow key={row.id}>
|
|
18
|
+
<TableCell>{row.name}</TableCell>
|
|
19
|
+
</TableRow>
|
|
20
|
+
))}
|
|
21
|
+
</TableBody>
|
|
22
|
+
</Table>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Prop | Type | Default | Description |
|
|
26
|
+
| --- | --- | --- | --- |
|
|
27
|
+
| `children` | `ReactNode` | — | `TableRow` children |
|
|
28
|
+
| `component` | `ElementType` | `'tbody'` | Override |
|
|
29
|
+
|
|
30
|
+
## Accessibility
|
|
31
|
+
|
|
32
|
+
Renders `<tbody>` — semantic role for table body comes for free. No additional ARIA needed.
|
|
33
|
+
|
|
34
|
+
## Edge cases
|
|
35
|
+
|
|
36
|
+
- **Empty state** — when `rows.length === 0`, render a single `TableRow` with one `TableCell` spanning all columns containing the empty-state message. Cite [`knowledge/patterns/empty-states.md`](../knowledge/patterns/empty-states.md).
|
|
37
|
+
- **Loading state** — show skeleton rows or a single overlay. Don't leave the body empty during fetch — users see a flash.
|
|
38
|
+
- **Virtualization** — for 100+ rows, use a virtualized table library (TanStack Virtual + MUI Table). MUI's `TableBody` doesn't virtualize automatically.
|
|
39
|
+
|
|
40
|
+
## Code example
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
{isLoading ? (
|
|
44
|
+
<TableBody>
|
|
45
|
+
{Array.from({ length: 5 }).map((_, i) => (
|
|
46
|
+
<TableRow key={i}>
|
|
47
|
+
{columns.map((col) => (
|
|
48
|
+
<TableCell key={col.key}><Skeleton /></TableCell>
|
|
49
|
+
))}
|
|
50
|
+
</TableRow>
|
|
51
|
+
))}
|
|
52
|
+
</TableBody>
|
|
53
|
+
) : rows.length === 0 ? (
|
|
54
|
+
<TableBody>
|
|
55
|
+
<TableRow>
|
|
56
|
+
<TableCell colSpan={columns.length} align="center" sx={{ py: 8 }}>
|
|
57
|
+
결과가 없어요
|
|
58
|
+
</TableCell>
|
|
59
|
+
</TableRow>
|
|
60
|
+
</TableBody>
|
|
61
|
+
) : (
|
|
62
|
+
<TableBody>
|
|
63
|
+
{rows.map((row) => <TableRow key={row.id}>...</TableRow>)}
|
|
64
|
+
</TableBody>
|
|
65
|
+
)}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Don't
|
|
69
|
+
|
|
70
|
+
- Don't render rows outside `TableBody` (or `TableHead` / `TableFooter`).
|
|
71
|
+
- Don't use for content that isn't tabular — Cards / Stacks fit better.
|
|
72
|
+
|
|
73
|
+
## References
|
|
74
|
+
|
|
75
|
+
- MUI: [`TableBody`](../refs/mui/packages/mui-material/src/TableBody/)
|
|
76
|
+
|
|
77
|
+
## Cross-reference
|
|
78
|
+
|
|
79
|
+
- [`component-table.md`](component-table.md)
|
|
80
|
+
- [`component-table-row.md`](component-table-row.md)
|
|
81
|
+
- [`component-table-cell.md`](component-table-cell.md)
|
|
82
|
+
- [`knowledge/patterns/empty-states.md`](../knowledge/patterns/empty-states.md)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# `TableCell` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from MUI `TableCell`. The single cell inside a `TableRow`. Handles padding density, alignment (number columns right-aligned by convention), header/body semantics via `component`.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Inside every `TableRow` (head, body, footer).
|
|
8
|
+
- For every column of tabular data.
|
|
9
|
+
|
|
10
|
+
## API
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
<TableCell align="right" component="td" padding="normal">
|
|
14
|
+
{row.amount.toLocaleString('ko-KR')}원
|
|
15
|
+
</TableCell>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
| Prop | Type | Default | Description |
|
|
19
|
+
| --- | --- | --- | --- |
|
|
20
|
+
| `align` | `'left' \| 'right' \| 'center' \| 'justify' \| 'inherit'` | `'inherit'` | Text alignment |
|
|
21
|
+
| `padding` | `'normal' \| 'checkbox' \| 'none'` | `'normal'` | Padding profile (`checkbox` is narrow for selection columns) |
|
|
22
|
+
| `size` | `'small' \| 'medium'` | inherited | Density |
|
|
23
|
+
| `component` | `ElementType` | `'td'` (body) / `'th'` (head) | Override |
|
|
24
|
+
| `scope` | `'col' \| 'row' \| 'colgroup' \| 'rowgroup'` | — | Header scope (use on `<th>` cells) |
|
|
25
|
+
| `sortDirection` | `'asc' \| 'desc' \| false` | `false` | Sort indicator |
|
|
26
|
+
| `variant` | `'head' \| 'body' \| 'footer'` | derived | Cell role |
|
|
27
|
+
|
|
28
|
+
## States
|
|
29
|
+
|
|
30
|
+
`TableCell` itself has no states. Selection / hover / active live on `TableRow`.
|
|
31
|
+
|
|
32
|
+
## Tokens consumed
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
--table-cell-padding-x-normal /* 16px */
|
|
36
|
+
--table-cell-padding-x-checkbox /* 0 */
|
|
37
|
+
--table-cell-padding-y /* 16px (medium) / 8px (small) */
|
|
38
|
+
--color-fg-default
|
|
39
|
+
--color-fg-muted /* head cells */
|
|
40
|
+
--color-divider /* bottom border */
|
|
41
|
+
--font-size-body
|
|
42
|
+
--font-size-small
|
|
43
|
+
--font-weight-semibold /* head cells */
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Accessibility
|
|
47
|
+
|
|
48
|
+
- Header cells render as `<th>` automatically when inside `<TableHead>`. Add `scope="col"` for column headers (or `scope="row"` for row headers in side-headed tables).
|
|
49
|
+
- For sort indicators, use `TableSortLabel` inside the cell — it provides keyboard activation + `aria-sort` on the cell.
|
|
50
|
+
- Right-aligned numeric columns: `align="right"` is visual only. Screen readers still read in DOM order.
|
|
51
|
+
- Cite [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md).
|
|
52
|
+
|
|
53
|
+
## Alignment conventions
|
|
54
|
+
|
|
55
|
+
- **Text columns** → `align="left"` (default in LTR locales).
|
|
56
|
+
- **Numeric columns** → `align="right"`.
|
|
57
|
+
- **Status / icon columns** → `align="center"`.
|
|
58
|
+
- **Action columns (last)** → `align="right"`.
|
|
59
|
+
- For Korean tables: same conventions; Korean reads left-to-right.
|
|
60
|
+
|
|
61
|
+
## Edge cases
|
|
62
|
+
|
|
63
|
+
- **Long text** — wraps. For ellipsis: wrap inner content in a `Box` with `noWrap` styling, AND set `Tooltip` to surface full text on hover.
|
|
64
|
+
- **Numeric tabular alignment** — pair `align="right"` with `font-variant-numeric: tabular-nums` for clean column alignment regardless of digit width.
|
|
65
|
+
- **Korean amount cells** — append `원` directly: `12,345원`. Don't put `원` in a separate column (creates layout waste).
|
|
66
|
+
- **Empty cells** — render `—` (em-dash) rather than empty; signals "intentionally empty" vs "data not loaded".
|
|
67
|
+
|
|
68
|
+
## Code example
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
<TableHead>
|
|
72
|
+
<TableRow>
|
|
73
|
+
<TableCell scope="col">이름</TableCell>
|
|
74
|
+
<TableCell scope="col">부서</TableCell>
|
|
75
|
+
<TableCell scope="col" align="right">
|
|
76
|
+
<TableSortLabel
|
|
77
|
+
active={orderBy === 'amount'}
|
|
78
|
+
direction={order}
|
|
79
|
+
onClick={() => handleSort('amount')}
|
|
80
|
+
>
|
|
81
|
+
급여
|
|
82
|
+
</TableSortLabel>
|
|
83
|
+
</TableCell>
|
|
84
|
+
<TableCell scope="col" align="right">상태</TableCell>
|
|
85
|
+
</TableRow>
|
|
86
|
+
</TableHead>
|
|
87
|
+
<TableBody>
|
|
88
|
+
{employees.map((emp) => (
|
|
89
|
+
<TableRow key={emp.id} hover>
|
|
90
|
+
<TableCell>{emp.name}</TableCell>
|
|
91
|
+
<TableCell>{emp.department}</TableCell>
|
|
92
|
+
<TableCell align="right" sx={{ fontVariantNumeric: 'tabular-nums' }}>
|
|
93
|
+
{emp.salary.toLocaleString('ko-KR')}원
|
|
94
|
+
</TableCell>
|
|
95
|
+
<TableCell align="right">
|
|
96
|
+
<Chip label={emp.status} size="small" />
|
|
97
|
+
</TableCell>
|
|
98
|
+
</TableRow>
|
|
99
|
+
))}
|
|
100
|
+
</TableBody>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Don't
|
|
104
|
+
|
|
105
|
+
- Don't omit `scope` on header cells — accessibility miss.
|
|
106
|
+
- Don't put block-level content (`Card`, full forms) inside cells — Tables aren't grid layouts.
|
|
107
|
+
- Don't mix `padding="checkbox"` with non-checkbox content — use `padding="none"` for tighter control.
|
|
108
|
+
|
|
109
|
+
## References
|
|
110
|
+
|
|
111
|
+
- MUI: [`TableCell`](../refs/mui/packages/mui-material/src/TableCell/)
|
|
112
|
+
|
|
113
|
+
## Cross-reference
|
|
114
|
+
|
|
115
|
+
- [`component-table.md`](component-table.md)
|
|
116
|
+
- [`component-table-row.md`](component-table-row.md)
|
|
117
|
+
- [`component-table-sort-label.md`](component-table-sort-label.md)
|
|
118
|
+
- [`component-table-head.md`](component-table-head.md)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# `TableContainer` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from MUI `TableContainer`. Wraps a `Table` to provide horizontal scroll, fixed height (with sticky header), and Paper styling. Without it, wide tables overflow the viewport ungracefully.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Every `Table` that might exceed viewport width on narrow screens.
|
|
8
|
+
- Tables inside Cards/Papers where you want consistent elevation.
|
|
9
|
+
- Tables with `stickyHeader` (requires `maxHeight` on container).
|
|
10
|
+
|
|
11
|
+
## API
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<TableContainer component={Paper} sx={{ maxHeight: 480 }}>
|
|
15
|
+
<Table stickyHeader>
|
|
16
|
+
<TableHead>...</TableHead>
|
|
17
|
+
<TableBody>...</TableBody>
|
|
18
|
+
</Table>
|
|
19
|
+
</TableContainer>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
| Prop | Type | Default | Description |
|
|
23
|
+
| --- | --- | --- | --- |
|
|
24
|
+
| `children` | `ReactNode` | — | A `Table` |
|
|
25
|
+
| `component` | `ElementType` | `'div'` | Wrap as `Paper` for elevation |
|
|
26
|
+
|
|
27
|
+
## Tokens consumed
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
--paper-bg
|
|
31
|
+
--paper-shadow-1
|
|
32
|
+
--paper-radius
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Accessibility
|
|
36
|
+
|
|
37
|
+
- The container itself adds no a11y semantics.
|
|
38
|
+
- For very wide tables that scroll horizontally, ensure keyboard users can navigate (the table itself stays focusable; arrow keys move within cells).
|
|
39
|
+
- Set `tabIndex={0}` + `role="region"` + `aria-label` on the container to make scrolling discoverable to screen readers.
|
|
40
|
+
|
|
41
|
+
## Edge cases
|
|
42
|
+
|
|
43
|
+
- **`stickyHeader` without `maxHeight`** — header doesn't stick (needs a scrollable parent).
|
|
44
|
+
- **Mobile pivot to card-list** — for very narrow viewports, breaking out of TableContainer entirely and rendering `<Stack><Card /></Stack>` reads better than horizontal scroll. Cite [`knowledge/patterns/list-and-feed.md`](../knowledge/patterns/list-and-feed.md).
|
|
45
|
+
|
|
46
|
+
## Code example
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<TableContainer
|
|
50
|
+
component={Paper}
|
|
51
|
+
sx={{ maxHeight: 480 }}
|
|
52
|
+
tabIndex={0}
|
|
53
|
+
role="region"
|
|
54
|
+
aria-label="직원 명단"
|
|
55
|
+
>
|
|
56
|
+
<Table stickyHeader>
|
|
57
|
+
<TableHead>...</TableHead>
|
|
58
|
+
<TableBody>...</TableBody>
|
|
59
|
+
</Table>
|
|
60
|
+
</TableContainer>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Don't
|
|
64
|
+
|
|
65
|
+
- Don't use without a `Table` child.
|
|
66
|
+
- Don't apply both `maxHeight` and `height: 100%` — unpredictable layout.
|
|
67
|
+
|
|
68
|
+
## References
|
|
69
|
+
|
|
70
|
+
- MUI: [`TableContainer`](../refs/mui/packages/mui-material/src/TableContainer/)
|
|
71
|
+
|
|
72
|
+
## Cross-reference
|
|
73
|
+
|
|
74
|
+
- [`component-table.md`](component-table.md)
|
|
75
|
+
- [`component-table-pagination.md`](component-table-pagination.md)
|