Skip to content

Commit 96c6beb

Browse files
docs(button, buttongroup, actionbutton, actiongroup): component analysis (#5788)
1 parent 169a999 commit 96c6beb

File tree

4 files changed

+1128
-155
lines changed

4 files changed

+1128
-155
lines changed

migration-roadmap/action-button.md

Lines changed: 394 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,394 @@
1+
# Action button migration roadmap
2+
3+
## Component specifications
4+
5+
### CSS
6+
7+
<details>
8+
<summary>CSS selectors</summary>
9+
10+
**Base component:**
11+
12+
- `.spectrum-ActionButton`
13+
14+
**Sizes:**
15+
16+
- `.spectrum-ActionButton--sizeXS`
17+
- `.spectrum-ActionButton--sizeS`
18+
- `.spectrum-ActionButton--sizeL`
19+
- `.spectrum-ActionButton--sizeXL`
20+
21+
**Variants and treatments:**
22+
23+
- `.spectrum-ActionButton.spectrum-ActionButton--quiet`
24+
- `.spectrum-ActionButton.spectrum-ActionButton--staticWhite`
25+
- `.spectrum-ActionButton.spectrum-ActionButton--staticWhite.spectrum-ActionButton--quiet`
26+
- `.spectrum-ActionButton.spectrum-ActionButton--staticBlack`
27+
- `.spectrum-ActionButton.spectrum-ActionButton--staticBlack.spectrum-ActionButton--quiet`
28+
29+
**Child elements:**
30+
31+
- `.spectrum-ActionButton .spectrum-ActionButton-hold`
32+
- `.spectrum-ActionButton .spectrum-ActionButton-icon`
33+
- `.spectrum-ActionButton .spectrum-ActionButton-label`
34+
- `.spectrum-ActionButton-hold`
35+
- `.spectrum-ActionButton-icon`
36+
- `.spectrum-ActionButton-label`
37+
- `.spectrum-ActionButton-label:empty`
38+
39+
**States:**
40+
41+
- `.spectrum-ActionButton.is-disabled`
42+
- `.spectrum-ActionButton.is-selected`
43+
- `.spectrum-ActionButton:disabled`
44+
- `.spectrum-ActionButton:active`
45+
- `.spectrum-ActionButton:hover`
46+
47+
**Selected state with variants:**
48+
49+
- `.spectrum-ActionButton.is-selected.spectrum-ActionButton--emphasized`
50+
- `.spectrum-ActionButton.is-selected.spectrum-ActionButton--staticWhite`
51+
- `.spectrum-ActionButton.is-selected.spectrum-ActionButton--staticBlack`
52+
- `.spectrum-ActionButton.spectrum-ActionButton--quiet.is-selected`
53+
- `.spectrum-ActionButton.spectrum-ActionButton--quiet:disabled:not(.is-selected)`
54+
55+
**Focus indicators:**
56+
57+
- `.spectrum-ActionButton:focus`
58+
- `.spectrum-ActionButton:focus-visible`
59+
- `.spectrum-ActionButton:focus-visible:after`
60+
- `.spectrum-ActionButton::-moz-focus-inner`
61+
- `.spectrum-ActionButton:after`
62+
63+
**Content detection:**
64+
65+
- `.spectrum-ActionButton:has(.spectrum-ActionButton-icon)`
66+
- `.spectrum-ActionButton:not(:has(.spectrum-ActionButton-label))`
67+
68+
**RTL support:**
69+
70+
- `.spectrum-ActionButton:dir(rtl)`
71+
72+
**Link variant:**
73+
74+
- `a.spectrum-ActionButton`
75+
76+
</details>
77+
78+
<details>
79+
<summary>Passthroughs</summary>
80+
81+
- `--mod-button-animation-duration`
82+
- `--mod-button-font-family`
83+
84+
</details>
85+
86+
<details>
87+
<summary>Modifiers</summary>
88+
89+
**Sizing and spacing:**
90+
91+
- `--mod-actionbutton-height`
92+
- `--mod-actionbutton-min-width`
93+
- `--mod-actionbutton-edge-to-visual`
94+
- `--mod-actionbutton-edge-to-visual-only`
95+
- `--mod-actionbutton-edge-to-text`
96+
- `--mod-actionbutton-edge-to-hold-icon`
97+
- `--mod-actionbutton-text-to-visual`
98+
- `--mod-actionbutton-icon-size`
99+
100+
**Typography:**
101+
102+
- `--mod-actionbutton-font-size`
103+
- `--mod-actionbutton-font-weight`
104+
- `--mod-actionbutton-font-style`
105+
- `--mod-actionbutton-line-height`
106+
- `--mod-actionbutton-label-color`
107+
108+
**Border and radius:**
109+
110+
- `--mod-actionbutton-border-radius`
111+
- `--mod-actionbutton-focus-indicator-border-radius`
112+
113+
**Focus indicators:**
114+
115+
- `--mod-actionbutton-focus-indicator-gap`
116+
- `--mod-actionbutton-focus-indicator-thickness`
117+
- `--mod-actionbutton-focus-indicator-color`
118+
119+
**Animation:**
120+
121+
- `--mod-actionbutton-animation-duration`
122+
123+
**Default state colors:**
124+
125+
- `--mod-actionbutton-background-color-default`
126+
- `--mod-actionbutton-content-color-default`
127+
128+
**Hover state colors:**
129+
130+
- `--mod-actionbutton-background-color-hover`
131+
- `--mod-actionbutton-content-color-hover`
132+
133+
**Focus state colors:**
134+
135+
- `--mod-actionbutton-background-color-focus`
136+
- `--mod-actionbutton-content-color-focus`
137+
138+
**Active/down state colors:**
139+
140+
- `--mod-actionbutton-background-color-down`
141+
- `--mod-actionbutton-content-color-down`
142+
143+
**Disabled state colors:**
144+
145+
- `--mod-actionbutton-background-color-disabled`
146+
- `--mod-actionbutton-content-color-disabled`
147+
148+
**Selected state colors:**
149+
150+
- `--mod-actionbutton-background-color-default-selected`
151+
- `--mod-actionbutton-content-color-default-selected`
152+
- `--mod-actionbutton-background-color-hover-selected`
153+
- `--mod-actionbutton-content-color-hover-selected`
154+
- `--mod-actionbutton-background-color-focus-selected`
155+
- `--mod-actionbutton-content-color-focus-selected`
156+
- `--mod-actionbutton-background-color-down-selected`
157+
- `--mod-actionbutton-content-color-down-selected`
158+
159+
**Selected + emphasized state colors:**
160+
161+
- `--mod-actionbutton-background-color-default-selected-emphasized`
162+
- `--mod-actionbutton-content-color-default-selected-emphasized`
163+
- `--mod-actionbutton-background-color-hover-selected-emphasized`
164+
- `--mod-actionbutton-content-color-hover-selected-emphasized`
165+
- `--mod-actionbutton-background-color-focus-selected-emphasized`
166+
- `--mod-actionbutton-content-color-focus-selected-emphasized`
167+
- `--mod-actionbutton-background-color-down-selected-emphasized`
168+
- `--mod-actionbutton-content-color-down-selected-emphasized`
169+
170+
</details>
171+
172+
### SWC
173+
174+
<details>
175+
<summary>Attributes</summary>
176+
177+
**Size:**
178+
179+
- `size` (values: `xs`, `s`, `m`, `l`, `xl`) - button size, no default
180+
181+
**Variants:**
182+
183+
- `emphasized` - adds visual emphasis to selected state (boolean)
184+
- `quiet` - applies quiet styling (boolean)
185+
- `static-color` (values: `white`, `black`) - static color variant for use over backgrounds
186+
187+
**Selection state:**
188+
189+
- `selected` - whether the button is selected (boolean)
190+
- `toggles` - whether to automatically manage selected state on interaction and use aria-pressed (boolean)
191+
192+
**Hold affordance:**
193+
194+
- `hold-affordance` - shows corner triangle indicator for longpress action (boolean)
195+
196+
**States:**
197+
198+
- `active` - active/pressed state (inherited from ButtonBase)
199+
- `disabled` - disabled state (inherited from Focusable)
200+
201+
**Content:**
202+
203+
- `label` - accessible label (inherited from LikeAnchor)
204+
205+
**Focus management:**
206+
207+
- `autofocus` - auto-focus on load (inherited from Focusable)
208+
- `tabIndex` - tab index (inherited from Focusable)
209+
210+
**Link behavior:**
211+
212+
- `href` - makes button behave as link (inherited from LikeAnchor)
213+
- `target` (values: `_blank`, `_parent`, `_self`, `_top`) - link target (inherited from LikeAnchor)
214+
- `download` - download attribute (inherited from LikeAnchor)
215+
- `referrerpolicy` - referrer policy (inherited from LikeAnchor)
216+
- `rel` - link relationship (inherited from LikeAnchor)
217+
218+
**Form behavior:**
219+
220+
- `type` (values: `button`, `submit`, `reset`) - button type (inherited from ButtonBase)
221+
- `name` - form field name (inherited from ButtonBase)
222+
- `value` - button value, defaults to trimmed text content
223+
224+
**ARIA:**
225+
226+
- `role` - ARIA role, defaults to `button`
227+
228+
</details>
229+
230+
<details>
231+
<summary>Slots</summary>
232+
233+
- Default slot - text label of the action button
234+
- `icon` - the icon to use for action button
235+
236+
</details>
237+
238+
## Comparison
239+
240+
### DOM structure changes
241+
242+
<details>
243+
<summary>Spectrum Web Components</summary>
244+
245+
```html
246+
<!-- Hold affordance icon (when hold-affordance=true) -->
247+
<!-- Size-specific corner triangle icon, rendered first -->
248+
<sp-icon-corner-triangle300
249+
class="hold-affordance spectrum-UIIcon-CornerTriangle{size}"
250+
></sp-icon-corner-triangle300>
251+
252+
<!-- Icon slot -->
253+
<slot name="icon"></slot>
254+
255+
<!-- Label -->
256+
<span id="label">
257+
<slot></slot>
258+
</span>
259+
```
260+
261+
</details>
262+
263+
<details>
264+
<summary>Legacy (CSS main branch)</summary>
265+
266+
```html
267+
<button
268+
class="spectrum-ActionButton spectrum-ActionButton--sizeM"
269+
aria-pressed="false"
270+
disabled
271+
>
272+
<!-- Hold affordance icon (when hasPopup provided) -->
273+
<svg class="spectrum-Icon spectrum-ActionButton-hold">...</svg>
274+
275+
<!-- Icon (when iconName provided) -->
276+
<svg class="spectrum-Icon spectrum-ActionButton-icon">...</svg>
277+
278+
<!-- Label (when label provided and not hideLabel) -->
279+
<span class="spectrum-ActionButton-label">Label</span>
280+
</button>
281+
```
282+
283+
</details>
284+
285+
<details>
286+
<summary>Spectrum 2 (CSS spectrum-two branch)</summary>
287+
288+
```html
289+
<button
290+
class="spectrum-ActionButton spectrum-ActionButton--sizeM"
291+
aria-pressed="false"
292+
disabled
293+
>
294+
<!-- Hold affordance icon (when hasPopup provided) -->
295+
<svg class="spectrum-Icon spectrum-ActionButton-hold">...</svg>
296+
297+
<!-- Icon (when iconName provided) -->
298+
<svg class="spectrum-Icon spectrum-ActionButton-icon">...</svg>
299+
300+
<!-- Label (when label provided and not hideLabel) -->
301+
<span class="spectrum-ActionButton-label">Label</span>
302+
</button>
303+
```
304+
305+
</details>
306+
307+
### CSS => SWC mapping
308+
309+
#### Sizes
310+
311+
| CSS selector | SWC attribute | Status |
312+
| -------------------------------- | ------------------------------- | ----------- |
313+
| `.spectrum-ActionButton` | Base component (default size M) | Implemented |
314+
| `.spectrum-ActionButton--sizeXS` | `size="xs"` | Implemented |
315+
| `.spectrum-ActionButton--sizeS` | `size="s"` | Implemented |
316+
| `.spectrum-ActionButton--sizeL` | `size="l"` | Implemented |
317+
| `.spectrum-ActionButton--sizeXL` | `size="xl"` | Implemented |
318+
319+
#### Variants and treatments
320+
321+
| CSS selector | SWC attribute | Status |
322+
| ---------------------------------------------------------------------------------------- | -------------------------------- | ----------- |
323+
| `.spectrum-ActionButton.spectrum-ActionButton--quiet` | `quiet` | Implemented |
324+
| `.spectrum-ActionButton.spectrum-ActionButton--staticWhite` | `static-color="white"` | Implemented |
325+
| `.spectrum-ActionButton.spectrum-ActionButton--staticBlack` | `static-color="black"` | Implemented |
326+
| `.spectrum-ActionButton.spectrum-ActionButton--staticWhite.spectrum-ActionButton--quiet` | `static-color="white"` + `quiet` | Implemented |
327+
| `.spectrum-ActionButton.spectrum-ActionButton--staticBlack.spectrum-ActionButton--quiet` | `static-color="black"` + `quiet` | Implemented |
328+
329+
#### States
330+
331+
| CSS selector | SWC attribute | Status |
332+
| -------------------------------------------------------------------------------- | ----------------------------------- | ----------- |
333+
| `.spectrum-ActionButton.is-selected` | `selected` | Implemented |
334+
| `.spectrum-ActionButton.is-disabled` | `disabled` | Implemented |
335+
| `.spectrum-ActionButton:disabled` | `disabled` | Implemented |
336+
| `.spectrum-ActionButton:active` | `active` | Implemented |
337+
| `.spectrum-ActionButton:hover` | Pseudo-state | Implemented |
338+
| `.spectrum-ActionButton.is-selected.spectrum-ActionButton--emphasized` | `selected` + `emphasized` | Implemented |
339+
| `.spectrum-ActionButton.is-selected.spectrum-ActionButton--staticWhite` | `selected` + `static-color="white"` | Implemented |
340+
| `.spectrum-ActionButton.is-selected.spectrum-ActionButton--staticBlack` | `selected` + `static-color="black"` | Implemented |
341+
| `.spectrum-ActionButton.spectrum-ActionButton--quiet.is-selected` | `quiet` + `selected` | Implemented |
342+
| `.spectrum-ActionButton.spectrum-ActionButton--quiet:disabled:not(.is-selected)` | `quiet` + `disabled` (not selected) | Implemented |
343+
344+
#### Focus indicators
345+
346+
| CSS selector | SWC attribute | Status |
347+
| -------------------------------------------- | --------------------- | ----------- |
348+
| `.spectrum-ActionButton:focus` | Pseudo-state | Implemented |
349+
| `.spectrum-ActionButton:focus-visible` | Pseudo-state | Implemented |
350+
| `.spectrum-ActionButton:focus-visible:after` | Focus ring | Implemented |
351+
| `.spectrum-ActionButton:after` | Focus ring element | Implemented |
352+
| `.spectrum-ActionButton::-moz-focus-inner` | Firefox focus styling | Implemented |
353+
354+
#### Content and layout
355+
356+
| CSS selector | SWC attribute/slot | Status |
357+
| ---------------------------------------------------------------- | ---------------------------------------- | ----------- |
358+
| `.spectrum-ActionButton .spectrum-ActionButton-icon` | `icon` slot | Implemented |
359+
| `.spectrum-ActionButton-icon` | `icon` slot | Implemented |
360+
| `.spectrum-ActionButton .spectrum-ActionButton-label` | Default slot | Implemented |
361+
| `.spectrum-ActionButton-label` | Default slot | Implemented |
362+
| `.spectrum-ActionButton-label:empty` | Empty label handling | Implemented |
363+
| `.spectrum-ActionButton .spectrum-ActionButton-hold` | `hold-affordance` attribute | Implemented |
364+
| `.spectrum-ActionButton-hold` | `hold-affordance` attribute | Implemented |
365+
| `.spectrum-ActionButton:has(.spectrum-ActionButton-icon)` | Detected when icon slot has content | Implemented |
366+
| `.spectrum-ActionButton:not(:has(.spectrum-ActionButton-label))` | Detected when default slot is empty | Implemented |
367+
| `.spectrum-ActionButton:dir(rtl)` | Browser RTL support | Implemented |
368+
| `a.spectrum-ActionButton` | `href` attribute makes it render as link | Implemented |
369+
370+
#### WC-only attributes
371+
372+
| SWC attribute | CSS equivalent | Notes |
373+
| ------------- | -------------- | --------------------------------------------- |
374+
| `toggles` | N/A | Manages selected state automatically on click |
375+
| `value` | N/A | Used for identification in action groups |
376+
| `role` | N/A | Dynamic ARIA role management |
377+
378+
## Summary of changes
379+
380+
### CSS => SWC implementation gaps
381+
382+
**Missing from WC:**
383+
None. All CSS selectors have corresponding web component implementations.
384+
385+
### CSS Spectrum 2 changes
386+
387+
**No structural changes:**
388+
The Action Button template is functionally identical between the main branch (legacy) and spectrum-two branch (Spectrum 2). Both branches render the same HTML DOM structure and use the same size-specific corner triangle icons (CornerTriangle75, CornerTriangle100, CornerTriangle200, CornerTriangle300).
389+
390+
## Resources
391+
392+
- [CSS migration](https://github.com/adobe/spectrum-css/pull/2669)
393+
- [Spectrum 2 preview](https://spectrumcss.z13.web.core.windows.net/pr-2352/index.html?path=/docs/components-action-button--docs)
394+
- [React](https://react-spectrum.adobe.com/s2/index.html?path=/docs/actionbutton--docs)

0 commit comments

Comments
 (0)