@sovereignfs/ui 0.40.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/dist/Accordion.module.css +3 -0
  2. package/dist/Alert.module.css +62 -0
  3. package/dist/AspectRatio.module.css +15 -0
  4. package/dist/Badge.module.css +75 -9
  5. package/dist/BalanceChip.module.css +32 -0
  6. package/dist/Breadcrumb.module.css +49 -0
  7. package/dist/Button.module.css +12 -3
  8. package/dist/ButtonGroup.module.css +29 -0
  9. package/dist/Card.module.css +6 -0
  10. package/dist/Checkbox.module.css +3 -1
  11. package/dist/Collapsible.module.css +70 -0
  12. package/dist/Combobox.module.css +122 -0
  13. package/dist/Command.module.css +80 -0
  14. package/dist/ConfirmDialog.module.css +5 -1
  15. package/dist/DataTable.module.css +28 -0
  16. package/dist/DatePicker.module.css +6 -2
  17. package/dist/Dialog.module.css +3 -0
  18. package/dist/HoverCard.module.css +3 -0
  19. package/dist/Input.module.css +6 -1
  20. package/dist/Item.module.css +70 -0
  21. package/dist/Kbd.module.css +14 -0
  22. package/dist/Label.module.css +11 -0
  23. package/dist/Marker.module.css +33 -0
  24. package/dist/MemberMultiSelect.module.css +27 -0
  25. package/dist/Menu.module.css +8 -1
  26. package/dist/Message.module.css +99 -0
  27. package/dist/MessageScroller.module.css +54 -0
  28. package/dist/NavigationMenu.module.css +53 -0
  29. package/dist/Pagination.module.css +98 -0
  30. package/dist/Progress.module.css +20 -0
  31. package/dist/RadioGroup.module.css +88 -0
  32. package/dist/Resizable.module.css +70 -0
  33. package/dist/ScrollArea.module.css +20 -0
  34. package/dist/Select.module.css +7 -3
  35. package/dist/Slider.module.css +95 -0
  36. package/dist/Table.module.css +45 -0
  37. package/dist/Tabs.module.css +6 -1
  38. package/dist/Toggle.module.css +6 -1
  39. package/dist/Typography.module.css +47 -0
  40. package/dist/index.d.ts +698 -5
  41. package/dist/index.js +1938 -482
  42. package/dist/tokens/primitives.css +22 -8
  43. package/package.json +1 -1
  44. package/src/components/Accordion/Accordion.module.css +3 -0
  45. package/src/components/Accordion/Accordion.stories.tsx +110 -0
  46. package/src/components/Accordion/Accordion.tsx +53 -0
  47. package/src/components/Accordion/__tests__/Accordion.test.tsx +61 -0
  48. package/src/components/Alert/Alert.module.css +62 -0
  49. package/src/components/Alert/Alert.stories.tsx +96 -0
  50. package/src/components/Alert/Alert.tsx +58 -0
  51. package/src/components/Alert/__tests__/Alert.test.tsx +75 -0
  52. package/src/components/AspectRatio/AspectRatio.module.css +15 -0
  53. package/src/components/AspectRatio/AspectRatio.stories.tsx +78 -0
  54. package/src/components/AspectRatio/AspectRatio.tsx +21 -0
  55. package/src/components/AspectRatio/__tests__/AspectRatio.test.tsx +27 -0
  56. package/src/components/Badge/Badge.module.css +75 -9
  57. package/src/components/Badge/Badge.stories.tsx +109 -1
  58. package/src/components/Badge/Badge.tsx +30 -2
  59. package/src/components/Badge/__tests__/Badge.test.tsx +26 -2
  60. package/src/components/BalanceChip/BalanceChip.module.css +32 -0
  61. package/src/components/BalanceChip/BalanceChip.stories.tsx +45 -0
  62. package/src/components/BalanceChip/BalanceChip.tsx +33 -0
  63. package/src/components/Breadcrumb/Breadcrumb.module.css +49 -0
  64. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +47 -0
  65. package/src/components/Breadcrumb/Breadcrumb.tsx +57 -0
  66. package/src/components/Breadcrumb/__tests__/Breadcrumb.test.tsx +52 -0
  67. package/src/components/Button/Button.module.css +12 -3
  68. package/src/components/Button/Button.stories.tsx +3 -2
  69. package/src/components/Button/Button.tsx +1 -1
  70. package/src/components/Button/__tests__/Button.test.tsx +10 -0
  71. package/src/components/ButtonGroup/ButtonGroup.module.css +29 -0
  72. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +57 -0
  73. package/src/components/ButtonGroup/ButtonGroup.tsx +27 -0
  74. package/src/components/ButtonGroup/__tests__/ButtonGroup.test.tsx +29 -0
  75. package/src/components/Card/Card.module.css +6 -0
  76. package/src/components/Checkbox/Checkbox.module.css +3 -1
  77. package/src/components/Collapsible/Collapsible.module.css +70 -0
  78. package/src/components/Collapsible/Collapsible.stories.tsx +62 -0
  79. package/src/components/Collapsible/Collapsible.tsx +66 -0
  80. package/src/components/Collapsible/__tests__/Collapsible.test.tsx +71 -0
  81. package/src/components/Combobox/Combobox.module.css +122 -0
  82. package/src/components/Combobox/Combobox.stories.tsx +79 -0
  83. package/src/components/Combobox/Combobox.tsx +186 -0
  84. package/src/components/Combobox/__tests__/Combobox.test.tsx +158 -0
  85. package/src/components/Command/Command.module.css +80 -0
  86. package/src/components/Command/Command.stories.tsx +104 -0
  87. package/src/components/Command/Command.tsx +168 -0
  88. package/src/components/Command/__tests__/Command.test.tsx +162 -0
  89. package/src/components/ConfirmDialog/ConfirmDialog.module.css +5 -1
  90. package/src/components/ContextMenu/ContextMenu.stories.tsx +81 -0
  91. package/src/components/ContextMenu/ContextMenu.tsx +100 -0
  92. package/src/components/ContextMenu/__tests__/ContextMenu.test.tsx +87 -0
  93. package/src/components/CurrencyInput/CurrencyInput.stories.tsx +50 -0
  94. package/src/components/CurrencyInput/CurrencyInput.tsx +60 -0
  95. package/src/components/DataTable/DataTable.module.css +28 -0
  96. package/src/components/DataTable/DataTable.stories.tsx +74 -0
  97. package/src/components/DataTable/DataTable.tsx +154 -0
  98. package/src/components/DataTable/__tests__/DataTable.test.tsx +123 -0
  99. package/src/components/DatePicker/DatePicker.module.css +6 -2
  100. package/src/components/Dialog/Dialog.module.css +3 -0
  101. package/src/components/HoverCard/HoverCard.module.css +3 -0
  102. package/src/components/HoverCard/HoverCard.stories.tsx +66 -0
  103. package/src/components/HoverCard/HoverCard.tsx +111 -0
  104. package/src/components/HoverCard/__tests__/HoverCard.test.tsx +99 -0
  105. package/src/components/Icon/icons/circle-check.tsx +21 -0
  106. package/src/components/Icon/icons/circle-x.tsx +22 -0
  107. package/src/components/Icon/icons/index.ts +8 -0
  108. package/src/components/Input/Input.module.css +6 -1
  109. package/src/components/Item/Item.module.css +70 -0
  110. package/src/components/Item/Item.stories.tsx +62 -0
  111. package/src/components/Item/Item.tsx +54 -0
  112. package/src/components/Item/__tests__/Item.test.tsx +39 -0
  113. package/src/components/Kbd/Kbd.module.css +14 -0
  114. package/src/components/Kbd/Kbd.stories.tsx +32 -0
  115. package/src/components/Kbd/Kbd.tsx +12 -0
  116. package/src/components/Kbd/__tests__/Kbd.test.tsx +14 -0
  117. package/src/components/Label/Label.module.css +11 -0
  118. package/src/components/Label/Label.stories.tsx +40 -0
  119. package/src/components/Label/Label.tsx +24 -0
  120. package/src/components/Label/__tests__/Label.test.tsx +32 -0
  121. package/src/components/Marker/Marker.module.css +33 -0
  122. package/src/components/Marker/Marker.stories.tsx +39 -0
  123. package/src/components/Marker/Marker.tsx +34 -0
  124. package/src/components/Marker/__tests__/Marker.test.tsx +23 -0
  125. package/src/components/MemberMultiSelect/MemberMultiSelect.module.css +27 -0
  126. package/src/components/MemberMultiSelect/MemberMultiSelect.stories.tsx +74 -0
  127. package/src/components/MemberMultiSelect/MemberMultiSelect.tsx +67 -0
  128. package/src/components/Menu/Menu.module.css +8 -1
  129. package/src/components/Menu/Menu.tsx +30 -8
  130. package/src/components/Menubar/Menubar.stories.tsx +52 -0
  131. package/src/components/Menubar/Menubar.tsx +42 -0
  132. package/src/components/Menubar/__tests__/Menubar.test.tsx +45 -0
  133. package/src/components/Message/Message.module.css +99 -0
  134. package/src/components/Message/Message.stories.tsx +79 -0
  135. package/src/components/Message/Message.tsx +41 -0
  136. package/src/components/Message/__tests__/Message.test.tsx +46 -0
  137. package/src/components/MessageScroller/MessageScroller.module.css +54 -0
  138. package/src/components/MessageScroller/MessageScroller.stories.tsx +84 -0
  139. package/src/components/MessageScroller/MessageScroller.tsx +72 -0
  140. package/src/components/MessageScroller/__tests__/MessageScroller.test.tsx +105 -0
  141. package/src/components/NavigationMenu/NavigationMenu.module.css +53 -0
  142. package/src/components/NavigationMenu/NavigationMenu.stories.tsx +58 -0
  143. package/src/components/NavigationMenu/NavigationMenu.tsx +125 -0
  144. package/src/components/NavigationMenu/__tests__/NavigationMenu.test.tsx +93 -0
  145. package/src/components/Pagination/Pagination.module.css +98 -0
  146. package/src/components/Pagination/Pagination.stories.tsx +49 -0
  147. package/src/components/Pagination/Pagination.tsx +87 -0
  148. package/src/components/Pagination/__tests__/Pagination.test.tsx +56 -0
  149. package/src/components/Progress/Progress.module.css +20 -0
  150. package/src/components/Progress/Progress.stories.tsx +40 -0
  151. package/src/components/Progress/Progress.tsx +35 -0
  152. package/src/components/Progress/__tests__/Progress.test.tsx +31 -0
  153. package/src/components/RadioGroup/RadioGroup.module.css +88 -0
  154. package/src/components/RadioGroup/RadioGroup.stories.tsx +69 -0
  155. package/src/components/RadioGroup/RadioGroup.tsx +99 -0
  156. package/src/components/RadioGroup/__tests__/RadioGroup.test.tsx +59 -0
  157. package/src/components/Resizable/Resizable.module.css +70 -0
  158. package/src/components/Resizable/Resizable.stories.tsx +82 -0
  159. package/src/components/Resizable/Resizable.tsx +313 -0
  160. package/src/components/Resizable/__tests__/Resizable.test.tsx +128 -0
  161. package/src/components/ScrollArea/ScrollArea.module.css +20 -0
  162. package/src/components/ScrollArea/ScrollArea.stories.tsx +57 -0
  163. package/src/components/ScrollArea/ScrollArea.tsx +27 -0
  164. package/src/components/ScrollArea/__tests__/ScrollArea.test.tsx +39 -0
  165. package/src/components/Select/Select.module.css +7 -3
  166. package/src/components/Slider/Slider.module.css +95 -0
  167. package/src/components/Slider/Slider.stories.tsx +64 -0
  168. package/src/components/Slider/Slider.tsx +77 -0
  169. package/src/components/Slider/__tests__/Slider.test.tsx +45 -0
  170. package/src/components/SplitMethodSelector/SplitMethodSelector.stories.tsx +33 -0
  171. package/src/components/SplitMethodSelector/SplitMethodSelector.tsx +43 -0
  172. package/src/components/Table/Table.module.css +45 -0
  173. package/src/components/Table/Table.stories.tsx +125 -0
  174. package/src/components/Table/Table.tsx +51 -0
  175. package/src/components/Table/__tests__/Table.test.tsx +50 -0
  176. package/src/components/Tabs/Tabs.module.css +6 -1
  177. package/src/components/Toggle/Toggle.module.css +6 -1
  178. package/src/components/Typography/Typography.module.css +47 -0
  179. package/src/components/Typography/Typography.stories.tsx +62 -0
  180. package/src/components/Typography/Typography.tsx +30 -0
  181. package/src/components/Typography/__tests__/Typography.test.tsx +34 -0
  182. package/src/index.ts +92 -1
  183. package/src/stories/DesignSystemOverview.stories.tsx +706 -2
  184. package/src/stories/MobilePatterns.stories.tsx +8 -2
  185. package/src/stories/TokenGallery.stories.tsx +112 -16
  186. package/src/tokens/primitives.css +22 -8
