|  | 
|  | 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