Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(web): Switch Toggle component to v3 design tokens #DS-1449 #1660

Merged
merged 2 commits into from
Oct 1, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ const ToggleDisabled = () => (
name="default"
isDisabled
/>
<UNSTABLE_Toggle
id="toggle-warning-helper-text-disabled"
label="Toggle Label"
helperText="Helper text"
validationText="Validation text"
validationState="warning"
name="default"
isDisabled
isChecked
/>
<UNSTABLE_Toggle id="toggle-indicators-disabled" label="Toggle Label" name="default" hasIndicators isDisabled />
<UNSTABLE_Toggle
id="toggle-indicators-disabled-checked"
label="Toggle Label"
name="default"
hasIndicators
isDisabled
isChecked
/>
</>
);

Expand Down
133 changes: 98 additions & 35 deletions packages/web/src/scss/components/UNSTABLE_Toggle/_UNSTABLE_Toggle.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
@use '../../settings/cursors';
@use '../../theme/form-fields' as form-fields-theme;
@use '../../tools/form-fields' as form-fields-tools;
@use '../../tools/svg';

$_field-name: 'UNSTABLE_Toggle';

Expand All @@ -11,7 +10,7 @@ $_field-name: 'UNSTABLE_Toggle';
align-items: start;
justify-content: space-between;
max-width: theme.$max-width;
margin-block: form-fields-theme.$gap;
margin-block: form-fields-theme.$inline-field-margin-y;
crishpeen marked this conversation as resolved.
Show resolved Hide resolved
cursor: cursors.$form-fields;
}

Expand All @@ -20,7 +19,7 @@ $_field-name: 'UNSTABLE_Toggle';
}

.UNSTABLE_Toggle__text {
margin-right: form-fields-theme.$gap;
margin-right: form-fields-theme.$inline-field-gap;
}

