Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .changeset/giant-windows-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
"@spectrum-css/colorwheel": major
---

# colorwheel S2 migration

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.

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.

Support is provided for the `240px` and `192px` sizes outlined in the design requirements.

The `forced-colors` media query has been moved to the bottom of the file consistent with our other component implementations.

Stories, tests and documentation have been updated to be consistent with these changes.

The following mods have been removed:

```css
--mod-colorwheel-height
--mod-colorwheel-width
--mod-colorwheel-min-width
--mod-colorwheel-path-borders
--mod-colorwheel-colorarea-margin
--mod-colorwheel-border-width
```
32 changes: 17 additions & 15 deletions components/colorwheel/dist/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,53 @@
".spectrum-ColorWheel",
".spectrum-ColorWheel-ColorArea-handle",
".spectrum-ColorWheel-ColorArea-handle:dir(rtl)",
".spectrum-ColorWheel-border",
".spectrum-ColorWheel-border.is-disabled",
".spectrum-ColorWheel-colorarea-container",
".spectrum-ColorWheel-handle",
".spectrum-ColorWheel-inner",
".spectrum-ColorWheel-slider",
".spectrum-ColorWheel-wheel",
".spectrum-ColorWheel-wheel.is-disabled",
".spectrum-ColorWheel.is-disabled",
".spectrum-ColorWheel.is-disabled .spectrum-ColorWheel-inner:before",
".spectrum-ColorWheel.is-disabled:after",
".spectrum-ColorWheel.is-disabled:before",
".spectrum-ColorWheel.is-dragged",
".spectrum-ColorWheel.is-focused",
".spectrum-ColorWheel:after",
".spectrum-ColorWheel:before",
"[dir=\"rtl\"] .spectrum-ColorWheel-ColorArea-handle"
],
"modifiers": [
"--mod-colorwheel-block-size",
"--mod-colorwheel-border-color",
"--mod-colorwheel-border-width",
"--mod-colorwheel-colorarea-container-size",
"--mod-colorwheel-colorarea-margin",
"--mod-colorwheel-fill-color-disabled",
"--mod-colorwheel-height",
"--mod-colorwheel-min-width",
"--mod-colorwheel-inline-size",
"--mod-colorwheel-min-inline-size",
"--mod-colorwheel-path",
"--mod-colorwheel-path-borders",
"--mod-colorwheel-track-width",
"--mod-colorwheel-width"
"--mod-colorwheel-track-width"
],
"component": [
"--spectrum-color-wheel-color-area-margin",
"--spectrum-color-wheel-border-opacity",
"--spectrum-color-wheel-minimum-width",
"--spectrum-color-wheel-width",
"--spectrum-colorwheel-block-size",
"--spectrum-colorwheel-border-color",
"--spectrum-colorwheel-border-color-rgb",
"--spectrum-colorwheel-border-opacity",
"--spectrum-colorwheel-border-width",
"--spectrum-colorwheel-colorarea-container-size",
"--spectrum-colorwheel-fill-color-disabled",
"--spectrum-colorwheel-height",
"--spectrum-colorwheel-inline-size",
"--spectrum-colorwheel-min-inline-size",
"--spectrum-colorwheel-path",
"--spectrum-colorwheel-path-borders",
"--spectrum-colorwheel-track-width",
"--spectrum-colorwheel-width"
"--spectrum-colorwheel-track-width"
],
"global": [
"--spectrum-border-width-100",
"--spectrum-color-control-track-width",
"--spectrum-disabled-background-color",
"--spectrum-transparent-black-300"
"--spectrum-gray-1000-rgb"
],
"passthroughs": [],
"high-contrast": [
Expand Down
105 changes: 68 additions & 37 deletions components/colorwheel/index.css
Comment thread
cdransf marked this conversation as resolved.
Comment thread
jawinn marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
* Copyright 2024 Adobe. All rights reserved.
* Copyright 2025 Adobe. All rights reserved.
*
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
Expand All @@ -11,46 +11,81 @@
* governing permissions and limitations under the License.
*/

/* Windows High Contrast Mode */
@media (forced-colors: active) {
.spectrum-ColorWheel {
--highcontrast-colorwheel-border-color-disabled: GrayText;
--highcontrast-colorwheel-fill-color-disabled: Canvas;
Comment on lines -17 to -18
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally spoke too soon on the WHCM stuff! I left an updated (more thought-through 😬 ) idea that should replicate what's on prod better now.

Looks like we still need the gradient itself, and then I have a better idea how to replicate this disabled state now:
(this is production when I test in AssistivLabs)
Screenshot 2025-02-04 at 9 03 56 AM

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm — took a look at current state in Assistiv and it looks better, but I'm not sure if it's exactly what we want?

image

Copy link
Copy Markdown
Collaborator

@marissahuysentruyt marissahuysentruyt Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah....I think there's a discrepancy between Canvas and CanvasText. I believe swapping this --highcontrast-colorwheel-fill-color-disabled: Canvas; instead of CanvasText should get rid of that white background in the disabled wheel.

Screenshot 2025-02-05 at 12 58 00 PM

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yep!
image

.spectrum-ColorWheel {
--spectrum-colorwheel-inline-size: var(--spectrum-color-wheel-width);
--spectrum-colorwheel-block-size: var(--spectrum-color-wheel-width);
--spectrum-colorwheel-min-inline-size: var(--spectrum-color-wheel-minimum-width);

forced-color-adjust: none;
}
}
/* @TODO: leveraging the rgb token in this case to achieve the desired border color implementation as rgb + opacity are required by the `rgba` function. */
--spectrum-colorwheel-border-color-rgb: var(--spectrum-gray-1000-rgb);
Comment thread
cdransf marked this conversation as resolved.

.spectrum-ColorWheel {
--spectrum-colorwheel-border-color: var(--spectrum-transparent-black-300);
--spectrum-colorwheel-border-opacity: var(--spectrum-color-wheel-border-opacity);
--spectrum-colorwheel-border-color: rgba(var(--spectrum-colorwheel-border-color-rgb), var(--spectrum-colorwheel-border-opacity));

--spectrum-colorwheel-width: var(--mod-colorwheel-width, var(--spectrum-color-wheel-width));
--spectrum-colorwheel-height: var(--mod-colorwheel-height, var(--spectrum-color-wheel-width));
--spectrum-colorwheel-fill-color-disabled: var(--mod-colorwheel-fill-color-disabled, var(--spectrum-disabled-background-color));
--spectrum-colorwheel-border-color: var(--spectrum-transparent-black-300);
--spectrum-colorwheel-border-width: var(--spectrum-border-width-100);
Comment thread
marissahuysentruyt marked this conversation as resolved.
--spectrum-colorwheel-track-width: var(--spectrum-color-control-track-width);

--spectrum-colorwheel-border-width: var(--mod-colorwheel-border-width, var(--spectrum-border-width-100));
--spectrum-colorwheel-track-width: var(--mod-colorwheel-track-width, var(--spectrum-color-control-track-width));
--spectrum-colorwheel-fill-color-disabled: var(--spectrum-disabled-background-color);

/* stylelint-disable-next-line spectrum-tools/no-unused-custom-properties -- used with JS in calculating the clip-path paths and colorarea-container-size */
--_track-width: var(--spectrum-colorwheel-track-width);
--_track-width: var(--mod-colorwheel-track-width, var(--spectrum-colorwheel-track-width));
/* stylelint-disable-next-line spectrum-tools/no-unused-custom-properties -- used with JS in calculating the clip-path paths and colorarea-container-size */
--_border-width: var(--spectrum-colorwheel-border-width);
Comment thread
cdransf marked this conversation as resolved.

position: relative;
display: block;
min-inline-size: var(--mod-colorwheel-min-width, var(--spectrum-color-wheel-minimum-width));
inline-size: var(--spectrum-colorwheel-width);
block-size: var(--spectrum-colorwheel-height);
min-inline-size: var(--mod-colorwheel-min-inline-size, var(--spectrum-colorwheel-min-inline-size));
inline-size: var(--mod-colorwheel-inline-size, var(--spectrum-colorwheel-inline-size));
block-size: var(--mod-colorwheel-block-size, var(--spectrum-colorwheel-block-size));
user-select: none;
cursor: default;

/**
* Color wheel exterior border
* - Calcs for `inline-size` and `block-size` subtract 4 times the component's border width
* (to account for the inset width of the exterior border) from the component's width.
*/
&::before {
Comment thread
cdransf marked this conversation as resolved.
inline-size: calc(var(--mod-colorwheel-inline-size, var(--spectrum-colorwheel-inline-size)) - calc(4 * var(--spectrum-colorwheel-border-width)));
block-size: calc(var(--mod-colorwheel-inline-size, var(--spectrum-colorwheel-inline-size)) - calc(4 * var(--spectrum-colorwheel-border-width)));
inset: var(--spectrum-colorwheel-border-width);
content: "";
position: absolute;
border-width: var(--spectrum-colorwheel-border-width);
border-style: solid;
border-color: var(--mod-colorwheel-border-color, var(--spectrum-colorwheel-border-color));
border-radius: 100%;
z-index: 1;
}

/**
* Color wheel interior border
* - Calcs for `inset` 2 times the component's border width from the
* track width (to account for the inset width of the interior border)
*/
&::after {
inset: calc(var(--mod-colorwheel-track-width, var(--spectrum-colorwheel-track-width)) - (calc(2 * var(--spectrum-colorwheel-border-width))));
content: "";
position: absolute;
border-width: var(--spectrum-colorwheel-border-width);
border-style: solid;
border-color: var(--mod-colorwheel-border-color, var(--spectrum-colorwheel-border-color));
border-radius: 100%;
z-index: 1;
}

&.is-focused {
z-index: 2;
}

&.is-disabled {
pointer-events: none;

&::before,
&::after,
.spectrum-ColorWheel-inner::before {
border-color: var(--highcontrast-colorwheel-border-color-disabled, transparent);
}
}

&.is-dragged {
Expand All @@ -77,7 +112,6 @@
display: flex;
align-items: center;
justify-content: center;
margin: var(--mod-colorwheel-colorarea-margin, var(--spectrum-color-wheel-color-area-margin));
}

.spectrum-ColorWheel-slider {
Expand All @@ -93,7 +127,7 @@
}

.spectrum-ColorWheel-handle {
transform: translate(calc(var(--spectrum-colorwheel-width) / 2 - var(--spectrum-colorwheel-track-width) / 2), 0);
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);
inset-block-start: 50%;
inset-inline: 50%;
Comment thread
cdransf marked this conversation as resolved.
}
Expand All @@ -107,19 +141,6 @@
}
}