@@ -0,0 +1,3 @@
1
+ .root {
2
+ border-top: 1px solid var(--sv-color-border);
3
+ }
@@ -0,0 +1,62 @@
1
+ .alert {
2
+ display: flex;
3
+ align-items: flex-start;
4
+ gap: var(--sv-space-2);
5
+ padding: var(--sv-space-3) var(--sv-space-4);
6
+ border: 1px solid transparent;
7
+ border-radius: var(--sv-radius-md);
8
+ font-size: var(--sv-font-size-sm);
9
+ }
10
+
11
+ .icon {
12
+ flex-shrink: 0;
13
+ /* Optically align to the first line of text rather than the box's
14
+ vertical center — matches how the heading/body cap-height sits. */
15
+ margin-top: 2px;
16
+ }
17
+
18
+ .content {
19
+ display: flex;
20
+ flex-direction: column;
21
+ gap: var(--sv-space-1);
22
+ min-width: 0;
23
+ }
24
+
25
+ .heading {
26
+ margin: 0;
27
+ font-weight: var(--sv-font-weight-semibold);
28
+ }
29
+
30
+ .body {
31
+ margin: 0;
32
+ }
33
+
34
+ .info {
35
+ background: var(--sv-color-info-surface);
36
+ border-color: var(--sv-color-info-border);
37
+ color: var(--sv-color-info-text);
38
+ }
39
+
40
+ .success {
41
+ background: var(--sv-color-success-surface);
42
+ border-color: var(--sv-color-success-border);
43
+ color: var(--sv-color-success-text);
44
+ }
45
+
46
+ .warning {
47
+ background: var(--sv-color-warning-surface);
48
+ border-color: var(--sv-color-warning-border);
49
+ color: var(--sv-color-warning-text);
50
+ }
51
+
52
+ .error {
53
+ background: var(--sv-color-error-surface);
54
+ border-color: var(--sv-color-error-border);
55
+ color: var(--sv-color-error-text);
56
+ }
57
+
58
+ .neutral {
59
+ background: var(--sv-color-surface-sunken);
60
+ border-color: var(--sv-color-border);
61
+ color: var(--sv-color-text-primary);
62
+ }
@@ -0,0 +1,15 @@
1
+ .root {
2
+ position: relative;
3
+ width: 100%;
4
+ overflow: hidden;
5
+ border-radius: var(--sv-radius-md);
6
+ }
7
+
8
+ /* A single direct child (img/video/iframe) fills the ratio box. */
9
+ .root > :global(*) {
10
+ position: absolute;
11
+ inset: 0;
12
+ width: 100%;
13
+ height: 100%;
14
+ object-fit: cover;
15
+ }
@@ -4,27 +4,28 @@
4
4
  gap: var(--sv-space-1);