.UNSTABLE_Toggle__label {
Expand All @@ -38,48 +37,100 @@ $_field-name: 'UNSTABLE_Toggle';
.UNSTABLE_Toggle__input {
@include form-fields-tools.inline-field-input();

display: grid;
flex-shrink: 0;
grid-template-areas: 'toggle';
width: theme.$input-width;
height: theme.$input-height;
border: theme.$input-border-width solid form-fields-theme.$inline-field-input-color-unchecked;
border: theme.$input-border-width solid theme.$input-border-color;
border-radius: theme.$input-border-radius;
background-image: svg.escape(theme.$input-mark);
background-position-x: theme.$input-mark-position-x;
background-position-y: theme.$input-mark-position-y;
background-size: theme.$input-mark-width theme.$input-mark-height;
background-repeat: no-repeat;
background-color: form-fields-theme.$inline-field-input-color-unchecked;
background-color: theme.$input-background-color;

@media (prefers-reduced-motion: no-preference) {
transition-property: border-color, background-color, background-position;
transition-property: border-color, background-color;
transition-duration: theme.$input-transition-duration;
transition-timing-function: theme.$input-transition-timing;
}

&:focus {
background-color: form-fields-theme.$inline-field-input-color-unchecked-active;
&::before,
&::after {
content: '';
display: block;
grid-area: toggle;
width: theme.$input-mark-size;
height: theme.$input-mark-size;
margin: theme.$input-mark-spacing;
border-radius: theme.$input-mark-border-radius;
background-color: theme.$input-mark-background-color;
box-shadow: theme.$input-mark-shadow;
transform: translateX(0);

@media (prefers-reduced-motion: no-preference) {
transition-property: transform, opacity, visibility;
transition-duration: theme.$input-transition-duration;
transition-timing-function: theme.$input-transition-timing;
}
}

&::before {
visibility: visible;
opacity: 1;
}

&::after {
visibility: hidden;
opacity: 0;
}

&:focus-visible {
box-shadow: theme.$input-focus-shadow;
}

&:checked {
border-color: form-fields-theme.$inline-field-input-color-checked;
background-position-x: theme.$input-mark-position-x-checked;
background-color: form-fields-theme.$inline-field-input-color-checked;
border-color: theme.$input-border-color-checked;
background-color: theme.$input-background-color-checked;

&::before,
&::after {
transform: translateX(100%);
}

&::before {
visibility: hidden;
opacity: 0;
}

&::after {
visibility: visible;
opacity: 1;
}
}

@media (hover: hover) {
&:hover {
background-color: form-fields-theme.$inline-field-input-color-unchecked-hover;
&:hover,
&:active {
background-color: theme.$input-background-color-hover;
}

&:checked:hover {
background-color: form-fields-theme.$inline-field-input-color-checked-hover;
&:checked:hover,
&:checked:active {
background-color: theme.$input-background-color-checked-hover;
}
}
}

.UNSTABLE_Toggle__input--indicators {
background-image: svg.escape(theme.$input-mark-indicators);
.UNSTABLE_Toggle__input--indicators::before,
.UNSTABLE_Toggle__input--indicators::after {
background-size: 100%;
background-color: transparent;
}

.UNSTABLE_Toggle__input--indicators::before {
background-image: theme.$input-mark-image;
}

.UNSTABLE_Toggle__input--indicators::after {
background-image: theme.$input-mark-image-checked;
}

.UNSTABLE_Toggle__validationText,
Expand All @@ -93,36 +144,48 @@ $_field-name: 'UNSTABLE_Toggle';

@include form-fields-tools.input-field-validation-states($_field-name);

.UNSTABLE_Toggle--disabled {
.UNSTABLE_Toggle:is(.UNSTABLE_Toggle--disabled, .is-disabled) {
@include form-fields-tools.inline-field-root-disabled();
}

.UNSTABLE_Toggle--disabled .UNSTABLE_Toggle__label {
.UNSTABLE_Toggle:is(.UNSTABLE_Toggle--disabled, .is-disabled) .UNSTABLE_Toggle__label {
@include form-fields-tools.label-disabled();
}

.UNSTABLE_Toggle--disabled > .UNSTABLE_Toggle__input,
.UNSTABLE_Toggle:is(.UNSTABLE_Toggle--disabled, .is-disabled) > .UNSTABLE_Toggle__input,
.UNSTABLE_Toggle > .UNSTABLE_Toggle__input:disabled {
@include form-fields-tools.input-disabled();

border-color: theme.$input-border-color-disabled;
background-image: svg.escape(theme.$input-mark-disabled);
background-color: transparent;
}
background-color: theme.$input-background-color-disabled;

.UNSTABLE_Toggle__input:checked:focus {
background-color: form-fields-theme.$inline-field-input-color-checked-active;
&::before,
&::after {
background-color: theme.$input-mark-background-color-disabled;
box-shadow: none;
}
}

.UNSTABLE_Toggle--disabled > .UNSTABLE_Toggle__input:checked,
.UNSTABLE_Toggle > .UNSTABLE_Toggle__input:disabled:checked {
background-image: svg.escape(theme.$input-mark-disabled-checked);
.UNSTABLE_Toggle:is(.UNSTABLE_Toggle--disabled, .is-disabled) > .UNSTABLE_Toggle__input--indicators,
.UNSTABLE_Toggle > .UNSTABLE_Toggle__input--indicators:disabled {
&::before,
&::after {
background-color: transparent;
}

&::before {
background-image: theme.$input-mark-image-disabled;
}

&::after {
background-image: theme.$input-mark-image-checked-disabled;
}
}

.UNSTABLE_Toggle--disabled .UNSTABLE_Toggle__validationText {
.UNSTABLE_Toggle:is(.UNSTABLE_Toggle--disabled, .is-disabled) .UNSTABLE_Toggle__validationText {
@include form-fields-tools.validation-text-disabled();
}

.UNSTABLE_Toggle--disabled .UNSTABLE_Toggle__helperText {
.UNSTABLE_Toggle:is(.UNSTABLE_Toggle--disabled, .is-disabled) .UNSTABLE_Toggle__helperText {
@include form-fields-tools.helper-text-disabled();
}
41 changes: 27 additions & 14 deletions packages/web/src/scss/components/UNSTABLE_Toggle/_theme.scss
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
@use '@tokens' as tokens;
@use '@global' as global-tokens;
@use '../../settings/globals';
@use '../../settings/transitions';

$max-width: 21rem;
$input-border-width: tokens.$border-width-100;
$input-border-radius: 12px;
$input-width: 44px;
$input-height: 24px;
$input-mark-height: 44px;
$input-mark-width: 52px;
$input-mark-position-y: -7px; // Position of the mark is offset because it has a shadow
$input-mark-position-x: -15px; // Position of the mark in non-checked state
$input-mark-position-x-checked: $input-mark-position-x + 20px; // Position of the mark in checked state
$input-mark: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="#{$input-mark-width}" height="#{$input-mark-height}" viewBox="0 0 52 44" fill="none"><g xmlns="http://www.w3.org/2000/svg" filter="url(#a)"><circle xmlns="http://www.w3.org/2000/svg" cx="26" cy="18" r="10" fill="#{tokens.$background-basic}"/></g><defs><filter id="a" width="44" height="44" x="4" y="0" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/><feOffset dy="4"/><feGaussianBlur stdDeviation="6"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/><feBlend in2="BackgroundImageFix" result="effect1_dropShadow_1_81"/><feBlend in="SourceGraphic" in2="effect1_dropShadow_1_81" result="shape"/></filter></defs></svg>');
$input-mark-indicators: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="#{$input-mark-width}" height="#{$input-mark-height}" viewBox="0 0 52 44" fill="none"><path fill="#{tokens.$background-basic}" d="M48.675 14.33a.58.58 0 0 0-.822 0L45 17.178l-2.852-2.852a.58.58 0 1 0-.823.823L44.177 18l-2.852 2.852a.58.58 0 1 0 .822.823L45 18.823l2.852 2.852a.58.58 0 1 0 .823-.823L45.823 18l2.852-2.852a.585.585 0 0 0 0-.817ZM5.25 20.651 3.208 18.61a.574.574 0 0 0-.816 0 .574.574 0 0 0 0 .817l2.444 2.444a.58.58 0 0 0 .822 0l6.184-6.177a.574.574 0 0 0 0-.817.574.574 0 0 0-.817 0L5.25 20.651Z"/><g xmlns="http://www.w3.org/2000/svg" filter="url(#a)"><circle xmlns="http://www.w3.org/2000/svg" cx="26" cy="18" r="10" fill="#{tokens.$background-basic}"/></g><defs><filter id="a" width="44" height="44" x="4" y="0" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/><feOffset dy="4"/><feGaussianBlur stdDeviation="6"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/><feBlend in2="BackgroundImageFix" result="effect1_dropShadow_1_81"/><feBlend in="SourceGraphic" in2="effect1_dropShadow_1_81" result="shape"/></filter></defs></svg>');
$input-mark-disabled: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="#{$input-mark-width}" height="#{$input-mark-height}" viewBox="0 0 52 44" fill="none"><circle xmlns="http://www.w3.org/2000/svg" cx="26" cy="18" r="10" fill="#{tokens.$action-unselected-disabled}"/></svg>');
$input-mark-disabled-checked: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="#{$input-mark-width}" height="#{$input-mark-height}" viewBox="0 0 52 44" fill="none"><circle xmlns="http://www.w3.org/2000/svg" cx="26" cy="18" r="10" fill="#{tokens.$action-selected-disabled}"/></svg>');
$input-border-width: global-tokens.$border-width-100;
$input-border-color: var(--#{globals.$prefix}color-action-toggle-unselected-border);
$input-border-color-checked: var(--#{globals.$prefix}color-action-toggle-selected-border);
$input-border-color-disabled: var(--#{globals.$prefix}color-disabled-border);
$input-background-color: var(--#{globals.$prefix}color-action-toggle-unselected-default);
$input-background-color-hover: var(--#{globals.$prefix}color-action-toggle-unselected-hover);
$input-background-color-checked: var(--#{globals.$prefix}color-action-toggle-selected-default);
crishpeen marked this conversation as resolved.
Show resolved Hide resolved
$input-background-color-checked-hover: var(--#{globals.$prefix}color-action-toggle-selected-hover);
$input-background-color-disabled: var(--#{globals.$prefix}color-disabled-background);
$input-border-radius: global-tokens.$radius-400;
$input-focus-shadow: global-tokens.$focus;

$input-mark-size: 20px;
$input-mark-spacing: global-tokens.$space-100;
$input-mark-position-x: global-tokens.$space-100;
$input-mark-position-y: global-tokens.$space-100;
$input-mark-border-radius: global-tokens.$radius-full;
$input-mark-background-color: var(--#{globals.$prefix}color-action-toggle-selected-content);
$input-mark-background-color-disabled: var(--#{globals.$prefix}color-disabled-foreground);
$input-mark-image: var(--#{globals.$prefix}toggle-input-mark-background-image-url);
$input-mark-image-checked: var(--#{globals.$prefix}toggle-input-mark-checked-background-image-url);
$input-mark-image-disabled: var(--#{globals.$prefix}toggle-input-mark-disabled-background-image-url);
$input-mark-image-checked-disabled: var(--#{globals.$prefix}toggle-input-mark-checked-disabled-background-image-url);
$input-mark-shadow: global-tokens.$shadow-200;

$input-transition-duration: transitions.$duration-100;
$input-transition-timing: transitions.$timing-eased-in-out;
$input-border-color-disabled: tokens.$border-primary-disabled;
$input-focus-shadow: tokens.$focus;
23 changes: 23 additions & 0 deletions packages/web/src/scss/components/UNSTABLE_Toggle/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,29 @@ <h2 class="docs-Heading">Disabled</h2>
<input type="checkbox" id="toggle-helper-text-disabled" class="UNSTABLE_Toggle__input" name="default" aria-describedby="toggle-helper-text-disabled-helper-text" disabled />
</label>

<label for="toggle-warning-helper-text-disabled" class="UNSTABLE_Toggle UNSTABLE_Toggle--warning UNSTABLE_Toggle--disabled">
<span class="UNSTABLE_Toggle__text">
<span class="UNSTABLE_Toggle__label">Toggle Label</span>
<span class="UNSTABLE_Toggle__helperText" id="toggle-warning-helper-text-helper-text-disabled">Helper text</span>
<span class="UNSTABLE_Toggle__validationText" id="toggle-warning-helper-text-validation-text-disabled">Validation text</span>
</span>
<input type="checkbox" id="toggle-warning-helper-text-disabled" class="UNSTABLE_Toggle__input" name="default" aria-describedby="toggle-warning-helper-text-helper-text toggle-warning-helper-text-validation-text" checked disabled />
</label>

<label for="toggle-indicators-disabled" class="UNSTABLE_Toggle UNSTABLE_Toggle--disabled">
<span class="UNSTABLE_Toggle__text">
<span class="UNSTABLE_Toggle__label">Toggle Label</span>
</span>
<input type="checkbox" id="toggle-indicators-disabled" class="UNSTABLE_Toggle__input UNSTABLE_Toggle__input--indicators" name="default" disabled />
</label>

<label for="toggle-indicators-disabled-checked" class="UNSTABLE_Toggle UNSTABLE_Toggle--disabled">
<span class="UNSTABLE_Toggle__text">
<span class="UNSTABLE_Toggle__label">Toggle Label</span>
</span>
<input type="checkbox" id="toggle-indicators-disabled-checked" class="UNSTABLE_Toggle__input UNSTABLE_Toggle__input--indicators" name="default" disabled checked />
</label>

</div>
</section>

Expand Down
3 changes: 1 addition & 2 deletions packages/web/src/scss/components/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,4 @@
@forward 'UNSTABLE_EmptyState';
@forward 'UNSTABLE_Section';
@forward 'UNSTABLE_Slider';

// @forward 'UNSTABLE_Toggle';
@forward 'UNSTABLE_Toggle';
11 changes: 7 additions & 4 deletions packages/web/src/scss/tools/_themes.scss
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,16 @@

// Toggle
--#{globals.$prefix}toggle-input-mark-background-image-url: #{svg.escape(
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="52" height="44" viewBox="0 0 52 44" fill="none"><g xmlns="http://www.w3.org/2000/svg" filter="url(#a)"><circle xmlns="http://www.w3.org/2000/svg" cx="26" cy="18" r="10" fill="#{map.get($themed-tokens, colors, action, toggle, content-basic)}" xmlns="http://www.w3.org/2000/svg"><rect x="0" width="8" height="1" rx="0.5" /><rect x="0" y="5" width="8" height="1" rx="0.5" /><rect x="0" y="10" width="8" height="1" rx="0.5" /><rect x="0" y="15" width="8" height="1" rx="0.5" /></svg>')
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none"><path fill="#{map.get($themed-tokens, colors, action, toggle, unselected-content)}" fill-rule="evenodd" d="M20 0H0v20h20V0Zm-7.302 6.177a.58.58 0 0 1 .823 0 .585.585 0 0 1 0 .816l-2.853 2.853 2.853 2.852a.58.58 0 1 1-.823.823l-2.852-2.853-2.853 2.853a.58.58 0 1 1-.822-.823l2.852-2.852-2.852-2.853a.58.58 0 1 1 .822-.822l2.853 2.852 2.852-2.846Z" clip-rule="evenodd"/></svg>')
)};
--#{globals.$prefix}toggle-input-mark-disabled-background-image-url: #{svg.escape(
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="52" height="44" viewBox="0 0 52 44" fill="none"><circle xmlns="http://www.w3.org/2000/svg" cx="26" cy="18" r="10" fill="#{map.get($themed-tokens, colors, disabled, foreground)}"/></svg>')
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none"><path fill="#{map.get($themed-tokens, colors, disabled, foreground)}" fill-rule="evenodd" d="M20 0H0v20h20V0Zm-7.302 6.177a.58.58 0 0 1 .823 0 .585.585 0 0 1 0 .816l-2.853 2.853 2.853 2.852a.58.58 0 1 1-.823.823l-2.852-2.853-2.853 2.853a.58.58 0 1 1-.822-.823l2.852-2.852-2.852-2.853a.58.58 0 1 1 .822-.822l2.853 2.852 2.852-2.846Z" clip-rule="evenodd"/></svg>')
)};
--#{globals.$prefix}toggle-input-mark-indicators-background-image-url: #{svg.escape(
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="52" height="44" viewBox="0 0 52 44" fill="none"><path fill="#{map.get($themed-tokens, colors, action, toggle, content-basic)}" d="M48.675 14.33a.58.58 0 0 0-.822 0L45 17.178l-2.852-2.852a.58.58 0 1 0-.823.823L44.177 18l-2.852 2.852a.58.58 0 1 0 .822.823L45 18.823l2.852 2.852a.58.58 0 1 0 .823-.823L45.823 18l2.852-2.852a.585.585 0 0 0 0-.817ZM5.25 20.651 3.208 18.61a.574.574 0 0 0-.816 0 .574.574 0 0 0 0 .817l2.444 2.444a.58.58 0 0 0 .822 0l6.184-6.177a.574.574 0 0 0 0-.817.574.574 0 0 0-.817 0L5.25 20.651Z"/><g xmlns="http://www.w3.org/2000/svg" filter="url(#a)"><circle xmlns="http://www.w3.org/2000/svg" cx="26" cy="18" r="10" fill="#{map.get($themed-tokens, colors, action, toggle, content-basic)}"/></g><defs><filter id="a" width="44" height="44" x="4" y="0" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/><feOffset dy="4"/><feGaussianBlur stdDeviation="6"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/><feBlend in2="BackgroundImageFix" result="effect1_dropShadow_1_81"/><feBlend in="SourceGraphic" in2="effect1_dropShadow_1_81" result="shape"/></filter></defs></svg>')
--#{globals.$prefix}toggle-input-mark-checked-background-image-url: #{svg.escape(
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none"><path fill="#{map.get($themed-tokens, colors, action, toggle, selected-content)}" fill-rule="evenodd" d="M20 0H0v20h20V0ZM5.987 9.904l2.042 2.042 5.775-5.775a.574.574 0 0 1 .817 0 .574.574 0 0 1 0 .816l-6.184 6.178a.58.58 0 0 1-.822 0L5.17 10.72a.574.574 0 0 1 0-.817.574.574 0 0 1 .816 0Z" clip-rule="evenodd"/></svg>')
)};
--#{globals.$prefix}toggle-input-mark-checked-disabled-background-image-url: #{svg.escape(
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none"><path fill="#{map.get($themed-tokens, colors, disabled, foreground)}" fill-rule="evenodd" d="M20 0H0v20h20V0ZM5.987 9.904l2.042 2.042 5.775-5.775a.574.574 0 0 1 .817 0 .574.574 0 0 1 0 .816l-6.184 6.178a.58.58 0 0 1-.822 0L5.17 10.72a.574.574 0 0 1 0-.817.574.574 0 0 1 .816 0Z" clip-rule="evenodd"/></svg>')
)};

// Tooltip
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/demo-components-compare.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { readdirSync } from 'fs';
import { formatPackageName, getServerUrl, takeScreenshot, waitForPageLoad } from '../helpers';

// Tests that are intentionally broken, but will be fixed in the future
const IGNORED_TESTS: string[] = ['Header', 'UNSTABLE_Toggle'];
const IGNORED_TESTS: string[] = ['Header'];

interface TestConfig {
packageDir: string;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading