@persona/design-system 0.10.1 → 0.10.3

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.
Files changed (120) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/{CheckboxGroupField-4dc7YXJY.d.mts → CheckboxGroupField-6E5o6bYi.d.mts} +2 -2
  3. package/dist/CheckboxGroupField.d.mts +1 -1
  4. package/dist/{Combobox-CcFJo68g.mjs → Combobox-CBM-oY-e.mjs} +6 -4
  5. package/dist/{Combobox-CcFJo68g.mjs.map → Combobox-CBM-oY-e.mjs.map} +1 -1
  6. package/dist/{Combobox-Bm2eSg56.d.mts → Combobox-DTeu9_RR.d.mts} +3 -3
  7. package/dist/Combobox.d.mts +2 -2
  8. package/dist/{ComboboxBase-B7ZcqU9p.d.mts → ComboboxBase-BMBdtP2Z.d.mts} +2 -2
  9. package/dist/ComboboxBase.d.mts +1 -1
  10. package/dist/{ComboboxMultiSelect-BkdRrH6K.d.mts → ComboboxMultiSelect-DY5bAep9.d.mts} +2 -2
  11. package/dist/ComboboxMultiSelect.d.mts +1 -1
  12. package/dist/{ComboboxSingleSelect-DIBRZmvS.d.mts → ComboboxSingleSelect-1NglA-u2.d.mts} +3 -3
  13. package/dist/ComboboxSingleSelect.d.mts +1 -1
  14. package/dist/{CompactBar-CfrrZ69k.d.mts → CompactBar-D9egXqY_.d.mts} +2 -2
  15. package/dist/CompactBar.d.mts +1 -1
  16. package/dist/{ControlBar-D9KflqmH.d.mts → ControlBar-RIz-xjxs.d.mts} +18 -1
  17. package/dist/ControlBar.d.mts +1 -1
  18. package/dist/{DataTable-BoAAKhVH.mjs → DataTable-DQ8axNfo.mjs} +3 -3
  19. package/dist/{DataTable-BoAAKhVH.mjs.map → DataTable-DQ8axNfo.mjs.map} +1 -1
  20. package/dist/{DataTable--_f1Obhj.d.mts → DataTable-l1bFeLXL.d.mts} +6 -5
  21. package/dist/DataTable.d.mts +1 -1
  22. package/dist/DropdownButton.d.mts +1 -1
  23. package/dist/{DropdownMenu-Bie2cWjb.d.mts → DropdownMenu-UIrnFxfG.d.mts} +2 -2
  24. package/dist/DropdownMenu.d.mts +1 -1
  25. package/dist/{FormField-C4B2qFgh.mjs → FormField-C0cd1zVd.mjs} +3 -3
  26. package/dist/{FormField-C4B2qFgh.mjs.map → FormField-C0cd1zVd.mjs.map} +1 -1
  27. package/dist/ImageThumbnail.d.mts +43 -0
  28. package/dist/IndexTableLayout.d.mts +3 -3
  29. package/dist/InlineCombobox.d.mts +1 -1
  30. package/dist/InlineInput.d.mts +1 -1
  31. package/dist/{ListBox-DIk8suJM.d.mts → ListBox-cH0dfeLN.d.mts} +2 -2
  32. package/dist/ListBox.d.mts +1 -1
  33. package/dist/{ListBoxField-DF8rqPsu.d.mts → ListBoxField-DOpaE0q4.d.mts} +4 -4
  34. package/dist/ListBoxField.d.mts +1 -1
  35. package/dist/{LogicRow-uxpe1vZ1.d.mts → LogicRow-CaxsteGU.d.mts} +2 -2
  36. package/dist/LogicRow.d.mts +1 -1
  37. package/dist/MaskedInput.d.mts +1 -1
  38. package/dist/{Menu-CrThaUX2.d.mts → Menu-5VknNr1T.d.mts} +2 -2
  39. package/dist/Menu.d.mts +1 -1
  40. package/dist/{Select-CsxK6A5m.d.mts → Select-CG_Xkx0m.d.mts} +2 -2
  41. package/dist/Select.d.mts +1 -1
  42. package/dist/SelectionCard.d.mts +46 -0
  43. package/dist/SelectionCardGroup.d.mts +37 -0
  44. package/dist/SmartTextInputField.d.mts +2 -2
  45. package/dist/{Spinner-uVZyOh1T.mjs → Spinner-7Camx1vs.mjs} +4 -3
  46. package/dist/{Spinner-uVZyOh1T.mjs.map → Spinner-7Camx1vs.mjs.map} +1 -1
  47. package/dist/{Table--o4ZLRbb.mjs → Table-BIDaC0uS.mjs} +2 -2
  48. package/dist/{Table--o4ZLRbb.mjs.map → Table-BIDaC0uS.mjs.map} +1 -1
  49. package/dist/{TableBox-3qunC9Nl.mjs → TableBox-Bn_XZEYd.mjs} +3 -3
  50. package/dist/{TableBox-3qunC9Nl.mjs.map → TableBox-Bn_XZEYd.mjs.map} +1 -1
  51. package/dist/TableBox.d.mts +1 -1
  52. package/dist/{TableBoxCell-okcOQ5Ec.d.mts → TableBoxCell-v_ag22E0.d.mts} +4 -4
  53. package/dist/TableBoxCell.d.mts +1 -1
  54. package/dist/{TableBoxField-DR-SJY9z.d.mts → TableBoxField-BTpSGmgW.d.mts} +5 -5
  55. package/dist/TableBoxField.d.mts +1 -1
  56. package/dist/{TableBoxRow-DiuAB_rV.d.mts → TableBoxRow-BBTztgTT.d.mts} +2 -2
  57. package/dist/TableBoxRow.d.mts +1 -1
  58. package/dist/{TableBoxRowActions-Cm4KJsAD.d.mts → TableBoxRowActions-B9QSVySz.d.mts} +2 -2
  59. package/dist/TableBoxRowActions.d.mts +1 -1
  60. package/dist/{TableControls-n16XKO9S.mjs → TableControls-qxoq5abn.mjs} +142 -61
  61. package/dist/TableControls-qxoq5abn.mjs.map +1 -0
  62. package/dist/{TableControls-B9bvsNUc.d.mts → TableControls-wM35j3g4.d.mts} +5 -4
  63. package/dist/TableControls.d.mts +1 -1
  64. package/dist/{TableControlsContext-CZThYoj5.d.mts → TableControlsContext-rTYwRi5S.d.mts} +2 -2
  65. package/dist/TableControlsContext.d.mts +1 -1
  66. package/dist/{TableViewConfigurationDropdown-CvN7tE98.d.mts → TableViewConfigurationDropdown-Gut16-vY.d.mts} +2 -2
  67. package/dist/TableViewConfigurationDropdown.d.mts +1 -1
  68. package/dist/{clientFilterUtils-BXEpzorX.d.mts → clientFilterUtils-D0Bwapen.d.mts} +2 -2
  69. package/dist/clientFilterUtils.d.mts +1 -1
  70. package/dist/components/Combobox/index.d.mts +2 -2
  71. package/dist/components/Combobox/index.mjs +1 -1
  72. package/dist/components/DataTable/TableControls/index.d.mts +7 -7
  73. package/dist/components/DataTable/TableControls/index.mjs +1 -1
  74. package/dist/components/DataTable/index.d.mts +5 -5
  75. package/dist/components/DataTable/index.mjs +1 -1
  76. package/dist/components/DataTable/types.d.mts +1 -1
  77. package/dist/components/DropdownMenu/index.d.mts +1 -1
  78. package/dist/components/FormField/index.d.mts +4 -4
  79. package/dist/components/FormField/index.mjs +1 -1
  80. package/dist/components/ImageTile/index.mjs +82 -52
  81. package/dist/components/ImageTile/index.mjs.map +1 -1
  82. package/dist/components/ListBox/index.d.mts +3 -3
  83. package/dist/components/Menu/index.d.mts +1 -1
  84. package/dist/components/Select/index.d.mts +1 -1
  85. package/dist/components/SelectionCard/index.d.mts +3 -0
  86. package/dist/components/SelectionCard/index.mjs +272 -0
  87. package/dist/components/SelectionCard/index.mjs.map +1 -0
  88. package/dist/components/SmartTextInput/index.mjs +1 -1
  89. package/dist/components/Spinner/index.mjs +1 -1
  90. package/dist/components/Table/index.mjs +1 -1
  91. package/dist/components/TableBox/index.d.mts +1 -1
  92. package/dist/components/TableBox/index.mjs +1 -1
  93. package/dist/components/VersionHistory/index.mjs +1 -1
  94. package/dist/fieldPickerOptions.d.mts +1 -1
  95. package/dist/{filters-ogUUmLEf.d.mts → filters-C8YLLbH3.d.mts} +2 -2
  96. package/dist/filters.d.mts +1 -1
  97. package/dist/{helpers-Dqw5PEva.d.mts → helpers-DvqDI2e5.d.mts} +2 -2
  98. package/dist/helpers.d.mts +1 -1
  99. package/dist/{index-Ck939aXd.d.mts → index-CNDe1Lij.d.mts} +3 -3
  100. package/dist/{inputFields-DVLg_2wz.d.mts → inputFields-BZcm1UV5.d.mts} +4 -4
  101. package/dist/inputFields.d.mts +1 -1
  102. package/dist/patterns/IndexTableLayout/index.mjs +1 -1
  103. package/dist/patterns/LayoutLoadingShimmer/index.mjs +1 -1
  104. package/dist/{types-Bdi8Y7ll.d.mts → types-Ci-KTHfu.d.mts} +3 -3
  105. package/dist/{types-BQP14Fng.d.mts → types-SYxBPX6o.d.mts} +2 -2
  106. package/dist/types5.d.mts +1 -1
  107. package/dist/useColumnConfiguration.d.mts +2 -2
  108. package/dist/useComboboxFooterAction.d.mts +1 -1
  109. package/dist/{useTableColumns-DdU0CLcU.d.mts → useTableColumns-PyxNyTD6.d.mts} +2 -2
  110. package/dist/useTableColumns.d.mts +1 -1
  111. package/dist/useTruncation.d.mts +1 -1
  112. package/llms.txt +2 -1
  113. package/package.json +4 -2
  114. package/skills/ui-authoring/COMPONENTS.md +1 -0
  115. package/skills/ui-authoring/PATTERNS.md +5 -1
  116. package/skills/ui-authoring/SKILL.md +8 -0
  117. package/skills/ui-authoring/STANDARD.md +137 -0
  118. package/skills/ui-authoring/TOKENS.md +3 -1
  119. package/skills/ui-authoring/lanes.json +22 -0
  120. package/dist/TableControls-n16XKO9S.mjs.map +0 -1
