|
| 1 | +# Checkbox migration roadmap |
| 2 | + |
| 3 | +## Component specifications |
| 4 | + |
| 5 | +### CSS |
| 6 | + |
| 7 | +<details> |
| 8 | +<summary>CSS selectors</summary> |
| 9 | + |
| 10 | +- `.spectrum-Checkbox` |
| 11 | +- `.spectrum-Checkbox .spectrum-Checkbox-box` |
| 12 | +- `.spectrum-Checkbox .spectrum-Checkbox-box:after` |
| 13 | +- `.spectrum-Checkbox .spectrum-Checkbox-box:before` |
| 14 | +- `.spectrum-Checkbox .spectrum-Checkbox-checkmark` |
| 15 | +- `.spectrum-Checkbox .spectrum-Checkbox-input` |
| 16 | +- `.spectrum-Checkbox .spectrum-Checkbox-input:checked + .spectrum-Checkbox-box .spectrum-Checkbox-checkmark` |
| 17 | +- `.spectrum-Checkbox .spectrum-Checkbox-input:checked + .spectrum-Checkbox-box:before` |
| 18 | +- `.spectrum-Checkbox .spectrum-Checkbox-input:checked:disabled + .spectrum-Checkbox-box:before` |
| 19 | +- `.spectrum-Checkbox .spectrum-Checkbox-input:checked:disabled ~ .spectrum-Checkbox-label` |
| 20 | +- `.spectrum-Checkbox .spectrum-Checkbox-input:checked:hover:disabled + .spectrum-Checkbox-box:before` |
| 21 | +- `.spectrum-Checkbox .spectrum-Checkbox-input:disabled` |
| 22 | +- `.spectrum-Checkbox .spectrum-Checkbox-input:disabled + .spectrum-Checkbox-box:before` |
| 23 | +- `.spectrum-Checkbox .spectrum-Checkbox-input:disabled ~ .spectrum-Checkbox-label` |
| 24 | +- `.spectrum-Checkbox .spectrum-Checkbox-input:focus-visible + .spectrum-Checkbox-box:after` |
| 25 | +- `.spectrum-Checkbox .spectrum-Checkbox-input:focus-visible + .spectrum-Checkbox-box:before` |
| 26 | +- `.spectrum-Checkbox .spectrum-Checkbox-input:focus-visible + .spectrum-Checkbox-label` |
| 27 | +- `.spectrum-Checkbox .spectrum-Checkbox-input:hover:disabled + .spectrum-Checkbox-box:before` |
| 28 | +- `.spectrum-Checkbox .spectrum-Checkbox-label` |
| 29 | +- `.spectrum-Checkbox .spectrum-Checkbox-partialCheckmark` |
| 30 | +- `.spectrum-Checkbox--emphasized.is-indeterminate .spectrum-Checkbox-box:before` |
| 31 | +- `.spectrum-Checkbox--emphasized.is-indeterminate .spectrum-Checkbox-input:checked + .spectrum-Checkbox-box:before` |
| 32 | +- `.spectrum-Checkbox--emphasized.is-indeterminate:hover .spectrum-Checkbox-box:before` |
| 33 | +- `.spectrum-Checkbox--emphasized.is-indeterminate:hover .spectrum-Checkbox-input:checked + .spectrum-Checkbox-box:before` |
| 34 | +- `.spectrum-Checkbox--emphasized.is-indeterminate:not(.is-invalid) .spectrum-Checkbox-input:focus-visible + .spectrum-Checkbox-box:before` |
| 35 | +- `.spectrum-Checkbox--emphasized:not(.is-invalid) .spectrum-Checkbox-input:focus-visible:checked + .spectrum-Checkbox-box:before` |
| 36 | +- `.spectrum-Checkbox-input:focus-visible + .spectrum-Checkbox-box` |
| 37 | +- `.spectrum-Checkbox.is-indeterminate .spectrum-Checkbox-box .spectrum-Checkbox-checkmark` |
| 38 | +- `.spectrum-Checkbox.is-indeterminate .spectrum-Checkbox-box .spectrum-Checkbox-partialCheckmark` |
| 39 | +- `.spectrum-Checkbox.is-indeterminate .spectrum-Checkbox-box:before` |
| 40 | +- `.spectrum-Checkbox.is-indeterminate .spectrum-Checkbox-input:checked + .spectrum-Checkbox-box .spectrum-Checkbox-checkmark` |
| 41 | +- `.spectrum-Checkbox.is-indeterminate .spectrum-Checkbox-input:checked + .spectrum-Checkbox-box .spectrum-Checkbox-partialCheckmark` |
| 42 | +- `.spectrum-Checkbox.is-indeterminate .spectrum-Checkbox-input:checked + .spectrum-Checkbox-box:before` |
| 43 | +- `.spectrum-Checkbox.is-invalid` |
| 44 | +- `.spectrum-Checkbox.is-invalid.is-indeterminate .spectrum-Checkbox-box:before` |
| 45 | +- `.spectrum-Checkbox.is-invalid.is-indeterminate .spectrum-Checkbox-input:checked:not(:disabled) + .spectrum-Checkbox-box:before` |
| 46 | +- `.spectrum-Checkbox.is-invalid.is-indeterminate .spectrum-Checkbox-input:focus-visible + .spectrum-Checkbox-box:before` |
| 47 | +- `.spectrum-Checkbox.is-invalid.is-indeterminate:hover .spectrum-Checkbox-box:before` |
| 48 | +- `.spectrum-Checkbox.is-invalid.is-indeterminate:hover .spectrum-Checkbox-input:checked:not(:disabled) + .spectrum-Checkbox-box:before` |
| 49 | +- `.spectrum-Checkbox.spectrum-Checkbox--emphasized` |
| 50 | +- `.spectrum-Checkbox.spectrum-Checkbox--sizeL` |
| 51 | +- `.spectrum-Checkbox.spectrum-Checkbox--sizeS` |
| 52 | +- `.spectrum-Checkbox.spectrum-Checkbox--sizeXL` |
| 53 | +- `.spectrum-Checkbox:active .spectrum-Checkbox-box:before` |
| 54 | +- `.spectrum-Checkbox:active .spectrum-Checkbox-input:checked + .spectrum-Checkbox-box:before` |
| 55 | +- `.spectrum-Checkbox:active .spectrum-Checkbox-label` |
| 56 | +- `.spectrum-Checkbox:hover .spectrum-Checkbox-box:before` |
| 57 | +- `.spectrum-Checkbox:hover .spectrum-Checkbox-input:checked + .spectrum-Checkbox-box:before` |
| 58 | +- `.spectrum-Checkbox:hover .spectrum-Checkbox-label` |
| 59 | +- `.spectrum-Checkbox:lang(ja)` |
| 60 | +- `.spectrum-Checkbox:lang(ko)` |
| 61 | +- `.spectrum-Checkbox:lang(zh)` |
| 62 | +- `.spectrum-Checkbox:not(.is-readOnly) .spectrum-Checkbox-input:active:not(:disabled) + .spectrum-Checkbox-box` |
| 63 | +- `.spectrum-Checkbox:not(.is-readOnly):active .spectrum-Checkbox-input:not(:disabled) + .spectrum-Checkbox-box` |
| 64 | + |
| 65 | +</details> |
| 66 | + |
| 67 | +<details> |
| 68 | +<summary>Passthroughs</summary> |
| 69 | + |
| 70 | +None found for this component. |
| 71 | + |
| 72 | +</details> |
| 73 | + |
| 74 | +<details> |
| 75 | +<summary>Modifiers</summary> |
| 76 | + |
| 77 | +- `--mod-checkbox-animation-duration` |
| 78 | +- `--mod-checkbox-border-width` |
| 79 | +- `--mod-checkbox-bottom-to-text` |
| 80 | +- `--mod-checkbox-checkmark-color` |
| 81 | +- `--mod-checkbox-content-color-default` |
| 82 | +- `--mod-checkbox-content-color-disabled` |
| 83 | +- `--mod-checkbox-content-color-down` |
| 84 | +- `--mod-checkbox-content-color-focus` |
| 85 | +- `--mod-checkbox-content-color-hover` |
| 86 | +- `--mod-checkbox-control-color-default` |
| 87 | +- `--mod-checkbox-control-color-disabled` |
| 88 | +- `--mod-checkbox-control-color-down` |
| 89 | +- `--mod-checkbox-control-color-focus` |
| 90 | +- `--mod-checkbox-control-color-hover` |
| 91 | +- `--mod-checkbox-control-corner-radius` |
| 92 | +- `--mod-checkbox-control-selected-color-default` |
| 93 | +- `--mod-checkbox-control-selected-color-down` |
| 94 | +- `--mod-checkbox-control-selected-color-hover` |
| 95 | +- `--mod-checkbox-control-size` |
| 96 | +- `--mod-checkbox-focus-indicator-color` |
| 97 | +- `--mod-checkbox-focus-indicator-gap` |
| 98 | +- `--mod-checkbox-focus-indicator-thickness` |
| 99 | +- `--mod-checkbox-font-size` |
| 100 | +- `--mod-checkbox-height` |
| 101 | +- `--mod-checkbox-line-height` |
| 102 | +- `--mod-checkbox-line-height-cjk` |
| 103 | +- `--mod-checkbox-margin-block` |
| 104 | +- `--mod-checkbox-selected-border-width` |
| 105 | +- `--mod-checkbox-text-to-control` |
| 106 | +- `--mod-checkbox-top-to-text` |
| 107 | +- `--mod-focus-indicator-thickness` |
| 108 | + |
| 109 | +</details> |
| 110 | + |
| 111 | +### SWC |
| 112 | + |
| 113 | +<details> |
| 114 | +<summary>Attributes</summary> |
| 115 | + |
| 116 | +- `disabled` - Boolean attribute to disable the checkbox |
| 117 | +- `indeterminate` - Boolean attribute for indeterminate state |
| 118 | +- `invalid` - Boolean attribute for invalid state styling |
| 119 | +- `emphasized` - Boolean attribute for emphasized styling |
| 120 | +- `checked` - Boolean attribute for checked state (inherited from CheckboxMixin) |
| 121 | +- `name` - String attribute for form submission (inherited from CheckboxMixin) |
| 122 | +- `readonly` - Boolean attribute for read-only state (inherited from CheckboxMixin) |
| 123 | +- `size` - String attribute with values: `s`, `m`, `l`, `xl` (from SizedMixin) |
| 124 | +- `tabindex` - Number attribute for tab order management |
| 125 | +- `autofocus` - Boolean HTML attribute for auto-focusing (handled in connectedCallback) |
| 126 | + |
| 127 | +</details> |
| 128 | + |
| 129 | +<details> |
| 130 | +<summary>Slots</summary> |
| 131 | + |
| 132 | +- Default slot - Content to display as the label for the Checkbox |
| 133 | + |
| 134 | +</details> |
| 135 | + |
| 136 | +## Comparison |
| 137 | + |
| 138 | +### DOM Structure changes |
| 139 | + |
| 140 | +<details> |
| 141 | +<summary>Spectrum Web Components:</summary> |
| 142 | + |
| 143 | +```html |
| 144 | +<!-- Current HTML structure from web component render() method --> |
| 145 | +<input |
| 146 | + id="input" |
| 147 | + name="example-name" |
| 148 | + type="checkbox" |
| 149 | + .checked="true" |
| 150 | + ?disabled="false" |
| 151 | + @change="handleChange" |
| 152 | +/> |
| 153 | +<span id="box"> |
| 154 | + <sp-icon-checkmark100 |
| 155 | + id="checkmark" |
| 156 | + class="spectrum-Icon spectrum-UIIcon-Checkmark100" |
| 157 | + ></sp-icon-checkmark100> |
| 158 | + <sp-icon-dash100 |
| 159 | + id="partialCheckmark" |
| 160 | + class="spectrum-Icon spectrum-UIIcon-Dash100" |
| 161 | + ></sp-icon-dash100> |
| 162 | +</span> |
| 163 | +<label id="label" for="input"><slot></slot></label> |
| 164 | +``` |
| 165 | + |
| 166 | +</details> |
| 167 | + |
| 168 | +<details> |
| 169 | +<summary>Legacy (CSS main branch):</summary> |
| 170 | + |
| 171 | +```html |
| 172 | +<label |
| 173 | + class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-Checkbox--emphasized is-indeterminate is-disabled is-invalid is-hover is-readOnly" |
| 174 | +> |
| 175 | + <input |
| 176 | + type="checkbox" |
| 177 | + class="spectrum-Checkbox-input" |
| 178 | + aria-labelledby="label-123" |
| 179 | + aria-disabled="true" |
| 180 | + checked="false" |
| 181 | + disabled="false" |
| 182 | + title="Checkbox title" |
| 183 | + value="checkbox-value" |
| 184 | + id="checkbox-input-123" |
| 185 | + /> |
| 186 | + <span class="spectrum-Checkbox-box"> |
| 187 | + <svg |
| 188 | + class="spectrum-Icon spectrum-UIIcon-Checkmark75 spectrum-Checkbox-checkmark" |
| 189 | + ></svg> |
| 190 | + <svg |
| 191 | + class="spectrum-Icon spectrum-UIIcon-Dash75 spectrum-Checkbox-partialCheckmark" |
| 192 | + ></svg> |
| 193 | + </span> |
| 194 | + <span class="spectrum-Checkbox-label">Checkbox Label</span> |
| 195 | +</label> |
| 196 | +``` |
| 197 | + |
| 198 | +</details> |
| 199 | + |
| 200 | +<details> |
| 201 | +<summary>Spectrum 2 (CSS spectrum-two branch):</summary> |
| 202 | + |
| 203 | +```html |
| 204 | +<label |
| 205 | + class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-Checkbox--emphasized is-indeterminate is-disabled is-invalid is-hover is-readOnly is-active" |
| 206 | +> |
| 207 | + <input |
| 208 | + type="checkbox" |
| 209 | + class="spectrum-Checkbox-input is-focus-visible is-active" |
| 210 | + aria-labelledby="label-123" |
| 211 | + aria-disabled="true" |
| 212 | + checked="false" |
| 213 | + disabled="false" |
| 214 | + title="Checkbox title" |
| 215 | + value="checkbox-value" |
| 216 | + id="checkbox-input-123" |
| 217 | + /> |
| 218 | + <span class="spectrum-Checkbox-box"> |
| 219 | + <svg |
| 220 | + class="spectrum-Icon spectrum-UIIcon-Checkmark75 spectrum-Checkbox-checkmark" |
| 221 | + ></svg> |
| 222 | + <svg |
| 223 | + class="spectrum-Icon spectrum-UIIcon-Dash75 spectrum-Checkbox-partialCheckmark" |
| 224 | + ></svg> |
| 225 | + </span> |
| 226 | + <span class="spectrum-Checkbox-label">Checkbox Label</span> |
| 227 | +</label> |
| 228 | +``` |
| 229 | + |
| 230 | +</details> |
| 231 | + |
| 232 | +<details> |
| 233 | +<summary>Diff: Legacy (CSS main) → Spectrum 2 (CSS spectrum-two)</summary> |
| 234 | + |
| 235 | +**No differences found between main and spectrum-two branches.** |
| 236 | + |
| 237 | +</details> |
| 238 | + |
| 239 | +### CSS => SWC mapping |
| 240 | + |
| 241 | +| CSS selector | Attribute or slot | Status | |
| 242 | +| ------------------------------------------------------------------------------------------- | ---------------------------------------------------- | ---------------- | |
| 243 | +| `.spectrum-Checkbox` | `:host` | Implemented | |
| 244 | +| `.spectrum-Checkbox--emphasized` | `emphasized` attribute | Implemented | |
| 245 | +| `.spectrum-Checkbox--sizeS` | `size="s"` attribute | Implemented | |
| 246 | +| `.spectrum-Checkbox--sizeL` | `size="l"` attribute | Implemented | |
| 247 | +| `.spectrum-Checkbox--sizeXL` | `size="xl"` attribute | Implemented | |
| 248 | +| `.spectrum-Checkbox.is-indeterminate` | `indeterminate` attribute | Implemented | |
| 249 | +| `.spectrum-Checkbox.is-invalid` | `invalid` attribute | Implemented | |
| 250 | +| `.spectrum-Checkbox-input` | Internal checkbox input element, `#input` | Implemented | |
| 251 | +| `.spectrum-Checkbox-input:checked` | `checked` attribute | Implemented | |
| 252 | +| `.spectrum-Checkbox-input:disabled` | `disabled` attribute | Implemented | |
| 253 | +| `.spectrum-Checkbox-box` | Internal checkbox box element, `#box` | Implemented | |
| 254 | +| `.spectrum-Checkbox-checkmark` | Checkmark icon element, `#checkmark` | Implemented | |
| 255 | +| `.spectrum-Checkbox-partialCheckmark` | Indeterminate dash icon element, `#partialCheckmark` | Implemented | |
| 256 | +| `.spectrum-Checkbox-label` | Default slot content | Implemented | |
| 257 | +| `.spectrum-Checkbox:lang(ja)`, `.spectrum-Checkbox:lang(ko)`, `.spectrum-Checkbox:lang(zh)` | Language-specific styling | Implemented | |
| 258 | +| `.spectrum-Checkbox.is-readOnly` | `readonly` attribute | Implemented | |
| 259 | +| | `name` attribute | Missing from CSS | |
| 260 | +| | `tabindex` attribute | Missing from CSS | |
| 261 | +| | `autofocus` attribute | Missing from CSS | |
| 262 | + |
| 263 | +## Summary of changes |
| 264 | + |
| 265 | +### CSS => SWC implementation gaps |
| 266 | + |
| 267 | +**New for S2:** |
| 268 | +The checkbox component in Spectrum 2 has the new down state (active) perspective shift applied. |
| 269 | + |
| 270 | +Note: There is some discussion ongoing about the invalid styles for checkbox. Currently, CSS supports individual red borders on the checkbox component, however, these styles are not present in the Figma specs for checkbox. The only invalid styling supported by design is the negative help text found in the field group component. When migrating, we'll need to consider clarifying the invalid styling with the design team for individual checkboxes. |
| 271 | + |
| 272 | +**Features Missing from CSS:** |
| 273 | + |
| 274 | +- `name` attribute for form submission has no corresponding CSS selector |
| 275 | +- `tabindex` attribute for accessibility has no CSS representation |
| 276 | +- `autofocus` attribute functionality implemented in JavaScript but has no CSS counterpart |
| 277 | + |
| 278 | +### CSS Spectrum 2 changes |
| 279 | + |
| 280 | +No structural differences found between the legacy (CSS main) and Spectrum 2 (CSS spectrum-two) branches. The template structure and class naming remain consistent across both branches. |
| 281 | + |
| 282 | +## Resources |
| 283 | + |
| 284 | +- [CSS migration](https://github.com/adobe/spectrum-css/pull/3531) |
| 285 | +- [Spectrum 2 preview](https://spectrumcss.z13.web.core.windows.net/pr-2352/index.html?path=/docs/components-checkbox--docs) |
| 286 | +- [React](https://react-spectrum.adobe.com/s2/index.html?path=/docs/checkbox--docs) |
0 commit comments