5
5
  border-radius: var(--sv-radius-sm);
6
6
  font-family: var(--sv-font-family);
7
- font-size: var(--sv-font-size-xs);
8
7
  line-height: 1;
9
8
  white-space: nowrap;
10
9
  user-select: none;
10
+ }
11
+
12
+ /* Applied by default (uppercase=true) — opt out for a title-case badge that
13
+ renders children exactly as passed in. */
14
+ .uppercase {
11
15
  text-transform: uppercase;
12
16
  letter-spacing: 0.05em;
13
17
  }
14
18
 
15
- /* role — neutral fill, border, title case */
19
+ /* role — neutral fill, border */
16
20
  .role {
17
- padding: 2px var(--sv-space-2);
18
21
  background: var(--sv-color-surface-sunken);
19
22
  border: 1px solid var(--sv-color-border);
20
23
  color: var(--sv-color-text-primary);
21
- font-size: var(--sv-font-size-label);
22
24
  font-weight: var(--sv-font-weight-semibold);
23
25
  }
24
26
 
25
27
  /* status — tinted chip with leading colour dot; colour set by chip* classes below */
26
28
  .status {
27
- padding: 2px var(--sv-space-2) 2px var(--sv-space-1);
28
29
  font-weight: var(--sv-font-weight-medium);
29
30
  }
30
31
 
@@ -54,23 +55,88 @@
54
55
 
55
56
  /* mono — monospace font, neutral surface, for type tags / versions */
56
57
  .mono {
57
- padding: 2px var(--sv-space-2);
58
58
  background: var(--sv-color-surface-sunken);
59
59
  border: 1px solid var(--sv-color-border);
60
60
  color: var(--sv-color-text-muted);
61
61
  font-family: var(--sv-font-family-mono);
62
+ }
63
+
64
+ /* Size × variant — font-size and padding are the two axes that change
65
+ together, so each combination is one compound rule rather than two
66
+ composed partials fighting over the same properties. `.role.md`,
67
+ `.status.md`, and `.mono.md` reproduce the badge's original (and, until
68
+ now, only) sizing exactly, so the default (no `size` prop) renders
69
+ pixel-identical to before this scale existed. */
70
+ .role.sm {
71
+ padding: 1px var(--sv-space-1);
72
+ font-size: var(--sv-font-size-label);
73
+ }
74
+
75
+ .role.md {
76
+ padding: 2px var(--sv-space-2);
77
+ font-size: var(--sv-font-size-label);
78
+ }
79
+
80
+ .role.lg {
81
+ padding: 3px var(--sv-space-3);
82
+ font-size: var(--sv-font-size-sm);
83
+ }
84
+
85
+ .mono.sm {
86
+ padding: 1px var(--sv-space-1);
87
+ font-size: var(--sv-font-size-label);
88
+ }
89
+
90
+ .mono.md {
91
+ padding: 2px var(--sv-space-2);
62
92
  font-size: var(--sv-font-size-xs);
63
93
  }