@@ -26,7 +26,11 @@ Which pattern to use, and for what. Patterns with a dedicated doc link to
26
26
  ## Page layouts
27
27
 
28
28
  Index pages backed by `DataTable` use `IndexTableLayout`, which owns its `Container`, `PageHeader`,
29
- `Section`, and `Card` shell. Other pages render `PageHeader`, then `SingleColumnLayout` or
29
+ `Section`, and `Card` shell. Import it from `@persona/design-system/patterns/IndexTableLayout`;
30
+ never copy it, persona-web's `DashboardDataTable` wrapper (PDS does not ship one), or
31
+ `TableControls`/filter panels into an app. Pass app-specific filters through the `controls` prop
32
+ (`controls={{ filters, filterResolver }}` or `controls={{ filterPanel }}`), and if the pattern lacks
33
+ a slot you need, add it here instead of forking the layout. Other pages render `PageHeader`, then `SingleColumnLayout` or
30
34
  `SplitColumnLayout`. Do not wrap those templates in `Container` or `Section`.
31
35
 
32
36
  ```tsx
@@ -8,6 +8,13 @@ metadata:
8
8
 
9
9
  # UI Authoring
10
10
 
11
+ ## Product UI standard
12
+
13
+ Building a screen in an app? [STANDARD.md](STANDARD.md) holds the rules every screen meets: text the
14
+ user reads is at least 11 px (8 px for a label inside a chart or diagram), contrast meets WCAG AA in light and dark, motion honours
15
+ `prefers-reduced-motion`, and status never relies on colour alone. It also defines the `new-screen`
16
+ lane for building one screen with no designer. Read it first, then the sections below.
17
+
11
18
  ## Design Tokens
12
19
 
13
20
  ```tsx
