@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,178 @@
|
|
|
1
|
+
# `Tooltip` — spec
|
|
2
|
+
|
|
3
|
+
> Citing Ant Design `Tooltip`, MUI `Tooltip`, shadcn-ui `tooltip`
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
A short hover/focus hint about an interactive element. **Help text, not content.** If users would miss the content without it, the content needs to be visible — not in a tooltip.
|
|
8
|
+
|
|
9
|
+
## When NOT to use a tooltip
|
|
10
|
+
|
|
11
|
+
- For critical instructions (use inline help text or labels).
|
|
12
|
+
- For long content (use Popover).
|
|
13
|
+
- On non-interactive elements that aren't focusable (keyboard users can't reach).
|
|
14
|
+
- For toolbar icon-only buttons that NEED tooltips → consider visible labels instead, or accept that hover is the only path.
|
|
15
|
+
|
|
16
|
+
## Anatomy
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
┌─────────────────────┐
|
|
20
|
+
│ Hint text │
|
|
21
|
+
└────────┬────────────┘
|
|
22
|
+
▼ (arrow)
|
|
23
|
+
[trigger element]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or other side: trigger above, tooltip below; etc. — depending on space.
|
|
27
|
+
|
|
28
|
+
## API
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
<Tooltip content="이 아이콘을 클릭하면 설정으로 이동합니다">
|
|
32
|
+
<IconButton aria-label="Settings"><SettingsIcon /></IconButton>
|
|
33
|
+
</Tooltip>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
| Prop | Type | Default | Description |
|
|
37
|
+
| --- | --- | --- | --- |
|
|
38
|
+
| `content` | `string \| ReactNode` | — | Required. The hint text. |
|
|
39
|
+
| `children` | `ReactElement` | — | The trigger. **Single element only**, must support `ref`. |
|
|
40
|
+
| `side` | `"top" \| "right" \| "bottom" \| "left"` | `"top"` | Preferred position |
|
|
41
|
+
| `align` | `"start" \| "center" \| "end"` | `"center"` | Alignment along the side |
|
|
42
|
+
| `delayMs` | `number` | `300` | Open delay (avoid flicker on quick mouse pass) |
|
|
43
|
+
| `closeDelayMs` | `number` | `100` | Close delay |
|
|
44
|
+
| `disabled` | `boolean` | `false` | Suppress tooltip without disabling trigger |
|
|
45
|
+
| `open` | `boolean` | — | Controlled open (overrides hover/focus) |
|
|
46
|
+
| `onOpenChange` | `(open: boolean) => void` | — | |
|
|
47
|
+
| `arrow` | `boolean` | `true` | Show arrow pointing at trigger |
|
|
48
|
+
|
|
49
|
+
## Behavior
|
|
50
|
+
|
|
51
|
+
| Trigger | Action |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| Mouse over trigger | Open after `delayMs` |
|
|
54
|
+
| Mouse leave | Close after `closeDelayMs` |
|
|
55
|
+
| Keyboard focus on trigger | Open immediately (no delay) |
|
|
56
|
+
| Keyboard blur | Close immediately |
|
|
57
|
+
| Click trigger | Tooltip closes (don't override the click) |
|
|
58
|
+
| Touch on trigger | **Don't show tooltip on touch** — interferes with tap. Use long-press to show OR don't show on touch at all (most common). |
|
|
59
|
+
|
|
60
|
+
## Sizes
|
|
61
|
+
|
|
62
|
+
| Size | Padding | Font | Max width |
|
|
63
|
+
| --- | --- | --- | --- |
|
|
64
|
+
| `sm` (default for icon button hints) | 4px 8px | 12px | 200px |
|
|
65
|
+
| `md` (default for buttons with labels) | 6px 10px | 13px | 280px |
|
|
66
|
+
| `lg` (descriptive, multi-line) | 8px 12px | 14px | 360px |
|
|
67
|
+
|
|
68
|
+
> Most tooltips should be `sm`. If you need `lg`, you probably want a Popover.
|
|
69
|
+
|
|
70
|
+
## States
|
|
71
|
+
|
|
72
|
+
| State | Visual |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| Closed | not in DOM (or `display: none`) |
|
|
75
|
+
| Opening | 100ms fade + slight scale 0.95 → 1 |
|
|
76
|
+
| Open | settled, dark bg + light text (or inverse, see token) |
|
|
77
|
+
| Closing | 75ms fade |
|
|
78
|
+
|
|
79
|
+
## Tokens consumed
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
--color-bg-tooltip (typically inverse of bg-default — dark in light mode, light in dark mode)
|
|
83
|
+
--color-text-on-tooltip (inverse of text-primary)
|
|
84
|
+
--space-xs, --space-sm
|
|
85
|
+
--radius-sm
|
|
86
|
+
--font-size-xs, --font-size-sm
|
|
87
|
+
--shadow-popover
|
|
88
|
+
--motion-fast, --easing-out
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Accessibility — critical
|
|
92
|
+
|
|
93
|
+
The native `title` attribute does NOT meet a11y requirements:
|
|
94
|
+
- Doesn't show on keyboard focus on most platforms.
|
|
95
|
+
- Mobile browsers ignore it.
|
|
96
|
+
- Inconsistent across screen readers.
|
|
97
|
+
|
|
98
|
+
**Use a real tooltip primitive** (Radix Tooltip / shadcn / Floating UI). Don't use `title`.
|
|
99
|
+
|
|
100
|
+
### ARIA wiring
|
|
101
|
+
|
|
102
|
+
- Trigger: `aria-describedby={tooltipId}` when tooltip is open; remove or empty when closed.
|
|
103
|
+
- Tooltip: `role="tooltip"`, `id={tooltipId}`.
|
|
104
|
+
- Trigger should also have its own accessible name (`aria-label` if icon-only) — the tooltip is supplementary, not the primary name.
|
|
105
|
+
|
|
106
|
+
```html
|
|
107
|
+
<!-- Bad: tooltip is the only accessible name -->
|
|
108
|
+
<button><CloseIcon /></button>
|
|
109
|
+
<Tooltip>Close</Tooltip>
|
|
110
|
+
|
|
111
|
+
<!-- Good: button has aria-label, tooltip is descriptive -->
|
|
112
|
+
<button aria-label="Close"><CloseIcon /></button>
|
|
113
|
+
<Tooltip>Closes the dialog and discards changes</Tooltip>
|
|
114
|
+
|
|
115
|
+
<!-- Best for icon button: hide tooltip when redundant with aria-label -->
|
|
116
|
+
<button aria-label="Close"><CloseIcon /></button>
|
|
117
|
+
<!-- (no tooltip — aria-label is the name and the visual icon is the affordance) -->
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Touch / mobile
|
|
121
|
+
|
|
122
|
+
- `hover` doesn't exist on touch.
|
|
123
|
+
- Long-press to show tooltip is iOS/Android convention but rarely implemented.
|
|
124
|
+
- **Best practice**: tooltips are a desktop affordance. On mobile, surface critical info inline or as a help drawer (`?` icon → bottom sheet).
|
|
125
|
+
|
|
126
|
+
## Code example
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
// Standard icon button with tooltip
|
|
130
|
+
<Tooltip content="새 항목 추가">
|
|
131
|
+
<IconButton aria-label="Add item" onClick={handleAdd}>
|
|
132
|
+
<PlusIcon />
|
|
133
|
+
</IconButton>
|
|
134
|
+
</Tooltip>
|
|
135
|
+
|
|
136
|
+
// Disabled tooltip on disabled button (workaround — disabled buttons don't fire hover events)
|
|
137
|
+
<Tooltip content="권한이 없습니다">
|
|
138
|
+
<span> {/* wrapper enables hover */}
|
|
139
|
+
<Button disabled>Edit</Button>
|
|
140
|
+
</span>
|
|
141
|
+
</Tooltip>
|
|
142
|
+
|
|
143
|
+
// Keyboard-shortcut hint
|
|
144
|
+
<Tooltip content="Save (Cmd+S)">
|
|
145
|
+
<Button onClick={handleSave}>Save</Button>
|
|
146
|
+
</Tooltip>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Edge cases
|
|
150
|
+
|
|
151
|
+
- **Tooltip on disabled button**: native `disabled` doesn't fire mouse events. Wrap in a `<span>` so the wrapper handles hover.
|
|
152
|
+
- **Tooltip on a link that wraps to new line**: the tooltip might appear far from the cursor. Better to make the tooltip follow the trigger's bounding box, or use `align="start"`.
|
|
153
|
+
- **Long content that wraps**: cap at max-width and wrap. If consistently long, you want a Popover.
|
|
154
|
+
- **Rapid mouse pass**: tooltip opens on hover delay (300ms), so quick mouse-bys don't trigger. Don't reduce the delay below 200ms.
|
|
155
|
+
- **Tooltip near viewport edge**: should auto-flip to opposite side. Use Floating UI or Radix's collision detection.
|
|
156
|
+
- **Reduced motion**: disable fade animation, just show/hide.
|
|
157
|
+
- **In a scrollable container**: tooltip should reposition or hide on scroll.
|
|
158
|
+
- **Korean tooltips**: short hangul fits comfortably; if your tooltip is > 1 line, reconsider — should probably be inline help.
|
|
159
|
+
|
|
160
|
+
## Don't
|
|
161
|
+
|
|
162
|
+
- Don't put critical content in tooltips. Keyboard-only users on mobile cannot access them.
|
|
163
|
+
- Don't use a tooltip on a non-interactive element (e.g., a static icon). Either make it interactive (focusable button) or use inline help text.
|
|
164
|
+
- Don't show a tooltip on an `aria-label` that says the same thing — redundant and noisy.
|
|
165
|
+
- Don't use HTML `title` attribute. Build a real tooltip.
|
|
166
|
+
- Don't put interactive elements inside the tooltip. It's hover-triggered and disappears on mouse-out.
|
|
167
|
+
- Don't show on click (that's a Popover).
|
|
168
|
+
|
|
169
|
+
## References
|
|
170
|
+
|
|
171
|
+
- Ant Design: [`refs/ant-design/components/tooltip/`](../refs/ant-design/components/tooltip/) — `Tooltip` with rich placement options (12 directions). `mouseEnterDelay` / `mouseLeaveDelay` props.
|
|
172
|
+
- MUI: [`refs/mui/packages/mui-material/src/Tooltip/`](../refs/mui/packages/mui-material/src/Tooltip/) — `Tooltip` with `placement`, `enterDelay`, `leaveDelay`, `arrow`. Solid implementation.
|
|
173
|
+
- shadcn-ui: [`refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/tooltip.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/tooltip.tsx) — Radix Tooltip primitive. **Default — best a11y of the three.**
|
|
174
|
+
|
|
175
|
+
## Cross-reference
|
|
176
|
+
|
|
177
|
+
- [knowledge/a11y/keyboard-and-focus.md](../knowledge/a11y/keyboard-and-focus.md) — focus-driven tooltips
|
|
178
|
+
- [WAI-ARIA Tooltip Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/)
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# `Tour` (in-product overlay tour) — spec
|
|
2
|
+
|
|
3
|
+
> Citing Ant Design `Tour`, MUI (no built-in), shadcn-ui (composition with Popover)
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
A series of overlay tooltips that highlight UI elements one at a time, with "Next / Previous / Skip" navigation. Used for: onboarding new users, surfacing new features, complex tool walkthroughs.
|
|
8
|
+
|
|
9
|
+
**Use sparingly.** See [`knowledge/patterns/onboarding.md`](../knowledge/patterns/onboarding.md) — tours have the highest friction of any onboarding pattern.
|
|
10
|
+
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
[Page content, dimmed except for the highlighted element]
|
|
15
|
+
|
|
16
|
+
┌──[ highlighted UI element ]──┐
|
|
17
|
+
│ [target, brightly visible] │
|
|
18
|
+
└──────────────────────────────┘
|
|
19
|
+
▼ (callout pointer)
|
|
20
|
+
┌────────────────────────────────────┐
|
|
21
|
+
│ Step 1 of 4 │
|
|
22
|
+
│ │
|
|
23
|
+
│ Click here to add a transaction. │
|
|
24
|
+
│ │
|
|
25
|
+
│ [Skip] [Next] │
|
|
26
|
+
└────────────────────────────────────┘
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
| Slot | Required | Notes |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| Backdrop dim | yes | Darkens the page (~50% black) |
|
|
32
|
+
| Spotlight area | yes | Cuts a hole around the target element so it's bright |
|
|
33
|
+
| Callout | yes | Position relative to target |
|
|
34
|
+
| Step indicator | yes | "Step N of M" |
|
|
35
|
+
| Title | yes | Action description |
|
|
36
|
+
| Next / Previous / Skip | yes | Step navigation |
|
|
37
|
+
|
|
38
|
+
## API
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
<Tour
|
|
42
|
+
open={tourOpen}
|
|
43
|
+
steps={[
|
|
44
|
+
{
|
|
45
|
+
target: "#add-button",
|
|
46
|
+
title: "거래 추가",
|
|
47
|
+
description: "여기를 클릭해 첫 거래를 추가해 보세요.",
|
|
48
|
+
placement: "bottom",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
target: "#filter-area",
|
|
52
|
+
title: "필터링",
|
|
53
|
+
description: "기간 / 카테고리로 거래를 필터링할 수 있어요.",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
target: "#export",
|
|
57
|
+
title: "내보내기",
|
|
58
|
+
description: "거래 내역을 CSV로 내보낼 수 있어요.",
|
|
59
|
+
},
|
|
60
|
+
]}
|
|
61
|
+
onClose={() => setTourOpen(false)}
|
|
62
|
+
onComplete={() => markFirstRunDone()}
|
|
63
|
+
/>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
| Prop | Type | Default | Description |
|
|
67
|
+
| --- | --- | --- | --- |
|
|
68
|
+
| `open` | `boolean` | — | Whether tour is active |
|
|
69
|
+
| `current` | `number` | `0` | Current step index (controlled mode) |
|
|
70
|
+
| `onChange` | `(step: number) => void` | — | |
|
|
71
|
+
| `steps` | `Step[]` | — | Tour steps |
|
|
72
|
+
| `onClose` | `() => void` | — | User clicked Skip / closed |
|
|
73
|
+
| `onComplete` | `() => void` | — | Reached the end |
|
|
74
|
+
| `placement` | `"top" \| "right" \| "bottom" \| "left"` (default callout side) | `"bottom"` | Per-step override possible |
|
|
75
|
+
| `mask` | `boolean` | `true` | Show backdrop dim |
|
|
76
|
+
| `maskClosable` | `boolean` | `false` | Click on backdrop closes |
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
type Step = {
|
|
80
|
+
target: string | HTMLElement; // CSS selector or element ref
|
|
81
|
+
title: string;
|
|
82
|
+
description: ReactNode;
|
|
83
|
+
placement?: "top" | "right" | "bottom" | "left";
|
|
84
|
+
hideArrow?: boolean;
|
|
85
|
+
beforeShow?: () => void | Promise<void>; // e.g., scroll target into view
|
|
86
|
+
afterHide?: () => void;
|
|
87
|
+
};
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Behavior
|
|
91
|
+
|
|
92
|
+
### Step transition
|
|
93
|
+
|
|
94
|
+
1. Tour finds target element by selector/ref.
|
|
95
|
+
2. Calls `beforeShow` (e.g., scroll into view, expand a section).
|
|
96
|
+
3. Fades in backdrop + cuts spotlight around target.
|
|
97
|
+
4. Renders callout near target.
|
|
98
|
+
5. User clicks Next → repeat for next step.
|
|
99
|
+
|
|
100
|
+
### Target element off-screen
|
|
101
|
+
|
|
102
|
+
`beforeShow` should `scrollIntoView` to bring the target into view. Wait for scroll to complete (200–300ms), then position callout.
|
|
103
|
+
|
|
104
|
+
### Target element not present
|
|
105
|
+
|
|
106
|
+
If selector doesn't match (e.g., conditional UI not rendered), skip the step or show error. Best: validate steps when starting tour.
|
|
107
|
+
|
|
108
|
+
### Closing
|
|
109
|
+
|
|
110
|
+
- **Skip**: closes tour, `onClose` fires. Current step is remembered (offer to resume later).
|
|
111
|
+
- **Complete**: reaches last step + clicks Done. `onComplete` fires.
|
|
112
|
+
- **Backdrop click**: only if `maskClosable=true`.
|
|
113
|
+
- **Escape key**: closes (UX convention — provide).
|
|
114
|
+
|
|
115
|
+
## States
|
|
116
|
+
|
|
117
|
+
| State | Visual |
|
|
118
|
+
| --- | --- |
|
|
119
|
+
| Idle | not visible |
|
|
120
|
+
| Animating in | fade backdrop + scale-in callout |
|
|
121
|
+
| Active step | spotlight + callout visible |
|
|
122
|
+
| Transitioning between steps | smooth cross-fade or slide |
|
|
123
|
+
|
|
124
|
+
## Tokens consumed
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
--color-bg-overlay (backdrop)
|
|
128
|
+
--color-bg-elevated (callout)
|
|
129
|
+
--color-text-primary
|
|
130
|
+
--color-text-secondary
|
|
131
|
+
--color-primary-default (Next button bg)
|
|
132
|
+
--space-md, --space-base
|
|
133
|
+
--radius-md
|
|
134
|
+
--shadow-popover
|
|
135
|
+
--motion-default (250-300ms transitions)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Accessibility
|
|
139
|
+
|
|
140
|
+
- Tour is a modal-equivalent: focus trap inside the callout while active.
|
|
141
|
+
- Each callout: `role="dialog"`, `aria-labelledby={titleId}`, `aria-describedby={descId}`.
|
|
142
|
+
- Backdrop: `aria-hidden="true"`.
|
|
143
|
+
- Step indicator: announced ("Step 1 of 4").
|
|
144
|
+
- Focus moves into callout on step change.
|
|
145
|
+
- Escape closes tour.
|
|
146
|
+
|
|
147
|
+
### Keyboard
|
|
148
|
+
|
|
149
|
+
| Key | Behavior |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `Tab` | Cycle through callout interactive elements (Next, Prev, Skip) |
|
|
152
|
+
| `Enter` (on Next) | Advance |
|
|
153
|
+
| `Escape` | Close tour |
|
|
154
|
+
| `←` `→` | Optional: previous / next step (not standard) |
|
|
155
|
+
|
|
156
|
+
## Don't
|
|
157
|
+
|
|
158
|
+
- Don't use Tour as the primary onboarding for simple products. Empty-state CTA is friendlier. See [`knowledge/patterns/onboarding.md`](../knowledge/patterns/onboarding.md).
|
|
159
|
+
- Don't run tours longer than 5 steps. User fatigue is real.
|
|
160
|
+
- Don't auto-show tours on every visit. Show once, dismiss, persist.
|
|
161
|
+
- Don't tour features the user might never use. Tour the core path.
|
|
162
|
+
- Don't make tours required. Always provide Skip.
|
|
163
|
+
- Don't run tour without scroll/visibility setup — target out of view = broken.
|
|
164
|
+
- Don't gate the feature behind the tour ("can't proceed until you complete tour").
|
|
165
|
+
|
|
166
|
+
## References
|
|
167
|
+
|
|
168
|
+
- Ant Design: [`refs/ant-design/components/tour/`](../refs/ant-design/components/tour/) — `Tour` with steps, target refs, custom rendering. Modern Ant addition.
|
|
169
|
+
- MUI: no built-in. Use libraries like `react-joyride` or `intro.js`.
|
|
170
|
+
- shadcn-ui: no built-in. Compose with Popover + custom backdrop.
|
|
171
|
+
|
|
172
|
+
## Cross-reference
|
|
173
|
+
|
|
174
|
+
- [`knowledge/patterns/onboarding.md`](../knowledge/patterns/onboarding.md) — when to use Tour vs other patterns
|
|
175
|
+
- [`examples/component-popover.md`](component-popover.md) — Tour callouts use popover pattern
|
|
176
|
+
- [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md) — focus trap, Escape behavior
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# `TransactionListItem` (custom — Korean fintech / 가계부) — spec
|
|
2
|
+
|
|
3
|
+
> Custom component pattern. The most-rendered row in any 가계부 / banking / payment app. Many tens of these per screen — performance + visual consistency matters.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
A single row in a transaction list — date, category, description, amount. Tappable to open detail.
|
|
8
|
+
|
|
9
|
+
## Anatomy
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌─────────────────────────────────────────────────────────┐
|
|
13
|
+
│ [icon] Description -₩12,500 │
|
|
14
|
+
│ Subtitle (category, payment method, time) │
|
|
15
|
+
└─────────────────────────────────────────────────────────┘
|
|
16
|
+
|
|
17
|
+
Example (expense):
|
|
18
|
+
🍽 스타벅스 강남점 -₩5,500
|
|
19
|
+
카페 · 12:34
|
|
20
|
+
|
|
21
|
+
Example (income):
|
|
22
|
+
💰 급여 +₩2,500,000
|
|
23
|
+
회사 · 09:00
|
|
24
|
+
|
|
25
|
+
Example (transfer between own accounts):
|
|
26
|
+
🔄 자동이체 (적금) ₩-100,000
|
|
27
|
+
국민은행 → 우리은행 · 어제 17:00
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
| Slot | Required | Notes |
|
|
31
|
+
| --- | --- | --- |
|
|
32
|
+
| Category icon | yes | Emoji or icon (matches CategoryPicker) |
|
|
33
|
+
| Title | yes | Merchant name or transaction description |
|
|
34
|
+
| Subtitle | yes | Category / payment method / time |
|
|
35
|
+
| Amount | yes | Right-aligned, tabular numerals, signed |
|
|
36
|
+
| Trailing chevron | optional | Drill-in affordance |
|
|
37
|
+
| Status badge | optional | "취소" (cancelled), "보류" (pending) |
|
|
38
|
+
|
|
39
|
+
## API
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
<TransactionListItem
|
|
43
|
+
icon="🍽"
|
|
44
|
+
title="스타벅스 강남점"
|
|
45
|
+
subtitle="카페 · 12:34"
|
|
46
|
+
amount={-5500}
|
|
47
|
+
type="expense"
|
|
48
|
+
onClick={() => openTransaction(id)}
|
|
49
|
+
/>
|
|
50
|
+
|
|
51
|
+
<TransactionListItem
|
|
52
|
+
icon="💰"
|
|
53
|
+
title="급여"
|
|
54
|
+
subtitle="회사 · 09:00"
|
|
55
|
+
amount={2500000}
|
|
56
|
+
type="income"
|
|
57
|
+
/>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
| Prop | Type | Default | Description |
|
|
61
|
+
| --- | --- | --- | --- |
|
|
62
|
+
| `icon` | `string \| ReactNode` | — | Emoji or icon (typically matches CategoryPicker) |
|
|
63
|
+
| `title` | `string \| ReactNode` | — | Merchant or description |
|
|
64
|
+
| `subtitle` | `string \| ReactNode` | — | Category · time / payment method |
|
|
65
|
+
| `amount` | `number` | — | Signed amount in smallest unit (won) |
|
|
66
|
+
| `type` | `"expense" \| "income" \| "transfer" \| "neutral"` | inferred from sign | Drives amount color |
|
|
67
|
+
| `currency` | `"KRW" \| ...` | `"KRW"` | Format |
|
|
68
|
+
| `onClick` | `() => void` | — | Drill-in handler |
|
|
69
|
+
| `status` | `"pending" \| "cancelled" \| "settled"` | `"settled"` | Optional status badge |
|
|
70
|
+
| `trailingMeta` | `ReactNode` | — | After amount; e.g., balance after this transaction |
|
|
71
|
+
|
|
72
|
+
## Amount color (critical)
|
|
73
|
+
|
|
74
|
+
Per [`knowledge/patterns/money-and-amount.md`](../knowledge/patterns/money-and-amount.md):
|
|
75
|
+
|
|
76
|
+
| Type | Color | Sign |
|
|
77
|
+
| --- | --- | --- |
|
|
78
|
+
| `expense` | `--color-money-negative` | `-` (e.g., `-₩5,500`) |
|
|
79
|
+
| `income` | `--color-money-positive` | `+` (e.g., `+₩2,500,000`) |
|
|
80
|
+
| `transfer` | `--color-money-neutral` (gray) | `-` or no sign |
|
|
81
|
+
| `neutral` | `--color-text-primary` | based on amount |
|
|
82
|
+
|
|
83
|
+
For Korean banking (not stocks): `money-positive` is green, `money-negative` is red. For Korean stock convention (red=up): different rules apply, but stock apps don't use `TransactionListItem` typically.
|
|
84
|
+
|
|
85
|
+
## Sizes
|
|
86
|
+
|
|
87
|
+
| Size | Row height | Icon | Title font | Subtitle font | Amount font |
|
|
88
|
+
| --- | --- | --- | --- | --- | --- |
|
|
89
|
+
| `compact` | 56px | 32px | 14px | 12px | 14px |
|
|
90
|
+
| `default` | 64px | 40px | 15px | 13px | 15px |
|
|
91
|
+
| `comfortable` | 72px | 48px | 16px | 14px | 17px |
|
|
92
|
+
|
|
93
|
+
Korean consumer apps: `default` is the right balance.
|
|
94
|
+
|
|
95
|
+
## States
|
|
96
|
+
|
|
97
|
+
| State | Visual |
|
|
98
|
+
| --- | --- |
|
|
99
|
+
| Default | resting |
|
|
100
|
+
| Hover | bg `--color-bg-subtle` |
|
|
101
|
+
| Pressed (tap) | bg `--color-bg-elevated` (mobile feedback) |
|
|
102
|
+
| Focus-visible | 2px ring around the row |
|
|
103
|
+
| Pending | "보류" badge + reduced opacity 0.7 |
|
|
104
|
+
| Cancelled | "취소" badge + strikethrough on amount |
|
|
105
|
+
|
|
106
|
+
## Tokens consumed
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
--color-bg-default
|
|
110
|
+
--color-bg-subtle (hover)
|
|
111
|
+
--color-bg-elevated (pressed)
|
|
112
|
+
--color-text-primary
|
|
113
|
+
--color-text-secondary (subtitle)
|
|
114
|
+
--color-money-positive
|
|
115
|
+
--color-money-negative
|
|
116
|
+
--color-money-neutral
|
|
117
|
+
--color-text-tertiary (separator dot, "·")
|
|
118
|
+
--color-warning (pending badge)
|
|
119
|
+
--color-error (cancelled badge)
|
|
120
|
+
--color-focus-ring
|
|
121
|
+
--space-sm, --space-md
|
|
122
|
+
--font-feature-amount: 'tnum' 1 (tabular numerals — critical)
|
|
123
|
+
--font-size-sm, --font-size-base
|
|
124
|
+
--radius-full (icon container)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Accessibility
|
|
128
|
+
|
|
129
|
+
- Render as `<button>` (or `<a>` if `onClick` is navigation). Don't use `<div onClick>`.
|
|
130
|
+
- Icon: `aria-hidden="true"` — the title carries meaning.
|
|
131
|
+
- `aria-label` on the row for screen readers, including amount and date:
|
|
132
|
+
```html
|
|
133
|
+
<button aria-label="스타벅스 강남점, 카페, 12:34, 5,500원 지출">
|
|
134
|
+
...
|
|
135
|
+
</button>
|
|
136
|
+
```
|
|
137
|
+
- For lists, `<ul>` + `<li>` containers.
|
|
138
|
+
- Touch target: ≥ 44×44 pt — `default` size at 64px exceeds.
|
|
139
|
+
|
|
140
|
+
## List performance
|
|
141
|
+
|
|
142
|
+
Lists of 100+ transactions:
|
|
143
|
+
- **Virtualize** with FlatList (React Native) or react-virtual / @tanstack/react-virtual (web).
|
|
144
|
+
- Memoize the row component to prevent re-renders.
|
|
145
|
+
- Lazy-load icons if using SVG imports.
|
|
146
|
+
|
|
147
|
+
Per [`knowledge/patterns/list-and-feed.md`](../knowledge/patterns/list-and-feed.md).
|
|
148
|
+
|
|
149
|
+
## Date / time grouping
|
|
150
|
+
|
|
151
|
+
Most apps group transactions by date with sticky headers:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
─── 5월 7일 (목) ────────────────────
|
|
155
|
+
🍽 스타벅스 강남점 -₩5,500
|
|
156
|
+
🚌 지하철 -₩1,500
|
|
157
|
+
|
|
158
|
+
─── 5월 6일 (수) ────────────────────
|
|
159
|
+
💰 급여 +₩2,500,000
|
|
160
|
+
🛍 마켓컬리 -₩48,000
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Header style: small (12-13px), `--color-text-tertiary`, sticky on scroll.
|
|
164
|
+
|
|
165
|
+
For "오늘" (today) and "어제" (yesterday): use the words instead of dates.
|
|
166
|
+
|
|
167
|
+
## Mobile patterns
|
|
168
|
+
|
|
169
|
+
### Swipe actions
|
|
170
|
+
|
|
171
|
+
iOS-style swipe to reveal actions (delete, edit, pin):
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
[🍽 스타벅스 ...] ←(swipe) [Edit] [Delete]
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Use sparingly per [`knowledge/patterns/list-and-feed.md`](../knowledge/patterns/list-and-feed.md).
|
|
178
|
+
|
|
179
|
+
### Long-press menu
|
|
180
|
+
|
|
181
|
+
Long-press opens a contextual action sheet:
|
|
182
|
+
- 수정 (Edit)
|
|
183
|
+
- 카테고리 변경 (Change category)
|
|
184
|
+
- 메모 추가 (Add memo)
|
|
185
|
+
- 삭제 (Delete)
|
|
186
|
+
|
|
187
|
+
Common in Korean 가계부 apps.
|
|
188
|
+
|
|
189
|
+
## Code example
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
function TransactionList({ transactions }: Props) {
|
|
193
|
+
const groupedByDate = useMemo(() => groupByDate(transactions), [transactions]);
|
|
194
|
+
|
|
195
|
+
return (
|
|
196
|
+
<FlatList
|
|
197
|
+
data={groupedByDate}
|
|
198
|
+
keyExtractor={(item) => item.date}
|
|
199
|
+
renderItem={({ item: group }) => (
|
|
200
|
+
<>
|
|
201
|
+
<DateHeader sticky>{formatDate(group.date)}</DateHeader>
|
|
202
|
+
{group.transactions.map((tx) => (
|
|
203
|
+
<TransactionListItem
|
|
204
|
+
key={tx.id}
|
|
205
|
+
icon={tx.category.icon}
|
|
206
|
+
title={tx.merchant}
|
|
207
|
+
subtitle={`${tx.category.label} · ${formatTime(tx.time)}`}
|
|
208
|
+
amount={tx.amount}
|
|
209
|
+
type={tx.type}
|
|
210
|
+
onClick={() => navigation.navigate("TransactionDetail", { id: tx.id })}
|
|
211
|
+
/>
|
|
212
|
+
))}
|
|
213
|
+
</>
|
|
214
|
+
)}
|
|
215
|
+
/>
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Don't
|
|
221
|
+
|
|
222
|
+
- Don't omit tabular numerals — amounts won't align in column.
|
|
223
|
+
- Don't use `--color-error` for expense color. Use `--color-money-negative`.
|
|
224
|
+
- Don't omit category icon — Korean users scan by emoji.
|
|
225
|
+
- Don't render 1000+ rows without virtualization.
|
|
226
|
+
- Don't truncate the amount — full precision matters in financial UI.
|
|
227
|
+
- Don't show "0원" for zero-amount placeholder rows. Hide them.
|
|
228
|
+
- Don't right-align title. Left-align (LTR) — only amount is right-aligned.
|
|
229
|
+
|
|
230
|
+
## API rationale
|
|
231
|
+
|
|
232
|
+
- **`amount: number` not formatted string**: source of truth is the integer; formatting is presentation. AmountInput stores numbers; consistent with this.
|
|
233
|
+
- **`type` separate from amount sign**: positive amount might still be a "transfer" (visually neutral), not income.
|
|
234
|
+
- **Icon as string accepts emoji**: Korean apps use emoji directly; allows flexibility for icons too.
|
|
235
|
+
|
|
236
|
+
## Cross-reference
|
|
237
|
+
|
|
238
|
+
- [`knowledge/patterns/money-and-amount.md`](../knowledge/patterns/money-and-amount.md) — money color semantics
|
|
239
|
+
- [`knowledge/patterns/list-and-feed.md`](../knowledge/patterns/list-and-feed.md) — list patterns, virtualization
|
|
240
|
+
- [`knowledge/i18n/korean-product-conventions.md`](../knowledge/i18n/korean-product-conventions.md) — Korean fintech conventions
|
|
241
|
+
- [`examples/component-category-picker.md`](component-category-picker.md) — paired with CategoryPicker
|
|
242
|
+
- [`examples/component-amount-input.md`](component-amount-input.md) — paired in transaction forms
|
|
243
|
+
- [`examples/component-card.md`](component-card.md) — TransactionListItem is essentially a list-row card
|