64
94
 
65
- /* Status dot */
95
+ .mono.lg {
96
+ padding: 3px var(--sv-space-3);
97
+ font-size: var(--sv-font-size-sm);
98
+ }
99
+
100
+ /* status keeps a tighter left edge than right at every size — the dot +
101
+ gap already read as space before the text, so a full padding-inline-start
102
+ would double it up. */
103
+ .status.sm {
104
+ padding: 1px var(--sv-space-1) 1px 3px;
105
+ font-size: var(--sv-font-size-label);
106
+ }
107
+
108
+ .status.md {
109
+ padding: 2px var(--sv-space-2) 2px var(--sv-space-1);
110
+ font-size: var(--sv-font-size-xs);
111
+ }
112
+
113
+ .status.lg {
114
+ padding: 3px var(--sv-space-3) 3px var(--sv-space-2);
115
+ font-size: var(--sv-font-size-sm);
116
+ }
117
+
118
+ /* Status dot — scales with size */
66
119
  .dot {
67
120
  display: inline-block;
68
- width: 6px;
69
- height: 6px;
70
121
  border-radius: var(--sv-radius-full);
71
122
  flex-shrink: 0;
72
123
  }
73
124
 
125
+ .sm .dot {
126
+ width: 5px;
127
+ height: 5px;
128
+ }
129
+
130
+ .md .dot {
131
+ width: 6px;
132
+ height: 6px;
133
+ }
134
+
135
+ .lg .dot {
136
+ width: 8px;
137
+ height: 8px;
138
+ }
139
+
74
140
  .dotGreen {
75
141
  background: var(--sv-color-success-text);
76
142
  }
@@ -0,0 +1,32 @@
1
+ .chip {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ max-width: 100%;
5
+ min-height: 24px;
6
+ padding: 2px var(--sv-space-2);
7
+ border: 1px solid var(--sv-color-border);
8
+ border-radius: var(--sv-radius-full);
9
+ font-family: var(--sv-font-family);
10
+ font-size: var(--sv-font-size-xs);
11
+ font-weight: var(--sv-font-weight-semibold);
12
+ line-height: 1.2;
13
+ white-space: nowrap;
14
+ }
15
+
16
+ .owed {
17
+ color: var(--sv-color-success-text);
18
+ background: var(--sv-color-success-surface);
19
+ border-color: var(--sv-color-success-border);
20
+ }
21
+
22
+ .owes {
23
+ color: var(--sv-color-error-text);
24
+ background: var(--sv-color-error-surface);
25
+ border-color: var(--sv-color-error-border);
26
+ }
27
+
28
+ .settled {
29
+ color: var(--sv-color-text-muted);
30
+ background: var(--sv-color-surface-sunken);
31
+ border-color: var(--sv-color-border);
32
+ }
@@ -0,0 +1,49 @@
1
+ .nav {
2
+ min-width: 0;
3
+ }
4
+
5
+ .list {
6
+ display: flex;
7
+ flex-wrap: wrap;
8
+ align-items: center;
9
+ gap: var(--sv-space-1);
10
+ margin: 0;
11
+ padding: 0;
12
+ list-style: none;
13
+ }
14
+
15
+ .item {
16
+ display: inline-flex;
17
+ align-items: center;
18
+ gap: var(--sv-space-1);
19
+ }
20
+
21
+ .link {
22
+ font-size: var(--sv-font-size-sm);
23
+ color: var(--sv-color-text-muted);
24
+ text-decoration: none;
25
+ }
26
+
27
+ @media (hover: hover) {
28
+ .link:hover {
29
+ color: var(--sv-color-text-primary);
30
+ text-decoration: underline;
31
+ }
32
+ }
33
+
34
+ .link:focus-visible {
35
+ outline: 2px solid var(--sv-color-focus-ring);
36
+ outline-offset: 2px;
37
+ border-radius: var(--sv-radius-sm);
38
+ }
39
+
40
+ .current {
41
+ font-size: var(--sv-font-size-sm);
42
+ font-weight: var(--sv-font-weight-medium);
43
+ color: var(--sv-color-text-primary);
44
+ }
45
+
46
+ .separator {
47
+ color: var(--sv-color-text-muted);
48
+ flex-shrink: 0;
49
+ }
@@ -37,14 +37,23 @@
37
37
  }
38
38
  }
39
39
 
40
- /* Sizes */
40
+ /* Sizes — 32px / 36px / 40px rendered height (font-size + padding*2 + border*2).
41
+ Vertical padding is hardcoded where the --sv-space-* scale can't hit the
42
+ exact target height; horizontal padding stays token-based, growing with
43
+ size for visual rhythm with the rest of this scale. */
41
44
  .sm {
42
- padding: var(--sv-space-1) var(--sv-space-3);
45
+ padding: var(--sv-space-2) var(--sv-space-3);
43
46
  font-size: var(--sv-font-size-sm);
44
47
  }
