@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,458 @@
|
|
|
1
|
+
<!-- @benchmark-cited: D5 retrofit 2026-05-18 — verified 0 world-class DS claim in body; blanket retract removed. -->
|
|
2
|
+
|
|
3
|
+
# Action Bar 設計原則
|
|
4
|
+
|
|
5
|
+
> **Foundational SSOT rationale**(cap 800,2026-04-25 approved):
|
|
6
|
+
> 跨 pattern operations / utilities 角色系統 SSOT。Toolbar / DataTable / FileViewer / Dialog 等 action region 皆消費本 spec 的 overflow mechanics / section divider rules / primary 位置 / danger placement。scope 本質 > 單一 pattern。
|
|
7
|
+
|
|
8
|
+
## 定位
|
|
9
|
+
|
|
10
|
+
**Layout Family**:composite(cross-pattern;consumed by Toolbar / DataTable / FileViewer / Dialog 等 action region)。本 pattern 為 role system + overflow mechanics SSOT,非單一 layout family。
|
|
11
|
+
|
|
12
|
+
操作列(Action Bar)是在有限空間內組合多個操作的排列模式,涵蓋 Toolbar、卡片操作列、對話框操作區等場景。
|
|
13
|
+
|
|
14
|
+
本文件定義:操作的語意角色、視覺 pattern、Variant 選擇、分群與分隔線、溢出機制。
|
|
15
|
+
Button 元件層規則(variant、size、icon、狀態)見 `button.spec.md`。
|
|
16
|
+
|
|
17
|
+
## 世界級對照(按 pattern 類型)
|
|
18
|
+
|
|
19
|
+
| 我們的 canonical | 對照 world-class |
|
|
20
|
+
|------------------|-----------------|
|
|
21
|
+
| Toolbar(純工具按鈕群)| Material Toolbar / VS Code EditorToolbar / Figma ToolbarLeft / Atlassian Appbar |
|
|
22
|
+
| Action bar(業務操作列,primary CTA 結尾)| Polaris `ActionList / PageActions` / Linear Cmd+K bar / GitHub `toolbar` + `Save` grouping |
|
|
23
|
+
| Search + filter(左搜尋右操作)| Gmail inbox toolbar / Linear list toolbar / Notion DB toolbar |
|
|
24
|
+
| Overflow rule(space 不足)| Material M3 menu anchor / Atlassian overflow menu |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 一、角色系統
|
|
29
|
+
|
|
30
|
+
操作列中的所有操作分為兩種語意角色。**角色決定視覺 pattern 與位置。**
|
|
31
|
+
|
|
32
|
+
### 業務操作(Operations)
|
|
33
|
+
|
|
34
|
+
**使用者在此功能脈絡下,為完成目標所採取的一切操作。**
|
|
35
|
+
|
|
36
|
+
> 判斷標準:移除這個操作,使用者是否無法完成他來這裡要做的事?是 → 業務操作。
|
|
37
|
+
|
|
38
|
+
| 類型 | 範例 |
|
|
39
|
+
|------|------|
|
|
40
|
+
| 內容 CRUD | 新增、編輯、刪除、封存 |
|
|
41
|
+
| 資料操作 | 篩選、排序、分組、搜尋 |
|
|
42
|
+
| 資料流 | 匯入、匯出、列印 |
|
|
43
|
+
| 協作 | 分享、指派、留言 |
|
|
44
|
+
| 狀態推進 | 發佈、送審、完成 |
|
|
45
|
+
|
|
46
|
+
### 工具操作(Utilities)
|
|
47
|
+
|
|
48
|
+
**支援工作條件的操作,而非執行功能的核心工作。**
|
|
49
|
+
|
|
50
|
+
> 判斷標準:這個操作跟「現在在做什麼任務」無關,任何頁面都可能有它?是 → 工具操作。
|
|
51
|
+
|
|
52
|
+
| 類型 | 範例 |
|
|
53
|
+
|------|------|
|
|
54
|
+
| 環境調整 | 全螢幕、縮放、密度切換 |
|
|
55
|
+
| 系統維護 | ↺ 刷新、重新載入 |
|
|
56
|
+
| 全域設定 | ⚙ 設定 |
|
|
57
|
+
| 輔助資源 | ? 說明文件、FAQ(外部連結亦同) |
|
|
58
|
+
|
|
59
|
+
### Search 的角色判斷
|
|
60
|
+
|
|
61
|
+
Search 的角色**不由「產品核心是不是搜尋」決定**,而由——
|
|
62
|
+
|
|
63
|
+
> **結果如何被使用?**
|
|
64
|
+
> - 點擊結果**跳走**(wayfinding) → **工具**
|
|
65
|
+
> - 結果**留在當前頁被操作**(filter、bulk action) → **業務**
|
|
66
|
+
|
|
67
|
+
| Search 類型 | 角色 | 代表 |
|
|
68
|
+
|-------------|------|------|
|
|
69
|
+
| 過濾當前視圖的資料 | **業務** | Data table / Kanban / list 的搜尋框,和 filter / sort / group 同類 |
|
|
70
|
+
| 跨頁跳轉(結果點擊後跳走) | **工具** | App header search、Cmd+K、跨 workspace 文件 search |
|
|
71
|
+
| 搜尋結果頁面(結果是操作對象) | **業務** | 結果頁本身支援圈選、批次處理;搜尋是進入該操作流程的入口 |
|
|
72
|
+
|
|
73
|
+
**Gmail 陷阱**:Gmail 核心任務是處理信件,但 header search 點擊結果後跳去那封信——是 wayfinding,是**工具**。把「產品核心」當判斷依據會讓所有 search 都算成業務,角色分類失效。
|
|
74
|
+
|
|
75
|
+
**擺放**:
|
|
76
|
+
- 業務 search → 業務層,和 filter / sort / group 同區
|
|
77
|
+
- 工具 search → 通常不在 action bar 內(放 app header 或快捷鍵);若必須放 action bar,放工具層最右側
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 二、標準結構
|
|
82
|
+
|
|
83
|
+
**工具層的位置由空間慣例決定,不由業務層排序推導。**
|
|
84
|
+
工具層永遠在操作列最右側(LTR 語境),不隨對齊方式或業務層內容改變。
|
|
85
|
+
|
|
86
|
+
> 為什麼:使用者對工具操作(設定、刷新、溢出)建立的是**位置記憶**,不是視覺掃描。位置一致比排序邏輯的對稱性更重要。
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
┌──────────────────────────┐ ┆ ┌──────────────────────┐
|
|
90
|
+
│ 業務操作群組 │ ┆ │ 工具操作 溢出 │
|
|
91
|
+
└──────────────────────────┘ ┆ └──────────────────────┘
|
|
92
|
+
Operations tier Utilities tier
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
兩種對齊的差異只在業務層內部排序方向,工具層位置不變:
|
|
96
|
+
|
|
97
|
+
**靠右對齊 Toolbar**(最常見):
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
業務操作(primary 在業務層最右) ┆ 工具操作 全域溢出
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**靠左對齊**:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
業務操作(primary 在業務層最左) ┆ 工具操作 全域溢出
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**對齊方向的決定**:操作列有標題時,標題在左、按鈕靠右(最常見)。操作列沒有標題時,按鈕靠左——空白放在右邊不會造成視覺斷裂,但空白放在左邊會讓按鈕群組像是漂在半空。
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 三、Variant 與排序
|
|
114
|
+
|
|
115
|
+
### 業務操作
|
|
116
|
+
|
|
117
|
+
| | |
|
|
118
|
+
|--|--|
|
|
119
|
+
| **允許 variant** | primary、secondary、tertiary、text、checked(`link` 是導覽語意,不屬於操作列) |
|
|
120
|
+
| **Variant 選擇** | 以有框 variant(primary、secondary、tertiary、checked)為主,`text` 用於視覺重量最低的輔助操作。有框操作定義「這是操作區的重心」,text 是補充,不是預設。 |
|
|
121
|
+
| **全局排序** | 先對所有可見業務按鈕做全局排序:`primary > secondary > tertiary > text`;靠右對齊時 primary 在業務層最右,靠左對齊時 primary 在業務層最左(工具層永遠在業務層右側,見第二節)。正確排序後有框操作自然在前、text 在後,不需要額外的集中規則。切換按鈕(text ↔ checked)依預設(未啟用)狀態的 variant 決定排序位置 |
|
|
122
|
+
| **danger 位置** | `danger` 不影響跨 variant 排序。同 variant 內,danger 排在非 danger 之後(遠離主要焦點)。`primary+danger` 不受此規則影響——在刪除確認等場景中,破壞性操作本身就是主要動作 |
|
|
123
|
+
| **danger 可見性** | 破壞性操作預設收進溢出選單。只有同時滿足**高頻**(使用者每次進入此畫面都可能用到)且**可逆**(有 undo 或垃圾桶機制)時,才值得攤開為可見按鈕。頻率不夠高或不可逆的破壞性操作,攤開只會增加誤觸風險(Gmail 的教訓:Delete 從預設可見改為隱藏,因為誤觸是最大客訴) |
|
|
124
|
+
| **功能性分群** | 排序完成後,依功能關係在適當位置加分隔線形成群組;**不要先定義群組再各自排序**(會導致多個 primary 競爭焦點) |
|
|
125
|
+
| **溢出位置** | 溢出按鈕(···)排除在全局排序之外,永遠放在所屬群組末端或工具層末端 |
|
|
126
|
+
| **Size** | Toolbar 用小尺寸維持緊湊;form / dialog 用中尺寸配合表單元素的高度 |
|
|
127
|
+
|
|
128
|
+
**可配置資料操作**(篩選、排序、分組)的 variant 建議:
|
|
129
|
+
|
|
130
|
+
| 狀態 | Variant | Label |
|
|
131
|
+
|------|---------|-------|
|
|
132
|
+
| 未配置 | `text`(預設,在 Toolbar 脈絡下)/`tertiary`(脈絡不明確時,見下方 affordance 原則) | 通常 icon-only;脈絡不明確時補 label |
|
|
133
|
+
| 已配置 / 啟用 | `checked`(`data-state=on`) | icon-only |
|
|
134
|
+
|
|
135
|
+
篩選、排序、分組三個圖示(Filter、ArrowUpDown、Layers)在資料表格脈絡下意義唯一,Toolbar 場景通常全程 icon-only。
|
|
136
|
+
|
|
137
|
+
**Checked 狀態的視覺依底層 variant 而變**:
|
|
138
|
+
- `text` + `data-state=on` → `bg-neutral-selected`(灰底 + 原色 icon),低調但仍可辨識
|
|
139
|
+
- `tertiary` + `data-state=on` → `bg-primary-subtle` + `text-primary`(藍底 + 藍色 icon),存在感更強
|
|
140
|
+
|
|
141
|
+
**Variant 選擇 narrow scope**(2026-05-20 codex Layer B D1 verdict + WebFetch ≥ 5 world-class):
|
|
142
|
+
|
|
143
|
+
| Context | Variant | Cite |
|
|
144
|
+
|---|---|---|
|
|
145
|
+
| **DataTable / Kanban / list 等 dense always-visible data toolbar** filter / sort / column controls | **`text` + pressed** + iconOnly + Popover wrap real panel(DataTableFilterPanel / DataTableSortManager) | `data-table.stories.tsx#WithBulkActions L998` SSOT |
|
|
146
|
+
| **Standalone / labeled** sole state carrier(toolbar 外 / 單獨 filter UI 非 DataTable context) | `tertiary` + pressed | 視 case |
|
|
147
|
+
| 純動作工具(無 state)/ 低重量輔助 | `text` | 既有 default |
|
|
148
|
+
|
|
149
|
+
**Rationale**:dense data toolbar 已自帶 affordance + active state 由 pressed/chips/badges 顯示,trigger 用 low visual weight `text` 不該放大重量。`tertiary` 反而留給 standalone 場景(無 toolbar 上下文,trigger 是唯一 state carrier)。
|
|
150
|
+
|
|
151
|
+
**World-class consensus(2026-05-20 WebFetch verified)**:
|
|
152
|
+
- MUI Data Grid toolbar = `baseIconButton`(text-equivalent)/ active filters 用 toolbar chips 顯示
|
|
153
|
+
- Polaris IndexFilters = toggle button + panel,active filters 用 badges/tags
|
|
154
|
+
- Carbon dense toolbar = icon-only button + ghost variant
|
|
155
|
+
- Linear filter button = low weight + filter chips 顯示 conditions
|
|
156
|
+
- Notion DB view settings = compact button + 不放大重量
|
|
157
|
+
|
|
158
|
+
**舊 wording**(retired 2026-05-20):「filter/sort 狀態是 toolbar 重點資訊 → tertiary」過寬,導致 DataTable scope 誤用 tertiary;canonical 已 narrow 到 standalone-only。
|
|
159
|
+
|
|
160
|
+
### 工具操作
|
|
161
|
+
|
|
162
|
+
| 子類型 | Variant |
|
|
163
|
+
|--------|---------|
|
|
164
|
+
| 純動作工具(點了就執行,無當前狀態) | `text` |
|
|
165
|
+
| 可切換工具(全螢幕等)— 未啟用 | `text` |
|
|
166
|
+
| 可切換工具 — 已啟用 | `checked` |
|
|
167
|
+
|
|
168
|
+
**不允許**:primary、secondary(工具層必須是操作列中最低視覺重量)。`danger` 不適用於工具層——破壞性操作一定是對物件的業務操作,不是環境調整。
|
|
169
|
+
|
|
170
|
+
**層內排序**:固定工具在前,全域溢出永遠最末。
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## 三之一、tertiary vs text 的選擇(affordance 原則)
|
|
175
|
+
|
|
176
|
+
`tertiary` 和 `text` 的差別**不是重要性程度,是 affordance 來源**:
|
|
177
|
+
|
|
178
|
+
- **`tertiary` = 自帶 affordance**:按鈕用自己的框主動告訴使用者「這是可點的」
|
|
179
|
+
- **`text` = 借用脈絡 affordance**:按鈕依賴周圍脈絡暗示可點
|
|
180
|
+
|
|
181
|
+
### 判斷標準
|
|
182
|
+
|
|
183
|
+
**這顆按鈕所在的位置,脈絡本身已經暗示「這裡可以點」了嗎?**
|
|
184
|
+
|
|
185
|
+
| 脈絡暗示可點? | 代表場景 | 選 |
|
|
186
|
+
|----------------|----------|-----|
|
|
187
|
+
| ✅ 是 | Toolbar、Table row hover、Card 的 action 區、已標記的 button group、Sidebar 內部操作 | **text** |
|
|
188
|
+
| ❌ 否 | Dialog footer、Empty state、Form 主區塊的次要動作、獨立頁面中孤立出現的 dropdown trigger | **tertiary** |
|
|
189
|
+
|
|
190
|
+
**為什麼**:若脈絡已經暗示可點,每顆按鈕再自帶框 = 視覺雜訊重複,搶走主要焦點;若脈絡沒暗示,`text` 按鈕會被當成純文字標籤看不見。
|
|
191
|
+
|
|
192
|
+
### 常見應用
|
|
193
|
+
|
|
194
|
+
| 情境 | Variant | 原因 |
|
|
195
|
+
|------|---------|------|
|
|
196
|
+
| Dialog Cancel / Back | **tertiary** | Footer 區域本身沒有點擊暗示,每顆按鈕要自帶 affordance |
|
|
197
|
+
| Toolbar 的 Filter / Sort / View icons | **text** | Toolbar 是明確的操作區,脈絡已暗示可點 |
|
|
198
|
+
| Table row 的 Edit / Delete | **text** | Row hover + 末端位置已是強線索 |
|
|
199
|
+
| Empty state 的次要 CTA | **tertiary** | 按鈕漂浮在空白中,無脈絡線索 |
|
|
200
|
+
| Dropdown trigger(Sort by ↓)在 Toolbar 內 | **text** | 借用 Toolbar 脈絡 |
|
|
201
|
+
| Dropdown trigger 獨立出現在 page header | **tertiary** | 沒有 Toolbar 脈絡包覆,需自帶框 |
|
|
202
|
+
| 可配置資料操作(filter/sort/group)在 Toolbar 的預設狀態 | **text** | 借用 Toolbar 脈絡 |
|
|
203
|
+
|
|
204
|
+
### 推論
|
|
205
|
+
|
|
206
|
+
- **同一顆按鈕搬家可能換 variant**:從 empty state 搬進 toolbar → tertiary 變 text。判斷依據不是按鈕本身,是它所處的脈絡
|
|
207
|
+
- **成對出現不等於按鈕群**:Dialog 的 Cancel + Confirm 是兩顆,但 footer 區沒有脈絡暗示,兩顆都需要自帶 affordance——Cancel 仍是 tertiary、Confirm 仍是 primary,不會因為「成對」就變成 text 群組
|
|
208
|
+
- **Toolbar 的工具按鈕群全程 text**:即使其中某顆被提升為 `tertiary` 想要加強可操作性,也要謹慎——它會在一排 text 按鈕中變得突兀。通常寧可全員 text + hover 狀態強化,也不要混合
|
|
209
|
+
|
|
210
|
+
### 反例
|
|
211
|
+
|
|
212
|
+
❌ **Toolbar 內用 tertiary 加強「可操作性」**
|
|
213
|
+
```
|
|
214
|
+
[🔽 tertiary] [👁 tertiary] [+ New (primary)] [⋯]
|
|
215
|
+
```
|
|
216
|
+
Toolbar 已經是明確操作區,tertiary 的框變成重複 affordance;多顆並排時視覺成格狀雜訊,還會和 primary 的視覺重量拉近,搶焦點。
|
|
217
|
+
|
|
218
|
+
✅ **正確版本**
|
|
219
|
+
```
|
|
220
|
+
[🔽 text] [👁 text] [+ New (primary)] [⋯]
|
|
221
|
+
```
|
|
222
|
+
Tool 按鈕群靠 Toolbar 脈絡 + hover 狀態浮出,視覺退讓給 primary。
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## 四、Icon 使用原則
|
|
227
|
+
|
|
228
|
+
### 業務操作
|
|
229
|
+
|
|
230
|
+
Icon 的目的是幫助辨識,不是視覺對稱。
|
|
231
|
+
|
|
232
|
+
| 情境 | 規則 |
|
|
233
|
+
|------|------|
|
|
234
|
+
| Icon 非強制 | form / dialog 等場景可省略,label 即可 |
|
|
235
|
+
| 同優先等級的操作 | 建議一致:同時有 `startIcon` 或同時沒有 |
|
|
236
|
+
| 不同優先等級(primary vs tertiary) | 可以不同,視覺重量差異是刻意設計 |
|
|
237
|
+
| `endIcon`(ChevronDown 等) | 互動指示器,不計入 `startIcon` 一致性判斷 |
|
|
238
|
+
|
|
239
|
+
### 工具操作
|
|
240
|
+
|
|
241
|
+
工具操作預設 icon-only。Icon 的適用性靠判斷,非硬規定:
|
|
242
|
+
|
|
243
|
+
| 類型 | 說明 | 範例 |
|
|
244
|
+
|------|------|------|
|
|
245
|
+
| 脈絡無關 | 任何頁面都能辨識,永遠安全 | ⚙ ··· ✕ ⤢ ? |
|
|
246
|
+
| 脈絡明確 | 在此 context 意義唯一 | ↺(資料 toolbar)、⬆(上傳功能區) |
|
|
247
|
+
| 需謹慎 | 同 icon 在不同 context 意義可能不同 | ⬆(上傳 or 移上 or 捲頂) |
|
|
248
|
+
|
|
249
|
+
原則:「在這個畫面脈絡下,使用者不需要讀 label 就能確定這個 icon 做什麼嗎?」若是,icon-only 可行;若不確定,補 label。
|
|
250
|
+
|
|
251
|
+
所有 icon-only 按鈕必須設定 `aria-label`,Button 元件自動產生 tooltip。
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## 五、分隔線規則
|
|
256
|
+
|
|
257
|
+
分隔線有兩種語意,各自適用不同場景:
|
|
258
|
+
|
|
259
|
+
**群組溢出邊界**
|
|
260
|
+
群組溢出(···)標記一個群組的結束。**群組溢出右側必須加分隔線**,無論右側是另一個業務群組還是工具層,也無論右側的視覺類型為何。群組溢出邊界優先於角色接壤:即使右側是 text 工具層,只要有群組溢出,就必加分隔線。
|
|
261
|
+
|
|
262
|
+
**角色接壤(無群組溢出時)**
|
|
263
|
+
業務層沒有群組溢出,最後一個真實業務按鈕直接接工具層:
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
[... 最後一個業務按鈕] ? [第一個工具按鈕 ...]
|
|
267
|
+
有框 → 無框 = 不加(視覺差異已標記邊界)
|
|
268
|
+
無框 → 無框 = 必須加(邊界不可見)
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**溢出按鈕(···)本身不構成工具層。** 工具層的存在取決於是否有固定工具按鈕(⚙ 設定、↺ 刷新、⤢ 全螢幕等)。沒有固定工具按鈕時,··· 是業務層的末端,不存在角色邊界,不加角色邊界分隔線。
|
|
272
|
+
|
|
273
|
+
| 情境 | 分隔線 | 依據 |
|
|
274
|
+
|------|--------|------|
|
|
275
|
+
| 群組溢出右側(接任何內容) | **必須** | 群組溢出邊界 |
|
|
276
|
+
| 業務層有框結尾 → 固定工具 text(無群組溢出) | **不加** | 角色接壤:視覺差異已足夠 |
|
|
277
|
+
| 業務層無框 text 結尾 → 固定工具 text(無群組溢出) | **必須** | 角色接壤:邊界不可見 |
|
|
278
|
+
| 業務操作層內的功能性分群 | **可選** | 同視覺類型功能域不同,視需要加 |
|
|
279
|
+
| 固定工具 → 全域溢出(同屬工具層) | **不加** | 同屬工具層 |
|
|
280
|
+
| 無固定工具(··· 是業務層末端) | **不加** | 沒有工具層,沒有角色邊界 |
|
|
281
|
+
| 最右側為關閉 / 解除按鈕 | **必須** | 誤觸保護 |
|
|
282
|
+
| 單一按鈕兩側都有分隔線 | 審查兩條各自的語意理由;正確套用規則後孤立自然不出現,若出現則代表某條分隔線應移除 | 孤立是症狀,根因是無語意的分隔線 |
|
|
283
|
+
|
|
284
|
+
**分隔線語意判斷**:遵守以上規則後孤立自然不出現。若出現孤立,先問「這條分隔線有語意理由嗎?」而非接受孤立。
|
|
285
|
+
|
|
286
|
+
**切換按鈕**:`text ↔ checked` 依預設(text)狀態決定位置與分隔線;切換為 checked 時不移動、不調整分隔線。
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 六、溢出選單
|
|
291
|
+
|
|
292
|
+
溢出是機制,不是角色。**溢出按鈕一律最低視覺重量(無框 icon-only)**,不隨業務層有框/無框而改變。溢出排除在全局排序之外。
|
|
293
|
+
|
|
294
|
+
### 判斷標準
|
|
295
|
+
|
|
296
|
+
所有群組的低頻操作放進同一個選單,使用者能快速找到目標嗎?
|
|
297
|
+
|
|
298
|
+
- **能** → 末端溢出(一個溢出在操作列最右,選單內用 section divider 分群)
|
|
299
|
+
- **不能**(群組之間功能性質差異大,混在一起找東西慢)→ 群組溢出(各群組各自管理)
|
|
300
|
+
|
|
301
|
+
### 末端溢出
|
|
302
|
+
|
|
303
|
+
**一個溢出按鈕,在操作列絕對末端。** 選單內用 section divider 表達功能分群。
|
|
304
|
+
|
|
305
|
+
適用於大多數操作列(資料表工具列、對話框操作區、卡片操作列等)。
|
|
306
|
+
|
|
307
|
+
```
|
|
308
|
+
[業務操作] ┆ [固定工具] [···]
|
|
309
|
+
↑ 唯一的溢出,永遠在最右
|
|
310
|
+
|
|
311
|
+
[業務操作] [···] ← 沒有固定工具時
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### 群組溢出
|
|
315
|
+
|
|
316
|
+
各群組各自管理可見與隱藏的項目。每個群組獨立決定——有些群組需要溢出,有些全部攤開:
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
[B I U ∨] | [☑ 🖼 @ 😀 🔗 +] | [↩ ↪]
|
|
320
|
+
↑ ↑ ↑
|
|
321
|
+
有溢出 沒有溢出 沒有溢出
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
群組溢出可以是**永久的**(低頻項目攤開是雜亂,設計師主動策展)、**響應式的**(空間不足時收合),或兩者疊加。在群組數量多、群組之間功能性質差異大的 toolbar 中較常見(如 rich text editor)。
|
|
325
|
+
|
|
326
|
+
規則:
|
|
327
|
+
- 溢出附著在所屬群組末端(左側直接接該群組按鈕,無分隔線),只收納該群組的項目
|
|
328
|
+
- 溢出右側必須加分隔線(群組溢出邊界,見第五節)
|
|
329
|
+
- 不與末端溢出混用——避免使用者分不清各個 ··· 的範疇
|
|
330
|
+
|
|
331
|
+
### 共通規則
|
|
332
|
+
|
|
333
|
+
- 溢出按鈕不構成工具層。工具層需要有固定工具按鈕(⚙ 設定、↺ 刷新、⤢ 全螢幕等)才存在,只有 ··· 不算
|
|
334
|
+
- **如果操作列出現大量溢出按鈕,這是資訊架構的問題,應回到功能規劃層重新設計**
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## 七、空間不足時的降級
|
|
339
|
+
|
|
340
|
+
### 末端溢出的操作列
|
|
341
|
+
|
|
342
|
+
```
|
|
343
|
+
1. 低頻業務操作收進末端溢出
|
|
344
|
+
2. 工具操作已是 icon-only,維持不變
|
|
345
|
+
3. 業務操作降級:低優先等級先降為 icon-only,主按鈕最後保留 label
|
|
346
|
+
4. 降級後的 icon-only 業務操作需符合 icon-only 辨識度條件
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### 群組溢出的操作列
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
1. 各群組內低頻項先收進該群組的溢出
|
|
353
|
+
2. 群組繼續收合:保留最高頻的按鈕作為群組代表,其餘進溢出
|
|
354
|
+
3. 單一按鈕的群組不需要溢出,空間極端不足時整個隱藏
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## 八、常見錯誤
|
|
360
|
+
|
|
361
|
+
### ❌ 工具操作混入業務層
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
[儲存 | 複製] ┆ [↺ | 🗑] ┆ [···] ┆ [✕]
|
|
365
|
+
↑ 角色混用:↺ 是工具操作,🗑 是業務操作
|
|
366
|
+
分在同一視覺群組 → 角色邊界失效,分隔線規則無從套用
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
正確版本:先分清角色,再套分隔線:
|
|
370
|
+
|
|
371
|
+
```
|
|
372
|
+
[儲存(framed) | 複製(framed) | 🗑(text danger)] ┆ [↺(text) | ···global] ┆ [✕]
|
|
373
|
+
↑ ↑
|
|
374
|
+
text→text 角色接壤 關閉保護
|
|
375
|
+
有框→無框接壤,不加分隔線(視覺差異已足夠)
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
- 儲存、複製 = 有框業務(tertiary);🗑 = 無框業務(text danger)→ 有框集中在前,不加分隔線
|
|
379
|
+
- 🗑(業務)→ ↺(工具)= text→text 角色接壤 → 必加分隔線
|
|
380
|
+
- ↺ → ···global = 同屬工具層 → 不加分隔線
|
|
381
|
+
- ✕ 在末端 → 關閉保護,分隔線在 ✕ 左側;···global 左側一條(角色接壤),右側一條(關閉保護),各有語意
|
|
382
|
+
|
|
383
|
+
### ❌ 同優先等級業務操作,icon 處理不一致
|
|
384
|
+
|
|
385
|
+
```
|
|
386
|
+
⬆ 上傳 匯出
|
|
387
|
+
(同為 text variant,一個有 startIcon 一個沒有)
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### ❌ 工具操作使用 primary 或 secondary
|
|
391
|
+
|
|
392
|
+
工具層必須是操作列中最低視覺重量,否則搶走業務操作的焦點。
|
|
393
|
+
|
|
394
|
+
### ❌ 工具層與全域溢出之間加分隔線,造成孤立
|
|
395
|
+
|
|
396
|
+
```
|
|
397
|
+
[ 業務操作 ] ┆ ⚙ ┆ ··· ← ❌ ⚙ 兩側都有分隔線
|
|
398
|
+
[ 業務操作 ] ┆ ⚙ ··· ← ✅
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### ❌ 無工具層卻加分隔線
|
|
402
|
+
|
|
403
|
+
```
|
|
404
|
+
⬆ 上傳 ⬇ 匯出 ┆ ··· ← ❌ 無角色邊界,分隔線無意義
|
|
405
|
+
⬆ 上傳 ⬇ 匯出 ··· ← ✅
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### ❌ Variant 排序錯誤:有框夾在無框之間
|
|
409
|
+
|
|
410
|
+
```
|
|
411
|
+
[ text ] [ tertiary ] [ text ] ← ❌ tertiary 重量高於 text,應排在前
|
|
412
|
+
[ tertiary ] [ text ] [ text ] ← ✅
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### ❌ 操作列被包上邊框
|
|
416
|
+
|
|
417
|
+
加上邊框會變成 Segmented Control,語意與互動完全不同,不可混用。
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## 九、快速判斷
|
|
422
|
+
|
|
423
|
+
```
|
|
424
|
+
這個操作是什麼角色?
|
|
425
|
+
├── 移除它,使用者無法完成任務 → 業務操作
|
|
426
|
+
│ ├── 一般操作 → label 或 icon + label
|
|
427
|
+
│ ├── 含多個子選項 → + endIcon={ChevronDown}
|
|
428
|
+
│ └── 可配置資料操作 → text(未配置)/ checked(已配置)
|
|
429
|
+
│ └── 需要更強可操作性提示 → tertiary(未配置)
|
|
430
|
+
└── 跟任務無關,服務環境 → 工具操作 → icon-only + tooltip
|
|
431
|
+
|
|
432
|
+
有工具層嗎?
|
|
433
|
+
├── 有 → 業務層用什麼結尾?
|
|
434
|
+
│ ├── 有框按鈕 → 不加分隔線(有框→無框視覺差異已足夠)
|
|
435
|
+
│ └── 無框 text 按鈕 → 必須加分隔線(無框→無框邊界不可見)
|
|
436
|
+
└── 無 → 不加任何分隔線(除非有關閉按鈕保護需求)
|
|
437
|
+
|
|
438
|
+
溢出用哪種?
|
|
439
|
+
└── 所有群組的低頻操作放進同一個選單,使用者能快速找到目標嗎?
|
|
440
|
+
├── 能 → 末端溢出(一個,在最右)
|
|
441
|
+
└── 不能(群組多、功能性質差異大、找東西慢)→ 群組各自管理溢出
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
## 關聯文件
|
|
447
|
+
|
|
448
|
+
- `button.spec.md`:Button 元件層的設計原則
|
|
449
|
+
|
|
450
|
+
## 被引用(auto-maintained,Dim 3 reciprocal audit)
|
|
451
|
+
|
|
452
|
+
> 本節由 `scripts/add-reciprocal-pointers.mjs` 自動維護,列出在 SSOT 語境下指向本 spec 的其他 spec。若要手動補充,寫在本節之前。
|
|
453
|
+
|
|
454
|
+
- `bulk-action-bar.spec.md`
|
|
455
|
+
- `calendar.spec.md`
|
|
456
|
+
- `data-table.spec.md`
|
|
457
|
+
- `file-viewer.spec.md`
|
|
458
|
+
- `popover.spec.md`
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
<!-- @benchmark-cited: D5 retrofit 2026-05-18 — body claims marked per-claim @benchmark-unverified inline; canonical source URLs in frontmatter benchmark list. -->
|
|
2
|
+
|
|
3
|
+
# Element Anatomy 設計原則(4-Family Model Taxonomy)
|
|
4
|
+
|
|
5
|
+
本檔是 design system 中 **element-level 結構分類系統**的頂層 governance doc——跨 pattern / cross-component。每個元件 spec 第一段**必須聲明 Layout Family**(1/2/3/4 或「非 family,self-contained / composite」)。
|
|
6
|
+
|
|
7
|
+
**為什麼住 `patterns/element-anatomy/` 而非 DS 根目錄**:taxonomy 橫跨 patterns + components 兩個家:
|
|
8
|
+
- Family 1+2(row 結構)→ runtime primitive 在同 folder `item-anatomy.{spec.md, tsx, stories.tsx}`
|
|
9
|
+
- Family 3(pill 結構)→ SSOT pointer 到 `components/Button/button.spec.md`
|
|
10
|
+
- Family 4(field control 結構)→ SSOT pointer 到 `components/Field/field-controls.spec.md`
|
|
11
|
+
|
|
12
|
+
Taxonomy 跟 F1+F2 runtime primitive **co-locate 在同 folder** 是 `packages/design-system/src/README.md` L17 的 home governance 決策:**「即使跨 pattern 的 taxonomy(如 4-Family Model)也住在最相關的 pattern topic 資料夾內,folder = topic home,不需要頂層 flat 檔案」**。co-location 讓新 element 查 taxonomy 時,runtime primitive 就在隔壁,查閱效率最高。
|
|
13
|
+
|
|
14
|
+
**與「layout」命名分家**:「anatomy」= element-level 結構分類;「layout」= page-level 版面(未來頁面設計原則的家)。世界級 DS 一致如此(Material Foundations > Layout = page grid / Polaris / Atlassian / Carbon 皆然)。
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 4 個可繼承的 Layout Family
|
|
19
|
+
|
|
20
|
+
| Family | 用途 | 結構 | Sizes baseline | SSOT |
|
|
21
|
+
|--------|------|------|----------------|------|
|
|
22
|
+
| **1. Menu item anatomy** | Menu 容器內的掃視單列(scanning mode)| `[small icon/avatar 16-20px] [content: label 單行 + desc 選用] [small suffix]`, tight density, leading-compact | **sm / md / lg** | `patterns/element-anatomy/item-anatomy.spec.md`「Family 1: Menu item」章節 |
|
|
23
|
+
| **2. List item anatomy** | 頁面上的閱讀式單列(reading mode)| `[larger icon/avatar 20-24px] [content: label + multi-line desc OK] [suffix action/button/counter]`, looser density, reading typography | **sm / md / lg** | `patterns/element-anatomy/item-anatomy.spec.md`「Family 2: List item」章節 |
|
|
24
|
+
| **3. Pill anatomy** | 單行互動 pill(action trigger / data indicator)| `[startIcon?] [<span px-1>label</span>] [suffix badge/endIcon/dismiss]`, single-line, whitespace-nowrap | **sm / md / lg + 可選 xs** | `components/Button/button.spec.md`「Pill Layout」章節 |
|
|
25
|
+
| **4. Field control anatomy** | 可編輯資料輸入(單行為主,Textarea 多行 variant) | `fieldWrapperStyles + [startIcon?] [<editable content>] [endAction?]`, **視覺對齊 Family 1** | **sm / md / lg** | `components/Field/field-controls.spec.md` |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 尺寸 baseline 與合法偏離
|
|
30
|
+
|
|
31
|
+
每個 Family 有明文 baseline sizes。消費元件**必須**實作 baseline,除非有合理理由偏離——偏離必須在元件 spec 明文記錄。
|
|
32
|
+
|
|
33
|
+
| 偏離類型 | 範例 | 合理理由 |
|
|
34
|
+
|---------|------|---------|
|
|
35
|
+
| **單一固定 size** | Chip (`h-field-sm`) / Notice / Alert / Toast | 世界級共識(Material 3 filter chips / Material Banner):此類元件不需密度選擇 | <!-- @benchmark-unverified: see frontmatter benchmark list for canonical DS source URL -->
|
|
36
|
+
| **Alias** | Tag lg=md=24px | 子元件補齊(discrete tier):consumer 傳 size 不 break,視覺等同 |
|
|
37
|
+
| **Mode 取代 Size** | FileItem(`compact` / `rich`) | **結構變體**非密度變體——用 size 會誤導 |
|
|
38
|
+
| **額外 xs**(Family 3 only) | Button / SegmentedControl xs | icon-only toolbar utility(24px 固定 不配對 Field) |
|
|
39
|
+
|
|
40
|
+
違反但無理由 = 設計 bug,必須改 code 或補 spec 理由。
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Family 3 兩個 sub-profile(重要)
|
|
45
|
+
|
|
46
|
+
同結構、不同 role、不同 padding / typography:
|
|
47
|
+
|
|
48
|
+
| Sub-profile | 成員 | Padding | Typography | Cursor | 為什麼 |
|
|
49
|
+
|-------------|------|---------|-----------|--------|------|
|
|
50
|
+
| **Action trigger** | Button / SegmentedControl / Chip | 較鬆(xs=`px-2`, sm+=`px-3`) | 對應 size 的 font-medium | pointer | 需命中區 + 視覺重量搶點擊焦點 |
|
|
51
|
+
| **Data indicator** | Tag | 較緊(`px-1` 所有 size) | font-normal | text | Passive 讀取,不搶焦點 |
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Size Pairing 規則(跨 Family)
|
|
56
|
+
|
|
57
|
+
| Pairing | 意義 |
|
|
58
|
+
|---------|------|
|
|
59
|
+
| Tag md ↔ Field md / Tag sm ↔ Field sm | Tag 的 size 對應同名 Field size,視覺對齊 form 內字級 |
|
|
60
|
+
| Button sm/md/lg ↔ Field sm/md/lg | Button 配對 Field 時 size 同名 |
|
|
61
|
+
| Button xs = 獨立 utility | 不配對 Field,用於 toolbar compact button |
|
|
62
|
+
| Family 4 視覺對齊 Family 1 | 讓 Select trigger + dropdown options 視覺連續 |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Consumers 快速查
|
|
67
|
+
|
|
68
|
+
| Family | Canonical | Consumers |
|
|
69
|
+
|--------|-----------|-----------|
|
|
70
|
+
| 1 Menu item | `MenuItem`(from `item-anatomy`) | `TreeItem`, `SidebarMenuButton`, `DropdownMenuItem`(重用 MenuItem), `SelectMenu` 內部 |
|
|
71
|
+
| 2 List item | (無單一 canonical) | `StepItem`(例外:indicator 對齊), `FileItem`(icon 作邊界), `Notice` → `Alert/Toast`(視覺一致非語意), `SelectionItem` variant → `RadioGroup` / `Checkbox` group |
|
|
72
|
+
| 3 Pill | `Button` | `SegmentedControlItem`, `Chip`, `Tag`(data indicator sub-profile) |
|
|
73
|
+
| 4 Field control | `Input`(field-controls SSOT) | `NumberInput`, `DatePicker`, `Select`, `Combobox`, `LinkInput`, `PeoplePicker`, `Textarea`(multi-line variant) |
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 不進 Family Model 的元件
|
|
78
|
+
|
|
79
|
+
不能舉一反三的不分類。**Composite 類再細分三子類**,因為三類的設計約束不同:
|
|
80
|
+
|
|
81
|
+
### Self-contained primitive(獨立視覺 atom,無 slot 結構)
|
|
82
|
+
|
|
83
|
+
Switch / Checkbox / Radio / Avatar / Badge / CircularProgress / ProgressBar / Skeleton / Separator
|
|
84
|
+
|
|
85
|
+
各自獨立視覺,spec 直接描述自己結構。
|
|
86
|
+
|
|
87
|
+
### Overlay-composite(浮層 composite,消費 overlay-surface pattern)
|
|
88
|
+
|
|
89
|
+
Dialog / Sheet / Popover / Tooltip / HoverCard / Coachmark / Command / SelectMenu / DropdownMenu
|
|
90
|
+
|
|
91
|
+
**共同約束**:
|
|
92
|
+
- 必消費 `patterns/overlay-surface/` 的 `SurfaceHeader` / `SurfaceBody` / `SurfaceFooter`(padding SSOT)
|
|
93
|
+
- elevation 走 `--elevation-200`+ 的 overlay layer
|
|
94
|
+
- dismiss 走 `onClose`(語意:關閉 overlay session,見 CLAUDE.md 命名 canonical)
|
|
95
|
+
- 部分 overlay 有 modal vs non-modal 分流(Dialog / Sheet modal;Popover / HoverCard non-modal)
|
|
96
|
+
- 在 dark-mode context(如 FileViewer chrome)中需支援 `data-theme="dark"` 子樹
|
|
97
|
+
|
|
98
|
+
### Page-composite(頁面內 composite,無 overlay 性質)
|
|
99
|
+
|
|
100
|
+
Tabs / Accordion / DataTable / Calendar / Carousel / Breadcrumb / Sidebar / NameCard / FileItem / FileUpload / FileViewer / OverflowIndicator
|
|
101
|
+
|
|
102
|
+
**共同約束**:
|
|
103
|
+
- 消費多個 row primitive 或 self-contained primitive
|
|
104
|
+
- 不走 overlay-surface(沒有 elevation / dismiss)
|
|
105
|
+
- 佈局 token 用 `--layout-space-*`(chrome / section)
|
|
106
|
+
- 各自 own 內部 layout SSOT(例:DataTable 的 header row、Calendar 的 grid、Carousel 的 track + arrow)
|
|
107
|
+
|
|
108
|
+
### Pure-wrapper(純行為 wrapper,無自己視覺)
|
|
109
|
+
|
|
110
|
+
CheckboxGroup / RadioGroup / FieldGroup(若建)
|
|
111
|
+
|
|
112
|
+
**共同約束**:
|
|
113
|
+
- 自己**無 render**(transparent wrapper)
|
|
114
|
+
- 提供 context(`CheckboxGroupContext`)給 descendant 同步 state
|
|
115
|
+
- spec 應明文「本元件無視覺」,對應 anatomy story 只有 `Overview` + `Inspector` 兩個(no ColorMatrix / SizeMatrix)
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### 判斷新 composite 時的流程
|
|
120
|
+
|
|
121
|
+
寫新 composite spec 時先自問:
|
|
122
|
+
1. 這是浮層(elevation / Portal / dismiss session)嗎? → **Overlay-composite**
|
|
123
|
+
2. 這是頁面內多區塊 layout 嗎? → **Page-composite**
|
|
124
|
+
3. 這本身無視覺、只是 context / state wrapper 嗎? → **Pure-wrapper**
|
|
125
|
+
|
|
126
|
+
三題全否 → 應該是 Family 1/2/3/4 或 Self-contained primitive,而不是 composite。
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 允許的跨 Family 視覺對齊
|
|
131
|
+
|
|
132
|
+
Family 4 的 Input / Select 視覺對齊 Family 1 的 menu-item(高度、字體、icon size)——但兩個 family **各自 own SSOT**。這是「視覺對齊」非「結構繼承」。
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Field Composition(不在 family 但相關)
|
|
137
|
+
|
|
138
|
+
`components/Field/field.spec.md` 描述 **form field composition pattern**——Field 容器如何包 Family 4 control + label + help。不同 scope 的 pattern(composition 非 element anatomy),不列入 4-Family。
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## 新元件判斷流程
|
|
143
|
+
|
|
144
|
+
1. **垂直列表裡?** → Family 1(menu 容器)/ Family 2(頁面)
|
|
145
|
+
2. **單行可點擊 / 可讀的 pill?** → Family 3(action trigger or data indicator)
|
|
146
|
+
3. **單行可編輯資料?** → Family 4(必須視覺對齊 Family 1)
|
|
147
|
+
4. **都不是?** → **停下討論**——新 family 還是 self-contained
|
|
148
|
+
|
|
149
|
+
CLAUDE.md `# 4-Family Layout Model` 留概要 + 判斷流程(每 session signal)。本檔 own 完整 taxonomy + Family 3 sub-profile + size pairing + consumers + exclusions。
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 視覺容器 breathing invariant(DS-wide canonical · 2026-04-22)
|
|
154
|
+
|
|
155
|
+
**規則**(rule · 必遵守):
|
|
156
|
+
|
|
157
|
+
> 任何**有明確視覺邊界的容器**(permanent `bg-*` / `border` / `shadow-*` 三者任一),**必有 inner padding**,不讓內容物(含 standalone card、pill、row、text 等任何 children)觸容器邊。
|
|
158
|
+
|
|
159
|
+
**責任層**:**父容器(chrome)** — 子元件 `w-full` responsive 不變。
|
|
160
|
+
|
|
161
|
+
**為什麼責任在父容器**:
|
|
162
|
+
- 子元件不知道自己會住在哪個 chrome → 硬綁 max-w / margin 會破壞 responsive
|
|
163
|
+
- 父容器知道自己的視覺 policy(bg/border/shadow 都是它的決策)→ 天然 SSOT
|
|
164
|
+
- 子元件統一 `w-full` 扣掉父 padding 自動有 breathing
|
|
165
|
+
|
|
166
|
+
**建議值**(guide · 非 strict):
|
|
167
|
+
|
|
168
|
+
| Chrome 類型 | 建議 inner padding | 範例 |
|
|
169
|
+
|------------|------------------|------|
|
|
170
|
+
| 一般 chrome(Dialog / Sheet / Popover / Card body) | `--layout-space-loose`(16/24)/`--layout-space-tight`(12/16) | SurfaceBody 已 own canonical |
|
|
171
|
+
| 側邊 chrome(Sidebar / Drawer section) | `--layout-space-tight` 到 `--layout-space-loose` | 視深度 |
|
|
172
|
+
| Inline pill(Badge / Chip / Tag) | `px-1` / `px-2` | 對齊元件 size |
|
|
173
|
+
| Form field control wrapper | `px-3`(固定,對齊 Field family)| fieldWrapperStyles |
|
|
174
|
+
|
|
175
|
+
Consumer 自建 chrome-like div 帶 bg/border/shadow 時,參考上表或就近取 `--layout-space-*` token。**具體值允許偏離,但 breathing 本身必存在**。
|
|
176
|
+
|
|
177
|
+
**世界級對照**(DS-wide 共識):
|
|
178
|
+
- Material Design 3:`<mat-card-content>` 16dp / `<mat-dialog-content>` 24dp / Drawer section padding
|
|
179
|
+
- Polaris(Shopify):`<Page>` 16-20px / `<Card>` 16-20px / `<Modal>` 20px
|
|
180
|
+
- Atlassian:`<Box padding="space.200">` / `<ModalBody>` 24px / Drawer body padding
|
|
181
|
+
- Ant Design:`<Modal.Body>` 24px / `<Card.Meta>` inner padding
|
|
182
|
+
- Apple HIG:Inset Grouped list group 16pt inset / Card 內容 16pt
|
|
183
|
+
- Carbon(IBM):Tile / Modal 內容 16-32px padding
|
|
184
|
+
|
|
185
|
+
無反例 — 6 家一致在 chrome 層提供 inner padding 當 SSOT。
|
|
186
|
+
|
|
187
|
+
**反例(破圖)**:
|
|
188
|
+
- Consumer 自建 `<div className="bg-surface-raised rounded-lg">{rich FileItem list}</div>` **無 padding** → rich card w-full 貼父 div 邊,card rounded 貼父 rounded 視覺「卡在一起」
|
|
189
|
+
- Consumer 自建 `<div className="border rounded-md">{text}</div>` 無 padding → text 貼 border 邊,看似斷字
|
|
190
|
+
- Chrome primitive 被 override 拿掉 padding(`<SheetBody className="p-0">`)後塞 card 元件 → 同上
|
|
191
|
+
|
|
192
|
+
**Enforcement**:
|
|
193
|
+
- Chrome primitive(SurfaceHeader / SurfaceBody / SurfaceFooter / Input wrapper / Field wrapper)**已 own canonical padding**,繼續守 SSOT
|
|
194
|
+
- Consumer 自建的有視覺邊界 div → hook `check_container_breathing.sh` warn(grep `bg-*|border|shadow-*` 無 `p*-`)
|
|
195
|
+
- Audit dim 新增:「consumer 自建 chrome 是否有 inner padding」
|
|
196
|
+
|
|
197
|
+
**與既有規則的關係**:
|
|
198
|
+
- `overlay-surface.spec.md` 「M11 state walk hover 檢查(三 invariant 必同時 ✓)」第 3 條(content 在 hover bg 內 breathing)= 本規則的**應用層 instance**(hover bg 也算「permanent」在該 state 內),非獨立規則
|
|
199
|
+
- `.claude/rules/ui-development.md`「Padding source 分層規則」定 **padding 來源**(token / Tailwind / calc);本規則定 **padding 是否存在**(是 invariant)
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 相關
|
|
204
|
+
|
|
205
|
+
- `patterns/element-anatomy/item-anatomy.spec.md` — Family 1+2 row anatomy deep SSOT + runtime primitive(`<MenuItem>` canonical + `<ItemIcon>` / `<ItemAvatar>` / `<ItemLabel>` / `<ItemSuffix>` / `<ItemInlineAction>` slot components)
|
|
206
|
+
- `components/Button/button.spec.md` — Family 3 Pill anatomy SSOT
|
|
207
|
+
- `components/Field/field-controls.spec.md` — Family 4 Field control anatomy SSOT
|
|
208
|
+
- CLAUDE.md `# 4-Family Layout Model` — 每 session signal 的概要 + judgment flow
|
|
209
|
+
|
|
210
|
+
## 被引用(auto-maintained,Dim 3 reciprocal audit)
|
|
211
|
+
|
|
212
|
+
> 本節由 `scripts/add-reciprocal-pointers.mjs` 自動維護,列出在 SSOT 語境下指向本 spec 的其他 spec。若要手動補充,寫在本節之前。
|
|
213
|
+
|
|
214
|
+
- `calendar.spec.md`
|
|
215
|
+
- `time-picker.spec.md`
|