/* a clip-path set border-width wider than than spectrum-colorwheel-wheel to create the appreance of a border */
.spectrum-ColorWheel-border {
position: relative;
background-color: var(--mod-colorwheel-border-color, var(--spectrum-colorwheel-border-color));
inline-size: var(--spectrum-colorwheel-width);
block-size: var(--spectrum-colorwheel-height);
clip-path: path(evenodd, var(--mod-colorwheel-path-borders, var(--spectrum-colorwheel-path-borders)));

&.is-disabled {
background-color: var(--highcontrast-colorwheel-border-color-disabled, var(--spectrum-colorwheel-fill-color-disabled));
}
}

.spectrum-ColorWheel-wheel {
position: absolute;
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);
Expand All @@ -129,6 +150,16 @@

&.is-disabled {
pointer-events: none;
background: var(--highcontrast-colorwheel-fill-color-disabled, var(--spectrum-colorwheel-fill-color-disabled));
background: var(--highcontrast-colorwheel-fill-color-disabled, var(--mod-colorwheel-fill-color-disabled, var(--spectrum-colorwheel-fill-color-disabled)));
}
}

/* Windows High Contrast Mode */
Comment thread
jawinn marked this conversation as resolved.
@media (forced-colors: active) {
.spectrum-ColorWheel {
--highcontrast-colorwheel-border-color-disabled: GrayText;
--highcontrast-colorwheel-fill-color-disabled: Canvas;

forced-color-adjust: none;
}
}
40 changes: 38 additions & 2 deletions components/colorwheel/stories/colorwheel.stories.js
Comment thread
jawinn marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,16 @@ export default {
if: { arg: "isDisabled", truthy: false },
},
isWithColorArea: {
name: "With Color Area",
name: "With color area",
type: { name: "boolean" },
table: {
type: { summary: "boolean" },
category: "State",
},
control: "boolean",
},
isWithColorLoupe: {
name: "With color loupe",
Comment thread
cdransf marked this conversation as resolved.
type: { name: "boolean" },
table: {
type: { summary: "boolean" },
Expand All @@ -44,6 +53,7 @@ export default {
isDisabled: false,
isFocused: false,
isWithColorArea: false,
isWithColorLoupe: true,
selectedColor: "rgba(255, 0, 0, 50%)",
},
parameters: {
Expand All @@ -59,6 +69,30 @@ export default {
export const Default = ColorWheelGroup.bind({});
Default.args = {};

/**
* 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:
* ```
* "--mod-colorwheel-inline-size": "300px",
* "--mod-colorwheel-block-size": "300px",
* "--mod-colorwheel-track-width": "30px",
* "--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"',
* ```
*/
export const CustomSizing = Template.bind({});
CustomSizing.tags = ["!dev"];
CustomSizing.args = {
Comment thread
cdransf marked this conversation as resolved.
customStyles: {
"--mod-colorwheel-inline-size": "300px",
"--mod-colorwheel-block-size": "300px",
"--mod-colorwheel-track-width": "30px",
"--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\"",
}
};
CustomSizing.parameters = {
chromatic: { disableSnapshot: true },
};


// ********* DOCS ONLY ********* //
export const Disabled = Template.bind({});
Disabled.tags = ["!dev"];
Expand All @@ -76,7 +110,9 @@ Disabled.parameters = {
*
* 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.
Comment thread
cdransf marked this conversation as resolved.
*
* `.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:
* 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.
*
* `--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:
* ```
* const wheel = document.querySelector(".spectrum-ColorWheel-wheel")
* getComputedStyle(wheel).getPropertyValue('--track-width')
Expand Down
13 changes: 13 additions & 0 deletions components/colorwheel/stories/colorwheel.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ export const ColorWheelGroup = Variants({
testHeading: "With color area",
isWithColorArea: true,
},
{
testHeading: "Without color loupe",
isWithColorLoupe: false,
},
Comment thread
cdransf marked this conversation as resolved.
{
testHeading: "Custom sizing",
customStyles: {
"--mod-colorwheel-inline-size": "300px",
"--mod-colorwheel-block-size": "300px",
"--mod-colorwheel-track-width": "30px",
"--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\"",
},
}
],
stateData: [
{
Expand Down
Loading