@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,277 @@
|
|
|
1
|
+
# `PaymentReceipt` (custom — Korean fintech) — spec
|
|
2
|
+
|
|
3
|
+
> Custom component pattern. Korean payment apps render post-purchase receipts in a distinctive layout — dotted divider lines, structured price breakdown, KakaoPay-style summary card.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Displays a payment confirmation receipt: items, subtotal, discounts, fees, total, payment method, timestamp. Used after checkout, in transaction detail screens, in 1:1 inquiries.
|
|
8
|
+
|
|
9
|
+
## Anatomy
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌─────────────────────────────────────────┐
|
|
13
|
+
│ ✓ │
|
|
14
|
+
│ 결제가 완료되었습니다 │ ← header
|
|
15
|
+
│ 2026.05.07 14:30:25 │
|
|
16
|
+
│ │
|
|
17
|
+
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│ ← dotted divider (Korean receipt convention)
|
|
18
|
+
│ │
|
|
19
|
+
│ 주문번호 ORD-2026-001234 │
|
|
20
|
+
│ 상점 스타벅스 강남점 │
|
|
21
|
+
│ 결제수단 KakaoPay │
|
|
22
|
+
│ │
|
|
23
|
+
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│
|
|
24
|
+
│ │
|
|
25
|
+
│ 아메리카노 (Tall) ₩4,500 │ ← items
|
|
26
|
+
│ 카페라떼 (Grande) ₩5,500 │
|
|
27
|
+
│ │
|
|
28
|
+
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│
|
|
29
|
+
│ │
|
|
30
|
+
│ 상품 합계 ₩10,000 │ ← breakdown
|
|
31
|
+
│ 할인 -₩1,000 │
|
|
32
|
+
│ ───────────── │
|
|
33
|
+
│ 총 결제 금액 ₩9,000 │ ← total (bold, larger)
|
|
34
|
+
│ │
|
|
35
|
+
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│
|
|
36
|
+
│ │
|
|
37
|
+
│ [영수증 공유] [재구매] │ ← actions
|
|
38
|
+
└─────────────────────────────────────────┘
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
| Slot | Required | Notes |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| Header | yes | Status icon + "결제 완료" + timestamp |
|
|
44
|
+
| Order metadata | yes | 주문번호, 상점, 결제수단 |
|
|
45
|
+
| Items | usually | Each item with name + price |
|
|
46
|
+
| Subtotal breakdown | yes | 상품 합계, 할인, 배송, 부가세 |
|
|
47
|
+
| Total | yes | Bold, larger |
|
|
48
|
+
| Actions | optional | 영수증 공유 / 재구매 / 취소 |
|
|
49
|
+
| Dotted dividers | yes | Korean receipt convention |
|
|
50
|
+
|
|
51
|
+
## API
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
<PaymentReceipt
|
|
55
|
+
status="completed"
|
|
56
|
+
timestamp={order.completedAt}
|
|
57
|
+
orderId={order.id}
|
|
58
|
+
merchant={order.merchant}
|
|
59
|
+
paymentMethod="KakaoPay"
|
|
60
|
+
items={order.items}
|
|
61
|
+
subtotal={order.subtotal}
|
|
62
|
+
discount={order.discount}
|
|
63
|
+
shipping={order.shipping}
|
|
64
|
+
tax={order.tax}
|
|
65
|
+
total={order.total}
|
|
66
|
+
actions={[
|
|
67
|
+
{ label: "영수증 공유", onClick: shareReceipt },
|
|
68
|
+
{ label: "재구매", onClick: reorder },
|
|
69
|
+
]}
|
|
70
|
+
/>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
| Prop | Type | Default | Description |
|
|
74
|
+
| --- | --- | --- | --- |
|
|
75
|
+
| `status` | `"completed" \| "pending" \| "cancelled" \| "refunded"` | — | Drives header icon + color |
|
|
76
|
+
| `timestamp` | `Date \| string` | — | When |
|
|
77
|
+
| `orderId` | `string` | — | |
|
|
78
|
+
| `merchant` | `string` | — | Store / business name |
|
|
79
|
+
| `paymentMethod` | `string` | — | "KakaoPay", "신한카드 ****-1234", etc. |
|
|
80
|
+
| `items` | `Item[]` | — | Line items |
|
|
81
|
+
| `subtotal` | `number` | — | Sum of items |
|
|
82
|
+
| `discount` | `number` | — | Negative number |
|
|
83
|
+
| `shipping` | `number` | — | |
|
|
84
|
+
| `tax` | `number` | — | |
|
|
85
|
+
| `total` | `number` | — | Final amount paid |
|
|
86
|
+
| `actions` | `Action[]` | — | Buttons at bottom |
|
|
87
|
+
| `cancellable` | `boolean` | `false` | Show cancel option |
|
|
88
|
+
| `refundable` | `boolean` | `false` | Show refund request option |
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
type Item = {
|
|
92
|
+
name: string;
|
|
93
|
+
description?: string;
|
|
94
|
+
quantity?: number;
|
|
95
|
+
unitPrice?: number;
|
|
96
|
+
totalPrice: number;
|
|
97
|
+
};
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Status → header
|
|
101
|
+
|
|
102
|
+
| Status | Icon | Color | Title |
|
|
103
|
+
| --- | --- | --- | --- |
|
|
104
|
+
| `completed` | ✓ | success | "결제가 완료되었습니다" |
|
|
105
|
+
| `pending` | ⏳ | warning | "결제 처리 중입니다" |
|
|
106
|
+
| `cancelled` | ✕ | error | "결제가 취소되었습니다" |
|
|
107
|
+
| `refunded` | ↶ | neutral | "환불 완료" |
|
|
108
|
+
|
|
109
|
+
## Sizes / variants
|
|
110
|
+
|
|
111
|
+
| Variant | Use |
|
|
112
|
+
| --- | --- |
|
|
113
|
+
| `default` | Order detail screen / receipt detail |
|
|
114
|
+
| `compact` | List-row preview |
|
|
115
|
+
| `print` | Print-optimized (no actions, plain colors) |
|
|
116
|
+
|
|
117
|
+
## Dotted divider
|
|
118
|
+
|
|
119
|
+
The `─ ─ ─` dotted divider is a strong Korean receipt convention (mimicking thermal-printed paper receipts):
|
|
120
|
+
|
|
121
|
+
```css
|
|
122
|
+
.receipt-divider {
|
|
123
|
+
border-top: 1px dashed var(--color-border-default);
|
|
124
|
+
margin: 16px 0;
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Optional: render as inline SVG for a more receipt-paper feel.
|
|
129
|
+
|
|
130
|
+
## Item row alignment
|
|
131
|
+
|
|
132
|
+
Item names left-aligned, prices right-aligned, tabular numerals. Quantity often shown as multiplier:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
아메리카노 (Tall) × 2 ₩9,000
|
|
136
|
+
₩4,500 / 개 ← optional unit price line
|
|
137
|
+
카페라떼 ₩5,500
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## States
|
|
141
|
+
|
|
142
|
+
| State | Visual |
|
|
143
|
+
| --- | --- |
|
|
144
|
+
| Completed | Success icon, full receipt visible |
|
|
145
|
+
| Pending | Warning icon, "처리 중" badge |
|
|
146
|
+
| Cancelled | Strikethrough on all amounts; cancellation reason |
|
|
147
|
+
| Refunded | "환불 처리됨" badge, refund timestamp |
|
|
148
|
+
| Loading | Skeleton matching receipt shape |
|
|
149
|
+
| Error | "영수증을 불러올 수 없어요" + retry |
|
|
150
|
+
|
|
151
|
+
## Tokens consumed
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
--color-bg-default
|
|
155
|
+
--color-bg-elevated
|
|
156
|
+
--color-text-primary
|
|
157
|
+
--color-text-secondary
|
|
158
|
+
--color-text-tertiary
|
|
159
|
+
--color-success (completed)
|
|
160
|
+
--color-warning (pending)
|
|
161
|
+
--color-error (cancelled)
|
|
162
|
+
--color-money-negative (discount)
|
|
163
|
+
--color-border-default (divider)
|
|
164
|
+
--space-md, --space-base, --space-lg
|
|
165
|
+
--radius-md
|
|
166
|
+
--font-mono (order ID — alphanumeric clarity)
|
|
167
|
+
--font-feature-amount: 'tnum' 1
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Accessibility
|
|
171
|
+
|
|
172
|
+
- Receipt as `<article>` with `aria-label="결제 영수증"`.
|
|
173
|
+
- Status icon: `aria-hidden="true"` (header text carries meaning).
|
|
174
|
+
- Total amount: `aria-label="총 결제 금액 9,000원"`.
|
|
175
|
+
- Items list: `<dl>` for name → price pairs, OR `<table>` if quantities + unit prices.
|
|
176
|
+
- Actions: standard buttons.
|
|
177
|
+
|
|
178
|
+
## Print
|
|
179
|
+
|
|
180
|
+
Receipts are commonly printed:
|
|
181
|
+
|
|
182
|
+
```css
|
|
183
|
+
@media print {
|
|
184
|
+
.receipt {
|
|
185
|
+
background: white;
|
|
186
|
+
color: black;
|
|
187
|
+
}
|
|
188
|
+
.receipt-actions {
|
|
189
|
+
display: none;
|
|
190
|
+
}
|
|
191
|
+
/* Use solid black for divider — dashed renders inconsistently */
|
|
192
|
+
.receipt-divider {
|
|
193
|
+
border-top-style: solid;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
For Korean app store policy compliance: receipts must be printable / saveable as PDF.
|
|
199
|
+
|
|
200
|
+
## Korean conventions
|
|
201
|
+
|
|
202
|
+
- "결제가 완료되었습니다" — standard completion language.
|
|
203
|
+
- "총 결제 금액" — final total label.
|
|
204
|
+
- "주문번호" — order ID label.
|
|
205
|
+
- "상점" / "가맹점" — merchant.
|
|
206
|
+
- 영수증 공유: KakaoTalk share is the most common; SMS as backup.
|
|
207
|
+
- For 사업자 영수증 (business receipts): include 사업자등록번호 if applicable.
|
|
208
|
+
- Tax (부가세) shown as separate line if applicable. For most e-commerce, tax is included in price (VAT-included).
|
|
209
|
+
|
|
210
|
+
## Code example
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
function OrderConfirmationScreen({ orderId }: Props) {
|
|
214
|
+
const order = useOrder(orderId);
|
|
215
|
+
|
|
216
|
+
return (
|
|
217
|
+
<Page>
|
|
218
|
+
<PaymentReceipt
|
|
219
|
+
status={order.status}
|
|
220
|
+
timestamp={order.completedAt}
|
|
221
|
+
orderId={order.displayId}
|
|
222
|
+
merchant={order.merchant}
|
|
223
|
+
paymentMethod={order.paymentMethodLabel}
|
|
224
|
+
items={order.items}
|
|
225
|
+
subtotal={order.subtotal}
|
|
226
|
+
discount={order.discountTotal}
|
|
227
|
+
shipping={order.shippingFee}
|
|
228
|
+
total={order.total}
|
|
229
|
+
actions={[
|
|
230
|
+
{
|
|
231
|
+
label: "영수증 공유",
|
|
232
|
+
onClick: () => share({ url: `/orders/${orderId}/receipt` }),
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
label: "재구매",
|
|
236
|
+
onClick: () => reorder(orderId),
|
|
237
|
+
},
|
|
238
|
+
]}
|
|
239
|
+
refundable={order.canRefund}
|
|
240
|
+
/>
|
|
241
|
+
</Page>
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Edge cases
|
|
247
|
+
|
|
248
|
+
- **Refunded items in a partially-fulfilled order**: show refund status per item with strikethrough.
|
|
249
|
+
- **Subscription receipts**: include "다음 결제일: 2026.06.07" in the metadata.
|
|
250
|
+
- **No items** (e.g., service charge, donation): hide items section, just show breakdown.
|
|
251
|
+
- **Discount > subtotal** (rare): show negative total OR cap at 0; handle case-by-case.
|
|
252
|
+
- **Tax-included vs tax-excluded**: clearly label. Korean apps default to tax-included; B2B may show separately.
|
|
253
|
+
|
|
254
|
+
## Don't
|
|
255
|
+
|
|
256
|
+
- Don't use heavy borders / boxes inside the receipt — keep it paper-like.
|
|
257
|
+
- Don't omit the timestamp.
|
|
258
|
+
- Don't show actions in print mode.
|
|
259
|
+
- Don't break dividers across pages on print.
|
|
260
|
+
- Don't shorten the order ID — full ID needed for support.
|
|
261
|
+
- Don't auto-redirect from the receipt screen — let user read.
|
|
262
|
+
|
|
263
|
+
## References
|
|
264
|
+
|
|
265
|
+
No upstream component is exactly this. The receipt pattern is universal but **Korean visual conventions** (dotted dividers, breakdown structure, share-receipt language) are domain-specific.
|
|
266
|
+
|
|
267
|
+
Closest analogs:
|
|
268
|
+
- Stripe Dashboard receipts (Western convention)
|
|
269
|
+
- KakaoBank / Toss receipt screens (Korean convention)
|
|
270
|
+
|
|
271
|
+
## Cross-reference
|
|
272
|
+
|
|
273
|
+
- [`examples/component-krw-amount.md`](component-krw-amount.md) — used internally for amounts
|
|
274
|
+
- [`examples/component-payment-method-selector.md`](component-payment-method-selector.md) — pre-checkout
|
|
275
|
+
- [`examples/component-result.md`](component-result.md) — result page (PaymentReceipt is its richer cousin)
|
|
276
|
+
- [`knowledge/i18n/korean-payments.md`](../knowledge/i18n/korean-payments.md) — Korean payment conventions
|
|
277
|
+
- [`knowledge/patterns/money-and-amount.md`](../knowledge/patterns/money-and-amount.md) — money display
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# `Popconfirm` — spec
|
|
2
|
+
|
|
3
|
+
> Synthesized from Ant Design `Popconfirm`. An inline confirmation popover triggered by a button — lightweight alternative to `AlertDialog` for in-place destructive actions.
|
|
4
|
+
|
|
5
|
+
## Popconfirm vs AlertDialog
|
|
6
|
+
|
|
7
|
+
| | Popconfirm | AlertDialog |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| Surface | Popover anchored to trigger | Centered modal |
|
|
10
|
+
| Use | Quick confirm of inline action | Full-stop destructive action |
|
|
11
|
+
| Visual weight | Light | Heavy |
|
|
12
|
+
| Backdrop | None | Yes |
|
|
13
|
+
| Focus trap | No | Yes |
|
|
14
|
+
|
|
15
|
+
For "are you sure?" on a small inline button: Popconfirm.
|
|
16
|
+
For account deletion / unrecoverable destructive: AlertDialog.
|
|
17
|
+
|
|
18
|
+
## Anatomy
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
[Delete]
|
|
22
|
+
↓ click
|
|
23
|
+
┌─────────────────────┐
|
|
24
|
+
│ ⚠ 정말 삭제할까요? │
|
|
25
|
+
│ [취소] [삭제] │
|
|
26
|
+
└─────────────────────┘
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
<Popconfirm
|
|
33
|
+
title="이 항목을 삭제할까요?"
|
|
34
|
+
description="삭제한 항목은 복구할 수 없어요."
|
|
35
|
+
onConfirm={handleDelete}
|
|
36
|
+
okText="삭제"
|
|
37
|
+
cancelText="취소"
|
|
38
|
+
okButtonProps={{ variant: "destructive" }}
|
|
39
|
+
>
|
|
40
|
+
<Button>삭제</Button>
|
|
41
|
+
</Popconfirm>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
| Prop | Type | Default | Description |
|
|
45
|
+
| --- | --- | --- | --- |
|
|
46
|
+
| `title` | `string` | required | Confirmation question |
|
|
47
|
+
| `description` | `string` | — | Optional consequence detail |
|
|
48
|
+
| `onConfirm` | `() => void \| Promise<void>` | — | Confirm callback |
|
|
49
|
+
| `onCancel` | `() => void` | — | Cancel callback |
|
|
50
|
+
| `okText` | `string` | "OK" / "확인" | Confirm button label |
|
|
51
|
+
| `cancelText` | `string` | "Cancel" / "취소" | Cancel button label |
|
|
52
|
+
| `okButtonProps` | Button props | — | Style confirm button (e.g., variant="destructive") |
|
|
53
|
+
| `placement` | `"top" \| "bottom" \| "left" \| "right"` (with -start / -end) | `"top"` | Popover position |
|
|
54
|
+
| `icon` | `ReactNode` | warning icon | Custom icon |
|
|
55
|
+
|
|
56
|
+
## States
|
|
57
|
+
|
|
58
|
+
| State | Visual |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| Closed | Trigger button only |
|
|
61
|
+
| Open | Popover with title + description + buttons |
|
|
62
|
+
| Loading (async confirm) | OK button shows spinner; both disabled |
|
|
63
|
+
| Closing | Fade-out 150ms |
|
|
64
|
+
|
|
65
|
+
## Async confirm
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
<Popconfirm
|
|
69
|
+
title="삭제할까요?"
|
|
70
|
+
onConfirm={async () => {
|
|
71
|
+
await api.delete(id); // popconfirm shows loading on OK button
|
|
72
|
+
toast.success("삭제됐어요");
|
|
73
|
+
}}
|
|
74
|
+
>
|
|
75
|
+
<Button>삭제</Button>
|
|
76
|
+
</Popconfirm>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Tokens consumed
|
|
80
|
+
|
|
81
|
+
Inherits from Popover:
|
|
82
|
+
```
|
|
83
|
+
--popover-bg
|
|
84
|
+
--popover-fg
|
|
85
|
+
--popover-border
|
|
86
|
+
--popover-shadow
|
|
87
|
+
--popover-icon-warning
|
|
88
|
+
--radius-md
|
|
89
|
+
--space-sm, --space-md
|
|
90
|
+
--motion-fast
|
|
91
|
+
--z-overlay
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Accessibility
|
|
95
|
+
|
|
96
|
+
- `role="dialog"` (or `alertdialog`) on the Popover content.
|
|
97
|
+
- `aria-labelledby` references title; `aria-describedby` references description.
|
|
98
|
+
- Focus moves to OK button on open.
|
|
99
|
+
- Esc closes (cancels).
|
|
100
|
+
- Click outside cancels.
|
|
101
|
+
- For destructive actions: prefer `AlertDialog` — focus trap + backdrop give the user a more deliberate moment.
|
|
102
|
+
|
|
103
|
+
## Code example — list item delete with Popconfirm
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
function ItemRow({ item }: Props) {
|
|
107
|
+
return (
|
|
108
|
+
<Item>
|
|
109
|
+
<ItemContent>{item.name}</ItemContent>
|
|
110
|
+
<ItemActions>
|
|
111
|
+
<Popconfirm
|
|
112
|
+
title="삭제할까요?"
|
|
113
|
+
description={`"${item.name}"을(를) 영구적으로 삭제해요.`}
|
|
114
|
+
onConfirm={() => api.delete(item.id)}
|
|
115
|
+
okText="삭제"
|
|
116
|
+
cancelText="취소"
|
|
117
|
+
okButtonProps={{ variant: "destructive" }}
|
|
118
|
+
>
|
|
119
|
+
<IconButton aria-label="삭제">
|
|
120
|
+
<TrashIcon />
|
|
121
|
+
</IconButton>
|
|
122
|
+
</Popconfirm>
|
|
123
|
+
</ItemActions>
|
|
124
|
+
</Item>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Don't
|
|
130
|
+
|
|
131
|
+
- Don't use Popconfirm for high-stakes destructive (account deletion). Use AlertDialog.
|
|
132
|
+
- Don't omit description for non-obvious consequences.
|
|
133
|
+
- Don't auto-confirm without explicit click. Popconfirm IS the confirmation.
|
|
134
|
+
- Don't pile up confirmations (one Popconfirm at a time per surface).
|
|
135
|
+
|
|
136
|
+
## References
|
|
137
|
+
|
|
138
|
+
- Ant: [`Popconfirm`](../refs/ant-design/components/popconfirm)
|
|
139
|
+
|
|
140
|
+
## Cross-reference
|
|
141
|
+
|
|
142
|
+
- [`examples/component-alert-dialog.md`](component-alert-dialog.md) — heavier modal alternative
|
|
143
|
+
- [`examples/component-popover.md`](component-popover.md) — base primitive
|
|
144
|
+
- [`examples/component-toast.md`](component-toast.md) — for "deleted, with Undo" pattern (alternative)
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# `Popover` — spec
|
|
2
|
+
|
|
3
|
+
> Citing Ant Design `Popover`, MUI `Popper`/`Popover`, shadcn-ui `popover`
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
A non-modal overlay anchored to a trigger element. Used for: filter detail, contextual settings, "more info" content, color picker, quick actions menu.
|
|
8
|
+
|
|
9
|
+
Different from related primitives:
|
|
10
|
+
|
|
11
|
+
| Primitive | Use |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| **Tooltip** | Short hover hint. No interaction. |
|
|
14
|
+
| **Popover** | Interactive content anchored to a trigger. Close on outside click. |
|
|
15
|
+
| **Modal/Dialog** | Centered, blocks page interaction. |
|
|
16
|
+
| **Dropdown menu** | List of actions (`Cmd+click`-style). Use Popover with menu styling. |
|
|
17
|
+
|
|
18
|
+
## Anatomy
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
[trigger button]
|
|
22
|
+
│
|
|
23
|
+
▼ (click)
|
|
24
|
+
┌──────────────────────┐
|
|
25
|
+
│ ▶ Popover header │
|
|
26
|
+
│ ───────────────── │
|
|
27
|
+
│ Body content │
|
|
28
|
+
│ Form / list / etc │
|
|
29
|
+
│ │
|
|
30
|
+
│ [action] [close] │
|
|
31
|
+
└──────────────────────┘
|
|
32
|
+
▲ (arrow optional)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
| Slot | Required | Notes |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| Trigger | yes | The element popover anchors to |
|
|
38
|
+
| Body | yes | Interactive content |
|
|
39
|
+
| Arrow | optional | Pointer at trigger; usually small triangle |
|
|
40
|
+
| Close button | optional | Explicit close affordance |
|
|
41
|
+
|
|
42
|
+
## API
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
<Popover>
|
|
46
|
+
<Popover.Trigger asChild>
|
|
47
|
+
<Button>Filter</Button>
|
|
48
|
+
</Popover.Trigger>
|
|
49
|
+
<Popover.Content side="bottom" align="start">
|
|
50
|
+
<FilterForm />
|
|
51
|
+
</Popover.Content>
|
|
52
|
+
</Popover>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Prop (root) | Type | Default | Description |
|
|
56
|
+
| --- | --- | --- | --- |
|
|
57
|
+
| `open` / `defaultOpen` | `boolean` | — | Controlled/uncontrolled |
|
|
58
|
+
| `onOpenChange` | `(open: boolean) => void` | — | |
|
|
59
|
+
| `modal` | `boolean` | `false` | If true, also traps focus + scroll lock (rare for popover) |
|
|
60
|
+
|
|
61
|
+
| Prop (Content) | Type | Default | Description |
|
|
62
|
+
| --- | --- | --- | --- |
|
|
63
|
+
| `side` | `"top" \| "right" \| "bottom" \| "left"` | `"bottom"` | Preferred position |
|
|
64
|
+
| `align` | `"start" \| "center" \| "end"` | `"center"` | Alignment along the side |
|
|
65
|
+
| `sideOffset` | `number` | `4` | Gap between trigger and popover |
|
|
66
|
+
| `collisionPadding` | `number` | `8` | Distance from viewport edge before flipping |
|
|
67
|
+
| `arrow` | `boolean` | `false` | Show arrow pointing at trigger |
|
|
68
|
+
|
|
69
|
+
## Behavior
|
|
70
|
+
|
|
71
|
+
| Trigger | Action |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| Click trigger | Open |
|
|
74
|
+
| Click trigger (when open) | Close |
|
|
75
|
+
| Click outside content | Close |
|
|
76
|
+
| Press Escape | Close |
|
|
77
|
+
| Tab away (focus leaves) | Close (if `modal={false}`) |
|
|
78
|
+
| Window resize | Reposition |
|
|
79
|
+
| Scroll | Reposition (or close if dramatic) |
|
|
80
|
+
|
|
81
|
+
For `modal={true}`: closes only via Escape or explicit close button. Use rarely — popover that needs modal behavior is usually a Dialog.
|
|
82
|
+
|
|
83
|
+
## Positioning
|
|
84
|
+
|
|
85
|
+
The popover positions relative to the trigger with collision detection:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
Preferred: side="bottom" align="start"
|
|
89
|
+
|
|
90
|
+
Trigger: [...]
|
|
91
|
+
▼
|
|
92
|
+
┌──────────┐
|
|
93
|
+
│ content │
|
|
94
|
+
└──────────┘
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If the popover would overflow the viewport, it auto-flips to the opposite side. Use Floating UI or Radix's collision detection — don't reinvent.
|
|
98
|
+
|
|
99
|
+
## Sizes
|
|
100
|
+
|
|
101
|
+
Popover doesn't have fixed sizes — content determines size. Set min-width based on the trigger's width, or use `width="trigger"` to match exactly.
|
|
102
|
+
|
|
103
|
+
| Width strategy | Use |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| Auto (content-driven) | Default |
|
|
106
|
+
| Match trigger width | Date picker, select-like popovers |
|
|
107
|
+
| Fixed (e.g., 320px) | Filter panels, detail cards |
|
|
108
|
+
| Max-content | Tooltips with rich content |
|
|
109
|
+
|
|
110
|
+
## States
|
|
111
|
+
|
|
112
|
+
| State | Visual |
|
|
113
|
+
| --- | --- |
|
|
114
|
+
| Closed | not in DOM (or `display: none`) |
|
|
115
|
+
| Opening | 100ms fade + slight scale 0.95 → 1 + slide |
|
|
116
|
+
| Open | settled, content visible |
|
|
117
|
+
| Closing | 75ms fade |
|
|
118
|
+
|
|
119
|
+
## Tokens consumed
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
--color-bg-elevated (popover surface)
|
|
123
|
+
--color-border-default
|
|
124
|
+
--color-text-primary
|
|
125
|
+
--space-md, --space-sm
|
|
126
|
+
--radius-md
|
|
127
|
+
--shadow-popover
|
|
128
|
+
--motion-fast, --easing-out
|
|
129
|
+
--z-popover (above page content, below modal)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Accessibility
|
|
133
|
+
|
|
134
|
+
- Trigger: `aria-haspopup="true"`, `aria-expanded={open}`, `aria-controls={contentId}`.
|
|
135
|
+
- Content: `role="dialog"` if interactive, OR plain region if just informational.
|
|
136
|
+
- For menu-flavored popovers (list of actions): use [`<DropdownMenu>`] instead of Popover — it's a different ARIA pattern.
|
|
137
|
+
|
|
138
|
+
### Focus
|
|
139
|
+
|
|
140
|
+
When popover opens via click:
|
|
141
|
+
- **Modal popover** (`modal={true}`): trap focus inside, return focus to trigger on close.
|
|
142
|
+
- **Non-modal popover** (default): focus moves into popover automatically (first focusable element). Tab cycles within and **eventually exits**, closing the popover when focus leaves.
|
|
143
|
+
|
|
144
|
+
### Keyboard
|
|
145
|
+
|
|
146
|
+
| Key | Behavior |
|
|
147
|
+
| --- | --- |
|
|
148
|
+
| `Tab` (on trigger) | Reaches trigger |
|
|
149
|
+
| `Enter` / `Space` | Open popover |
|
|
150
|
+
| `Tab` (inside) | Cycle through interactive content |
|
|
151
|
+
| `Esc` | Close, return focus to trigger |
|
|
152
|
+
| Click outside | Close (no focus transfer) |
|
|
153
|
+
|
|
154
|
+
## Tooltip vs Popover
|
|
155
|
+
|
|
156
|
+
A common confusion. Use Tooltip for:
|
|
157
|
+
- Short hint, hover-triggered
|
|
158
|
+
- No interactive content
|
|
159
|
+
- No persistent need to interact
|
|
160
|
+
|
|
161
|
+
Use Popover for:
|
|
162
|
+
- Click-triggered (or focus-triggered for keyboard)
|
|
163
|
+
- Has buttons, inputs, links inside
|
|
164
|
+
- User needs time to read or interact
|
|
165
|
+
|
|
166
|
+
Don't put interactive content in a tooltip. Tooltips disappear on mouse-out.
|
|
167
|
+
|
|
168
|
+
## Code example
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
// Filter popover
|
|
172
|
+
<Popover>
|
|
173
|
+
<Popover.Trigger asChild>
|
|
174
|
+
<Button variant="outline" iconStart={<FilterIcon />}>
|
|
175
|
+
필터 {activeCount > 0 && `(${activeCount})`}
|
|
176
|
+
</Button>
|
|
177
|
+
</Popover.Trigger>
|
|
178
|
+
<Popover.Content side="bottom" align="end" style={{ width: 320 }}>
|
|
179
|
+
<FilterForm />
|
|
180
|
+
<div className="flex justify-between p-3 border-t">
|
|
181
|
+
<Button variant="ghost" onClick={resetFilters}>초기화</Button>
|
|
182
|
+
<Button onClick={applyFilters}>적용</Button>
|
|
183
|
+
</div>
|
|
184
|
+
</Popover.Content>
|
|
185
|
+
</Popover>
|
|
186
|
+
|
|
187
|
+
// User menu popover
|
|
188
|
+
<Popover>
|
|
189
|
+
<Popover.Trigger asChild>
|
|
190
|
+
<Avatar src={user.photoUrl} alt={user.name} />
|
|
191
|
+
</Popover.Trigger>
|
|
192
|
+
<Popover.Content side="bottom" align="end">
|
|
193
|
+
<div className="p-3 border-b">
|
|
194
|
+
<p className="font-medium">{user.name}</p>
|
|
195
|
+
<p className="text-sm text-text-secondary">{user.email}</p>
|
|
196
|
+
</div>
|
|
197
|
+
<ul role="menu">
|
|
198
|
+
<li><a href="/profile">프로필</a></li>
|
|
199
|
+
<li><a href="/settings">설정</a></li>
|
|
200
|
+
<li><button onClick={signOut}>로그아웃</button></li>
|
|
201
|
+
</ul>
|
|
202
|
+
</Popover.Content>
|
|
203
|
+
</Popover>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
(Note: a list of actions like the user menu is more strictly a `DropdownMenu` — use that primitive for proper menu a11y. Popover here is illustrative.)
|
|
207
|
+
|
|
208
|
+
## Edge cases
|
|
209
|
+
|
|
210
|
+
- **Popover near viewport edge**: auto-flip handled by Floating UI / Radix.
|
|
211
|
+
- **Popover wider than viewport**: not allowed — cap at `100vw - 16px`.
|
|
212
|
+
- **Trigger inside a scrollable container**: popover repositions on scroll.
|
|
213
|
+
- **Multiple popovers stacked**: avoid. Refactor — usually means navigation should change.
|
|
214
|
+
- **Popover with form inside**: typing must not close popover. Make sure outside-click handler ignores trigger and content.
|
|
215
|
+
- **iOS Safari**: virtual keyboard pushes content; popover may need to reposition.
|
|
216
|
+
- **Click on trigger that's inside another clickable** (e.g., card with popover button): event must `stopPropagation` so card doesn't also fire.
|
|
217
|
+
|
|
218
|
+
## Don't
|
|
219
|
+
|
|
220
|
+
- Don't use Popover when a Tooltip suffices (no interaction needed).
|
|
221
|
+
- Don't use Popover when a Modal/Dialog suffices (decision/blocking interaction).
|
|
222
|
+
- Don't put critical CTAs inside a popover that's not also reachable elsewhere.
|
|
223
|
+
- Don't ship a popover without `aria-expanded` on the trigger — keyboard users need to know state.
|
|
224
|
+
- Don't make the popover "sticky" — it should close on outside click. (Exception: `modal={true}` for special cases.)
|
|
225
|
+
- Don't open popovers on hover unless they truly contain a tooltip (then use Tooltip).
|
|
226
|
+
|
|
227
|
+
## References
|
|
228
|
+
|
|
229
|
+
- Ant Design: [`refs/ant-design/components/popover/`](../refs/ant-design/components/popover/) — `Popover` with rich placement, `trigger="hover" | "click" | "focus"`. Hover trigger is generally avoided in modern UIs.
|
|
230
|
+
- MUI: [`refs/mui/packages/mui-material/src/Popper/`](../refs/mui/packages/mui-material/src/Popper/) — low-level positioning primitive. `Popover` adds backdrop + focus management.
|
|
231
|
+
- shadcn-ui: [`refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/popover.tsx`](../refs/shadcn-ui/apps/v4/registry/new-york-v4/ui/popover.tsx) — Radix Popover primitive. **Default for new projects.**
|
|
232
|
+
|
|
233
|
+
## Cross-reference
|
|
234
|
+
|
|
235
|
+
- [`examples/component-tooltip.md`](component-tooltip.md) — for hover-only hints
|
|
236
|
+
- [`examples/component-modal.md`](component-modal.md) — for blocking/decision interactions
|
|
237
|
+
- [`examples/component-select.md`](component-select.md) — uses popover-pattern for combobox
|
|
238
|
+
- [`knowledge/a11y/keyboard-and-focus.md`](../knowledge/a11y/keyboard-and-focus.md)
|
|
239
|
+
- [WAI-ARIA Dialog Pattern (modal popover)](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/)
|