45
48
 
46
49
  .md {
47
- padding: 13px var(--sv-space-4);
50
+ padding: 10px var(--sv-space-4);
51
+ font-size: var(--sv-font-size-sm);
52
+ font-weight: var(--sv-font-weight-semibold);
53
+ }
54
+
55
+ .lg {
56
+ padding: var(--sv-space-3) var(--sv-space-5);
48
57
  font-size: var(--sv-font-size-sm);
49
58
  font-weight: var(--sv-font-weight-semibold);
50
59
  }
@@ -0,0 +1,29 @@
1
+ .root {
2
+ display: inline-flex;
3
+ }
4
+
5
+ .root > :global(button),
6
+ .root > :global(a) {
7
+ border-radius: 0;
8
+ margin-left: -1px;
9
+ }
10
+
11
+ .root > :global(button):first-child,
12
+ .root > :global(a):first-child {
13
+ margin-left: 0;
14
+ border-top-left-radius: var(--sv-radius-md);
15
+ border-bottom-left-radius: var(--sv-radius-md);
16
+ }
17
+
18
+ .root > :global(button):last-child,
19
+ .root > :global(a):last-child {
20
+ border-top-right-radius: var(--sv-radius-md);
21
+ border-bottom-right-radius: var(--sv-radius-md);
22
+ }
23
+
24
+ /* Keep the focus ring above sibling borders instead of being clipped by them. */
25
+ .root > :global(button):focus-visible,
26
+ .root > :global(a):focus-visible {
27
+ position: relative;
28
+ z-index: 1;
29
+ }
@@ -1,3 +1,9 @@
1
+ /* Sizing audit: reviewed padding/radius against this scale's other
2
+ surfaces. Left unchanged rather than edited: Card is consumed across
3
+ most first-party plugin screens, and changing its padding/radius
4
+ site-wide has a blast radius no visual regression tooling exists yet to
5
+ verify (see epic task 9.14, not landed). Revisit once that tooling
6
+ exists. */
1
7
  .card {
2
8
  background: var(--sv-color-surface-raised);
3
9
  border: 1px solid var(--sv-color-border);
@@ -5,7 +5,9 @@
5
5
  cursor: pointer;
6
6
  }
7
7
 
