@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,199 @@
|
|
|
1
|
+
# `AutoComplete` β spec
|
|
2
|
+
|
|
3
|
+
> Citing Ant Design `AutoComplete`, MUI `Autocomplete`, shadcn-ui (composition with `command`)
|
|
4
|
+
>
|
|
5
|
+
> Distinct from `Select` (covered combined in [`component-select.md`](component-select.md)) β AutoComplete allows **free-form text input** with suggestions, while Select requires choosing from the list.
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
A text input with type-ahead suggestions. User can:
|
|
10
|
+
- Pick a suggestion (like Select).
|
|
11
|
+
- Type free text (unlike Select).
|
|
12
|
+
|
|
13
|
+
Used for: search bars with suggestions, address auto-fill, email input with recent contacts, tag creation, command palettes.
|
|
14
|
+
|
|
15
|
+
## When AutoComplete vs Select vs Combobox
|
|
16
|
+
|
|
17
|
+
| Pattern | Behavior |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| **Select** | User picks from list. Free text not allowed. |
|
|
20
|
+
| **AutoComplete** | User can pick OR type free text. |
|
|
21
|
+
| **Combobox** (the WAI-ARIA pattern) | Umbrella term; both Select and AutoComplete are flavors. |
|
|
22
|
+
|
|
23
|
+
If your input requires the value be from a list: Select.
|
|
24
|
+
If your input allows custom values: AutoComplete (or Select with `creatable`).
|
|
25
|
+
|
|
26
|
+
## Anatomy
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Closed: Typing (open):
|
|
30
|
+
βββββββββββββββββββββββββββ βββββββββββββββββββββββββββ
|
|
31
|
+
β Search recipes... πβ β chocolate β β
|
|
32
|
+
βββββββββββββββββββββββββββ βββββββββββββββββββββββββββ€
|
|
33
|
+
β βΆ chocolate cake β
|
|
34
|
+
β chocolate chip cookies β
|
|
35
|
+
β chocolate fondue β
|
|
36
|
+
β βββ β
|
|
37
|
+
β Recent searches: β
|
|
38
|
+
β chocolate truffles β
|
|
39
|
+
βββββββββββββββββββββββββββ
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## API
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
<AutoComplete
|
|
46
|
+
value={query}
|
|
47
|
+
onValueChange={setQuery}
|
|
48
|
+
options={suggestions}
|
|
49
|
+
onSelect={(value) => navigate(`/recipes?q=${value}`)}
|
|
50
|
+
placeholder="λ μνΌ κ²μ"
|
|
51
|
+
loading={isLoading}
|
|
52
|
+
/>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Prop | Type | Default | Description |
|
|
56
|
+
| --- | --- | --- | --- |
|
|
57
|
+
| `value` | `string` | β | Input value (controlled) |
|
|
58
|
+
| `onValueChange` | `(value: string) => void` | β | Fires per keystroke |
|
|
59
|
+
| `onSelect` | `(value: string, option: Option) => void` | β | Fires when user picks a suggestion (vs typing then submitting) |
|
|
60
|
+
| `options` | `Option[]` or `(query: string) => Promise<Option[]>` | β | Suggestions; can be async |
|
|
61
|
+
| `loading` | `boolean` | `false` | Shows spinner in dropdown |
|
|
62
|
+
| `placeholder` | `string` | β | |
|
|
63
|
+
| `disabled` | `boolean` | `false` | |
|
|
64
|
+
| `error` / `errorText` | β | β | |
|
|
65
|
+
| `freeText` | `boolean` | `true` | Allow committing values not in suggestions |
|
|
66
|
+
| `clearable` | `boolean` | `true` | β to clear |
|
|
67
|
+
| `iconStart` | `ReactNode` | β | E.g., search icon |
|
|
68
|
+
| `noResultsMessage` | `ReactNode` | "κ²°κ³Ό μμ" | When suggestions empty |
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
type Option = {
|
|
72
|
+
value: string;
|
|
73
|
+
label?: ReactNode; // Custom display
|
|
74
|
+
description?: string;
|
|
75
|
+
group?: string;
|
|
76
|
+
data?: unknown;
|
|
77
|
+
};
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Behavior
|
|
81
|
+
|
|
82
|
+
- Typing fires `onValueChange` (per keystroke, debounced for async).
|
|
83
|
+
- Suggestions filter (client) or fetch (async).
|
|
84
|
+
- User picks a suggestion: `onSelect` fires with the picked value.
|
|
85
|
+
- User types and presses Enter without picking: input commits free text.
|
|
86
|
+
- Search suggestions vs typing: matched substring highlighted.
|
|
87
|
+
|
|
88
|
+
## States
|
|
89
|
+
|
|
90
|
+
| State | Visual |
|
|
91
|
+
| --- | --- |
|
|
92
|
+
| Empty | Placeholder, no dropdown |
|
|
93
|
+
| Typing | Dropdown opens with filtered suggestions |
|
|
94
|
+
| Loading | Spinner in dropdown |
|
|
95
|
+
| Has suggestions | List visible |
|
|
96
|
+
| No results | "κ²°κ³Ό μμ" empty state |
|
|
97
|
+
| Selected | Input shows picked value, dropdown closes |
|
|
98
|
+
| Disabled | Standard |
|
|
99
|
+
|
|
100
|
+
## Korean IME composition
|
|
101
|
+
|
|
102
|
+
Critical for Korean apps. Don't fire suggestions during IME composition (mid-syllable):
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
const [isComposing, setIsComposing] = useState(false);
|
|
106
|
+
|
|
107
|
+
<input
|
|
108
|
+
onCompositionStart={() => setIsComposing(true)}
|
|
109
|
+
onCompositionEnd={(e) => {
|
|
110
|
+
setIsComposing(false);
|
|
111
|
+
setQuery(e.target.value); // Now fire suggestions
|
|
112
|
+
}}
|
|
113
|
+
onChange={(e) => {
|
|
114
|
+
if (!isComposing) setQuery(e.target.value);
|
|
115
|
+
}}
|
|
116
|
+
/>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Cite [`knowledge/i18n/korean-typography.md`](../knowledge/i18n/korean-typography.md) for IME details.
|
|
120
|
+
|
|
121
|
+
## Accessibility β WAI-ARIA Combobox pattern
|
|
122
|
+
|
|
123
|
+
- Input: `role="combobox"`, `aria-autocomplete="list"`, `aria-expanded={isOpen}`, `aria-controls={listboxId}`.
|
|
124
|
+
- Listbox: `role="listbox"`, `id={listboxId}`.
|
|
125
|
+
- Each option: `role="option"`, `aria-selected={isHighlighted}`.
|
|
126
|
+
- Highlighted option: `aria-activedescendant={optionId}` on the input.
|
|
127
|
+
|
|
128
|
+
### Keyboard
|
|
129
|
+
|
|
130
|
+
| Key | Behavior |
|
|
131
|
+
| --- | --- |
|
|
132
|
+
| `Tab` | Reach input |
|
|
133
|
+
| `β` (closed) | Open dropdown |
|
|
134
|
+
| `β` / `β` (open) | Move highlight |
|
|
135
|
+
| `Enter` | Select highlighted (if any) OR commit typed value |
|
|
136
|
+
| `Esc` | Close dropdown (first press), clear input (second press) |
|
|
137
|
+
|
|
138
|
+
## Common patterns
|
|
139
|
+
|
|
140
|
+
### Search bar
|
|
141
|
+
|
|
142
|
+
User types a query; dropdown shows matching items + recent searches:
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
<AutoComplete
|
|
146
|
+
options={searchResults}
|
|
147
|
+
onSelect={navigate}
|
|
148
|
+
iconStart={<SearchIcon />}
|
|
149
|
+
placeholder="κ²μ"
|
|
150
|
+
/>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
See [`knowledge/patterns/search-ux.md`](../knowledge/patterns/search-ux.md).
|
|
154
|
+
|
|
155
|
+
### Email input with contacts
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
<AutoComplete
|
|
159
|
+
options={contacts.map(c => ({ value: c.email, label: c.name, description: c.email }))}
|
|
160
|
+
freeText
|
|
161
|
+
iconStart={<EnvelopeIcon />}
|
|
162
|
+
/>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Address auto-fill
|
|
166
|
+
|
|
167
|
+
For Korean addresses: don't use AutoComplete. Use Daum Postcode lookup. See [`component-address-input.md`](component-address-input.md).
|
|
168
|
+
|
|
169
|
+
### Tag creation
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
<AutoComplete
|
|
173
|
+
options={existingTags}
|
|
174
|
+
freeText
|
|
175
|
+
onSelect={(value, option) => addTag(value, !option ? "new" : "existing")}
|
|
176
|
+
/>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
When user selects an option: existing tag. When user types and commits: new tag.
|
|
180
|
+
|
|
181
|
+
## Don't
|
|
182
|
+
|
|
183
|
+
- Don't use AutoComplete when the value MUST be from a list. Use Select.
|
|
184
|
+
- Don't fire suggestions on every keystroke during IME composition.
|
|
185
|
+
- Don't ship without keyboard navigation.
|
|
186
|
+
- Don't show 100+ suggestions. Cap at 10β20; let the user refine the query.
|
|
187
|
+
- Don't force user to pick a suggestion. Allow free text commit.
|
|
188
|
+
|
|
189
|
+
## References
|
|
190
|
+
|
|
191
|
+
- Ant Design: [`refs/ant-design/components/auto-complete/`](../refs/ant-design/components/auto-complete/) β `AutoComplete`. Built on top of Select with free-text mode.
|
|
192
|
+
- MUI: [`refs/mui/packages/mui-material/src/Autocomplete/`](../refs/mui/packages/mui-material/src/Autocomplete/) β `Autocomplete` with `freeSolo` prop. Most comprehensive.
|
|
193
|
+
- shadcn-ui: compose `command` (cmdk) + Popover for autocomplete-like behavior.
|
|
194
|
+
|
|
195
|
+
## Cross-reference
|
|
196
|
+
|
|
197
|
+
- [`examples/component-select.md`](component-select.md) β for picking from a list (no free text)
|
|
198
|
+
- [`knowledge/patterns/search-ux.md`](../knowledge/patterns/search-ux.md) β when AutoComplete is a search bar
|
|
199
|
+
- [`knowledge/i18n/korean-typography.md`](../knowledge/i18n/korean-typography.md) β IME composition handling
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# `AvatarGroup` - spec
|
|
2
|
+
|
|
3
|
+
> Direct upstream component: MUI `AvatarGroup`. Parent pattern references: Ant Design `Avatar.Group`, MUI `AvatarGroup`, shadcn-ui avatar examples.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
`AvatarGroup` shows a compact set of people or entities by overlapping avatars and summarizing overflow as a surplus item such as `+3`. Use it in collaboration surfaces, assignee lists, chat participants, document viewers, and activity feeds.
|
|
8
|
+
|
|
9
|
+
Use a text list instead when the user must compare every participant name.
|
|
10
|
+
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
AvatarGroup
|
|
15
|
+
βββ Avatar item 1
|
|
16
|
+
βββ Avatar item 2
|
|
17
|
+
βββ Avatar item 3
|
|
18
|
+
βββ Surplus item optional; "+N" or custom renderer
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
| Part | Required | Purpose |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| Root | yes | Groups stacked avatars as one visual unit. |
|
|
24
|
+
| Avatar child | yes | Individual `Avatar` components or compatible nodes. |
|
|
25
|
+
| Surplus item | conditional | Represents hidden participants when `total > max`. |
|
|
26
|
+
| Tooltip/popover | optional | Reveals hidden names when surplus is interactive. |
|
|
27
|
+
|
|
28
|
+
## API
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
<AvatarGroup
|
|
32
|
+
max={4}
|
|
33
|
+
total={project.members.length}
|
|
34
|
+
renderSurplus={(count) => `+${count}`}
|
|
35
|
+
>
|
|
36
|
+
{project.members.slice(0, 4).map((member) => (
|
|
37
|
+
<Avatar key={member.id} src={member.photoUrl} alt={member.name} />
|
|
38
|
+
))}
|
|
39
|
+
</AvatarGroup>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
| Prop | Type | Default | Description |
|
|
43
|
+
| --- | --- | --- | --- |
|
|
44
|
+
| `children` | `ReactNode` | - | Avatars to stack. |
|
|
45
|
+
| `classes` | `Partial<AvatarGroupClasses>` | - | Style override hooks for MUI-style implementations. |
|
|
46
|
+
| `component` | `React.ElementType` | `"div"` | Root element override. Use semantic list elements when names are meaningful content. |
|
|
47
|
+
| `max` | `number` | `5` | Maximum visible avatars before showing surplus. |
|
|
48
|
+
| `renderSurplus` | `(surplus: number) => ReactNode` | - | Custom surplus renderer. Keep accessible text. |
|
|
49
|
+
| `spacing` | `"small" \| "medium" \| number` | `"medium"` | Overlap distance between avatars. |
|
|
50
|
+
| `slots` | `{ surplus?: React.ElementType }` | - | Slot override for surplus item. |
|
|
51
|
+
| `slotProps` | `{ surplus?: object }` | - | Props forwarded to surplus slot. |
|
|
52
|
+
| `sx` | `SxProps<Theme>` | - | MUI system override. Prefer tokens for shared design-system code. |
|
|
53
|
+
| `total` | `number` | `children.length` | Total count when only a subset of avatars is rendered. |
|
|
54
|
+
| `variant` | `"circular" \| "rounded" \| "square"` | `"circular"` | Shape passed to visible avatars and surplus. |
|
|
55
|
+
|
|
56
|
+
## API choices made
|
|
57
|
+
|
|
58
|
+
- Keep `max`, `total`, and `renderSurplus` because they solve the common virtualized/partial-render participant case.
|
|
59
|
+
- Keep `spacing` as a token-mapped prop, but prefer named values over arbitrary numbers in product code.
|
|
60
|
+
- Do not add `size` to this thin spec because parent `Avatar` already owns sizing. A product wrapper may pass size to children.
|
|
61
|
+
- Use composition over an `items` prop so existing `Avatar` fallback, status, and image behavior stay intact.
|
|
62
|
+
|
|
63
|
+
## States
|
|
64
|
+
|
|
65
|
+
| State | Trigger | Visual rule |
|
|
66
|
+
| --- | --- | --- |
|
|
67
|
+
| Default | `children.length <= max` | Avatars overlap by a tokenized offset and share a border ring. |
|
|
68
|
+
| Surplus | `total > max` | Last visible item displays surplus count with same size/shape as avatars. |
|
|
69
|
+
| Hover | Pointer over interactive avatar/surplus | Raise z-index and show tooltip/popover only if the item is actionable. |
|
|
70
|
+
| Focus-visible | Keyboard focus on interactive child | 2px focus ring, not clipped by overlap. |
|
|
71
|
+
| Active | Press interactive surplus | Pressed state belongs to the surplus button/popover trigger. |
|
|
72
|
+
| Disabled | Parent surface disabled | Avoid interactive affordances; avatars remain visible but muted only if the parent is disabled. |
|
|
73
|
+
| Loading | Participants loading | Use skeleton avatars with fixed group width to avoid layout shift. |
|
|
74
|
+
| Error | Failed participant load | Fall back to initials/default avatar; do not hide the person. |
|
|
75
|
+
|
|
76
|
+
## Tokens consumed
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
--avatar-size-sm
|
|
80
|
+
--avatar-size-md
|
|
81
|
+
--avatar-size-lg
|
|
82
|
+
--avatar-overlap-sm
|
|
83
|
+
--avatar-overlap-md
|
|
84
|
+
--color-bg-default
|
|
85
|
+
--color-bg-subtle
|
|
86
|
+
--color-text-primary
|
|
87
|
+
--color-text-secondary
|
|
88
|
+
--color-border-default
|
|
89
|
+
--color-focus-ring
|
|
90
|
+
--radius-full
|
|
91
|
+
--radius-md
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If these avatar tokens do not exist, map them to the existing size, spacing, border, and radius tokens instead of adding raw values.
|
|
95
|
+
|
|
96
|
+
## Accessibility
|
|
97
|
+
|
|
98
|
+
- If the group conveys meaningful membership, render as `<ul aria-label="μ°Έμ¬μ">` with each avatar in an `<li>`.
|
|
99
|
+
- If visible names already appear adjacent to the group, the avatar images can be hidden from the accessibility tree to avoid duplicate announcements.
|
|
100
|
+
- Each image avatar still needs correct `alt` text when it is the only name representation.
|
|
101
|
+
- Surplus item needs an accessible name such as `aria-label="μΈ 3λͺ
"`.
|
|
102
|
+
- If surplus opens a popover, it must be a real `<button>` and the popover must list the hidden names.
|
|
103
|
+
- Interactive avatars must meet 44x44 mobile touch target. For smaller visual avatars, extend hit area without changing visual size.
|
|
104
|
+
|
|
105
|
+
## Layout rules
|
|
106
|
+
|
|
107
|
+
| Rule | Value |
|
|
108
|
+
| --- | --- |
|
|
109
|
+
| Stacking | Later avatars sit visually above earlier avatars in LTR unless `direction` is explicitly reversed by a wrapper. |
|
|
110
|
+
| Border ring | Use `--color-bg-default` or parent surface color so overlap remains legible. |
|
|
111
|
+
| Overlap | About one quarter to one third of avatar size; use tokens. |
|
|
112
|
+
| Surplus | Same size and shape as avatars; do not use a loose text label outside the stack. |
|
|
113
|
+
| RTL | Reverse margin direction with logical CSS. |
|
|
114
|
+
|
|
115
|
+
## Code example
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
<AvatarGroup
|
|
119
|
+
component="ul"
|
|
120
|
+
aria-label="νλ‘μ νΈ μ°Έμ¬μ"
|
|
121
|
+
max={4}
|
|
122
|
+
total={members.length}
|
|
123
|
+
renderSurplus={(count) => (
|
|
124
|
+
<button type="button" aria-label={`μΈ ${count}λͺ
보기`}>
|
|
125
|
+
+{count}
|
|
126
|
+
</button>
|
|
127
|
+
)}
|
|
128
|
+
>
|
|
129
|
+
{members.slice(0, 4).map((member) => (
|
|
130
|
+
<li key={member.id}>
|
|
131
|
+
<Avatar
|
|
132
|
+
src={member.photoUrl}
|
|
133
|
+
alt={member.name}
|
|
134
|
+
fallback={initials(member.name)}
|
|
135
|
+
/>
|
|
136
|
+
</li>
|
|
137
|
+
))}
|
|
138
|
+
</AvatarGroup>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Edge cases
|
|
142
|
+
|
|
143
|
+
- **`max` less than 2**: clamp in product wrappers or warn in development. One visible avatar plus surplus is the minimum useful group.
|
|
144
|
+
- **`total` exceeds rendered children**: surplus should use `total - visibleCount`, not hidden rendered children only.
|
|
145
|
+
- **Duplicate names**: tooltip/popover should include secondary identifiers, such as team or email.
|
|
146
|
+
- **Hundreds of participants**: render only visible avatars plus surplus; do not mount every avatar image.
|
|
147
|
+
- **RTL**: overlap direction and z-index order must be reviewed visually.
|
|
148
|
+
- **High contrast mode**: overlap boundaries must remain visible through border, not only shadow.
|
|
149
|
+
- **Failed image loads**: each avatar follows `Avatar` fallback rules; group layout must not shift.
|
|
150
|
+
|
|
151
|
+
## Don't
|
|
152
|
+
|
|
153
|
+
- Don't use `AvatarGroup` when exact identity comparison is the primary task.
|
|
154
|
+
- Don't make each avatar separately clickable inside a clickable parent row.
|
|
155
|
+
- Don't show `+0` or a surplus item when all avatars are visible.
|
|
156
|
+
- Don't use color alone to indicate online/away status in the group.
|
|
157
|
+
|
|
158
|
+
## References
|
|
159
|
+
|
|
160
|
+
- MUI direct source: [`refs/mui/packages/mui-material/src/AvatarGroup/AvatarGroup.d.ts`](../refs/mui/packages/mui-material/src/AvatarGroup/AvatarGroup.d.ts)
|
|
161
|
+
- MUI implementation: [`refs/mui/packages/mui-material/src/AvatarGroup/AvatarGroup.js`](../refs/mui/packages/mui-material/src/AvatarGroup/AvatarGroup.js)
|
|
162
|
+
- Ant Design parent pattern: [`refs/ant-design/components/avatar/`](../refs/ant-design/components/avatar/)
|
|
163
|
+
- shadcn-ui avatar source: [`refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/avatar.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/avatar.tsx)
|
|
164
|
+
- shadcn-ui group examples: [`refs/shadcn-ui/apps/v4/examples/base/avatar-group.tsx`](../refs/shadcn-ui/apps/v4/examples/base/avatar-group.tsx)
|
|
165
|
+
- Accessibility baseline: [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md)
|
|
166
|
+
|
|
167
|
+
## Cross-reference
|
|
168
|
+
|
|
169
|
+
- [examples/component-avatar.md](component-avatar.md)
|
|
170
|
+
- [knowledge/patterns/list-and-feed.md](../knowledge/patterns/list-and-feed.md)
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# `Avatar` β spec
|
|
2
|
+
|
|
3
|
+
> Citing Ant Design `Avatar`, MUI `Avatar`, shadcn-ui `avatar`
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
A small visual representation of a user, group, or entity. Optimized for image, with deterministic fallbacks (initials, then default icon) when image is missing or fails to load.
|
|
8
|
+
|
|
9
|
+
## Anatomy
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
[image] [initials] [default icon] [group β cluster]
|
|
13
|
+
β― β― β― β―β―β―+2
|
|
14
|
+
"κΉλ―Όμ§"
|
|
15
|
+
MJ
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## API
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
<Avatar
|
|
22
|
+
src="/avatars/minji.jpg"
|
|
23
|
+
alt="κΉλ―Όμ§"
|
|
24
|
+
fallback="λ―Όμ§"
|
|
25
|
+
size="md"
|
|
26
|
+
/>
|
|
27
|
+
|
|
28
|
+
<AvatarGroup max={4} size="sm">
|
|
29
|
+
<Avatar src="..." alt="A" fallback="A" />
|
|
30
|
+
<Avatar src="..." alt="B" fallback="B" />
|
|
31
|
+
<Avatar src="..." alt="C" fallback="C" />
|
|
32
|
+
<Avatar src="..." alt="D" fallback="D" />
|
|
33
|
+
<Avatar src="..." alt="E" fallback="E" />
|
|
34
|
+
</AvatarGroup>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
| Prop | Type | Default | Description |
|
|
38
|
+
| --- | --- | --- | --- |
|
|
39
|
+
| `src` | `string` | β | Image URL |
|
|
40
|
+
| `alt` | `string` | β | Alt text. Required if `src` set. |
|
|
41
|
+
| `fallback` | `string \| ReactNode` | first 1β2 chars of `alt` | Initials, emoji, or custom node when image fails/missing |
|
|
42
|
+
| `size` | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` or `number` | `"md"` | |
|
|
43
|
+
| `shape` | `"circle" \| "rounded"` | `"circle"` | `rounded` for org / company avatars |
|
|
44
|
+
| `bgColor` | `string` | derived from name hash | Background when showing fallback |
|
|
45
|
+
| `status` | `"online" \| "offline" \| "away" \| "busy"` | β | Optional indicator dot |
|
|
46
|
+
| `loading` | `boolean` | `false` | Show skeleton variant |
|
|
47
|
+
|
|
48
|
+
### AvatarGroup
|
|
49
|
+
|
|
50
|
+
| Prop | Type | Default | Description |
|
|
51
|
+
| --- | --- | --- | --- |
|
|
52
|
+
| `max` | `number` | `5` | Visible avatars before "+N" |
|
|
53
|
+
| `size` | same as Avatar | `"md"` | Applied to all children |
|
|
54
|
+
| `direction` | `"row" \| "row-reverse"` | `"row-reverse"` | Stacking order (rightmost overlaps leftmost when row-reverse) |
|
|
55
|
+
|
|
56
|
+
## Sizes
|
|
57
|
+
|
|
58
|
+
| Size | Diameter | Font (initials) |
|
|
59
|
+
| --- | --- | --- |
|
|
60
|
+
| `xs` | 16px | 9px |
|
|
61
|
+
| `sm` | 24px | 11px |
|
|
62
|
+
| `md` (default) | 32px | 13px |
|
|
63
|
+
| `lg` | 48px | 16px |
|
|
64
|
+
| `xl` | 64px | 22px |
|
|
65
|
+
| Hero (custom number) | 96px+ | 28px+ |
|
|
66
|
+
|
|
67
|
+
## Fallback strategy
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
1. Try image (src)
|
|
71
|
+
2. On image error β render initials (fallback)
|
|
72
|
+
3. If no fallback or empty β render default user icon
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Initials rules:
|
|
76
|
+
- Latin: 1β2 uppercase chars from first name + last name (e.g., "Jane Smith" β "JS").
|
|
77
|
+
- Korean: usually 1 char (μ± β surname). "κΉλ―Όμ§" β "λ―Ό" or "κΉ". Pick one and be consistent. Many KR apps prefer the given name's first syllable (`λ―Ό`) over surname (`κΉ`).
|
|
78
|
+
- Empty / unknown: default user icon.
|
|
79
|
+
|
|
80
|
+
### Background color from name
|
|
81
|
+
|
|
82
|
+
Hash the name to a stable color from a curated palette of 8β12 colors. Same name always gets same color across the app:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const colors = ['#EF4444', '#F59E0B', '#10B981', '#3B82F6', '#8B5CF6', '#EC4899', '#14B8A6', '#F97316'];
|
|
86
|
+
const hash = name.split('').reduce((acc, c) => acc + c.charCodeAt(0), 0);
|
|
87
|
+
const bg = colors[hash % colors.length];
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Pick colors with text readable in white.
|
|
91
|
+
|
|
92
|
+
## States
|
|
93
|
+
|
|
94
|
+
| State | Visual |
|
|
95
|
+
| --- | --- |
|
|
96
|
+
| Loading image | Skeleton placeholder, 4β6 sec timeout to fallback |
|
|
97
|
+
| Image loaded | Cropped to circle, `object-fit: cover` |
|
|
98
|
+
| Image failed | Fallback (initials or icon) |
|
|
99
|
+
| With status indicator | Small dot at bottom-right (1/4 of diameter, 2px white border) |
|
|
100
|
+
|
|
101
|
+
## Tokens consumed
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
--color-bg-subtle (default fallback bg)
|
|
105
|
+
--color-text-primary (initials text on light fallback)
|
|
106
|
+
--color-text-on-fallback (initials text β usually white)
|
|
107
|
+
--color-border-default (status dot border, group offset)
|
|
108
|
+
--color-success (online status)
|
|
109
|
+
--color-text-tertiary (offline)
|
|
110
|
+
--color-warning (away)
|
|
111
|
+
--color-error (busy / do-not-disturb)
|
|
112
|
+
--radius-full (circle)
|
|
113
|
+
--radius-md (rounded square)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Group behavior
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
βββββ +3
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
- Avatars overlap by 25β30% of their width (depending on size).
|
|
123
|
+
- The "+N" item is the same size as avatars, with `--color-bg-subtle` background and `--color-text-primary` text.
|
|
124
|
+
- Hover/focus on "+N" shows a Popover or Tooltip with the full list.
|
|
125
|
+
- Direction: `row-reverse` is the default stacking order (rightmost on top), looks more natural in LTR.
|
|
126
|
+
|
|
127
|
+
## Accessibility
|
|
128
|
+
|
|
129
|
+
- `<img alt="...">` for image avatars. **Don't omit alt** β even if you think the image is decorative, the user's name matters for context.
|
|
130
|
+
- Initials fallback should also include `aria-label="Jane Smith"` or wrap text in `aria-hidden="true"` if the avatar has a separate visible name nearby.
|
|
131
|
+
- Default icon (no fallback): `aria-label="User"` or appropriate generic.
|
|
132
|
+
- Avatar group "+N": `aria-label="3 more"` or `"3 more users"`.
|
|
133
|
+
- Avatar inside a clickable card / button: don't make avatar separately clickable β let the parent handle.
|
|
134
|
+
- For large hero avatars used as buttons (e.g., "change avatar"): `<button>` wrapper with proper label.
|
|
135
|
+
|
|
136
|
+
## Code example
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
// Standard user avatar
|
|
140
|
+
<Avatar src={user.photoUrl} alt={user.name} fallback={initials(user.name)} />
|
|
141
|
+
|
|
142
|
+
// Avatar with status (online indicator)
|
|
143
|
+
<Avatar src={user.photoUrl} alt={user.name} fallback="λ―Όμ§" status="online" />
|
|
144
|
+
|
|
145
|
+
// Avatar group
|
|
146
|
+
<AvatarGroup max={3}>
|
|
147
|
+
{participants.map(p => (
|
|
148
|
+
<Avatar key={p.id} src={p.photoUrl} alt={p.name} fallback={initials(p.name)} />
|
|
149
|
+
))}
|
|
150
|
+
</AvatarGroup>
|
|
151
|
+
|
|
152
|
+
// Org / company (rounded square)
|
|
153
|
+
<Avatar shape="rounded" src={org.logoUrl} alt={org.name} fallback={org.name[0]} />
|
|
154
|
+
|
|
155
|
+
// Hero size for profile screen
|
|
156
|
+
<Avatar src={user.photoUrl} alt={user.name} size={120} />
|
|
157
|
+
|
|
158
|
+
// Default fallback icon (user has no image, no name)
|
|
159
|
+
<Avatar />
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Edge cases
|
|
163
|
+
|
|
164
|
+
- **Image takes too long to load**: render fallback after 6s of waiting.
|
|
165
|
+
- **Image returns 200 with broken bytes**: catch via `onerror`; render fallback.
|
|
166
|
+
- **Image without `alt`**: lint should flag. Don't silently skip alt.
|
|
167
|
+
- **Name with emoji**: "κΉλ―Όμ§ πΈ" β strip emoji from initials computation, but keep in `alt`.
|
|
168
|
+
- **All-Latin name in Korean app**: still works; initials draw from the Latin name as expected.
|
|
169
|
+
- **Anonymous users**: use a stable random ID-based color but a default icon fallback (no initials).
|
|
170
|
+
- **Cropping issues**: `object-fit: cover` + `object-position: center`. For face-aware cropping, depend on server-side image processing.
|
|
171
|
+
- **Hi-DPI**: serve 2Γ resolution image for retina; use `srcset` if available.
|
|
172
|
+
|
|
173
|
+
## Don't
|
|
174
|
+
|
|
175
|
+
- Don't omit `alt`. Empty avatars have no semantic meaning.
|
|
176
|
+
- Don't let initials wrap to two lines β use `overflow: hidden` and clip.
|
|
177
|
+
- Don't use rectangular avatars for people. People are circles, organizations can be rounded squares.
|
|
178
|
+
- Don't use the same fallback color for every avatar β distinguishable colors help readability.
|
|
179
|
+
- Don't put status indicators on avatars where the status isn't meaningful (e.g., a list of past authors β they're not "online").
|
|
180
|
+
- Don't wrap avatars in additional buttons for navigation if the parent row is already clickable.
|
|
181
|
+
|
|
182
|
+
## References
|
|
183
|
+
|
|
184
|
+
- Ant Design: [`refs/ant-design/components/avatar/`](../refs/ant-design/components/avatar/) β `Avatar`, `Avatar.Group`. `shape="circle" | "square"`. Multi-size + scaling for groups.
|
|
185
|
+
- MUI: [`refs/mui/packages/mui-material/src/Avatar/`](../refs/mui/packages/mui-material/src/Avatar/) β `Avatar` + `AvatarGroup`. Falls back to first letter of `children` text.
|
|
186
|
+
- shadcn-ui: [`refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/avatar.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/avatar.tsx) β Radix Avatar primitive. Composition: `Avatar`, `AvatarImage`, `AvatarFallback`.
|
|
187
|
+
|
|
188
|
+
## Cross-reference
|
|
189
|
+
|
|
190
|
+
- [knowledge/i18n/korean-typography.md](../knowledge/i18n/korean-typography.md) β Korean initials conventions
|
|
191
|
+
- [knowledge/patterns/list-and-feed.md](../knowledge/patterns/list-and-feed.md) β chat / conversation list avatars
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# `BackTop` β spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from Ant Design `BackTop`. Floating "scroll to top" button that appears after the user scrolls past a threshold. Pairs with long-content pages.
|
|
4
|
+
|
|
5
|
+
## When to use
|
|
6
|
+
|
|
7
|
+
- Long content pages (articles, feeds, dashboards) where users scroll far.
|
|
8
|
+
- Mobile particularly (more painful to scroll back).
|
|
9
|
+
|
|
10
|
+
When NOT to use:
|
|
11
|
+
- Short pages (< 1.5 viewport heights).
|
|
12
|
+
- Scroll-snap pages where each snap is a "section" (different nav pattern).
|
|
13
|
+
|
|
14
|
+
## Anatomy
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
[content]
|
|
18
|
+
[content]
|
|
19
|
+
[content]
|
|
20
|
+
[content]
|
|
21
|
+
[content]
|
|
22
|
+
[β] β appears after scroll past threshold
|
|
23
|
+
[content]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## API
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
<BackTop
|
|
30
|
+
visibilityHeight={400}
|
|
31
|
+
duration={500}
|
|
32
|
+
onClick={() => track("back-to-top")}
|
|
33
|
+
>
|
|
34
|
+
<button className="back-top-button">β</button>
|
|
35
|
+
</BackTop>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
| Prop | Type | Default | Description |
|
|
39
|
+
| --- | --- | --- | --- |
|
|
40
|
+
| `visibilityHeight` | `number` | `400` | Px scrolled before button appears |
|
|
41
|
+
| `duration` | `number` | `450` | Ms for smooth-scroll-up animation |
|
|
42
|
+
| `target` | `() => HTMLElement` | window | Scrollable container |
|
|
43
|
+
| `onClick` | `() => void` | β | Custom callback |
|
|
44
|
+
|
|
45
|
+
## States
|
|
46
|
+
|
|
47
|
+
| State | Visual |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| Hidden (scroll < threshold) | Not rendered / fade-out |
|
|
50
|
+
| Visible | Floating button bottom-right; subtle shadow |
|
|
51
|
+
| Hover | Subtle bg shift |
|
|
52
|
+
| Pressed | Scrolling animation in progress |
|
|
53
|
+
|
|
54
|
+
## Position + tokens
|
|
55
|
+
|
|
56
|
+
Bottom-right anchor; safe-area-aware for iOS.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
--back-top-bg
|
|
60
|
+
--back-top-fg
|
|
61
|
+
--back-top-shadow
|
|
62
|
+
--back-top-size (40-48px)
|
|
63
|
+
--space-md (offset from edges)
|
|
64
|
+
--motion-medium (fade + scroll)
|
|
65
|
+
--ease-out
|
|
66
|
+
--z-fab
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Accessibility
|
|
70
|
+
|
|
71
|
+
- `<button aria-label="νμ΄μ§ 맨 μλ‘ μ΄λ">`.
|
|
72
|
+
- Smooth scroll respects `prefers-reduced-motion` (instant scroll if reduced).
|
|
73
|
+
- Focus visible.
|
|
74
|
+
- Keyboard: Home key also scrolls to top in many browsers; BackTop is a visual affordance, not a replacement.
|
|
75
|
+
|
|
76
|
+
## Code example
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
<BackTop visibilityHeight={600}>
|
|
80
|
+
<button
|
|
81
|
+
className="back-top-button"
|
|
82
|
+
aria-label="맨 μλ‘"
|
|
83
|
+
>
|
|
84
|
+
<ArrowUpIcon />
|
|
85
|
+
</button>
|
|
86
|
+
</BackTop>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Reduced motion
|
|
90
|
+
|
|
91
|
+
```css
|
|
92
|
+
@media (prefers-reduced-motion: reduce) {
|
|
93
|
+
/* Replace smooth scroll with instant jump */
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
JS:
|
|
98
|
+
```js
|
|
99
|
+
const reduced = matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
100
|
+
window.scrollTo({ top: 0, behavior: reduced ? "auto" : "smooth" });
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Korean conventions
|
|
104
|
+
|
|
105
|
+
- 맨 μλ‘ / μλ‘ / μ²μμΌλ‘ β typical labels (ν΄μ체 OK).
|
|
106
|
+
- For Korean B2C: chevron arrow icon usual; some apps use full-text "맨 μλ‘" in narrow strip.
|
|
107
|
+
|
|
108
|
+
## Don't
|
|
109
|
+
|
|
110
|
+
- Don't show BackTop on short pages β visual noise.
|
|
111
|
+
- Don't omit `aria-label`.
|
|
112
|
+
- Don't override scroll behavior without reduced-motion check.
|
|
113
|
+
- Don't auto-fire scroll without user click.
|
|
114
|
+
|
|
115
|
+
## References
|
|
116
|
+
|
|
117
|
+
- Ant: [`BackTop`](../refs/ant-design/components/back-top)
|
|
118
|
+
- Native: `window.scrollTo({ behavior: "smooth" })`
|
|
119
|
+
|
|
120
|
+
## Cross-reference
|
|
121
|
+
|
|
122
|
+
- [`examples/component-float-button.md`](component-float-button.md)
|
|
123
|
+
- [`examples/component-affix.md`](component-affix.md) β sticky positioning sibling
|