@sarjallab09/figma-intelligence 1.0.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/LICENSE +26 -0
- package/README.md +327 -0
- package/bin/cli.js +859 -0
- package/design-bridge/.env.example +5 -0
- package/design-bridge/bridge.js +196 -0
- package/design-bridge/lib/assets.js +367 -0
- package/design-bridge/lib/prompt.js +85 -0
- package/design-bridge/lib/server.js +66 -0
- package/design-bridge/lib/stitch.js +37 -0
- package/design-bridge/lib/tokens.js +82 -0
- package/design-bridge/package-lock.json +579 -0
- package/design-bridge/package.json +19 -0
- package/figma-bridge-plugin/README.md +97 -0
- package/figma-bridge-plugin/anthropic-chat-runner.js +192 -0
- package/figma-bridge-plugin/bridge-relay.js +2363 -0
- package/figma-bridge-plugin/chat-runner.js +459 -0
- package/figma-bridge-plugin/code.js +1528 -0
- package/figma-bridge-plugin/codex-runner.js +505 -0
- package/figma-bridge-plugin/component-schemas.js +110 -0
- package/figma-bridge-plugin/content-context.js +869 -0
- package/figma-bridge-plugin/create-button.js +216 -0
- package/figma-bridge-plugin/gemini-cli-runner.js +291 -0
- package/figma-bridge-plugin/gemini-runner.js +187 -0
- package/figma-bridge-plugin/html-to-figma.js +927 -0
- package/figma-bridge-plugin/knowledge-hub/.gitkeep +0 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/anatomy-spec.md +159 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/api-spec.md +162 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/color-spec.md +148 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/full-spec-template.md +314 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/property-spec.md +175 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/screen-reader-spec.md +180 -0
- package/figma-bridge-plugin/knowledge-hub/uspec-references/structure-spec.md +165 -0
- package/figma-bridge-plugin/manifest.json +21 -0
- package/figma-bridge-plugin/package-lock.json +1936 -0
- package/figma-bridge-plugin/package.json +20 -0
- package/figma-bridge-plugin/perplexity-runner.js +188 -0
- package/figma-bridge-plugin/references/SKILL.md +178 -0
- package/figma-bridge-plugin/references/anatomy-spec.md +159 -0
- package/figma-bridge-plugin/references/api-spec.md +162 -0
- package/figma-bridge-plugin/references/color-spec.md +148 -0
- package/figma-bridge-plugin/references/full-spec-template.md +314 -0
- package/figma-bridge-plugin/references/property-spec.md +175 -0
- package/figma-bridge-plugin/references/screen-reader-spec.md +180 -0
- package/figma-bridge-plugin/references/structure-spec.md +165 -0
- package/figma-bridge-plugin/shared-prompt-config.js +604 -0
- package/figma-bridge-plugin/spec-helpers/build-table.js +269 -0
- package/figma-bridge-plugin/spec-helpers/classify-elements.js +189 -0
- package/figma-bridge-plugin/spec-helpers/index.js +35 -0
- package/figma-bridge-plugin/spec-helpers/parse-figma-link.js +49 -0
- package/figma-bridge-plugin/spec-helpers/position-markers.js +158 -0
- package/figma-bridge-plugin/stitch-auth.js +322 -0
- package/figma-bridge-plugin/stitch-runner.js +1427 -0
- package/figma-bridge-plugin/token-resolver.js +107 -0
- package/figma-bridge-plugin/ui.html +4467 -0
- package/figma-intelligence-layer/.env.example +39 -0
- package/figma-intelligence-layer/docs/local-image-generation.md +60 -0
- package/figma-intelligence-layer/examples/comfyui-workflow-template.example.json +101 -0
- package/figma-intelligence-layer/jest.config.js +14 -0
- package/figma-intelligence-layer/mcp-config.json +19 -0
- package/figma-intelligence-layer/package-lock.json +5892 -0
- package/figma-intelligence-layer/package.json +48 -0
- package/figma-intelligence-layer/scripts/setup-comfyui-local.sh +67 -0
- package/figma-intelligence-layer/scripts/start-comfyui.sh +33 -0
- package/figma-intelligence-layer/src/index.ts +2233 -0
- package/figma-intelligence-layer/src/shared/auto-layout-validator.ts +404 -0
- package/figma-intelligence-layer/src/shared/cache.ts +187 -0
- package/figma-intelligence-layer/src/shared/color-operations.ts +533 -0
- package/figma-intelligence-layer/src/shared/color-utils.ts +138 -0
- package/figma-intelligence-layer/src/shared/component-script-builder.ts +413 -0
- package/figma-intelligence-layer/src/shared/component-templates.ts +2767 -0
- package/figma-intelligence-layer/src/shared/concept-taxonomy.ts +694 -0
- package/figma-intelligence-layer/src/shared/decision-log.ts +128 -0
- package/figma-intelligence-layer/src/shared/design-system-context.ts +568 -0
- package/figma-intelligence-layer/src/shared/design-system-intelligence.ts +131 -0
- package/figma-intelligence-layer/src/shared/design-system-matcher.ts +184 -0
- package/figma-intelligence-layer/src/shared/design-system-normalizers.ts +196 -0
- package/figma-intelligence-layer/src/shared/design-system-tokens.ts +295 -0
- package/figma-intelligence-layer/src/shared/dtcg-validator.ts +530 -0
- package/figma-intelligence-layer/src/shared/enrichment-pipeline.ts +671 -0
- package/figma-intelligence-layer/src/shared/figma-bridge.ts +1408 -0
- package/figma-intelligence-layer/src/shared/font-config.ts +126 -0
- package/figma-intelligence-layer/src/shared/icon-catalog.ts +360 -0
- package/figma-intelligence-layer/src/shared/icon-fetch.ts +80 -0
- package/figma-intelligence-layer/src/shared/prototype-script-builder.ts +162 -0
- package/figma-intelligence-layer/src/shared/response-compression.ts +440 -0
- package/figma-intelligence-layer/src/shared/semantic-token-catalog.ts +324 -0
- package/figma-intelligence-layer/src/shared/token-binder.ts +505 -0
- package/figma-intelligence-layer/src/shared/token-math.ts +427 -0
- package/figma-intelligence-layer/src/shared/token-naming.ts +468 -0
- package/figma-intelligence-layer/src/shared/token-utils.ts +420 -0
- package/figma-intelligence-layer/src/shared/types.ts +346 -0
- package/figma-intelligence-layer/src/shared/typography-presets.ts +94 -0
- package/figma-intelligence-layer/src/shared/unsplash.ts +165 -0
- package/figma-intelligence-layer/src/shared/vision-client.ts +607 -0
- package/figma-intelligence-layer/src/shared/vision-provider-anthropic.ts +334 -0
- package/figma-intelligence-layer/src/shared/vision-provider-openai.ts +446 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/a11y-annotate-handler.ts +782 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/a11y-annotate-renderer.ts +496 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/a11y-annotation-kit.ts +230 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/colorblind-sim.ts +66 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/index.ts +810 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/keyboard-sr-order-analyzer.ts +1191 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/keyboard-sr-order-figma-page.ts +1346 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/keyboard-sr-order-handler.ts +148 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/vpat-figma-page.ts +499 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/vpat-report.ts +910 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/wcag-checker.ts +989 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/wcag-criteria.ts +1160 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/design-from-ref/index.ts +424 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/component-recognizer.ts +38 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/ds-matcher.ts +111 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/font-matcher.ts +114 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/icon-resolver.ts +103 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/index.ts +1060 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/layout-segmenter.ts +18 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/token-inferencer.ts +39 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/vision-pipeline.ts +58 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/sketch-to-design/index.ts +298 -0
- package/figma-intelligence-layer/src/tools/phase1-vision/visual-audit/index.ts +197 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/component-audit/index.ts +494 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/intent-translator/index.ts +356 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/layout-intelligence/container-patterns.ts +123 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/layout-intelligence/index.ts +663 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/lint-rules/built-in-rules.yaml +56 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/lint-rules/index.ts +614 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/lint-rules/rule-engine.ts +113 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/theme-generator/color-theory.ts +178 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/theme-generator/index.ts +470 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/variant-expander/index.ts +429 -0
- package/figma-intelligence-layer/src/tools/phase2-accuracy/variant-expander/token-override-maps.ts +226 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/ai-image-insert/index.ts +535 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/component-archaeologist/index.ts +660 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/component-archaeologist/pattern-fingerprints.ts +209 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/composition-builder/index.ts +540 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/figma-animated-build.ts +391 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/page-architect/index.ts +2019 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/page-architect/screen-templates.ts +131 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/prototype-map/index.ts +381 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/prototype-wire/index.ts +565 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/swarm-build/index.ts +764 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/system-drift/index.ts +535 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/unsplash-search/index.ts +84 -0
- package/figma-intelligence-layer/src/tools/phase3-generation/url-to-frame/index.ts +401 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/code-generators/css-animations.ts +68 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/code-generators/framer-motion.ts +78 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/code-generators/swift-animations.ts +93 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/index.ts +596 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/ci-check/index.ts +462 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/export-tokens/index.ts +1470 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/generate-component-code/index.ts +829 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/handoff-spec/index.ts +702 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/icon-library-sync/index.ts +483 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/sync-from-code/index.ts +501 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/sync-from-code/storybook-parser.ts +106 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/watch-docs/index.ts +676 -0
- package/figma-intelligence-layer/src/tools/phase4-sync/webhook-listener/index.ts +560 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/apg-doc/index.ts +1043 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/component-detection.ts +620 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/anatomy.ts +331 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/color-tokens.ts +77 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/properties.ts +54 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/snapshot.ts +287 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/spacing.ts +71 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/states.ts +43 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/typography.ts +71 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/index.ts +221 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/_default.ts +166 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/accordion.ts +232 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/alert.ts +234 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/avatar-group.ts +270 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/avatar.ts +249 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/badge.ts +231 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/banner.ts +293 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/breadcrumb.ts +240 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/button.ts +243 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/calendar.ts +307 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/card.ts +143 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/checkbox.ts +227 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/chip.ts +233 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/combobox.ts +282 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/datepicker.ts +276 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/divider.ts +223 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/drawer.ts +255 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/dropdown-menu.ts +289 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/empty-state.ts +261 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/file-uploader.ts +290 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/form.ts +265 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/grid.ts +238 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/icon.ts +255 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/index.ts +128 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/inline-edit.ts +286 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/inline-message.ts +255 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/input.ts +330 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/link.ts +247 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/list.ts +250 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/menu.ts +247 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/modal.ts +144 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/navbar.ts +264 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/navigation.ts +251 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/number-input.ts +261 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/pagination.ts +248 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/popover.ts +270 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/progress.ts +251 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/radio.ts +142 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/range-slider.ts +282 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/rating.ts +250 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/search.ts +258 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/segmented-control.ts +265 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/select.ts +319 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/skeleton.ts +256 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/slider.ts +232 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/spinner.ts +239 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/status-dot.ts +252 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/stepper.ts +270 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/table.ts +244 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/tabs.ts +143 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/tag.ts +243 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/textarea.ts +259 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/time-picker.ts +293 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/toast.ts +144 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/toggle.ts +289 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/toolbar.ts +267 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/tooltip.ts +232 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/treeview.ts +257 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/typography.ts +319 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/legacy-compat.ts +121 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/anatomy-diagram.ts +430 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/figma-page.ts +312 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/json.ts +129 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/markdown.ts +78 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/visual-doc.ts +2333 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/accessibility.ts +100 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/anatomy.ts +32 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/color-tokens.ts +59 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/content-guidance.ts +18 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/design-tokens.ts +53 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/interaction-rules.ts +19 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/overview.ts +91 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/properties-api.ts +71 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/qa-criteria.ts +19 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/related-components.ts +110 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/responsive.ts +19 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/size-specs.ts +67 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/spacing-structure.ts +58 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/state-specs.ts +79 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/states.ts +50 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/type-hierarchy.ts +33 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/typography.ts +55 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/usage-guidelines.ts +73 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/variants.ts +81 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/types.ts +409 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec-sheet/index.ts +198 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec-sheet/renderer.ts +701 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/component-spec-sheet/types.ts +88 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/decision-log/index.ts +135 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/design-decision-log/index.ts +491 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/ds-primitives/index.ts +416 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/ds-scaffolder/index.ts +722 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/ds-variables/index.ts +449 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/health-report/index.ts +393 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/index.ts +406 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/figma-page.ts +292 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/json.ts +24 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/markdown.ts +172 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/naming-guide.ts +409 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/token-analytics/index.ts +594 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/token-docs/index.ts +710 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/token-migrate/index.ts +458 -0
- package/figma-intelligence-layer/src/tools/phase5-governance/token-naming/index.ts +134 -0
- package/figma-intelligence-layer/tests/apg-doc.test.ts +101 -0
- package/figma-intelligence-layer/tests/design-system-context.test.ts +152 -0
- package/figma-intelligence-layer/tests/design-system-matcher.test.ts +144 -0
- package/figma-intelligence-layer/tests/figma-bridge.test.ts +83 -0
- package/figma-intelligence-layer/tests/generate-image-and-insert.test.ts +56 -0
- package/figma-intelligence-layer/tests/screen-cloner-regression.test.ts +69 -0
- package/figma-intelligence-layer/tests/smoke.test.ts +174 -0
- package/figma-intelligence-layer/tests/spec-generator.test.ts +127 -0
- package/figma-intelligence-layer/tests/token-migrate.test.ts +21 -0
- package/figma-intelligence-layer/tests/token-naming.test.ts +30 -0
- package/figma-intelligence-layer/tsconfig.json +19 -0
- package/package.json +35 -0
- package/scripts/clean-existing-chunks.js +179 -0
- package/scripts/connect-ai-tool.js +490 -0
- package/scripts/convert-hub-pdfs.js +425 -0
- package/scripts/figma-mcp-status.js +349 -0
- package/scripts/register-codex-mcp.js +96 -0
package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/combobox.ts
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* combobox.ts — Gold-standard design knowledge for Combobox components
|
|
3
|
+
*/
|
|
4
|
+
import type { ComponentKnowledge } from "../types.js";
|
|
5
|
+
|
|
6
|
+
export const comboboxKnowledge: ComponentKnowledge = {
|
|
7
|
+
description:
|
|
8
|
+
"Input with dropdown suggestions and autocomplete | Combines free-text entry with option selection | Supports filtering, custom values, and validation",
|
|
9
|
+
|
|
10
|
+
stateSpecifications: [
|
|
11
|
+
{
|
|
12
|
+
state: "Default",
|
|
13
|
+
visualChange: "Field shows border with chevron indicator on the right; optional placeholder text in muted color",
|
|
14
|
+
opacity: "1",
|
|
15
|
+
cursorWeb: "text",
|
|
16
|
+
usage: "Resting state — combobox is interactive and ready for input or selection",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
state: "Open",
|
|
20
|
+
visualChange: "Listbox dropdown appears below the field; chevron rotates to indicate expanded state; focus ring visible",
|
|
21
|
+
opacity: "1",
|
|
22
|
+
cursorWeb: "text",
|
|
23
|
+
usage: "User has clicked or focused the field, revealing the option list",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
state: "Focused",
|
|
27
|
+
visualChange: "Border transitions to focus color; 2px focus ring appears; cursor blinks inside the field",
|
|
28
|
+
opacity: "1",
|
|
29
|
+
cursorWeb: "text",
|
|
30
|
+
usage: "Field has keyboard focus but the dropdown may or may not be open",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
state: "Filtered",
|
|
34
|
+
visualChange: "Listbox shows only options matching the typed query; non-matching options are hidden",
|
|
35
|
+
opacity: "1",
|
|
36
|
+
cursorWeb: "text",
|
|
37
|
+
usage: "User has typed text that filters the available options in real-time",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
state: "Error",
|
|
41
|
+
visualChange: "Border switches to error token; error message appears below the field; chevron retains default color",
|
|
42
|
+
opacity: "1",
|
|
43
|
+
cursorWeb: "text",
|
|
44
|
+
usage: "Validation has failed — selected value or typed text does not meet requirements",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
state: "Disabled",
|
|
48
|
+
visualChange: "Background and border switch to disabled tokens; chevron is muted; no interaction possible",
|
|
49
|
+
opacity: "0.4",
|
|
50
|
+
cursorWeb: "not-allowed",
|
|
51
|
+
usage: "Combobox is unavailable due to form state, permissions, or prerequisites",
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
|
|
55
|
+
propertyDescriptions: {
|
|
56
|
+
label: "Visible text label rendered above the combobox; describes the expected selection (e.g. 'Country', 'Category')",
|
|
57
|
+
placeholder: "Hint text displayed inside the field when no value is selected; should suggest the action (e.g. 'Select or type...')",
|
|
58
|
+
options: "Array of selectable option items displayed in the dropdown listbox; each option has a label and value",
|
|
59
|
+
value: "The currently selected option value or typed custom text; controlled or uncontrolled depending on framework usage",
|
|
60
|
+
onSelect: "Callback fired when the user selects an option from the dropdown or submits a custom value",
|
|
61
|
+
filterFn: "Custom filter function used to match options against the typed query; defaults to case-insensitive substring match",
|
|
62
|
+
size: "Dimensional preset controlling height, padding, font-size, and icon-size (Small, Medium, Large)",
|
|
63
|
+
required: "When true, a value must be selected before form submission; adds a required indicator to the label",
|
|
64
|
+
allowCustom: "When true, the user can submit a value that does not exist in the options list; when false, only listed options are valid",
|
|
65
|
+
loading: "When true, a spinner replaces the chevron to indicate that options are being loaded asynchronously",
|
|
66
|
+
helperText: "Optional instructional text below the field providing guidance on expected selection or constraints",
|
|
67
|
+
errorMessage: "Validation error message displayed below the field in error state; replaces helperText when visible",
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
sizeSpecifications: [
|
|
71
|
+
{
|
|
72
|
+
size: "Small",
|
|
73
|
+
height: "32px",
|
|
74
|
+
paddingLR: "12px",
|
|
75
|
+
fontSize: "12px",
|
|
76
|
+
iconSize: "16px",
|
|
77
|
+
borderRadius: "6px",
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
size: "Medium",
|
|
81
|
+
height: "40px",
|
|
82
|
+
paddingLR: "16px",
|
|
83
|
+
fontSize: "14px",
|
|
84
|
+
iconSize: "20px",
|
|
85
|
+
borderRadius: "8px",
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
size: "Large",
|
|
89
|
+
height: "48px",
|
|
90
|
+
paddingLR: "20px",
|
|
91
|
+
fontSize: "16px",
|
|
92
|
+
iconSize: "24px",
|
|
93
|
+
borderRadius: "10px",
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
|
|
97
|
+
designTokenBindings: [
|
|
98
|
+
{
|
|
99
|
+
property: "Background",
|
|
100
|
+
tokenName: "$field-bg",
|
|
101
|
+
role: "Default field background color",
|
|
102
|
+
fallback: "#FFFFFF",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
property: "Border",
|
|
106
|
+
tokenName: "$field-border",
|
|
107
|
+
role: "Default field border color",
|
|
108
|
+
fallback: "#D0D5DD",
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
property: "Option Hover",
|
|
112
|
+
tokenName: "$option-hover-bg",
|
|
113
|
+
role: "Background color of an option on mouse hover or keyboard highlight",
|
|
114
|
+
fallback: "#F2F4F7",
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
property: "Option Selected",
|
|
118
|
+
tokenName: "$option-selected-bg",
|
|
119
|
+
role: "Background color of the currently selected option in the listbox",
|
|
120
|
+
fallback: "#EFF8FF",
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
property: "Focus Ring",
|
|
124
|
+
tokenName: "$focus-ring",
|
|
125
|
+
role: "Keyboard and click focus indicator ring",
|
|
126
|
+
fallback: "0 0 0 2px #FFFFFF, 0 0 0 4px #2E90FA",
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
property: "Listbox Shadow",
|
|
130
|
+
tokenName: "$shadow-lg",
|
|
131
|
+
role: "Elevation shadow on the dropdown listbox",
|
|
132
|
+
fallback: "0 4px 16px rgba(0,0,0,0.12)",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
property: "Text Color",
|
|
136
|
+
tokenName: "$field-text",
|
|
137
|
+
role: "User-entered or selected value text color",
|
|
138
|
+
fallback: "#1D2939",
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
property: "Placeholder",
|
|
142
|
+
tokenName: "$field-placeholder",
|
|
143
|
+
role: "Placeholder hint text color",
|
|
144
|
+
fallback: "#98A2B3",
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
property: "Error Text",
|
|
148
|
+
tokenName: "$field-error-text",
|
|
149
|
+
role: "Error message text color below the field",
|
|
150
|
+
fallback: "#D92D20",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
property: "Error Border",
|
|
154
|
+
tokenName: "$field-error-border",
|
|
155
|
+
role: "Border color when field is in error state",
|
|
156
|
+
fallback: "#FDA29B",
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
property: "Chevron Icon",
|
|
160
|
+
tokenName: "$icon-secondary",
|
|
161
|
+
role: "Dropdown chevron indicator color",
|
|
162
|
+
fallback: "#667085",
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
property: "Label Color",
|
|
166
|
+
tokenName: "$field-label",
|
|
167
|
+
role: "Label text color above the field",
|
|
168
|
+
fallback: "#344054",
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
|
|
172
|
+
structureRules: [
|
|
173
|
+
"Container uses vertical Auto Layout: label on top, field in the middle, helper/error text at the bottom",
|
|
174
|
+
"Field element uses horizontal Auto Layout with center vertical alignment: text input area + chevron icon",
|
|
175
|
+
"Chevron icon is the last child of the field row; it rotates 180 degrees when the dropdown is open",
|
|
176
|
+
"Dropdown listbox is absolutely positioned below the field with a 4px gap ($spacing-xs)",
|
|
177
|
+
"Each option in the listbox uses horizontal Auto Layout with padding matching the field; optional check icon on the left for selected state",
|
|
178
|
+
"Listbox has a max-height of 240px with overflow-y scroll to prevent oversized dropdowns",
|
|
179
|
+
"Helper text and error message occupy the same slot — error replaces helper when visible",
|
|
180
|
+
"Touch target for the chevron button area is at least 44x44px regardless of visual icon size",
|
|
181
|
+
"Field width defaults to fill-container on the horizontal axis",
|
|
182
|
+
],
|
|
183
|
+
|
|
184
|
+
typeHierarchyRules: [
|
|
185
|
+
"Label uses font weight Medium (500) at one step smaller than the field font size",
|
|
186
|
+
"Field text and option text use Regular (400) weight at the size-appropriate font size",
|
|
187
|
+
"Placeholder text uses the same font size and weight as field text but in the placeholder color token",
|
|
188
|
+
"Helper and error text use font size 12px regardless of field size",
|
|
189
|
+
"Matched filter substring within options is highlighted with Medium (500) weight for scannability",
|
|
190
|
+
],
|
|
191
|
+
|
|
192
|
+
interactionRules: [
|
|
193
|
+
{ event: "Click Field", trigger: "pointerdown inside field bounds", action: "Enter focused state; open the dropdown listbox; place cursor in text input" },
|
|
194
|
+
{ event: "Click Chevron", trigger: "pointerdown on chevron icon area", action: "Toggle the dropdown open/closed; focus the text input" },
|
|
195
|
+
{ event: "Focus", trigger: "Tab key or focus()", action: "Show focus ring; do not open dropdown automatically on Tab focus" },
|
|
196
|
+
{ event: "Blur", trigger: "Focus moves away from field and dropdown", action: "Close dropdown; validate value; remove focus ring" },
|
|
197
|
+
{ event: "Input", trigger: "Keypress while focused", action: "Filter options against typed text; open dropdown if closed; reset active descendant" },
|
|
198
|
+
{ event: "Arrow Down", trigger: "ArrowDown while dropdown is open", action: "Move highlight to next option; wrap to first at end; scroll into view" },
|
|
199
|
+
{ event: "Arrow Up", trigger: "ArrowUp while dropdown is open", action: "Move highlight to previous option; wrap to last at start; scroll into view" },
|
|
200
|
+
{ event: "Enter Key", trigger: "Enter key while dropdown is open", action: "Select the highlighted option; close dropdown; fire onSelect callback" },
|
|
201
|
+
{ event: "Escape Key", trigger: "Escape key while dropdown is open", action: "Close dropdown without changing the value; retain focus on field" },
|
|
202
|
+
{ event: "Option Click", trigger: "pointerdown on a dropdown option", action: "Select the clicked option; close dropdown; update field value; fire onSelect" },
|
|
203
|
+
{ event: "Home Key", trigger: "Home key while dropdown is open", action: "Move highlight to the first option in the list" },
|
|
204
|
+
{ event: "End Key", trigger: "End key while dropdown is open", action: "Move highlight to the last option in the list" },
|
|
205
|
+
],
|
|
206
|
+
|
|
207
|
+
contentGuidance: [
|
|
208
|
+
"Labels should clearly describe the selection category: 'Country', 'Department', 'Assignee'",
|
|
209
|
+
"Placeholder text should suggest the interaction: 'Select or type...', 'Choose a category...'",
|
|
210
|
+
"Option labels should be concise and scannable — no more than 50 characters per option",
|
|
211
|
+
"Group related options with section headers when the list exceeds 10 items",
|
|
212
|
+
"Helper text should explain constraints: 'Required' or 'You can also type a custom value'",
|
|
213
|
+
"Error messages should be specific: 'Please select a valid country' instead of 'Invalid selection'",
|
|
214
|
+
],
|
|
215
|
+
|
|
216
|
+
responsiveBehaviour: [
|
|
217
|
+
{ breakpoint: "Mobile (<768px)", behavior: "Combobox expands to full width; dropdown overlays content and may use a bottom sheet pattern on small screens" },
|
|
218
|
+
{ breakpoint: "Tablet (768-1023px)", behavior: "Standard sizing; dropdown appears below the field within the content flow" },
|
|
219
|
+
{ breakpoint: "Desktop (1024-1439px)", behavior: "Standard sizing; dropdown respects container width; long option text truncates with ellipsis" },
|
|
220
|
+
{ breakpoint: "Ultra-wide (>=1440px)", behavior: "Max-width cap prevents overly wide comboboxes; dropdown width matches field width" },
|
|
221
|
+
],
|
|
222
|
+
|
|
223
|
+
accessibilitySpec: {
|
|
224
|
+
intro:
|
|
225
|
+
"Comboboxes are complex composite widgets requiring careful ARIA implementation. The WAI-ARIA combobox pattern (1.2) must be followed precisely for screen reader and keyboard compatibility.",
|
|
226
|
+
requirements: [
|
|
227
|
+
{ requirement: "Role Combobox", level: "A", notes: "The input element must have role='combobox' to identify it as a composite widget" },
|
|
228
|
+
{ requirement: "Expanded State", level: "A", notes: "Set aria-expanded='true' on the input when the listbox is visible; 'false' when closed" },
|
|
229
|
+
{ requirement: "Active Descendant", level: "A", notes: "Use aria-activedescendant on the input to reference the currently highlighted option by ID" },
|
|
230
|
+
{ requirement: "Listbox Role", level: "A", notes: "The dropdown container must have role='listbox'; it is owned by the combobox via aria-owns or DOM containment" },
|
|
231
|
+
{ requirement: "Option Role", level: "A", notes: "Each selectable item in the listbox must have role='option' with a unique ID" },
|
|
232
|
+
{ requirement: "Selected State", level: "A", notes: "The currently selected option must have aria-selected='true'; all other options have aria-selected='false'" },
|
|
233
|
+
{ requirement: "Label Association", level: "A", notes: "Label must be programmatically associated via for/id or aria-labelledby" },
|
|
234
|
+
{ requirement: "Contrast Ratio", level: "AA", notes: "Text-to-background: 4.5:1 minimum; option hover/selected backgrounds must maintain text contrast" },
|
|
235
|
+
{ requirement: "Error Identification", level: "A", notes: "Error state must set aria-invalid='true' and reference the error message via aria-describedby" },
|
|
236
|
+
{ requirement: "Keyboard Navigation", level: "A", notes: "ArrowUp/Down navigates options; Enter selects; Escape closes; Home/End jump to first/last" },
|
|
237
|
+
],
|
|
238
|
+
outro: [
|
|
239
|
+
"Ensure screen readers announce the number of available options when the dropdown opens: '8 options available'",
|
|
240
|
+
"Use aria-live='polite' on a status region to announce filter result changes without interrupting the user",
|
|
241
|
+
"Never trap keyboard focus inside the dropdown — Escape must always close it and return focus to the input",
|
|
242
|
+
],
|
|
243
|
+
},
|
|
244
|
+
|
|
245
|
+
qaAcceptanceCriteria: [
|
|
246
|
+
{ check: "Visual Regression", platform: "All", expectedResult: "Combobox renders pixel-perfect against baseline for each size and state" },
|
|
247
|
+
{ check: "Focus State", platform: "Web", expectedResult: "Focus ring visible on Tab; cursor blinks inside field; dropdown does not open on Tab alone" },
|
|
248
|
+
{ check: "Dropdown Open", platform: "Web", expectedResult: "Click or ArrowDown opens dropdown; chevron rotates; aria-expanded='true'" },
|
|
249
|
+
{ check: "Filtering", platform: "Web", expectedResult: "Typing filters options in real-time; non-matching options are hidden; empty state shown when no matches" },
|
|
250
|
+
{ check: "Option Selection", platform: "Web", expectedResult: "Click or Enter selects option; dropdown closes; field shows selected label; onSelect fires" },
|
|
251
|
+
{ check: "Keyboard Navigation", platform: "Web", expectedResult: "ArrowUp/Down moves highlight; Enter selects; Escape closes; Home/End jump to extremes" },
|
|
252
|
+
{ check: "Error State", platform: "All", expectedResult: "Error border, error message visible; helper text replaced; aria-invalid='true'" },
|
|
253
|
+
{ check: "Disabled State", platform: "All", expectedResult: "Muted visuals; pointer-events none; aria-disabled='true'; not focusable via Tab" },
|
|
254
|
+
{ check: "Screen Reader", platform: "Web", expectedResult: "Announces role 'combobox', accessible name, expanded state, active option, and selected state" },
|
|
255
|
+
{ check: "Custom Value", platform: "Web", expectedResult: "When allowCustom is true, typed text not in options is accepted; when false, it is rejected on blur" },
|
|
256
|
+
{ check: "Loading State", platform: "Web", expectedResult: "Spinner replaces chevron; options may show skeleton or 'Loading...' message" },
|
|
257
|
+
{ check: "Touch Target", platform: "Mobile", expectedResult: "Chevron tap area is at least 44x44px; options have minimum 44px height for touch" },
|
|
258
|
+
{ check: "Contrast", platform: "All", expectedResult: "All text passes 4.5:1 contrast; hover/selected backgrounds maintain text contrast ratio" },
|
|
259
|
+
{ check: "RTL Support", platform: "Web", expectedResult: "Chevron moves to left; text aligns right; dropdown alignment mirrors" },
|
|
260
|
+
{ check: "Scroll Behavior", platform: "Web", expectedResult: "Listbox scrolls when options exceed max-height; highlighted option scrolls into view" },
|
|
261
|
+
],
|
|
262
|
+
|
|
263
|
+
dos: [
|
|
264
|
+
"Always pair the combobox with a visible label that clearly describes the selection category",
|
|
265
|
+
"Use filtering to help users find options quickly in long lists (10+ items)",
|
|
266
|
+
"Highlight the matching substring within filtered options for visual scanning",
|
|
267
|
+
"Provide a clear empty-state message when filtering produces zero results",
|
|
268
|
+
"Use aria-activedescendant to manage focus within the listbox instead of moving DOM focus",
|
|
269
|
+
"Close the dropdown and validate the value on blur for a predictable user experience",
|
|
270
|
+
"Show a loading indicator when options are being fetched asynchronously",
|
|
271
|
+
],
|
|
272
|
+
|
|
273
|
+
donts: [
|
|
274
|
+
"Do not use a combobox when there are fewer than 5 options — use a select or radio group instead",
|
|
275
|
+
"Do not allow the dropdown to extend beyond the viewport — reposition or constrain as needed",
|
|
276
|
+
"Do not remove options from the DOM when filtering — hide them visually so screen readers can report accurate counts",
|
|
277
|
+
"Do not close the dropdown on option hover — only close on explicit selection or Escape",
|
|
278
|
+
"Do not use a combobox for multi-select — use a multi-select component with checkboxes instead",
|
|
279
|
+
"Do not override design token colors with hard-coded hex values",
|
|
280
|
+
"Do not trap keyboard focus inside the dropdown — Escape must always close it",
|
|
281
|
+
],
|
|
282
|
+
};
|
package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/datepicker.ts
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* datepicker.ts — Gold-standard design knowledge for DatePicker components
|
|
3
|
+
*/
|
|
4
|
+
import type { ComponentKnowledge } from "../types.js";
|
|
5
|
+
|
|
6
|
+
export const datepickerKnowledge: ComponentKnowledge = {
|
|
7
|
+
description:
|
|
8
|
+
"Date selection compound component | Input trigger with calendar popup | Supports single date and date range selection",
|
|
9
|
+
|
|
10
|
+
stateSpecifications: [
|
|
11
|
+
{
|
|
12
|
+
state: "Default",
|
|
13
|
+
visualChange: "Trigger input shows placeholder text with calendar icon; border uses default token",
|
|
14
|
+
opacity: "1",
|
|
15
|
+
cursorWeb: "pointer",
|
|
16
|
+
usage: "Resting state — no date selected, calendar is closed",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
state: "Open",
|
|
20
|
+
visualChange: "Calendar dropdown is visible below the trigger; trigger border switches to active/focus token; selected day highlighted",
|
|
21
|
+
opacity: "1",
|
|
22
|
+
cursorWeb: "default",
|
|
23
|
+
usage: "User has clicked the trigger or pressed Enter/Space to open the calendar popup",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
state: "Focused",
|
|
27
|
+
visualChange: "2px focus ring offset by 2px from the trigger edge, using $focus-ring token; calendar remains closed until activated",
|
|
28
|
+
opacity: "1",
|
|
29
|
+
cursorWeb: "pointer",
|
|
30
|
+
usage: "Trigger receives keyboard focus via Tab key or programmatic focus call",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
state: "Error",
|
|
34
|
+
visualChange: "Trigger border switches to $color-error; error icon appears; error message text displayed below the trigger",
|
|
35
|
+
opacity: "1",
|
|
36
|
+
cursorWeb: "pointer",
|
|
37
|
+
usage: "Selected date is outside min/max bounds, format is invalid, or required field is empty on validation",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
state: "Disabled",
|
|
41
|
+
visualChange: "Trigger background and text switch to muted/disabled tokens; calendar icon is desaturated; click does not open calendar",
|
|
42
|
+
opacity: "0.4",
|
|
43
|
+
cursorWeb: "not-allowed",
|
|
44
|
+
usage: "Date selection is unavailable due to form state or permissions",
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
|
|
48
|
+
propertyDescriptions: {
|
|
49
|
+
label: "Visible label text rendered above or beside the trigger; identifies the date field purpose (e.g. 'Start date')",
|
|
50
|
+
value: "Currently selected date value in ISO 8601 format (YYYY-MM-DD) or null when no date is selected",
|
|
51
|
+
placeholder: "Hint text shown in the trigger when no date is selected; should reflect the expected format (e.g. 'mm/dd/yyyy')",
|
|
52
|
+
minDate: "Earliest selectable date; days before this date are rendered as disabled in the calendar grid",
|
|
53
|
+
maxDate: "Latest selectable date; days after this date are rendered as disabled in the calendar grid",
|
|
54
|
+
format: "Display format string for the selected date (e.g. 'MM/DD/YYYY', 'DD.MM.YYYY', 'YYYY-MM-DD')",
|
|
55
|
+
type: "Selection mode — 'single' for one date or 'range' for a start-and-end date pair",
|
|
56
|
+
locale: "BCP 47 locale tag controlling day/month names, first day of week, and number formatting (e.g. 'en-US', 'de-DE')",
|
|
57
|
+
size: "Dimensional preset controlling trigger height, padding, font-size, and icon-size (Small, Medium, Large)",
|
|
58
|
+
required: "When true the field must have a value before form submission; adds required indicator to the label",
|
|
59
|
+
helperText: "Supplementary guidance text rendered below the trigger in default state (e.g. 'Select your preferred date')",
|
|
60
|
+
errorMessage: "Validation error text rendered below the trigger in error state, replacing helper text",
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
sizeSpecifications: [
|
|
64
|
+
{
|
|
65
|
+
size: "Small",
|
|
66
|
+
height: "32px",
|
|
67
|
+
paddingLR: "12px",
|
|
68
|
+
fontSize: "12px",
|
|
69
|
+
iconSize: "16px",
|
|
70
|
+
borderRadius: "6px",
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
size: "Medium",
|
|
74
|
+
height: "40px",
|
|
75
|
+
paddingLR: "16px",
|
|
76
|
+
fontSize: "14px",
|
|
77
|
+
iconSize: "20px",
|
|
78
|
+
borderRadius: "8px",
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
size: "Large",
|
|
82
|
+
height: "48px",
|
|
83
|
+
paddingLR: "20px",
|
|
84
|
+
fontSize: "16px",
|
|
85
|
+
iconSize: "24px",
|
|
86
|
+
borderRadius: "10px",
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
|
|
90
|
+
designTokenBindings: [
|
|
91
|
+
{
|
|
92
|
+
property: "Trigger Background",
|
|
93
|
+
tokenName: "$datepicker-trigger-bg",
|
|
94
|
+
role: "Background fill for the input trigger area",
|
|
95
|
+
fallback: "#FFFFFF",
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
property: "Trigger Border",
|
|
99
|
+
tokenName: "$datepicker-trigger-border",
|
|
100
|
+
role: "Border color for the input trigger in default state",
|
|
101
|
+
fallback: "#D0D5DD",
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
property: "Calendar Background",
|
|
105
|
+
tokenName: "$datepicker-calendar-bg",
|
|
106
|
+
role: "Background fill for the calendar dropdown panel",
|
|
107
|
+
fallback: "#FFFFFF",
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
property: "Calendar Shadow",
|
|
111
|
+
tokenName: "$datepicker-calendar-shadow",
|
|
112
|
+
role: "Elevation shadow on the calendar dropdown panel",
|
|
113
|
+
fallback: "0 4px 16px rgba(0,0,0,0.12)",
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
property: "Day Default",
|
|
117
|
+
tokenName: "$datepicker-day-text",
|
|
118
|
+
role: "Text color for selectable day cells in their default state",
|
|
119
|
+
fallback: "#344054",
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
property: "Day Hover",
|
|
123
|
+
tokenName: "$datepicker-day-hover-bg",
|
|
124
|
+
role: "Background fill when a selectable day cell is hovered",
|
|
125
|
+
fallback: "#F2F4F7",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
property: "Day Selected",
|
|
129
|
+
tokenName: "$datepicker-day-selected-bg",
|
|
130
|
+
role: "Background fill for the currently selected day cell",
|
|
131
|
+
fallback: "#2563EB",
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
property: "Day Today",
|
|
135
|
+
tokenName: "$datepicker-day-today-border",
|
|
136
|
+
role: "Border or underline indicator on today's date cell",
|
|
137
|
+
fallback: "#2563EB",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
property: "Day Range",
|
|
141
|
+
tokenName: "$datepicker-day-range-bg",
|
|
142
|
+
role: "Background fill for days within a selected date range (between start and end)",
|
|
143
|
+
fallback: "#EFF6FF",
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
property: "Day Disabled",
|
|
147
|
+
tokenName: "$datepicker-day-disabled-text",
|
|
148
|
+
role: "Text color for days outside the min/max bounds or other months",
|
|
149
|
+
fallback: "#98A2B3",
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
property: "Month Nav Arrows",
|
|
153
|
+
tokenName: "$datepicker-nav-icon",
|
|
154
|
+
role: "Icon color for previous/next month navigation arrows",
|
|
155
|
+
fallback: "#667085",
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
property: "Focus Ring",
|
|
159
|
+
tokenName: "$focus-ring",
|
|
160
|
+
role: "Keyboard focus indicator ring on the trigger and individual day cells",
|
|
161
|
+
fallback: "0 0 0 2px #FFFFFF, 0 0 0 4px #2E90FA",
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
|
|
165
|
+
structureRules: [
|
|
166
|
+
"Component is a compound structure: input trigger + calendar dropdown overlay",
|
|
167
|
+
"Trigger uses horizontal Auto Layout with center vertical alignment; contains placeholder/value text and calendar icon",
|
|
168
|
+
"Calendar dropdown is positioned absolutely below the trigger with a 4px gap",
|
|
169
|
+
"Calendar grid header row contains abbreviated day-of-week names (Su, Mo, Tu, etc.) based on locale",
|
|
170
|
+
"Calendar grid body contains 6 rows x 7 columns of day cells; days from adjacent months are visible but dimmed",
|
|
171
|
+
"Navigation row at the top of the calendar contains previous/next month arrows and current month-year label",
|
|
172
|
+
"Range mode renders a highlighted band across all days between the start and end selection",
|
|
173
|
+
"Calendar dropdown should flip above the trigger when insufficient viewport space exists below",
|
|
174
|
+
"Touch target for each day cell is at least 44x44px; grid cells may use transparent padding to meet this",
|
|
175
|
+
"Trigger width defaults to 280px but stretches to fill-container in full-width mode",
|
|
176
|
+
],
|
|
177
|
+
|
|
178
|
+
typeHierarchyRules: [
|
|
179
|
+
"Trigger value text uses the field's fontSize token — matches the size preset (12/14/16px)",
|
|
180
|
+
"Calendar month-year header uses font-weight Medium (500) at one step larger than day cell text",
|
|
181
|
+
"Day-of-week abbreviations use font-weight Medium (500) at the same size as day cell text",
|
|
182
|
+
"Day cell numbers use font-weight Regular (400); selected day uses font-weight Medium (500)",
|
|
183
|
+
"Label text uses sentence case; helper and error text use sentence case at one step smaller than the trigger text",
|
|
184
|
+
],
|
|
185
|
+
|
|
186
|
+
interactionRules: [
|
|
187
|
+
{ event: "Click Trigger", trigger: "pointerup on trigger", action: "Toggle calendar open/closed; focus the currently selected or today's date cell" },
|
|
188
|
+
{ event: "Click Day", trigger: "pointerup on a day cell", action: "Select the date, update the trigger value, close the calendar (single mode)" },
|
|
189
|
+
{ event: "Click Range Start", trigger: "pointerup on first day cell (range mode)", action: "Set range start; keep calendar open awaiting end date selection" },
|
|
190
|
+
{ event: "Click Range End", trigger: "pointerup on second day cell (range mode)", action: "Set range end; highlight range band; close calendar" },
|
|
191
|
+
{ event: "Click Nav Arrow", trigger: "pointerup on prev/next arrow", action: "Navigate to previous or next month; do not close calendar" },
|
|
192
|
+
{ event: "Keyboard Enter/Space", trigger: "Enter or Space on trigger", action: "Open calendar and focus the currently selected or today's day cell" },
|
|
193
|
+
{ event: "Arrow Keys", trigger: "Arrow keys while calendar is open", action: "Move focus between day cells: Left/Right by 1 day, Up/Down by 1 week" },
|
|
194
|
+
{ event: "Page Up/Down", trigger: "Page Up or Page Down while calendar is open", action: "Navigate to the same day in the previous or next month" },
|
|
195
|
+
{ event: "Home/End", trigger: "Home or End key while calendar is open", action: "Move focus to the first or last day of the current month" },
|
|
196
|
+
{ event: "Escape", trigger: "Escape key while calendar is open", action: "Close the calendar without changing the selected value; return focus to the trigger" },
|
|
197
|
+
{ event: "Tab", trigger: "Tab key while calendar is open", action: "Close calendar and move focus to the next focusable element in the page" },
|
|
198
|
+
{ event: "Outside Click", trigger: "pointerdown outside the component", action: "Close the calendar dropdown without changing selection" },
|
|
199
|
+
],
|
|
200
|
+
|
|
201
|
+
contentGuidance: [
|
|
202
|
+
"Labels should clearly describe which date is expected: 'Start date', 'Date of birth', 'Departure date'",
|
|
203
|
+
"Placeholder text should reflect the display format: 'mm/dd/yyyy' or 'dd.mm.yyyy' per locale",
|
|
204
|
+
"Helper text may describe constraints: 'Must be a future date' or 'Select a weekday only'",
|
|
205
|
+
"Error messages should be specific: 'Date must be after Jan 1, 2024' rather than 'Invalid date'",
|
|
206
|
+
"For range selection, use paired labels: 'Start date' and 'End date' rather than a single ambiguous label",
|
|
207
|
+
"Month and day names must respect the locale prop — never hardcode English names",
|
|
208
|
+
],
|
|
209
|
+
|
|
210
|
+
responsiveBehaviour: [
|
|
211
|
+
{ breakpoint: "Mobile (<768px)", behavior: "Calendar opens as a full-width bottom sheet or modal overlay; trigger stretches to full width; day cells are 48px touch targets" },
|
|
212
|
+
{ breakpoint: "Tablet (768-1023px)", behavior: "Calendar opens as a dropdown below trigger; trigger may be full-width or fixed-width depending on form layout" },
|
|
213
|
+
{ breakpoint: "Desktop (1024-1439px)", behavior: "Standard dropdown calendar positioned below the trigger; trigger width follows form column grid" },
|
|
214
|
+
{ breakpoint: "Ultra-wide (>=1440px)", behavior: "Calendar size remains capped at standard dimensions — does not scale with viewport" },
|
|
215
|
+
],
|
|
216
|
+
|
|
217
|
+
accessibilitySpec: {
|
|
218
|
+
intro:
|
|
219
|
+
"Date pickers are complex widgets requiring careful ARIA markup and full keyboard navigation to be usable by screen reader and keyboard-only users.",
|
|
220
|
+
requirements: [
|
|
221
|
+
{ requirement: "Calendar Grid Role", level: "A", notes: "Calendar uses role='grid' with role='row' for each week and role='gridcell' for each day" },
|
|
222
|
+
{ requirement: "Day Cell Selection", level: "A", notes: "Selected day cell has aria-selected='true'; all other cells have aria-selected='false'" },
|
|
223
|
+
{ requirement: "Roving Tabindex", level: "A", notes: "Only the focused day cell has tabindex='0'; all others have tabindex='-1' for roving focus" },
|
|
224
|
+
{ requirement: "Arrow Key Navigation", level: "A", notes: "Left/Right moves by day, Up/Down by week; Page Up/Down navigates months; Home/End jump to month boundaries" },
|
|
225
|
+
{ requirement: "Live Region", level: "A", notes: "Month changes announced via aria-live='polite' region: 'March 2024' when navigating months" },
|
|
226
|
+
{ requirement: "Trigger Label", level: "A", notes: "Trigger input has aria-label or aria-labelledby pointing to the visible label; describes the field purpose" },
|
|
227
|
+
{ requirement: "Expanded State", level: "A", notes: "Trigger has aria-expanded='true' when calendar is open, 'false' when closed; aria-haspopup='dialog'" },
|
|
228
|
+
{ requirement: "Contrast Ratio", level: "AA", notes: "Day text to background: 4.5:1 minimum; selected day indicator to calendar background: 3:1 minimum" },
|
|
229
|
+
{ requirement: "Error Association", level: "A", notes: "Error message linked via aria-describedby on the trigger; aria-invalid='true' in error state" },
|
|
230
|
+
{ requirement: "Touch Target", level: "AA", notes: "Each day cell provides at least 44x44px touch target per WCAG 2.5.5" },
|
|
231
|
+
],
|
|
232
|
+
outro: [
|
|
233
|
+
"Ensure focus returns to the trigger when the calendar is dismissed via Escape or outside click",
|
|
234
|
+
"Screen readers should announce the full date when a day cell receives focus: 'Tuesday, March 15, 2024'",
|
|
235
|
+
"Disabled dates must be announced as unavailable: 'March 20, 2024, not available'",
|
|
236
|
+
],
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
qaAcceptanceCriteria: [
|
|
240
|
+
{ check: "Visual Regression", platform: "All", expectedResult: "Trigger and calendar render pixel-perfect against baseline for each size and state" },
|
|
241
|
+
{ check: "Calendar Open", platform: "Web", expectedResult: "Calendar dropdown appears below trigger on click; positioned correctly relative to viewport edges" },
|
|
242
|
+
{ check: "Date Selection", platform: "Web", expectedResult: "Clicking a day cell updates the trigger value and closes the calendar (single mode)" },
|
|
243
|
+
{ check: "Range Selection", platform: "Web", expectedResult: "First click sets start, second click sets end; range band highlights correctly between dates" },
|
|
244
|
+
{ check: "Min/Max Bounds", platform: "All", expectedResult: "Days outside minDate–maxDate are visually disabled and not selectable" },
|
|
245
|
+
{ check: "Keyboard Navigation", platform: "Web", expectedResult: "Arrow keys, Page Up/Down, Home/End navigate the calendar grid correctly" },
|
|
246
|
+
{ check: "Escape to Close", platform: "Web", expectedResult: "Escape closes calendar without changing value; focus returns to trigger" },
|
|
247
|
+
{ check: "Focus State", platform: "Web", expectedResult: "Focus ring visible on trigger via Tab; focus-visible hides ring on mouse click" },
|
|
248
|
+
{ check: "Error State", platform: "All", expectedResult: "Error border, icon, and message appear; aria-invalid='true' and aria-describedby set" },
|
|
249
|
+
{ check: "Disabled State", platform: "All", expectedResult: "Muted visuals; click does not open calendar; aria-disabled='true'" },
|
|
250
|
+
{ check: "Screen Reader", platform: "Web", expectedResult: "Announces trigger label, expanded state, grid role, and selected date correctly" },
|
|
251
|
+
{ check: "Locale Support", platform: "All", expectedResult: "Day/month names, first day of week, and date format change correctly per locale prop" },
|
|
252
|
+
{ check: "Touch Target Size", platform: "Mobile", expectedResult: "Day cells and navigation arrows are at least 44x44px" },
|
|
253
|
+
{ check: "Contrast", platform: "All", expectedResult: "All text passes 4.5:1 contrast; selected/today indicators pass 3:1 non-text contrast" },
|
|
254
|
+
{ check: "RTL Support", platform: "Web", expectedResult: "Calendar grid, navigation arrows, and trigger layout mirror correctly in RTL locales" },
|
|
255
|
+
],
|
|
256
|
+
|
|
257
|
+
dos: [
|
|
258
|
+
"Use the DatePicker for dates that benefit from a visual calendar context (e.g. scheduling, booking)",
|
|
259
|
+
"Provide clear min/max date constraints and communicate them through helper text",
|
|
260
|
+
"Use locale-appropriate date formatting — never hardcode a single format for international audiences",
|
|
261
|
+
"Show today's date with a visual indicator (border or dot) so users can orient themselves",
|
|
262
|
+
"Pre-populate the value when a sensible default exists (e.g. today's date for 'start date')",
|
|
263
|
+
"Use range mode for selecting date spans rather than two separate single-date pickers",
|
|
264
|
+
"Ensure the calendar flips above the trigger when near the bottom of the viewport",
|
|
265
|
+
],
|
|
266
|
+
|
|
267
|
+
donts: [
|
|
268
|
+
"Do not use a DatePicker for known dates like birthdays — a simple text input with masking is faster",
|
|
269
|
+
"Do not allow selection of dates outside the valid min/max range — disable them visually",
|
|
270
|
+
"Do not close the calendar on month navigation — only close on date selection or explicit dismissal",
|
|
271
|
+
"Do not remove the focus ring from day cells — keyboard users rely on it for orientation",
|
|
272
|
+
"Do not hardcode English day/month names — always derive them from the locale prop",
|
|
273
|
+
"Do not render the calendar inline by default — use the dropdown pattern to conserve space",
|
|
274
|
+
"Do not override calendar shadow or elevation tokens with hardcoded values",
|
|
275
|
+
],
|
|
276
|
+
};
|