diff --git a/.changeset/giant-windows-smoke.md b/.changeset/giant-windows-smoke.md new file mode 100644 index 0000000000..f7e79a8e75 --- /dev/null +++ b/.changeset/giant-windows-smoke.md @@ -0,0 +1,27 @@ +--- +"@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 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 +``` + +The mod `--mod-colorwheel-track-width` has been added. diff --git a/components/colorwheel/dist/metadata.json b/components/colorwheel/dist/metadata.json index 07c9f09723..6172420696 100644 --- a/components/colorwheel/dist/metadata.json +++ b/components/colorwheel/dist/metadata.json @@ -4,8 +4,6 @@ ".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", @@ -13,42 +11,46 @@ ".spectrum-ColorWheel-wheel", ".spectrum-ColorWheel-wheel.is-disabled", ".spectrum-ColorWheel.is-disabled", + ".spectrum-ColorWheel.is-disabled .spectrum-ColorWheel-inner:before", + ".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": [ diff --git a/components/colorwheel/index.css b/components/colorwheel/index.css index fe4b7865ba..1a8638381f 100644 --- a/components/colorwheel/index.css +++ b/components/colorwheel/index.css @@ -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 @@ -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; +.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); -.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); + --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); + --_border-width: var(--mod-colorwheel-border-width, var(--spectrum-colorwheel-border-width)); 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 { + inline-size: calc(var(--mod-colorwheel-inline-size, var(--spectrum-colorwheel-inline-size)) - calc(4 * var(--mod-colorwheel-border-width, var(--spectrum-colorwheel-border-width)))); + block-size: calc(var(--mod-colorwheel-inline-size, var(--spectrum-colorwheel-inline-size)) - calc(4 * var(--mod-colorwheel-border-width, var(--spectrum-colorwheel-border-width)))); + inset-block-start: var(--mod-colorwheel-border-width, var(--spectrum-colorwheel-border-width)); + inset-inline-start: var(--mod-colorwheel-border-width, var(--spectrum-colorwheel-border-width)); + content: ""; + position: absolute; + border-width: var(--mod-colorwheel-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(--mod-colorwheel-border-width, var(--spectrum-colorwheel-border-width))))); + content: ""; + position: absolute; + border-width: var(--mod-colorwheel-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, + .spectrum-ColorWheel-inner::before { + border-color: var(--highcontrast-colorwheel-border-color-disabled, transparent); + } } &.is-dragged { @@ -71,13 +106,16 @@ margin: auto; } +/* + * While unused, we should factor in the `--spectrum-color-wheel-color-area-margin` which resolves to a value of + * 12px when calculating the size of the color area relative to the color wheel that contains it. + */ .spectrum-ColorWheel-colorarea-container { block-size: auto; inline-size: 100%; display: flex; align-items: center; justify-content: center; - margin: var(--mod-colorwheel-colorarea-margin, var(--spectrum-color-wheel-color-area-margin)); } .spectrum-ColorWheel-slider { @@ -93,7 +131,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%; } @@ -107,28 +145,25 @@ } } -/* 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); - inset-block: var(--spectrum-colorwheel-border-width); - inset-inline: var(--spectrum-colorwheel-border-width); + inset-block: var(--mod-colorwheel-border-width, var(--spectrum-colorwheel-border-width)); + inset-inline: var(--mod-colorwheel-border-width, var(--spectrum-colorwheel-border-width)); clip-path: path(evenodd, var(--mod-colorwheel-path, var(--spectrum-colorwheel-path))); &.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 */ +@media (forced-colors: active) { + .spectrum-ColorWheel { + --highcontrast-colorwheel-border-color-disabled: GrayText; + --highcontrast-colorwheel-fill-color-disabled: Canvas; + + forced-color-adjust: none; } } diff --git a/components/colorwheel/stories/colorwheel.stories.js b/components/colorwheel/stories/colorwheel.stories.js index 15bba48a20..2d70472e13 100644 --- a/components/colorwheel/stories/colorwheel.stories.js +++ b/components/colorwheel/stories/colorwheel.stories.js @@ -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", type: { name: "boolean" }, table: { type: { summary: "boolean" }, @@ -44,6 +53,7 @@ export default { isDisabled: false, isFocused: false, isWithColorArea: false, + isWithColorLoupe: true, selectedColor: "rgba(255, 0, 0, 50%)", }, parameters: { @@ -74,9 +84,7 @@ Disabled.parameters = { * * To display a color area inside of the color wheel, add a color area component to `.spectrum-ColorWheel-colorarea-container` element and define the custom width and height styles with `--mod-colorarea-width` and `--mod-colorarea-height` variables. * - * 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. - * - * `.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: + * `--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') diff --git a/components/colorwheel/stories/colorwheel.test.js b/components/colorwheel/stories/colorwheel.test.js index 7271a8d080..a420c54b4c 100644 --- a/components/colorwheel/stories/colorwheel.test.js +++ b/components/colorwheel/stories/colorwheel.test.js @@ -11,6 +11,10 @@ export const ColorWheelGroup = Variants({ testHeading: "With color area", isWithColorArea: true, }, + { + testHeading: "Without color loupe", + isWithColorLoupe: false, + }, ], stateData: [ { diff --git a/components/colorwheel/stories/template.js b/components/colorwheel/stories/template.js index 1d02f5e782..91831c0af3 100644 --- a/components/colorwheel/stories/template.js +++ b/components/colorwheel/stories/template.js @@ -12,6 +12,7 @@ export const Template = ({ isDisabled = false, isFocused = false, isWithColorArea = false, + isWithColorLoupe = true, colorHandleStyle = {}, selectedColor = "rgba(255, 0, 0, 50%)", } = {}, context = {}) => { @@ -37,20 +38,16 @@ export const Template = ({