@@ -184,6 +191,7 @@ Add `ComponentName.stories.tsx` for every new component or visual variant.
184
191
 
185
192
  ## Resources
186
193
 
194
+ - [STANDARD.md](STANDARD.md) — product UI standard: accessibility values, screen brief, `new-screen` lane ([lanes.json](lanes.json)), checks, departures
187
195
  - [TOKENS.md](TOKENS.md) — semantic color tokens (Fg / Surface / Border / Action / Input / Feedback / Status / Opacity), recipes and dark-mode checklist; Spacing / Typography catalog, radius, elevation, charts
188
196
  - [PATTERNS.md](PATTERNS.md) — forms, layout, panels, indicators, feedback, empty states
189
197
  - [COMPONENTS.md](COMPONENTS.md) — which PDS component to use, and its import path; APIs live in each component's `.mdx`
@@ -0,0 +1,137 @@
1
+ # Product UI standard
2
+
3
+ The rules every screen built on PDS meets, above the shared accessibility floor. This is the product
4
+ UI area standard of the Persona design harness. It cites `persona-id/design-harness` at
5
+ **`core-v0.3`**, where the product UI area's entry is `areas/product-ui.md`.
6
+
7
+ - **Owner:** Michael Hu.
8
+ - **Covers:** screens in Persona apps built on `@persona/design-system` (the dashboard, internal
9
+ apps, App Builder).
10
+ - **Pinned by the app's PDS version.** The installed package is the live source and beats any
11
+ description of it, this file included (PDH-S1).
12
+
13
+ ## Ranks
14
+
15
+ PDH-P1 (honesty) and PDH-P2 (brand) rank first and second. Then:
16
+
17
+ 3. **Component-first.** A PDS pattern or component over custom code. Tokens only style what no
18
+ component covers. The failure this guards against is one-off UI that drifts from every other
19
+ screen.
20
+ 4. **Craft.** Hierarchy, spacing, copy and every state (loading, empty, error, disabled) finished,
21
+ not just working.
22
+
23
+ ## Parameters
24
+
25
+ | Rule | Product UI value |
26
+ | ---- | ---------------- |
27
+ | PDH-F1 contrast | The core value, WCAG 2.2 AA, in every colour mode the screen ships (light and dark) |
28
+ | PDH-F2 copy | **11 CSS px** for text the user reads, the core web-copy value. 10 px styles are below it (see Checks); use `TextSmall` or `TextSmallMono` (12 px) |
29
+ | PDH-F2 label inside a graphic | **8 CSS px** for a label inside a chart, a diagram or rebuilt product UI, the core value |
30
+ | PDH-F3 reduced motion | Every animation and transition honours `prefers-reduced-motion`; flashing follows PDH-F3 |
31
+ | PDH-F4 status | An icon or label as well as colour. `StatusIndicator` and `Sticker` already do this |
32
+
33
+ Product UI shown in a fixed frame (a slide, a video) takes the core's fixed-frame value instead.
34
+
35
+ ## Types
36
+
37
+ | Type | What | Governed by |
38
+ | ---- | ---- | ----------- |
39
+ | `screen` | A route, page, panel or modal flow in app code | This file. It bends nothing here without a departure row |
40
+ | `component` | A component or pattern in PDS itself | `REVIEW.md` and the `design-system-component-authoring` skill, plus this file's parameters |
41
+
42
+ No type bends the floor or PDH-P1.
43
+
44
+ ## What `persona` means here
45
+
46
+ Product UI is always `persona` (PDH-M4): PDS as shipped, in the app's theme. Briefs and receipts
47
+ record `brand: persona` without asking. Work that needs to be `unbranded` isn't covered by this
48
+ standard.
49
+
50
+ ## Screen brief
51
+
52
+ Record these in the PR body before building, so the source is consulted at intake (PDH-S2):
53
+
54
+ - **Intent:** who uses the screen, to do what, in one line.
55
+ - **Source:** the live product, a Figma link, or none. Say so if a source couldn't be reached.
56
+ - **PDS version:** from the app's lockfile.
57
+ - **Brand:** `persona`.
58
+ - **Lane:** `new-screen`, or none.
59
+
60
+ ## Lanes
61
+
62
+ A lane is a strict path for one common task. A PR opts in with a commit trailer, and the diff is then
63
+ held to the lane's allow-list. Work that fits no lane goes without a trailer, through normal review;
64
+ don't stretch a lane to fit it.
65
+
66
+ Lanes are data, in [lanes.json](lanes.json). They name roles, not paths. Each app's harness config
67
+ maps roles to its own paths, so one lane works in any app.
68
+
69
+ ### `new-screen`
70
+
71
+ One new screen built from PDS, with no designer (App Builder, internal apps).
72
+
73
+ - **Opt in:** a `Harness-Task: new-screen` trailer on any commit in the PR.
74
+ - **Allowed:** one new screen directory (`screen`), its tests and stories (`screen-tests`), and
75
+ locale files (`locale`).
76
+ - **Reported, not failed:** edits to the route table (`route-table`), so the screen can be reached.
77
+ - **Forbidden:** shared components (`shared`), theme (`theme`), and code mirrored from PDS
78
+ (`pds-mirror`). A change there is its own PR, or a PDS change.
79
+ - A file that matches no allowed or reported role fails. A file that matches a forbidden role is
80
+ forbidden, even if it also matches another role.
81
+ - Build only from PDS patterns, components and tokens, per [SKILL.md](SKILL.md), and finish with the
82
+ "Before you hand it over" list in [TOKENS.md](TOKENS.md).
83
+
84
+ ### Adding a lane
85
+
86
+ Add an entry under `lanes` in `lanes.json`: a `description`, `newScreens` (how many new screen
87
+ directories the diff may add; `0` for an edit-only lane), and `allow`, `note` and `forbid` role
88
+ lists. Add a role only when no existing one covers the paths. Then describe the lane here.
89
+ Specialized work gets its own lane; never loosen `new-screen` to fit it.
90
+
91
+ ## Checks
92
+
93
+ All of these are review until the screen checker ships. When it does, it fails only on new findings;
94
+ existing ones are grandfathered.
95
+
96
+ | Rule | Source | Check |
97
+ | ---- | ------ | ----- |
98
+ | Painted colours are semantic: no hex, no `Color.*` outside the `semanticColor` fallback | PDS; keeps PDH-F1 in dark mode | Review |
99
+ | Complete `Typography` styles, never individual font properties or a raw `font-size` | PDS; makes PDH-F2 checkable | Review |
100
+ | No copy under 11 px. The 10 px routes are `Typography.TextExtraSmall` and `TextExtraSmallMono`, `theme.text.paragraph.xs`, the text mixin's `xs` (`Paragraph` / `Label` `size="xs"`), and the `TextMono` + `TextExtraSmall.fontSize` composite | PDH-F2 | Review. Report-only once automated, since a text check can't tell copy from a label inside a graphic |
101
+ | `@keyframes`, `animation` or `transition` only with a `prefers-reduced-motion` block | PDH-F3 | Review. Report-only once automated |
102
+ | No hand-rolled `<table>`, `<th>` or `<td>` | PDS (Table Guidelines in SKILL.md) | Review |
103
+ | Contrast | PDH-F1 | Review |
104
+ | Status not by colour alone | PDH-F4 | Review |
105
+ | The diff stays within its lane | `lanes.json` | Review |
106
+
107
+ ## Departure ledger
108
+
109
+ Departures from this file or the core that aren't tightenings, one row each, in the PDH-M3 format:
110
+ `rule ID · what changed · scope · reason (medium or audience) · owner · expiry or "standing" · date`.
111
+ A one-screen departure goes in that PR's brief instead.
112
+
113
+ | Rule | What changed | Scope | Reason | Owner | Expiry | Date |
114
+ | ---- | ------------ | ----- | ------ | ----- | ------ | ---- |
115
+ | PDH-F2 | 10 px mono text (`TextMono` + `TextExtraSmall.fontSize`) | `components/TechnicalSticker/TechnicalSticker.tsx`, the `font-size` in the `TechnicalText` style | PDS's existing 10 px step for dense technical identifiers; predates this standard | Michael Hu | standing | 2026-10-26 |
116
+ | PDH-F2 | 10 px mono pill text (`Typography.TextExtraSmall`, mono family) | `components/SmartTextInput/PillType.tsx`, the `PillType` style | PDS's existing 10 px step for type pills in the editor; predates this standard | Michael Hu | standing | 2026-10-26 |
117
+ | PDH-F2 | 10 px helper copy (`paragraphMixins.xs`); copy, not a label inside a graphic | `components/DataTable/TableControls/FiltersV2/FilterPopover/FilterPopover.tsx`, the `Footer` style | PDS's existing 10 px step for the filter popover's field note; predates this standard | Michael Hu | standing | 2026-10-26 |
118
+ | PDH-F2 | 10 px `xs` paragraph mixin (`Typography.TextExtraSmall`), reached by `Paragraph` / `Label` `size="xs"` | `mixins/text.ts` `xs` | PDS's existing 10 px step, kept for current callers; predates this standard | Michael Hu | standing | 2026-10-26 |
119
+ | PDH-F2 | 10 px theme value (`Typography.TextExtraSmall`) | `theme.ts` `text.paragraph.xs` | Part of the theme contract consumers compile against; predates this standard | Michael Hu | standing | 2026-10-26 |
120
+
121
+ `lib/middleTruncateText.ts` needs no row: its 10 px `DEFAULT_FONT` only measures text on a canvas
122
+ and paints nothing.
123
+
124
+ ## Receipt
125
+
126
+ Each screen records the receipt core (design-harness `spec/receipt.md`) plus `brand: persona`,
127
+ `departures`, and `shared_components_touched` (the shared components changed, with every screen they
128
+ reach). Until the screen receipt is automated, the screen brief in the PR body stands in for it.
129
+
130
+ ## Citations and tightenings
131
+
132
+ No tightenings for now: every value above is the core's value.
133
+
134
+ Core rules cited, all at `persona-id/design-harness` `core-v0.3`: PDH-P1, PDH-P2 (ranks 1–2) · PDH-F1 to PDH-F4 ·
135
+ PDH-S1, PDH-S2 · PDH-M1, host side (a screen hosting an illustration, such as an empty state, sets the
136
+ surface it sits on) · PDH-M3 · PDH-M4 · PDH-M5 (a correction meant to hold lands as a PR to this
137
+ file). Not cited: PDH-M2, campaigns don't apply to product UI.
@@ -634,9 +634,11 @@ Typography.TextMediumLink // 14px, regular, underlined
634
634
  Typography.TextSmall // 12px, regular
