Skip to content

Commit b9f61e4

Browse files
authored
feat(colorwheel): s2 migration (#3390)
- chore(colorwheel): update property name - chore(colorwheel): wip inset borders - chore(colorwheel): fix lint violations - chore(colorwheel): move mod declarations - chore(colorwheel): drop unused property + update metadata - chore(colorwheel): remove underlying border node + class - chore(colorwheel): remove unused property - fix(colorwheel): add missing mod - fix(colorwheel): comments for updated before spacing/positioning - fix(colorwheel): adopt proper token for border opacity - fix(colorwheel): remove inset border on disabled state - fix(colorwheel): remove global token reference - chore(colorwheel): highlight removed/added mods - chore(colorwheel): update copyright year - chore(colorwheel): add color loupe to default story - fix(colorwheel): correct WHC disabled background color value - chore(colorwheel): update test heading - fix(colorwheel): typos - chore(colorwheel): update token usage - chore(colorwheel): add without loupe test - chore(colorwheel): restore WHC styles - chore(colorwheel): move isWithColorLoupe property - fix(colorwheel): whc disabled background - fix(colorwheel): improve interior border styles - fix(colorwheel): token/classnames in story; remove unnecessary margin - chore(colorwheel): fix inset borders + improve comments - chore(colorwheel): update changeset - chore(colorwheel): add note re --spectrum-color-wheel-color-area-margin token - chore(colorwheel): restore missing mods; naming consistency - chore(colorwheel): add sizing stories - chore(colorwheel): restore comment - chore(colorwheel): inset shorthand - chore(colorwheel): remove unnecessary colorwheel template + story - chore(colorwheel): remove unnecessary custom sizing story from sidebar - chore(colorwheel): add custom sizing test - chore(colorwheel): move comment to docs - fix(colorwheel): after pseudo selector disabled state - fix(colorwheel): remove problematic border width mod - fix(colorwheel): typos + drop sentence
1 parent 11d00e3 commit b9f61e4

File tree

6 files changed

+177
-67
lines changed

6 files changed

+177
-67
lines changed

.changeset/giant-windows-smoke.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
"@spectrum-css/colorwheel": major
3+
---
4+
5+
# colorwheel S2 migration
6+
7+
This change migrates the colorwheel component to S2. It adds the `--spectrum-colorwheel-border-color-rgb` and `--spectrum-colorwheel-border-opacity` custom properties. It updates `--spectrum-colorwheel-border-color` to leverage these tokens in an `rgba(...)` function.
8+
9+
This removes the `spectrum-ColorWheel-border` and associated template DOM node as the outside/underlying border are no longer present in the S2 designs. `::before` and `::after` pseudo elements are now used to draw the exterior and interior borders that overlay the exterior and interior edges of the color wheel.
10+
11+
Support is provided for the `240px` and `192px` sizes outlined in the design requirements.
12+
13+
The `forced-colors` media query has been moved to the bottom of the file consistent with our other component implementations.
14+
15+
Stories, tests and documentation have been updated to be consistent with these changes.
16+
17+
The following mods have been removed:
18+
19+
```css
20+
--mod-colorwheel-height
21+
--mod-colorwheel-width
22+
--mod-colorwheel-min-width
23+
--mod-colorwheel-path-borders
24+
--mod-colorwheel-colorarea-margin
25+
--mod-colorwheel-border-width
26+
```

components/colorwheel/dist/metadata.json

+17-15
Original file line numberDiff line numberDiff line change
@@ -4,51 +4,53 @@
44
".spectrum-ColorWheel",
55
".spectrum-ColorWheel-ColorArea-handle",
66
".spectrum-ColorWheel-ColorArea-handle:dir(rtl)",
7-
".spectrum-ColorWheel-border",
8-
".spectrum-ColorWheel-border.is-disabled",
97
".spectrum-ColorWheel-colorarea-container",
108
".spectrum-ColorWheel-handle",
119
".spectrum-ColorWheel-inner",
1210
".spectrum-ColorWheel-slider",
1311
".spectrum-ColorWheel-wheel",
1412
".spectrum-ColorWheel-wheel.is-disabled",
1513
".spectrum-ColorWheel.is-disabled",
14+
".spectrum-ColorWheel.is-disabled .spectrum-ColorWheel-inner:before",
15+
".spectrum-ColorWheel.is-disabled:after",
16+
".spectrum-ColorWheel.is-disabled:before",
1617
".spectrum-ColorWheel.is-dragged",
1718
".spectrum-ColorWheel.is-focused",
19+
".spectrum-ColorWheel:after",
20+
".spectrum-ColorWheel:before",
1821
"[dir=\"rtl\"] .spectrum-ColorWheel-ColorArea-handle"
1922
],
2023
"modifiers": [
24+
"--mod-colorwheel-block-size",
2125
"--mod-colorwheel-border-color",
22-
"--mod-colorwheel-border-width",
2326
"--mod-colorwheel-colorarea-container-size",
24-
"--mod-colorwheel-colorarea-margin",
2527
"--mod-colorwheel-fill-color-disabled",
26-
"--mod-colorwheel-height",
27-
"--mod-colorwheel-min-width",
28+
"--mod-colorwheel-inline-size",
29+
"--mod-colorwheel-min-inline-size",
2830
"--mod-colorwheel-path",
29-
"--mod-colorwheel-path-borders",
30-
"--mod-colorwheel-track-width",
31-
"--mod-colorwheel-width"
31+
"--mod-colorwheel-track-width"
3232
],
3333
"component": [
34-
"--spectrum-color-wheel-color-area-margin",
34+
"--spectrum-color-wheel-border-opacity",
3535
"--spectrum-color-wheel-minimum-width",
3636
"--spectrum-color-wheel-width",
37+
"--spectrum-colorwheel-block-size",
3738
"--spectrum-colorwheel-border-color",
39+
"--spectrum-colorwheel-border-color-rgb",
40+
"--spectrum-colorwheel-border-opacity",
3841
"--spectrum-colorwheel-border-width",
3942
"--spectrum-colorwheel-colorarea-container-size",
4043
"--spectrum-colorwheel-fill-color-disabled",
41-
"--spectrum-colorwheel-height",
44+
"--spectrum-colorwheel-inline-size",
45+
"--spectrum-colorwheel-min-inline-size",
4246
"--spectrum-colorwheel-path",
43-
"--spectrum-colorwheel-path-borders",
44-
"--spectrum-colorwheel-track-width",
45-
"--spectrum-colorwheel-width"
47+
"--spectrum-colorwheel-track-width"
4648
],
4749
"global": [
4850
"--spectrum-border-width-100",
4951
"--spectrum-color-control-track-width",
5052
"--spectrum-disabled-background-color",
51-
"--spectrum-transparent-black-300"
53+
"--spectrum-gray-1000-rgb"
5254
],
5355
"passthroughs": [],
5456
"high-contrast": [

components/colorwheel/index.css

+68-37
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*!
2-
* Copyright 2024 Adobe. All rights reserved.
2+
* Copyright 2025 Adobe. All rights reserved.
33
*
44
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License. You may obtain a copy
@@ -11,46 +11,81 @@
1111
* governing permissions and limitations under the License.
1212
*/
1313

14-
/* Windows High Contrast Mode */
15-
@media (forced-colors: active) {
16-
.spectrum-ColorWheel {
17-
--highcontrast-colorwheel-border-color-disabled: GrayText;
18-
--highcontrast-colorwheel-fill-color-disabled: Canvas;
14+
.spectrum-ColorWheel {
15+
--spectrum-colorwheel-inline-size: var(--spectrum-color-wheel-width);
16+
--spectrum-colorwheel-block-size: var(--spectrum-color-wheel-width);
17+
--spectrum-colorwheel-min-inline-size: var(--spectrum-color-wheel-minimum-width);
1918

20-
forced-color-adjust: none;
21-
}
22-
}
19+
/* @TODO: leveraging the rgb token in this case to achieve the desired border color implementation as rgb + opacity are required by the `rgba` function. */
20+
--spectrum-colorwheel-border-color-rgb: var(--spectrum-gray-1000-rgb);
2321

24-
.spectrum-ColorWheel {
25-
--spectrum-colorwheel-border-color: var(--spectrum-transparent-black-300);
22+
--spectrum-colorwheel-border-opacity: var(--spectrum-color-wheel-border-opacity);
23+
--spectrum-colorwheel-border-color: rgba(var(--spectrum-colorwheel-border-color-rgb), var(--spectrum-colorwheel-border-opacity));
2624

27-
--spectrum-colorwheel-width: var(--mod-colorwheel-width, var(--spectrum-color-wheel-width));
28-
--spectrum-colorwheel-height: var(--mod-colorwheel-height, var(--spectrum-color-wheel-width));
29-
--spectrum-colorwheel-fill-color-disabled: var(--mod-colorwheel-fill-color-disabled, var(--spectrum-disabled-background-color));
30-
--spectrum-colorwheel-border-color: var(--spectrum-transparent-black-300);
25+
--spectrum-colorwheel-border-width: var(--spectrum-border-width-100);
26+
--spectrum-colorwheel-track-width: var(--spectrum-color-control-track-width);
3127

32-
--spectrum-colorwheel-border-width: var(--mod-colorwheel-border-width, var(--spectrum-border-width-100));
33-
--spectrum-colorwheel-track-width: var(--mod-colorwheel-track-width, var(--spectrum-color-control-track-width));
28+
--spectrum-colorwheel-fill-color-disabled: var(--spectrum-disabled-background-color);
3429

3530
/* stylelint-disable-next-line spectrum-tools/no-unused-custom-properties -- used with JS in calculating the clip-path paths and colorarea-container-size */
36-
--_track-width: var(--spectrum-colorwheel-track-width);
31+
--_track-width: var(--mod-colorwheel-track-width, var(--spectrum-colorwheel-track-width));
3732
/* stylelint-disable-next-line spectrum-tools/no-unused-custom-properties -- used with JS in calculating the clip-path paths and colorarea-container-size */
3833
--_border-width: var(--spectrum-colorwheel-border-width);
3934

4035
position: relative;
4136
display: block;
42-
min-inline-size: var(--mod-colorwheel-min-width, var(--spectrum-color-wheel-minimum-width));
43-
inline-size: var(--spectrum-colorwheel-width);
44-
block-size: var(--spectrum-colorwheel-height);
37+
min-inline-size: var(--mod-colorwheel-min-inline-size, var(--spectrum-colorwheel-min-inline-size));
38+
inline-size: var(--mod-colorwheel-inline-size, var(--spectrum-colorwheel-inline-size));
39+
block-size: var(--mod-colorwheel-block-size, var(--spectrum-colorwheel-block-size));
4540
user-select: none;
4641
cursor: default;
4742

43+
/**
44+
* Color wheel exterior border
45+
* - Calcs for `inline-size` and `block-size` subtract 4 times the component's border width
46+
* (to account for the inset width of the exterior border) from the component's width.
47+
*/
48+
&::before {
49+
inline-size: calc(var(--mod-colorwheel-inline-size, var(--spectrum-colorwheel-inline-size)) - calc(4 * var(--spectrum-colorwheel-border-width)));
50+
block-size: calc(var(--mod-colorwheel-inline-size, var(--spectrum-colorwheel-inline-size)) - calc(4 * var(--spectrum-colorwheel-border-width)));
51+
inset: var(--spectrum-colorwheel-border-width);
52+
content: "";
53+
position: absolute;
54+
border-width: var(--spectrum-colorwheel-border-width);
55+
border-style: solid;
56+
border-color: var(--mod-colorwheel-border-color, var(--spectrum-colorwheel-border-color));
57+
border-radius: 100%;
58+
z-index: 1;
59+
}
60+
61+
/**
62+
* Color wheel interior border
63+
* - Calcs for `inset` 2 times the component's border width from the
64+
* track width (to account for the inset width of the interior border)
65+
*/
66+
&::after {
67+
inset: calc(var(--mod-colorwheel-track-width, var(--spectrum-colorwheel-track-width)) - (calc(2 * var(--spectrum-colorwheel-border-width))));
68+
content: "";
69+
position: absolute;
70+
border-width: var(--spectrum-colorwheel-border-width);
71+
border-style: solid;
72+
border-color: var(--mod-colorwheel-border-color, var(--spectrum-colorwheel-border-color));
73+
border-radius: 100%;
74+
z-index: 1;
75+
}
76+
4877
&.is-focused {
4978
z-index: 2;
5079
}
5180

5281
&.is-disabled {
5382
pointer-events: none;
83+
84+
&::before,
85+
&::after,
86+
.spectrum-ColorWheel-inner::before {
87+
border-color: var(--highcontrast-colorwheel-border-color-disabled, transparent);
88+
}
5489
}
5590

5691
&.is-dragged {
@@ -77,7 +112,6 @@
77112
display: flex;
78113
align-items: center;
79114
justify-content: center;
80-
margin: var(--mod-colorwheel-colorarea-margin, var(--spectrum-color-wheel-color-area-margin));
81115
}
82116

83117
.spectrum-ColorWheel-slider {
@@ -93,7 +127,7 @@
93127
}
94128

95129
.spectrum-ColorWheel-handle {
96-
transform: translate(calc(var(--spectrum-colorwheel-width) / 2 - var(--spectrum-colorwheel-track-width) / 2), 0);
130+
transform: translate(calc(var(--mod-colorwheel-inline-size, var(--spectrum-colorwheel-inline-size)) / 2 - var(--mod-colorwheel-track-width, var(--mod-colorwheel-track-width, var(--spectrum-colorwheel-track-width))) / 2), 0);
97131
inset-block-start: 50%;
98132
inset-inline: 50%;
99133
}
@@ -107,19 +141,6 @@
107141
}
108142
}
109143

110-
/* a clip-path set border-width wider than than spectrum-colorwheel-wheel to create the appreance of a border */
111-
.spectrum-ColorWheel-border {
112-
position: relative;
113-
background-color: var(--mod-colorwheel-border-color, var(--spectrum-colorwheel-border-color));
114-
inline-size: var(--spectrum-colorwheel-width);
115-
block-size: var(--spectrum-colorwheel-height);
116-
clip-path: path(evenodd, var(--mod-colorwheel-path-borders, var(--spectrum-colorwheel-path-borders)));
117-
118-
&.is-disabled {
119-
background-color: var(--highcontrast-colorwheel-border-color-disabled, var(--spectrum-colorwheel-fill-color-disabled));
120-
}
121-
}
122-
123144
.spectrum-ColorWheel-wheel {
124145
position: absolute;
125146
background: conic-gradient(from 90deg, red, rgb(255 128 0), rgb(255 255 0), rgb(128 255 0), rgb(0 255 0), rgb(0 255 128), rgb(0 255 255), rgb(0 128 255), rgb(0 0 255), rgb(128 0 255), rgb(255 0 255), rgb(255 0 128), red);
@@ -129,6 +150,16 @@
129150

130151
&.is-disabled {
131152
pointer-events: none;
132-
background: var(--highcontrast-colorwheel-fill-color-disabled, var(--spectrum-colorwheel-fill-color-disabled));
153+
background: var(--highcontrast-colorwheel-fill-color-disabled, var(--mod-colorwheel-fill-color-disabled, var(--spectrum-colorwheel-fill-color-disabled)));
154+
}
155+
}
156+
157+
/* Windows High Contrast Mode */
158+
@media (forced-colors: active) {
159+
.spectrum-ColorWheel {
160+
--highcontrast-colorwheel-border-color-disabled: GrayText;
161+
--highcontrast-colorwheel-fill-color-disabled: Canvas;
162+
163+
forced-color-adjust: none;
133164
}
134165
}

components/colorwheel/stories/colorwheel.stories.js

+38-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,16 @@ export default {
2323
if: { arg: "isDisabled", truthy: false },
2424
},
2525
isWithColorArea: {
26-
name: "With Color Area",
26+
name: "With color area",
27+
type: { name: "boolean" },
28+
table: {
29+
type: { summary: "boolean" },
30+
category: "State",
31+
},
32+
control: "boolean",
33+
},
34+
isWithColorLoupe: {
35+
name: "With color loupe",
2736
type: { name: "boolean" },
2837
table: {
2938
type: { summary: "boolean" },
@@ -44,6 +53,7 @@ export default {
4453
isDisabled: false,
4554
isFocused: false,
4655
isWithColorArea: false,
56+
isWithColorLoupe: true,
4757
selectedColor: "rgba(255, 0, 0, 50%)",
4858
},
4959
parameters: {
@@ -59,6 +69,30 @@ export default {
5969
export const Default = ColorWheelGroup.bind({});
6070
Default.args = {};
6171

72+
/**
73+
* By default, the color wheel has both a fixed size and a minimum size. The color wheel may be displayed at custom sizes by setting some of its modifiable custom properties. Below, the wheel is displayed at `300px` with the following mod values:
74+
* ```
75+
* "--mod-colorwheel-inline-size": "300px",
76+
* "--mod-colorwheel-block-size": "300px",
77+
* "--mod-colorwheel-track-width": "30px",
78+
* "--mod-colorwheel-path": '"M 149 149 m -149 0 a 149 149 0 1 0 298 0 a 149 149 0 1 0 -298 0 M 149 149 m -121 0 a 121 121 0 1 0 242 0 a 121 121 0 1 0 -242 0"',
79+
* ```
80+
*/
81+
export const CustomSizing = Template.bind({});
82+
CustomSizing.tags = ["!dev"];
83+
CustomSizing.args = {
84+
customStyles: {
85+
"--mod-colorwheel-inline-size": "300px",
86+
"--mod-colorwheel-block-size": "300px",
87+
"--mod-colorwheel-track-width": "30px",
88+
"--mod-colorwheel-path": "\"M 149 149 m -149 0 a 149 149 0 1 0 298 0 a 149 149 0 1 0 -298 0 M 149 149 m -121 0 a 121 121 0 1 0 242 0 a 121 121 0 1 0 -242 0\"",
89+
}
90+
};
91+
CustomSizing.parameters = {
92+
chromatic: { disableSnapshot: true },
93+
};
94+
95+
6296
// ********* DOCS ONLY ********* //
6397
export const Disabled = Template.bind({});
6498
Disabled.tags = ["!dev"];
@@ -76,7 +110,9 @@ Disabled.parameters = {
76110
*
77111
* The `.spectrum-colorwheel-colorarea-container-size` is hard coded to position the color area within the color wheel using `.spectrum-color-wheel-color-area-margin`. Implementations using JS can calculate the container size with `Math.sqrt(2 * R * R)`, where `R` is the inner radius as calculated for the clip paths.
78112
*
79-
* `.spectrum-colorwheel-path`, `.spectrum-colorwheel-path-borders` and `.spectrum-colorwheel-colorarea-container` are hard coded in CSS, and include token values as custom CSS variables so they can be accessed with JS. To use and calculate these values, implementations should consider:
113+
* Implementations should factor in the value of `--spectrum-color-wheel-color-area-margin`, as illustrated in the token specs, when calculating the size of the color area relative to the color wheel that contains it.
114+
*
115+
* `--spectrum-colorwheel-path` and `--spectrum-colorwheel-colorarea-container-size` are hard coded in CSS, and include token values as custom CSS variables so they can be accessed with JS. To use and calculate these values, implementations should consider:
80116
* ```
81117
* const wheel = document.querySelector(".spectrum-ColorWheel-wheel")
82118
* getComputedStyle(wheel).getPropertyValue('--track-width')

components/colorwheel/stories/colorwheel.test.js

+13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ export const ColorWheelGroup = Variants({
1111
testHeading: "With color area",
1212
isWithColorArea: true,
1313
},
14+
{
15+
testHeading: "Without color loupe",
16+
isWithColorLoupe: false,
17+
},
18+
{
19+
testHeading: "Custom sizing",
20+
customStyles: {
21+
"--mod-colorwheel-inline-size": "300px",
22+
"--mod-colorwheel-block-size": "300px",
23+
"--mod-colorwheel-track-width": "30px",
24+
"--mod-colorwheel-path": "\"M 149 149 m -149 0 a 149 149 0 1 0 298 0 a 149 149 0 1 0 -298 0 M 149 149 m -121 0 a 121 121 0 1 0 242 0 a 121 121 0 1 0 -242 0\"",
25+
},
26+
}
1427
],
1528
stateData: [
1629
{

0 commit comments

Comments
 (0)