8
- /* The visual box */
8
+ /* The visual box. Sizing audit: reviewed against the rest of this scale's
9
+ compact controls. Kept the 18px box unchanged — deliberately on the
10
+ larger side for touch-friendliness, not a gap to close. */
9
11
  .box {
10
12
  --checkbox-box-size: 18px;
11
13
  position: relative;
@@ -0,0 +1,70 @@
1
+ .root {
2
+ border-bottom: 1px solid var(--sv-color-border);
3
+ }
4
+
5
+ .trigger {
6
+ display: flex;
7
+ align-items: center;
8
+ justify-content: space-between;
9
+ gap: var(--sv-space-2);
10
+ width: 100%;
11
+ padding: var(--sv-space-3) 0;
12
+ border: none;
13
+ background: transparent;
14
+ color: var(--sv-color-text-primary);
15
+ font-family: var(--sv-font-family);
16
+ font-size: var(--sv-font-size-sm);
17
+ font-weight: var(--sv-font-weight-medium);
18
+ text-align: left;
19
+ cursor: pointer;
20
+ }
21
+
22
+ .trigger:focus-visible {
23
+ outline: 2px solid var(--sv-color-focus-ring);
24
+ outline-offset: 2px;
25
+ border-radius: var(--sv-radius-sm);
26
+ }
27
+
28
+ .triggerLabel {
29
+ min-width: 0;
30
+ }
31
+
32
+ .chevron {
33
+ flex-shrink: 0;
34
+ color: var(--sv-color-text-muted);
35
+ transition: transform 0.2s ease;
36
+ }
37
+
38
+ .chevronOpen {
39
+ transform: rotate(180deg);
40
+ }
41
+
42
+ /* Expand/collapse via grid-template-rows (0fr closed, 1fr open) instead of
43
+ animating height, which can't transition to/from auto in CSS. The inner
44
+ wrapper clips content during the transition. */
45
+ .contentWrapper {
46
+ display: grid;
47
+ grid-template-rows: 0fr;
48
+ transition: grid-template-rows 0.2s ease;
49
+ }
50
+
51
+ .contentWrapper[data-open='true'] {
52
+ grid-template-rows: 1fr;
53
+ }
54
+
55
+ .contentInner {
56
+ overflow: hidden;
57
+ font-size: var(--sv-font-size-sm);
58
+ color: var(--sv-color-text-primary);
59
+ }
60
+
61
+ .contentWrapper[data-open='true'] .contentInner {
62
+ padding-bottom: var(--sv-space-3);
63
+ }
64
+
65
+ @media (prefers-reduced-motion: reduce) {
66
+ .contentWrapper,
67
+ .chevron {
68
+ transition: none;
69
+ }
70
+ }
@@ -0,0 +1,122 @@
1
+ /* Trigger styled to match Input/DatePicker's height/border/radius/focus ring
2
+ * for visual consistency as a form field. */
3
+
4
+ .trigger {
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: space-between;
8
+ gap: var(--sv-space-2);
9
+ width: 100%;
10
+ height: 36px;
11
+ box-sizing: border-box;
12
+ padding: 4px var(--sv-space-3);
13
+ font-family: var(--sv-font-family);
14
+ font-size: var(--sv-font-size-sm);
15
+ line-height: 1.5;
16
+ color: var(--sv-color-text-primary);
17
+ background-color: var(--sv-color-surface);
18
+ border: 1px solid var(--sv-color-border-strong);
19
+ border-radius: var(--sv-radius-md);
20
+ cursor: pointer;
21
+ transition:
22
+ border-color 0.15s ease,
23
+ box-shadow 0.15s ease;
24
+ }
25
+
26
+ @media (pointer: coarse) {
27
+ .trigger {
28
+ font-size: var(--sv-font-size-md);
29
+ }
30
+ }
31
+
32
+ .trigger:focus-visible {
33
+ outline: none;
34
+ border-color: var(--sv-color-accent);
35
+ box-shadow: 0 0 0 2px var(--sv-color-focus-ring);
36
+ }
37
+
38
+ .trigger:disabled {
39
+ opacity: 0.5;
40
+ cursor: not-allowed;
41
+ }
42
+
43
+ .triggerValue {
44
+ overflow: hidden;
45
+ color: var(--sv-color-text-primary);
46
+ text-overflow: ellipsis;
47
+ white-space: nowrap;
48
+ }
49
+
50
+ .triggerPlaceholder {
51
+ color: var(--sv-color-text-muted);
52
+ }
53
+
54
+ .body {
55
+ display: flex;
56
+ flex-direction: column;
57
+ max-height: min(60vh, 360px);
58
+ }
59
+
60
+ .search {
61
+ flex-shrink: 0;
62
+ width: 100%;
63
+ border: none;
64
+ border-bottom: 1px solid var(--sv-color-border);
65
+ background: transparent;
66
+ color: var(--sv-color-text-primary);
67
+ font: inherit;
68
+ font-size: var(--sv-font-size-md);
69
+ padding: var(--sv-space-3);
70
+ }
71
+
72
+ .search:focus {
73
+ outline: none;
74
+ }
75
+
76
+ .search::placeholder {
77
+ color: var(--sv-color-text-muted);
78
+ }
79
+
80
+ .list {
81
+ list-style: none;
82
+ margin: 0;
83
+ padding: var(--sv-space-1);
84
+ overflow-y: auto;
85
+ }
86
+
87
+ .option {
88
+ display: flex;
89
+ align-items: center;
90
+ gap: var(--sv-space-2);
91
+ width: 100%;
92
+ min-height: var(--sv-touch-target-min, 44px);
93
+ padding: var(--sv-space-2) var(--sv-space-3);
94
+ border: none;
95
+ border-radius: var(--sv-radius-sm);
96
+ background: transparent;
97
+ color: var(--sv-color-text-primary);
98
+ font: inherit;
99
+ font-size: var(--sv-font-size-sm);
100
+ text-align: left;
101
+ cursor: pointer;
102
+ }
103
+
104
+ .optionHighlighted {
105
+ background: var(--sv-color-surface-sunken);
106
+ }
107
+
108
+ .check {
109
+ display: inline-flex;
110
+ flex-shrink: 0;
111
+ width: var(--sv-icon-size-sm);
112
+ height: var(--sv-icon-size-sm);
113
+ align-items: center;
114
+ justify-content: center;
115
+ }
116
+
117
+ .empty {
118
+ padding: var(--sv-space-4) var(--sv-space-3);
119
+ color: var(--sv-color-text-muted);
120
+ font-size: var(--sv-font-size-sm);
121
+ text-align: center;
122
+ }
@@ -0,0 +1,80 @@
1
+ /* Command — rendered inside Dialog's own panel/scroll chrome; this file only
2
+ * owns the search input and the filtered result list beneath it. */
3
+
4
+ .root {
5
+ display: flex;
6
+ flex-direction: column;
7
+ /* Panel content area is otherwise unbounded; cap so a long result list
8
+ scrolls internally instead of growing the dialog indefinitely. */
9
+ max-height: min(60vh, 420px);
10
+ }
11
+
12
+ .input {
13
+ flex-shrink: 0;
14
+ width: 100%;
15
+ border: none;
16
+ border-bottom: 1px solid var(--sv-color-border);
17
+ background: transparent;
18
+ color: var(--sv-color-text-primary);
19
+ font: inherit;
20
+ font-size: var(--sv-font-size-md);
21
+ padding: var(--sv-space-3);
22
+ }
23
+
24
+ .input:focus {
25
+ outline: none;
26
+ }
27
+
28
+ .input::placeholder {
29
+ color: var(--sv-color-text-muted);
30
+ }
31
+
32
+ .list {
33
+ list-style: none;
34
+ margin: 0;
35
+ padding: var(--sv-space-1);
36
+ overflow-y: auto;
37
+ }
38
+
39
+ .groupList {
40
+ list-style: none;
41
+ margin: 0;
42
+ padding: 0;
43
+ }
44
+
45
+ .groupLabel {
46
+ padding: var(--sv-space-2) var(--sv-space-3) var(--sv-space-1);
47
+ font-size: var(--sv-font-size-label);
48
+ font-weight: var(--sv-font-weight-semibold);
49
+ color: var(--sv-color-text-muted);
50
+ text-transform: uppercase;
51
+ letter-spacing: 0.04em;
52
+ }
53
+
54
+ .item {
55
+ display: flex;
56
+ align-items: center;
57
+ gap: var(--sv-space-2);
58
+ width: 100%;
59
+ min-height: var(--sv-touch-target-min, 44px);
60
+ padding: var(--sv-space-2) var(--sv-space-3);
61
+ border: none;
62
+ border-radius: var(--sv-radius-sm);
63
+ background: transparent;
64
+ color: var(--sv-color-text-primary);
65
+ font: inherit;
66
+ font-size: var(--sv-font-size-sm);
67
+ text-align: left;
68
+ cursor: pointer;
69
+ }
70
+
71
+ .itemHighlighted {
72
+ background: var(--sv-color-surface-sunken);
73
+ }
74
+
75
+ .empty {
76
+ padding: var(--sv-space-4) var(--sv-space-3);
77
+ color: var(--sv-color-text-muted);
78
+ font-size: var(--sv-font-size-sm);
79
+ text-align: center;
80
+ }
@@ -65,7 +65,11 @@
65
65
  align-items: center;
66
66
  justify-content: center;
67
67
  gap: var(--sv-space-2);
68
- padding: 13px var(--sv-space-4);
68
+ /* Kept in sync with Button's .md rule by hand (see design-system.md
69
+ "Button and Checkbox touch ergonomics" — not a literal reuse of
70
+ Button). Matches Button's md padding, updated alongside it (10px,
71
+ 36px rendered height). */
72
+ padding: 10px var(--sv-space-4);
69
73
  border: 1px solid transparent;
70
74
  border-radius: var(--sv-radius-md);
71
75
  font-family: var(--sv-font-family);
@@ -0,0 +1,28 @@
1
+ .sortButton {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ gap: var(--sv-space-1);
5
+ border: none;
6
+ background: transparent;
7
+ padding: 0;
8
+ margin: 0;
9
+ color: inherit;
10
+ font: inherit;
11
+ font-weight: inherit;
12
+ cursor: pointer;
13
+ }
14
+
15
+ .sortButton:focus-visible {
16
+ outline: 2px solid var(--sv-color-focus-ring);
17
+ outline-offset: 2px;
18
+ border-radius: var(--sv-radius-sm);
19
+ }
20
+
21
+ .sortIcon {
22
+ display: inline-flex;
23
+ flex-shrink: 0;
24
+ width: var(--sv-icon-size-sm);
25
+ height: var(--sv-icon-size-sm);
26
+ align-items: center;
27
+ justify-content: center;
28
+ }
@@ -1,5 +1,7 @@
1
1
  /* DatePicker — trigger styled to match Input's height/border/radius/focus
2
- * ring for visual consistency as a form field. */
2
+ * ring for visual consistency as a form field. Kept in sync with Input's
3
+ * own sizing by hand (36px rendered height via explicit height +
4
+ * border-box, not a literal reuse of Input). */
3
5
 
4
6
  .trigger {
5
7
  display: flex;
@@ -7,7 +9,9 @@
7
9
  justify-content: space-between;
8
10
  gap: var(--sv-space-2);
9
11
  width: 100%;
10
- padding: var(--sv-space-2) var(--sv-space-3);
12
+ height: 36px;
13
+ box-sizing: border-box;
14
+ padding: 4px var(--sv-space-3);
11
15
  font-family: var(--sv-font-family);
12
16
  font-size: var(--sv-font-size-sm);
13
17
  line-height: 1.5;