635
635
  Typography.TextSmallBold // 12px, bold
636
636
  Typography.TextSmallLink // 12px, regular, underlined
637
- Typography.TextExtraSmall // 10px
637
+ Typography.TextExtraSmall // 10px, below the 11px minimum for text the user reads (STANDARD.md)
638
638
 
639
639
  Typography.TextMono // 14px, monospace
640
+ Typography.TextSmallMono // 12px, monospace
641
+ Typography.TextExtraSmallMono // 10px, monospace, below the 11px minimum for text the user reads (STANDARD.md)
640
642
  ```
641
643
 
642
644
  ## Radius
@@ -0,0 +1,22 @@
1
+ {
2
+ "version": 1,
3
+ "trailer": "Harness-Task",
4
+ "roles": {
5
+ "screen": "Files inside the screen or route directory the lane adds. The app's harness config names where screen directories live.",
6
+ "screen-tests": "Tests and stories for that screen kept outside its directory.",
7
+ "locale": "Locale (translation) files.",
8
+ "route-table": "The app's route or navigation table.",
9
+ "shared": "Components, hooks and layouts used by more than one screen.",
10
+ "theme": "Theme, global styles and token overrides.",
11
+ "pds-mirror": "Code mirrored or copied from @persona/design-system."
12
+ },
13
+ "lanes": {
14
+ "new-screen": {
15
+ "description": "One new screen built from PDS patterns and components, with no designer.",
16
+ "newScreens": 1,
17
+ "allow": ["screen", "screen-tests", "locale"],
18
+ "note": ["route-table"],
19
+ "forbid": ["shared", "theme", "pds-mirror"]
20
+ }
21
+ }
22
+ }