@qijenchen/design-system 0.1.0-beta.10 → 0.1.0-beta.13
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.md +201 -0
- package/README.md +7 -15
- package/cli-init.mjs +90 -0
- package/ds-canonical/commands/README.md +26 -0
- package/ds-canonical/commands/gov-status.md +79 -0
- package/ds-canonical/hooks/README.md +145 -0
- package/ds-canonical/hooks/_log-fire.sh +44 -0
- package/ds-canonical/hooks/block_prototype_imports.py +111 -0
- package/ds-canonical/hooks/check_app_shell_primary_header_consistency.sh +68 -0
- package/ds-canonical/hooks/check_audit_post_report_validator.sh +88 -0
- package/ds-canonical/hooks/check_audit_sample_escape.sh +73 -0
- package/ds-canonical/hooks/check_benchmark_citation.sh +106 -0
- package/ds-canonical/hooks/check_canonical_propagation.sh +189 -0
- package/ds-canonical/hooks/check_chrome_header_handcraft.sh +70 -0
- package/ds-canonical/hooks/check_codex_brief_invariants.sh +83 -0
- package/ds-canonical/hooks/check_codex_collab_5step.sh +108 -0
- package/ds-canonical/hooks/check_datatable_invariants.sh +117 -0
- package/ds-canonical/hooks/check_dim_count_drift.sh +72 -0
- package/ds-canonical/hooks/check_field_controls_contracts.sh +110 -0
- package/ds-canonical/hooks/check_field_family_invariants.sh +205 -0
- package/ds-canonical/hooks/check_file_size_budget.sh +60 -0
- package/ds-canonical/hooks/check_header_with_tabs_border.sh +87 -0
- package/ds-canonical/hooks/check_main_branch_workbench.sh +93 -0
- package/ds-canonical/hooks/check_naming_and_abstraction.sh +165 -0
- package/ds-canonical/hooks/check_opacity_token_usage.sh +149 -0
- package/ds-canonical/hooks/check_pattern_invariants.sh +194 -0
- package/ds-canonical/hooks/check_peoplepicker_ssot_drift.sh +56 -0
- package/ds-canonical/hooks/check_pixel_quantified_audit.sh +53 -0
- package/ds-canonical/hooks/check_propose_plain_chinese.sh +74 -0
- package/ds-canonical/hooks/check_propose_pre_grep_verify.sh +70 -0
- package/ds-canonical/hooks/check_select_all_canonical.sh +58 -0
- package/ds-canonical/hooks/check_solo_workflow.sh +258 -0
- package/ds-canonical/hooks/check_spec_class_drift.sh +88 -0
- package/ds-canonical/hooks/check_story_invariants.sh +612 -0
- package/ds-canonical/hooks/check_substantive_edit_approval_preflight.sh +105 -0
- package/ds-canonical/hooks/check_tab_lg_chrome_header_equal.sh +66 -0
- package/ds-canonical/hooks/check_wrapper_primitive_schema_drift.sh +104 -0
- package/ds-canonical/hooks/enforce_home_charter.sh +44 -0
- package/ds-canonical/hooks/inject_pending_self_audit.sh +204 -0
- package/ds-canonical/hooks/lib/_approval_re.sh +33 -0
- package/ds-canonical/hooks/lib/_code_quality.sh +73 -0
- package/ds-canonical/hooks/lib/_cva_default_sync.sh +69 -0
- package/ds-canonical/hooks/lib/_governance_coverage_check.sh +49 -0
- package/ds-canonical/hooks/lib/_hardcoded_strings.sh +163 -0
- package/ds-canonical/hooks/lib/_layout_space_canonical.sh +56 -0
- package/ds-canonical/hooks/lib/_overlay_handcraft.sh +141 -0
- package/ds-canonical/hooks/lib/_person_data_richness.sh +42 -0
- package/ds-canonical/hooks/lib/_story_compile_drift.sh +48 -0
- package/ds-canonical/hooks/lib/_token_hygiene.sh +95 -0
- package/ds-canonical/hooks/log_governance_fires.sh +50 -0
- package/ds-canonical/hooks/log_skill_invokes.sh +41 -0
- package/ds-canonical/hooks/post_edit_dispatcher.sh +62 -0
- package/ds-canonical/hooks/retired/check_anatomy_section_numbering.sh +106 -0
- package/ds-canonical/hooks/retired/check_avatar_hovercard.sh +90 -0
- package/ds-canonical/hooks/retired/check_button_icon_literal.sh.retired-2026-04-28 +38 -0
- package/ds-canonical/hooks/retired/check_container_breathing.sh +142 -0
- package/ds-canonical/hooks/retired/check_governance_compliance.sh +61 -0
- package/ds-canonical/hooks/retired/check_icon_only_padding_formula.sh +104 -0
- package/ds-canonical/hooks/retired/check_item_content_primitive.sh +150 -0
- package/ds-canonical/hooks/retired/check_item_list_gap.sh +153 -0
- package/ds-canonical/hooks/retired/check_sideoffset_canonical.sh +65 -0
- package/ds-canonical/hooks/retired/check_spec_iteration_tag.sh +87 -0
- package/ds-canonical/hooks/retired/check_ssot_consultation.sh +88 -0
- package/ds-canonical/hooks/retired/check_sync_update.sh +20 -0
- package/ds-canonical/hooks/retired/check_third_party_dom_verified.sh +95 -0
- package/ds-canonical/hooks/retired/enforce_home_charter.sh +125 -0
- package/ds-canonical/hooks/retired/post_edit_canonical_interrogate.sh +109 -0
- package/ds-canonical/hooks/retired/pre_edit_spec_check.sh +68 -0
- package/ds-canonical/hooks/retired/pre_new_component_spec.sh +39 -0
- package/ds-canonical/hooks/retired/pre_write_subsumption_check.sh +112 -0
- package/ds-canonical/hooks/retired/stop_meta_self_audit.sh.retired-2026-05-13 +76 -0
- package/ds-canonical/hooks/retired/tests/test_check_anatomy_section_numbering.sh +14 -0
- package/ds-canonical/hooks/retired/tests/test_check_avatar_hovercard.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_container_breathing.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_governance_compliance.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_icon_only_padding_formula.sh +79 -0
- package/ds-canonical/hooks/retired/tests/test_check_item_content_primitive.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_item_list_gap.sh +163 -0
- package/ds-canonical/hooks/retired/tests/test_check_sideoffset_canonical.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_spec_iteration_tag.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_ssot_consultation.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_sync_update.sh +14 -0
- package/ds-canonical/hooks/retired/tests/test_check_third_party_dom_verified.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_enforce_home_charter.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_pre_edit_spec_check.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_pre_new_component_spec.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_pre_write_subsumption_check.sh +63 -0
- package/ds-canonical/hooks/session_start_governance_check.sh +263 -0
- package/ds-canonical/hooks/stop_passive_logging.sh +322 -0
- package/ds-canonical/hooks/stop_self_audit.sh +450 -0
- package/ds-canonical/hooks/tests/KNOWN-BROKEN.md +15 -0
- package/ds-canonical/hooks/tests/run-all.sh +76 -0
- package/ds-canonical/hooks/tests/test_block_prototype_imports.sh +143 -0
- package/ds-canonical/hooks/tests/test_check_app_shell_primary_header_consistency.sh +140 -0
- package/ds-canonical/hooks/tests/test_check_audit_post_report_validator.sh +115 -0
- package/ds-canonical/hooks/tests/test_check_audit_sample_escape.sh +93 -0
- package/ds-canonical/hooks/tests/test_check_benchmark_citation.sh +115 -0
- package/ds-canonical/hooks/tests/test_check_canonical_propagation.sh +133 -0
- package/ds-canonical/hooks/tests/test_check_chrome_header_handcraft.sh +123 -0
- package/ds-canonical/hooks/tests/test_check_code_quality.sh +15 -0
- package/ds-canonical/hooks/tests/test_check_codex_collab_5step.sh +96 -0
- package/ds-canonical/hooks/tests/test_check_cva_default_sync.sh +15 -0
- package/ds-canonical/hooks/tests/test_check_datatable_invariants.sh +122 -0
- package/ds-canonical/hooks/tests/test_check_dim_count_drift.sh +98 -0
- package/ds-canonical/hooks/tests/test_check_field_controls_contracts.sh +126 -0
- package/ds-canonical/hooks/tests/test_check_field_family_invariants.sh +194 -0
- package/ds-canonical/hooks/tests/test_check_file_size_budget.sh +32 -0
- package/ds-canonical/hooks/tests/test_check_hardcoded_strings.sh +14 -0
- package/ds-canonical/hooks/tests/test_check_header_with_tabs_border.sh +110 -0
- package/ds-canonical/hooks/tests/test_check_layout_space_canonical.sh +73 -0
- package/ds-canonical/hooks/tests/test_check_main_branch_workbench.sh +147 -0
- package/ds-canonical/hooks/tests/test_check_naming_and_abstraction.sh +136 -0
- package/ds-canonical/hooks/tests/test_check_opacity_token_usage.sh +110 -0
- package/ds-canonical/hooks/tests/test_check_overlay_handcraft.sh +126 -0
- package/ds-canonical/hooks/tests/test_check_pattern_invariants.sh +148 -0
- package/ds-canonical/hooks/tests/test_check_peoplepicker_ssot_drift.sh +108 -0
- package/ds-canonical/hooks/tests/test_check_person_data_richness.sh +58 -0
- package/ds-canonical/hooks/tests/test_check_pixel_quantified_audit.sh +142 -0
- package/ds-canonical/hooks/tests/test_check_propose_plain_chinese.sh +126 -0
- package/ds-canonical/hooks/tests/test_check_propose_pre_grep_verify.sh +117 -0
- package/ds-canonical/hooks/tests/test_check_select_all_canonical.sh +125 -0
- package/ds-canonical/hooks/tests/test_check_solo_workflow.sh +201 -0
- package/ds-canonical/hooks/tests/test_check_spec_class_drift.sh +135 -0
- package/ds-canonical/hooks/tests/test_check_story_anatomy.sh.broken +197 -0
- package/ds-canonical/hooks/tests/test_check_story_category.sh.broken +187 -0
- package/ds-canonical/hooks/tests/test_check_story_compile_drift.sh +15 -0
- package/ds-canonical/hooks/tests/test_check_story_invariants.sh +209 -0
- package/ds-canonical/hooks/tests/test_check_story_name_jargon.sh.broken +53 -0
- package/ds-canonical/hooks/tests/test_check_story_slot_split.sh +156 -0
- package/ds-canonical/hooks/tests/test_check_substantive_edit_approval_preflight.sh +176 -0
- package/ds-canonical/hooks/tests/test_check_tab_lg_chrome_header_equal.sh +138 -0
- package/ds-canonical/hooks/tests/test_check_token_hygiene.sh +21 -0
- package/ds-canonical/hooks/tests/test_check_wrapper_primitive_schema_drift.sh +169 -0
- package/ds-canonical/hooks/tests/test_enforce_home_charter.sh +77 -0
- package/ds-canonical/hooks/tests/test_inject_pending_self_audit.sh +125 -0
- package/ds-canonical/hooks/tests/test_log_governance_fires.sh +10 -0
- package/ds-canonical/hooks/tests/test_log_skill_invokes.sh +7 -0
- package/ds-canonical/hooks/tests/test_post_edit_dispatcher.sh +108 -0
- package/ds-canonical/hooks/tests/test_session_start_governance_check.sh +143 -0
- package/ds-canonical/hooks/tests/test_stop_capture_metrics.sh +95 -0
- package/ds-canonical/hooks/tests/test_stop_governance_drift_check.sh.broken +125 -0
- package/ds-canonical/hooks/tests/test_stop_harvest_corrections.sh +10 -0
- package/ds-canonical/hooks/tests/test_stop_passive_logging.sh +100 -0
- package/ds-canonical/hooks/tests/test_stop_self_audit.sh +76 -0
- package/ds-canonical/hooks/tests/test_stop_tsc_sanity.sh +10 -0
- package/ds-canonical/references/README.md +43 -0
- package/ds-canonical/references/audit-coverage-vs-24-checklist.md +74 -0
- package/ds-canonical/references/build-ui-canonicals.md +69 -0
- package/ds-canonical/references/cva-patterns.md +41 -0
- package/ds-canonical/references/drag-canonical.md +331 -0
- package/ds-canonical/references/item-anatomy-recipe.md +225 -0
- package/ds-canonical/references/naming-conventions.md +56 -0
- package/ds-canonical/references/principle-dim-map.json +515 -0
- package/ds-canonical/references/props-naming.md +45 -0
- package/ds-canonical/references/spec-rules.md +58 -0
- package/ds-canonical/references/ssot-consultation.md +63 -0
- package/ds-canonical/references/ssot-index.md +40 -0
- package/ds-canonical/references/story-baseline-registry.json +79 -0
- package/ds-canonical/references/structural-token-retention.md +42 -0
- package/ds-canonical/references/tailwind-gotchas.md +87 -0
- package/ds-canonical/references/ui-dev-rules.md +60 -0
- package/ds-canonical/rules/README.md +34 -0
- package/ds-canonical/rules/meta-patterns.md +87 -0
- package/ds-canonical/rules/self-verify.md +53 -0
- package/ds-canonical/rules/spec-rules.md +25 -0
- package/ds-canonical/rules/story-rules.md +56 -0
- package/ds-canonical/rules/ui-development.md +87 -0
- package/ds-canonical/skills/README.md +88 -0
- package/ds-canonical/skills/bug-fix-rhythm/SKILL.md +181 -0
- package/ds-canonical/skills/code-quality-audit/SKILL.md +63 -0
- package/ds-canonical/skills/codex-collab/SKILL.md +249 -0
- package/ds-canonical/skills/codex-collab/references/brief-template.md +48 -0
- package/ds-canonical/skills/codex-collab/references/transport.md +58 -0
- package/ds-canonical/skills/codify-corrections/SKILL.md +184 -0
- package/ds-canonical/skills/codify-principle/SKILL.md +151 -0
- package/ds-canonical/skills/component-quality-gate/SKILL.md +102 -0
- package/ds-canonical/skills/component-quality-gate/references/checklist.md +79 -0
- package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +247 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/phase-a-workflow.md +123 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/phase-b-codex-brief.md +165 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +91 -0
- package/ds-canonical/skills/delivery-handoff/SKILL.md +229 -0
- package/ds-canonical/skills/delivery-handoff/references/flow-diagram.md +180 -0
- package/ds-canonical/skills/delivery-handoff/references/handoff-template.md +177 -0
- package/ds-canonical/skills/delivery-handoff/references/inventory-checklist.md +196 -0
- package/ds-canonical/skills/design-system-audit/SKILL.md +343 -0
- package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +1260 -0
- package/ds-canonical/skills/design-system-audit/references/checkpoints.md +240 -0
- package/ds-canonical/skills/design-system-audit/references/historical-bugs.md +240 -0
- package/ds-canonical/skills/design-system-audit/references/principle-audit-protocol.md +364 -0
- package/ds-canonical/skills/design-system-audit/references/rule-placement.md +175 -0
- package/ds-canonical/skills/design-system-audit/references/spec-template.md +66 -0
- package/ds-canonical/skills/ensure-canonical/SKILL.md +196 -0
- package/ds-canonical/skills/governance-health/SKILL.md +146 -0
- package/ds-canonical/skills/knowledge-prune/SKILL.md +303 -0
- package/ds-canonical/skills/new-component/SKILL.md +170 -0
- package/ds-canonical/skills/new-component/references/new-component-checklist.md +85 -0
- package/ds-canonical/skills/performance-audit/SKILL.md +107 -0
- package/ds-canonical/skills/product-ui-audit/SKILL.md +230 -0
- package/ds-canonical/skills/product-ui-audit/references/audit-checks.md +246 -0
- package/ds-canonical/skills/product-ui-audit/references/common-misuses.md +329 -0
- package/ds-canonical/skills/product-ui-audit/references/report-template.md +159 -0
- package/ds-canonical/skills/propose-options/SKILL.md +177 -0
- package/ds-canonical/skills/prototype/SKILL.md +244 -0
- package/ds-canonical/skills/prototype/references/audit-checks.md +37 -0
- package/ds-canonical/skills/prototype/references/benchmark-sources.md +94 -0
- package/ds-canonical/skills/prototype/references/checkpoints.md +191 -0
- package/ds-canonical/skills/prototype/references/evaluation-matrix.md +141 -0
- package/ds-canonical/skills/prototype/references/ooux-template.md +198 -0
- package/ds-canonical/skills/prototype/references/proposal-template.md +229 -0
- package/ds-canonical/skills/scan-similar-bugs/SKILL.md +198 -0
- package/ds-canonical/skills/story-auto-compile-migrate/SKILL.md +159 -0
- package/ds-canonical/skills/story-writing/SKILL.md +122 -0
- package/ds-canonical/skills/story-writing/references/anatomy-standard.md +217 -0
- package/ds-canonical/skills/story-writing/references/category-templates.md +174 -0
- package/ds-canonical/skills/story-writing/references/example-selection.md +70 -0
- package/ds-canonical/skills/story-writing/references/self-check.md +20 -0
- package/ds-canonical/skills/ux-audit/SKILL.md +130 -0
- package/ds-canonical/skills/visual-audit/SKILL.md +245 -0
- package/ds-canonical/skills/visual-audit/output/.gitkeep +0 -0
- package/ds-canonical/skills/visual-audit/references/audit-architecture.md +100 -0
- package/ds-canonical/skills/visual-audit/references/visual-checklist.md +297 -0
- package/ds-canonical/skills/visual-audit/references/world-class-benchmarks.md +198 -0
- package/package.json +9 -5
- package/src/components/Accordion/accordion.spec.md +114 -0
- package/src/components/Alert/alert.spec.md +197 -0
- package/src/components/AppShell/app-shell.spec.md +331 -0
- package/src/components/AspectRatio/aspect-ratio.spec.md +134 -0
- package/src/components/Avatar/avatar.spec.md +329 -0
- package/src/components/Badge/badge.spec.md +380 -0
- package/src/components/Breadcrumb/breadcrumb.spec.md +257 -0
- package/src/components/BulkActionBar/bulk-action-bar.spec.md +210 -0
- package/src/components/Button/button.spec.md +460 -0
- package/src/components/Calendar/calendar.spec.md +242 -0
- package/src/components/Carousel/carousel.spec.md +253 -0
- package/src/components/Chart/chart.spec.md +155 -0
- package/src/components/Checkbox/checkbox.spec.md +344 -0
- package/src/components/Chip/chip.spec.md +237 -0
- package/src/components/CircularProgress/circular-progress.spec.md +268 -0
- package/src/components/Coachmark/coachmark.spec.md +230 -0
- package/src/components/Combobox/combobox.spec.md +180 -0
- package/src/components/Command/command.spec.md +171 -0
- package/src/components/DataTable/data-table.spec.md +525 -0
- package/src/components/DateGrid/date-grid.spec.md +215 -0
- package/src/components/DatePicker/date-picker.spec.md +334 -0
- package/src/components/DescriptionList/description-list.spec.md +214 -0
- package/src/components/Dialog/dialog.spec.md +202 -0
- package/src/components/DropdownMenu/dropdown-menu.spec.md +250 -0
- package/src/components/Empty/empty.spec.md +214 -0
- package/src/components/Field/field-controls.spec.md +338 -0
- package/src/components/Field/field.spec.md +438 -0
- package/src/components/Field/form-validation.spec.md +152 -0
- package/src/components/FieldControlGroup/field-control-group.spec.md +176 -0
- package/src/components/FileItem/file-item.spec.md +467 -0
- package/src/components/FileUpload/file-upload.spec.md +123 -0
- package/src/components/FileViewer/file-viewer.spec.md +373 -0
- package/src/components/HoverCard/hover-card.spec.md +157 -0
- package/src/components/Input/input.spec.md +193 -0
- package/src/components/LinkInput/link-input.spec.md +130 -0
- package/src/components/Menu/menu-item.spec.md +290 -0
- package/src/components/NameCard/name-card.spec.md +171 -0
- package/src/components/Notice/notice.spec.md +149 -0
- package/src/components/NumberInput/number-input.spec.md +126 -0
- package/src/components/OverflowIndicator/overflow-indicator.spec.md +120 -0
- package/src/components/PeoplePicker/people-picker.spec.md +263 -0
- package/src/components/Popover/popover.spec.md +198 -0
- package/src/components/ProgressBar/progress-bar.spec.md +232 -0
- package/src/components/RadioGroup/radio-group.spec.md +141 -0
- package/src/components/Rating/rating.spec.md +208 -0
- package/src/components/ScrollArea/scroll-area.spec.md +145 -0
- package/src/components/SegmentedControl/segmented-control.spec.md +295 -0
- package/src/components/Select/select.spec.md +299 -0
- package/src/components/SelectMenu/select-menu.spec.md +220 -0
- package/src/components/SelectionControl/selection-item.spec.md +128 -0
- package/src/components/Separator/separator.spec.md +109 -0
- package/src/components/Sheet/sheet.spec.md +148 -0
- package/src/components/Sidebar/sidebar.spec.md +713 -0
- package/src/components/Skeleton/skeleton.spec.md +104 -0
- package/src/components/Slider/slider.spec.md +353 -0
- package/src/components/Steps/steps.spec.md +465 -0
- package/src/components/Switch/switch.spec.md +215 -0
- package/src/components/Tabs/tabs.spec.md +314 -0
- package/src/components/Tag/tag.spec.md +282 -0
- package/src/components/Textarea/textarea.spec.md +151 -0
- package/src/components/TimePicker/time-picker.spec.md +279 -0
- package/src/components/Toast/toast.spec.md +177 -0
- package/src/components/Tooltip/tooltip.spec.md +139 -0
- package/src/components/TreeView/tree-view.spec.md +374 -0
- package/src/patterns/action-bar/action-bar.spec.md +458 -0
- package/src/patterns/element-anatomy/element-anatomy.spec.md +215 -0
- package/src/patterns/element-anatomy/inline-action.spec.md +315 -0
- package/src/patterns/element-anatomy/item-anatomy.spec.md +1042 -0
- package/src/patterns/header-canonical/header-canonical.spec.md +285 -0
- package/src/patterns/horizontal-overflow/horizontal-overflow.spec.md +191 -0
- package/src/patterns/overlay-surface/overlay-surface.spec.md +428 -0
- package/src/patterns/resize-handle/resize-handle.spec.md +109 -0
- package/src/tokens/color/color.spec.md +804 -0
- package/src/tokens/density/density.spec.md +127 -0
- package/src/tokens/elevation/elevation.spec.md +81 -0
- package/src/tokens/layoutSpace/layoutSpace.spec.md +314 -0
- package/src/tokens/motion/motion.spec.md +97 -0
- package/src/tokens/opacity/opacity.spec.md +78 -0
- package/src/tokens/orphan-tokens.spec.md +117 -0
- package/src/tokens/radius/radius.spec.md +123 -0
- package/src/tokens/typography/typography.spec.md +202 -0
- package/src/tokens/uiSize/uiSize.spec.md +438 -0
- package/src/styles/preset.css +0 -31
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
<!-- @benchmark-cited: D5 retrofit 2026-05-18 — verified 0 world-class DS claim in body; blanket retract removed. -->
|
|
2
|
+
|
|
3
|
+
# Inline Action 設計規格(SSOT)
|
|
4
|
+
|
|
5
|
+
**Layout Family**:non-family(hosted inline element,無 own layout — 由宿主 family 1/4 提供)。
|
|
6
|
+
|
|
7
|
+
**定位**:嵌入在其他元件內部的互動觸發點(Tag dismiss / Field endAction / Row suffix action)。不是獨立 Button,由宿主元件渲染 + 控制。
|
|
8
|
+
|
|
9
|
+
**本 spec 是 Inline Action 的獨立 SSOT**(2026-04-24 從 `item-anatomy.spec.md` 抽出,避免單一 spec 過長)。Row primitive 結構走 `item-anatomy.spec.md`;本 spec 含「確定用 Inline Action」後的完整視覺 / API / predicate / same-row consistency 規格。
|
|
10
|
+
|
|
11
|
+
### 視覺規則
|
|
12
|
+
|
|
13
|
+
1. **Icon 視覺尺寸跟隨宿主 tier**,排版以 icon 為準
|
|
14
|
+
2. **平時透明**,視覺上等同靜態 icon
|
|
15
|
+
3. **Hover 時顯示背景色區域**,提示可點擊。背景色區域 = icon + 2px(直徑,即每邊 +1px),不影響排版(用 absolute positioning 或 negative margin 溢出)
|
|
16
|
+
|
|
17
|
+
### 互動狀態
|
|
18
|
+
|
|
19
|
+
與 Button text variant 一致:
|
|
20
|
+
|
|
21
|
+
| 狀態 | 背景 | 過渡 |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| 預設 | transparent | — |
|
|
24
|
+
| hover | `bg-neutral-hover` | transition-colors |
|
|
25
|
+
| active(mouse down) | `bg-neutral-active` | transition-colors |
|
|
26
|
+
| **overlay 開啟**(`data-state=open`)| **同 host hover**(該元件 hover 什麼樣就維持) | transition-colors |
|
|
27
|
+
| focus-visible | `outline: 2px solid var(--ring)` | — |
|
|
28
|
+
| 宿主 disabled | 不渲染 inline action | — |
|
|
29
|
+
|
|
30
|
+
**Overlay trigger canonical**(2026-04-29 訂 / 2026-05-02 改 / 2026-05-05 prop 化):trigger 透過 `asChild` 作 DropdownMenu / Popover / Tooltip / HoverCard trigger 時,Radix 自動 set `data-state="open"`,**trigger 維持 host hover 樣式**直到浮層關閉。對齊**狀態極簡派**(shadcn / Radix Themes / Material — 不另開 4th token);避免 state 增生 + 跨 host(neutral / colored)規則同步。
|
|
31
|
+
|
|
32
|
+
**2026-05-05 修正:overlay vs in-place 語意分離**。`Radix Collapsible.Trigger` 也 emit 同 `data-state="open"`,但語意完全不同(展開內容**接在下方非 floating**,user 不需追溯)。原 `ItemInlineActionButton` 將規則**無條件**套用於所有 `data-state=open`,造成 Sidebar collapsible group label 的 chevron 展開時殘留 hover bg(2026-05-05 user reported)。修正:`ItemInlineActionButton` 加 `overlayTrigger?: boolean` prop,**default `false`**。consumer 顯式宣告:
|
|
33
|
+
|
|
34
|
+
| Consumer 場景 | `overlayTrigger` |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `<DropdownMenuTrigger asChild>` / `<PopoverTrigger asChild>` / `<TooltipTrigger asChild>` / `<HoverCardTrigger asChild>` | `true`(opt-in) |
|
|
37
|
+
| `<CollapsiblePrimitive.Trigger asChild>` | `false`(default) |
|
|
38
|
+
| 純 onClick handler / drag handle / dismiss X | `false`(default) |
|
|
39
|
+
|
|
40
|
+
落實同源:`fieldWrapperStyles data-[state=open]:border-border-hover` 對 Combobox/DatePicker overlay trigger 仍正確(這些只用於 overlay 包覆)。Button 變體的 `data-[state=open]` 規則目前**未 prop 化**(latent — Button 從未被當 `Collapsible.Trigger` asChild 包覆,故無 active bug);若未來出現 Button 包覆 Collapsible 場景,同 prop 化處理。
|
|
41
|
+
|
|
42
|
+
### Icon 色彩(按 host 分兩類,2026-04-21 D6 矛盾解)
|
|
43
|
+
|
|
44
|
+
Inline action icon 色彩規則 **依 host 是否有自帶色彩分兩支**。共同精神:inline action 視覺融入 host — neutral host 的融入方式是「退到 muted」,colored host 的融入方式是「接收 host 色」。
|
|
45
|
+
|
|
46
|
+
**預設(neutral host)**:預設 `fg-muted`,hover / active 時變 `foreground`
|
|
47
|
+
- 適用:Field endAction(Input clear button)/ TreeItem inline action / Menu inline action / DropdownMenu trigger inline action 等 **neutral 容器內**的 inline action
|
|
48
|
+
- 語意:utility icon 是輔助操作,預設退到背景,hover 時提示可操作
|
|
49
|
+
|
|
50
|
+
**例外(colored host)**:**繼承 host 文字色**(非 `fg-muted`)
|
|
51
|
+
- 適用:**Tag dismiss** / 未來任何 **宿主自帶 branded / categorical 色彩** 的 inline action
|
|
52
|
+
- 語意:宿主 bg 有色(Tag subtle blue 底 + blue-text 文字),inline action icon 用 `fg-muted` 會視覺不連貫(視覺斷裂 / 顏色不連貫);繼承 host 文字色維持「一個整體視覺單元」
|
|
53
|
+
- Hover / active 背景:跟 host 同色系的 hover / active token(例 Tag solid blue dismiss → `--blue-hover`)
|
|
54
|
+
|
|
55
|
+
**判斷法**:宿主 bg 是 surface / transparent(neutral)→ 走預設;宿主有 branded / categorical 色彩 → 走 colored host 例外。
|
|
56
|
+
|
|
57
|
+
**現況清單**:
|
|
58
|
+
| Host | 規則分類 | Icon 色 |
|
|
59
|
+
|------|---------|--------|
|
|
60
|
+
| Field / Input / NumberInput / DatePicker / Combobox endAction | neutral host | `fg-muted` → `foreground` |
|
|
61
|
+
| TreeItem / Menu / DropdownMenu inline action | neutral host | `fg-muted` → `foreground` |
|
|
62
|
+
| Tag dismiss | colored host | 繼承 Tag 文字色 |
|
|
63
|
+
|
|
64
|
+
### 尺寸對照
|
|
65
|
+
|
|
66
|
+
| 宿主 | Icon 視覺 | Hover 背景 | 圓角 | 排版佔位 |
|
|
67
|
+
|---|---|---|---|---|
|
|
68
|
+
| Tag sm (20px) | 16px | 18px | rounded-md | 16px |
|
|
69
|
+
| Tag md/lg (24px) | 16px | 18px | rounded-md | 16px |
|
|
70
|
+
| Field sm/md | 16px | 18px | rounded-md | 16px |
|
|
71
|
+
| Field lg | 20px | 22px | rounded-md | 20px |
|
|
72
|
+
| TreeItem sm/md | 16px | 18px | rounded-md | 16px |
|
|
73
|
+
| TreeItem lg | 20px | 22px | rounded-md | 20px |
|
|
74
|
+
| Panel list row(visibility / sort / filter panels)| 16px | 18px | rounded-md | 16px |
|
|
75
|
+
|
|
76
|
+
**Consumer wrapping rule**:當 consumer 包 `ItemInlineActionButton` 在 reserve slot(如 hover-reveal opacity wrapper),**reserve 寬度 = 排版佔位**(sm/md=16,lg=20),**禁止自訂為 24 / 28**(過大會在 cell 留 phantom space)。歷史:DataTable header reserve 24 → 16 修正(2026-04-29)。
|
|
77
|
+
|
|
78
|
+
### 多個 Inline Action 並排
|
|
79
|
+
|
|
80
|
+
當一個宿主有多個 inline action(如 Select 的 clear X + ChevronDown,或 TreeItem 的 ⋯ + +)時:
|
|
81
|
+
|
|
82
|
+
- **間距**:`gap-2`(8px)——跟 fieldWrapperStyles 的元素間距一致(Select 的 clear X 和 ChevronDown 就是 gap-2)
|
|
83
|
+
- **對齊**:全部垂直置中在同一行(`flex items-center`)
|
|
84
|
+
- **出現時機**:全部一起出現(TreeItem 的 hover-reveal 是同時淡入所有 action,不逐個)
|
|
85
|
+
|
|
86
|
+
### API 設計
|
|
87
|
+
|
|
88
|
+
Inline action 由宿主元件渲染,消費者只需宣告 intent:
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
// ❌ 舊:消費者自行決定 Button size、icon size
|
|
92
|
+
<Input endAction={<Button size="xs" iconOnly startIcon={X} aria-label="清除" onClick={...} />} />
|
|
93
|
+
|
|
94
|
+
// ✅ 新:宣告式,Field 自己根據 size tier 渲染
|
|
95
|
+
<Input endAction={{ icon: X, label: '清除', onClick: handleClear }} />
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Field 內部根據自己的 size 決定 icon 尺寸、hover 背景大小、視覺層級。消費者不需要知道這些。
|
|
99
|
+
|
|
100
|
+
### 實作要求
|
|
101
|
+
|
|
102
|
+
- 必須是 `<button>` 元素,不是 `<span>` + onClick
|
|
103
|
+
- 必須有 `aria-label`
|
|
104
|
+
- 必須有 `cursor-pointer`——可點擊的元素必須有明確的游標指引
|
|
105
|
+
- 必須有 Tooltip(`label` 欄位同時作為 `aria-label` 和 tooltip 內容)——icon-only 控件沒有可見文字,tooltip 是使用者理解功能的唯一視覺提示
|
|
106
|
+
- 宿主 disabled 時不渲染(不可操作就不該暗示可以操作)
|
|
107
|
+
|
|
108
|
+
### Predicate:Inline Action vs Button iconOnly(canonical)
|
|
109
|
+
|
|
110
|
+
DS 跨元件 icon action primitive 的 canonical。接到 icon 相關決策,跑下面決策樹。
|
|
111
|
+
|
|
112
|
+
#### 三種 icon primitive 的身份
|
|
113
|
+
|
|
114
|
+
| Primitive | 定義 | 實作 |
|
|
115
|
+
|-----------|------|------|
|
|
116
|
+
| **Decorative indicator** | 純視覺提示(點了不做事,host 是 click target)| Host 內 `<Icon aria-hidden pointer-events-none />` |
|
|
117
|
+
| **Inline Action** | **可點擊的 icon**,embedded 在 host 內部(content flow / chrome padding)| `ItemInlineAction` / `ItemInlineActionButton`(詳下方 API 區)|
|
|
118
|
+
| **Button** | **獨立按鈕**,有 chrome,可參與 action group | `<Button iconOnly />`(詳 button.spec.md)|
|
|
119
|
+
|
|
120
|
+
#### 決策樹(3 步)
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
Q1. icon 點了要做事嗎?
|
|
124
|
+
├─ 否 → Decorative indicator(host 內 <Icon aria-hidden />,本 spec 不討論)
|
|
125
|
+
└─ 是 ↓
|
|
126
|
+
Q2. 位置在哪?
|
|
127
|
+
├─ Host 內部(chrome padding / content flow / row inline suffix)→ Inline Action
|
|
128
|
+
├─ Row 獨立 action slot(跟 content 視覺分開,有獨立 column/分隔線)→ 看 Q3
|
|
129
|
+
└─ Action group region(toolbar / chrome corner / standalone)→ Button
|
|
130
|
+
Q3. Row 多大?
|
|
131
|
+
├─ ≤ 24(compact / xs row)→ Inline Action(Button xs 24 填滿 row,無呼吸)
|
|
132
|
+
└─ ≥ 28(sm/md/lg row)→ Button iconOnly xs(固定 24,不隨 row 放大)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### Row action 絕對值 cap(核心原則)
|
|
136
|
+
|
|
137
|
+
**Row dedicated action 永遠 ≤ 24px**,不隨 row tier 放大。超過 24 action 會搶 content 視覺焦點,違反「資料 > 行動」的視覺階層。
|
|
138
|
+
|
|
139
|
+
**世界級對照**:Material DataGrid / Polaris ResourceList / Atlassian Table / Ant Design Table / Apple HIG — **全部固定小尺寸 icon button**,不依 row height 放大 action。
|
|
140
|
+
|
|
141
|
+
#### 3 條關鍵補充
|
|
142
|
+
|
|
143
|
+
1. **Inline Action 不參與 action group 規則** — 沒有 Button 的 variant chrome / Separator 分群 / size 對稱要求;只是 host 內部 tap target
|
|
144
|
+
2. **Button 必對齊 action group 規則** — 同 size、Separator 分群(詳 `patterns/action-bar.spec.md`)
|
|
145
|
+
3. **Dismiss X(close)特殊弱化** — Inline Action default 已 `fg-muted`;Button 需加 `dismiss` prop 才 override(詳本 spec 下方 dismiss 節)
|
|
146
|
+
|
|
147
|
+
#### Real case 表(所有 DS 用法一覽)
|
|
148
|
+
|
|
149
|
+
| Host | Context | Primitive | Why |
|
|
150
|
+
|------|---------|-----------|-----|
|
|
151
|
+
| Input / NumberInput / Combobox clear X | Field chrome padding | Inline Action | Embedded |
|
|
152
|
+
| Tag dismiss X | Pill body | Inline Action(colored host 繼承色)| Embedded |
|
|
153
|
+
| Menu / TreeView / SidebarMenuButton / SelectionItem suffix | Row inline flow | Inline Action | Inline with content |
|
|
154
|
+
| SidebarGroup header chevron | Aux toggle | Inline Action | Inline header toggle |
|
|
155
|
+
| Select ChevronDown / DatePicker Calendar / Combobox ChevronDown | Field chrome(裝飾)| **Decorative**(不是 action)| Click falls through;host 是 trigger |
|
|
156
|
+
| **FileItem compact**(row 24)| Row slot | Inline Action | Row 太小容不下 Button xs 24 |
|
|
157
|
+
| **FileItem rich**(row 56 sm/md rich)| Row slot | Button xs iconOnly(24 固定)| ≤ 24 cap,不放大 |
|
|
158
|
+
| **DataTable header cell internal**(sort indicator / ⌄ menu / filter funnel / pin)| Header cell host internal | **Inline Action**(`ItemInlineActionButton` asChild for DropdownMenu)| Embedded inline,跟 label 一體 |
|
|
159
|
+
| **DataTable body cell internal**(display endAction / clear / edit indicator)| Cell content host internal | **Inline Action**(自動繼承 Field family endAction)| Field display 元件已對齊 |
|
|
160
|
+
| **DataTable row dedicated action column**(編輯 / 刪除 / 更多 ⋯)| Row dedicated column | Button xs iconOnly(24 固定)| ≤ 24 cap;有獨立 column divider 視覺分離 |
|
|
161
|
+
| **Breadcrumb 中段折疊 ⋯**(`BreadcrumbEllipsis`)| BreadcrumbList row inline flow(host 內)| **Inline Action**(`ItemInlineActionButton` `size="md"` + `overlayTrigger` + asChild for DropdownMenuTrigger)| Embedded inline,跟 BreadcrumbLink 同 row;14-16px text row(compact tier);click 展開 DropdownMenu(2026-05-10 重寫,自刻 button retired)|
|
|
162
|
+
| **Dialog / Sheet / Popover / Alert corner close** | Chrome corner | Button iconOnly `dismiss`(size sm)| Action group region |
|
|
163
|
+
| **Toolbar commands**(FileViewer zoom / editor bold)| Toolbar | Button iconOnly(md 常見)| Action group region |
|
|
164
|
+
| FileViewer / rich text editor formatting group | Toolbar action group | Button iconOnly 同 size + Separator | Action group 完整範例 |
|
|
165
|
+
|
|
166
|
+
#### Content-role vs action-role 分層(附補充原理)
|
|
167
|
+
|
|
168
|
+
Row 內元件分兩類,**size 規則不同**:
|
|
169
|
+
- **Content-role**(display 資料):`<Input mode="display">` / Badge / Avatar / Tag → size 對應 row tier(sm row → sm)
|
|
170
|
+
- **Action-role**(互動觸發):row action icon → **固定 ≤ 24**,不參與 content size-pair
|
|
171
|
+
|
|
172
|
+
Row action 的 affordance 是「次要功能」,不是 primary CTA。Button chrome 過度強調;用 **Button xs 24 固定** 提供 command affordance 但不侵蝕 content hierarchy。
|
|
173
|
+
|
|
174
|
+
### Same-row consistency rule(防混用)
|
|
175
|
+
|
|
176
|
+
**同一 row 所有 icon action 必同一類**(不混 Inline Action + Button)— 消除 box size 不一致造成 gap 斷裂(InlineAction 16+18 vs Button text sm 28)。
|
|
177
|
+
|
|
178
|
+
**範例(panel list row 內 inline action)**:
|
|
179
|
+
```
|
|
180
|
+
✅ DataTable column visibility row(panel list):
|
|
181
|
+
[⋮⋮ drag] [label] [👁️ toggle] ← 全 ItemInlineActionButton size=md(16+18 hover bg)
|
|
182
|
+
|
|
183
|
+
❌ 混用 anti-pattern:
|
|
184
|
+
[⋮⋮ ItemInlineActionButton] [label] [Button text sm Eye 28x28] ← box size 不一致 gap 斷裂
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**chrome corner action group(Alert / Toast / Dialog / Popover header corner)** 屬 **Button family**(action group region,不是 inline action)。Canonical 不在本 spec — 詳:
|
|
188
|
+
- 尺寸:`patterns/overlay-surface/overlay-surface.spec.md`「Chrome dismiss size canonical」(overlay sm + v5 trick / banner xs explicit)
|
|
189
|
+
- variant / divider:`patterns/action-bar/action-bar.spec.md`(corner action group)
|
|
190
|
+
|
|
191
|
+
### Inline action 共用元件(`ItemInlineAction` / `ItemSuffix`)
|
|
192
|
+
|
|
193
|
+
Canonical 實作於 `item-anatomy.tsx`,匯出 `ItemInlineAction` / `ItemSuffix`(從 `RowSizeContext` 自動查 icon size / hover bg / tooltip / aria-label / fg-muted → foreground 全內建)。
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
// 單一 action
|
|
197
|
+
<ItemInlineAction action={{ icon: X, label: '清除', onClick: handleClear }} />
|
|
198
|
+
// 多個 + hover-reveal
|
|
199
|
+
<ItemSuffix hoverReveal>{actions.map((a) => <ItemInlineAction action={a} />)}</ItemSuffix>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Host 走宣告式 API**(`inlineActions?: InlineActionConfig[]` prop)— 不自刻 button JSX。已遷移:`SidebarMenuButton`。Pending refactor:`Input` / `NumberInput` / `Tag` / `LinkInput` / `Combobox`。
|
|
203
|
+
|
|
204
|
+
### Dismiss canonical — X close only
|
|
205
|
+
|
|
206
|
+
**Dismiss 語意嚴格定義**:「**關閉 surface / 忽略訊息**」— **只屬 X(close)icon**。
|
|
207
|
+
|
|
208
|
+
**不是 dismiss 的情境**(常被誤判):
|
|
209
|
+
- Trash / Delete / Remove — destructive action(破壞性移除),不是 dismiss
|
|
210
|
+
- Clear — 欄位清空(value 設 empty,元件本身不關),不是 dismiss
|
|
211
|
+
- 以上三者**禁止套 dismiss 弱化**
|
|
212
|
+
|
|
213
|
+
**世界級對照**:
|
|
214
|
+
- Dismiss:Material `IconButton` close / Polaris `Banner.onDismiss` / Ant Design `Alert.closable` / Apple HIG window close → 一律 icon = `X`
|
|
215
|
+
- Destructive:Material `IconButton` Delete(red)/ Polaris `Button destructive` / 我們的 row Trash → 一般 primitive(無 dismiss 弱化)
|
|
216
|
+
|
|
217
|
+
#### Dismiss X 的實作(按 position 決定)
|
|
218
|
+
|
|
219
|
+
| 位置 | 實作 | 視覺弱化 |
|
|
220
|
+
|------|------|---------|
|
|
221
|
+
| Chrome corner(Dialog / Sheet / Popover / Alert / Toast / Coachmark 右上 X)| **Button iconOnly + `dismiss` prop**(Cat 3)| `dismiss` prop 套 fg-muted override |
|
|
222
|
+
| Host chrome padding 內(Input clear X / Tag 內 X)| **Inline Action**(Cat 1)| default 已 fg-muted(內建)|
|
|
223
|
+
| 獨立 standalone close(罕見)| **Button iconOnly + `dismiss` prop**(Cat 3)| `dismiss` prop 套 fg-muted override |
|
|
224
|
+
|
|
225
|
+
#### `dismiss` prop 觸發條件(Button 限定)
|
|
226
|
+
|
|
227
|
+
**明示**:`<Button dismiss />` 或 callback = `onClose` / `onDismiss` → 觸發弱化 override(icon fg-muted → hover foreground;variant 強制 text)
|
|
228
|
+
|
|
229
|
+
**不觸發**:callback = `onRemove`(collection 操作)/ `onClear`(欄位清空)/ `onDelete` — 這些不是 dismiss 語意,Button 用對應 variant 即可
|
|
230
|
+
|
|
231
|
+
#### Colored host 例外(Tag 內 X)
|
|
232
|
+
|
|
233
|
+
Tag solid / branded color variant(`red / blue / orange`)→ Tag 內 X **繼承 host 文字色**(非 fg-muted),hover bg 配色相。詳「Icon 色彩原則」段。
|
|
234
|
+
|
|
235
|
+
#### ❌ 禁止
|
|
236
|
+
|
|
237
|
+
- 帶文字 label 的 Button 作 dismiss(「關閉」字按鈕)— 雙重 affordance
|
|
238
|
+
- 自刻 `<button><X /></button>` — 繞過 `ItemInlineAction` / Button `dismiss` 的 a11y + 尺寸自動化
|
|
239
|
+
- **Trash / Clear / Delete 套 `dismiss` prop** — 語意誤用,destructive 本身已有破壞性意涵不需再弱化
|
|
240
|
+
- Button dismiss 用 `variant="primary/secondary/tertiary"` — `dismiss` prop 強制 `variant="text"`
|
|
241
|
+
- Chrome corner close 用 Inline Action — corner 屬 action group region,必用 Button
|
|
242
|
+
|
|
243
|
+
#### 第三方 managed 不是例外
|
|
244
|
+
|
|
245
|
+
sonner toast auto-dismiss / Radix Dialog `DialogClose` wiring — 第三方只管 state logic(何時關),**我們渲染的視覺按鈕必套對應 canonical**(chrome corner → Button dismiss;chrome padding → Inline Action)。
|
|
246
|
+
|
|
247
|
+
hook `check_story_anatomy.sh` 規則 B 已在 stories 層攔 label Button 作 dismiss。
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Escape hatch — config 表達不出時的 10% case
|
|
252
|
+
|
|
253
|
+
**90% case 走 `InlineActionConfig` 宣告式 API**(host 根據 size tier 自動渲染 — 視覺一致 / a11y 內建 / drift 杜絕)。
|
|
254
|
+
|
|
255
|
+
少數 config 結構表達不出的場景:
|
|
256
|
+
- 自訂 popover trigger(DropdownMenuTrigger asChild + 自家 anchor)
|
|
257
|
+
- 多 tier 動作(stepper button group / 多個 chevron)
|
|
258
|
+
- 跟 host 自帶 chrome 互動的元素(如 Combobox 的 ChevronDown 不屬 endAction)
|
|
259
|
+
|
|
260
|
+
**Canonical**:每個 inline-action host 必須提供 `xxxSlot?: React.ReactNode` 作 escape hatch:
|
|
261
|
+
|
|
262
|
+
| Host family | Config prop | Escape hatch slot prop |
|
|
263
|
+
|---|---|---|
|
|
264
|
+
| Field family(Input / NumberInput / DatePicker / Combobox / LinkInput / TimePicker) | `endAction?: InlineActionConfig` | `endSlot?: React.ReactNode` |
|
|
265
|
+
| Row family(TreeView.TreeItem / SidebarMenuButton)| `inlineActions?: InlineActionConfig[]` | `inlineActionsSlot?: React.ReactNode` |
|
|
266
|
+
|
|
267
|
+
```tsx
|
|
268
|
+
// ✅ 90% case
|
|
269
|
+
<Input endAction={{ icon: X, label: '清除', onClick: handleClear }} />
|
|
270
|
+
<TreeItem inlineActions={[{ icon: MoreVertical, label: '更多', onClick: ... }]} />
|
|
271
|
+
|
|
272
|
+
// ✅ 10% case(escape hatch)
|
|
273
|
+
<Input endSlot={<DropdownMenuTrigger asChild><MyChevron /></DropdownMenuTrigger>} />
|
|
274
|
+
<TreeItem inlineActionsSlot={<MyCustomActionGroup />} />
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**規則**:
|
|
278
|
+
- Slot 跟 config 互斥(slot 優先,config 被忽略)
|
|
279
|
+
- `disabled / readonly` 模式 / Sidebar `collapsible=icon` 模式跟 config 一致(slot 也要被相同條件隱藏)
|
|
280
|
+
- Reveal 模式(`actionsReveal="hover"`)、絕對定位 chrome 跟 config 共用,consumer 不需重做
|
|
281
|
+
- Padding budget(Sidebar)slot mode 預設按 1 icon 寬度預留,多 icon 寬度需 consumer 自控 className
|
|
282
|
+
- 視覺一致性 by consumer — 但 **app-code 不可直接 import L3 primitive**(`ItemInlineActionButton` / `ItemInlineAction` / `RowSizeProvider`),由 `check_l3_primitive_import.sh` 攔截。需要視覺一致 inline-action button 時,(a) 用 host 自帶 slot(此 escape hatch)、(b) 用 `<Button iconOnly variant="text" />`、(c) 走 spec rationale 例外申請
|
|
283
|
+
|
|
284
|
+
**現況清單**(2026-04-25 補完):
|
|
285
|
+
- ✅ `Input.endSlot`
|
|
286
|
+
- ✅ `NumberInput.endSlot`
|
|
287
|
+
- ✅ `TreeView.TreeItem.inlineActionsSlot`
|
|
288
|
+
- ✅ `SidebarMenuButton.inlineActionsSlot`
|
|
289
|
+
|
|
290
|
+
**不適用清單**:DatePicker / Combobox / Select / TimePicker / LinkInput 右側由元件自帶 chrome 獨佔(Calendar / ChevronDown / Clock / ExternalLink 等 intrinsic affordance),不開放 consumer 放置 endAction/endSlot — 這些元件的 inline-action 需求走**內建 clear X**(consumer 透過 `clearable` prop opt-in)或 `<Button iconOnly />` 放在 Field 外側。Escape hatch canonical 不涵蓋此類 host(本質上非 consumer-facing slot)。
|
|
291
|
+
|
|
292
|
+
**世界級對照**:
|
|
293
|
+
- Material UI:`InputAdornment` ReactNode slot(無 config,純 escape hatch 派 — 我們的 90/10 比 Material 更有結構)
|
|
294
|
+
- Polaris:`TextField.connectedRight` ReactNode 只接 Button,但無 config-based 簡化,API 一致性差
|
|
295
|
+
- Ant Design:`Input.suffix` ReactNode slot,跟 Material 同派
|
|
296
|
+
- Atlassian:`Textfield.elementAfterInput` ReactNode
|
|
297
|
+
|
|
298
|
+
我們採「config-first + slot escape hatch」屬刻意 deviation,rationale:90% case 宣告式 API 阻止 visual drift / a11y 漏失;10% case 仍提供逃生口,不強迫 consumer fork 元件。
|
|
299
|
+
|
|
300
|
+
## 被引用(auto-maintained,Dim 3 reciprocal audit)
|
|
301
|
+
|
|
302
|
+
> 本節由 `scripts/add-reciprocal-pointers.mjs` 自動維護,列出在 SSOT 語境下指向本 spec 的其他 spec。若要手動補充,寫在本節之前。
|
|
303
|
+
|
|
304
|
+
- `alert.spec.md`
|
|
305
|
+
- `breadcrumb.spec.md`
|
|
306
|
+
- `button.spec.md`
|
|
307
|
+
- `data-table.spec.md`
|
|
308
|
+
- `field-controls.spec.md`
|
|
309
|
+
- `popover.spec.md`
|
|
310
|
+
|
|
311
|
+
## 被引用(auto-maintained,Dim 3 reciprocal audit)
|
|
312
|
+
|
|
313
|
+
> 本節由 `scripts/add-reciprocal-pointers.mjs` 自動維護,列出在 SSOT 語境下指向本 spec 的其他 spec。若要手動補充,寫在本節之前。
|
|
314
|
+
|
|
315
|
+
- `sheet.spec.md`
|