diff --git a/packages/css/index.css b/packages/css/index.css index 884fb499e3..07c7159076 100644 --- a/packages/css/index.css +++ b/packages/css/index.css @@ -10,3 +10,4 @@ @import url('./ingress.css'); @import url('./skiplink.css'); @import url('./accordion.css'); +@import url('./switch.css'); diff --git a/packages/css/react-css-modules.css b/packages/css/react-css-modules.css index 7961d0fb92..55729a292f 100644 --- a/packages/css/react-css-modules.css +++ b/packages/css/react-css-modules.css @@ -1331,223 +1331,6 @@ } } -@layer fds.switch { - .fds-switch-switch-9a6b03bc { - --fds-transition: 200ms; - --fds-switch-height: 1.75rem; - --fds-switch-focus-border-width: 3px; - - position: relative; - } - - @media (prefers-reduced-motion) { - .fds-switch-switch-9a6b03bc { - --fds-transition: 0; - } - } - - .fds-switch-label-9a6b03bc { - min-height: var(--fds-sizing-10); - min-width: min-content; - display: grid; - grid-template-columns: auto 1fr; - gap: var(--fds-spacing-1); - align-items: center; - cursor: pointer; - } - - .fds-switch-track-9a6b03bc { - position: relative; - display: inline-block; - pointer-events: none; - width: var(--fds-switch-width); - height: var(--fds-switch-height); - margin: auto; - overflow: visible; - border-radius: var(--fds-border_radius-full); - background-color: var(--fds-semantic-surface-neutral-dark); - transition: background-color var(--fds-transition) ease; - margin-right: var(--fds-spacing-1); - } - - .fds-switch-description-9a6b03bc { - padding-left: calc(var(--fds-switch-width) + var(--fds-spacing-2)); - margin-top: calc(var(--fds-spacing-2) * -1); - color: var(--fds-semantic-text-neutral-subtle); - } - - .fds-switch-padlock-9a6b03bc { - height: 1.2em; - width: 1.2em; - } - - .fds-switch-right-9a6b03bc { - grid-template-columns: 1fr auto; - grid-auto-flow: dense; - } - - .fds-switch-right-9a6b03bc .fds-switch-track-9a6b03bc { - order: 1; - margin-right: 0; - } - - .fds-switch-right-9a6b03bc + .fds-switch-description-9a6b03bc { - padding-left: 0; - } - - .fds-switch-input-9a6b03bc { - position: absolute; - width: 2.75rem; - height: 2.75rem; - z-index: 1; - opacity: 0; - cursor: pointer; - margin: 0; - } - - .fds-switch-readonly-9a6b03bc > .fds-switch-label-9a6b03bc { - grid-template-columns: auto min-content 1fr; - } - - .fds-switch-readonly-9a6b03bc > .fds-switch-label-9a6b03bc:where(.fds-switch-right-9a6b03bc) { - grid-template-columns: min-content 1fr auto; - } - - .fds-switch-readonly-9a6b03bc > .fds-switch-input-9a6b03bc, - .fds-switch-readonly-9a6b03bc > .fds-switch-label-9a6b03bc { - cursor: default; - } - - .fds-switch-disabled-9a6b03bc > .fds-switch-input-9a6b03bc, - .fds-switch-disabled-9a6b03bc > .fds-switch-label-9a6b03bc, - .fds-switch-disabled-9a6b03bc > .fds-switch-track-9a6b03bc { - cursor: not-allowed; - } - - .fds-switch-disabled-9a6b03bc > .fds-switch-label-9a6b03bc, - .fds-switch-disabled-9a6b03bc > .fds-switch-track-9a6b03bc, - .fds-switch-disabled-9a6b03bc > .fds-switch-description-9a6b03bc { - opacity: var(--fds-opacity-disabled); - } - - .fds-switch-readonly-9a6b03bc > .fds-switch-description-9a6b03bc { - margin-left: var(--fds-spacing-1); - } - - .fds-switch-small-9a6b03bc, - .fds-switch-small-9a6b03bc .fds-switch-label-9a6b03bc { - min-height: var(--fds-sizing-6); - } - - .fds-switch-medium-9a6b03bc, - .fds-switch-medium-9a6b03bc .fds-switch-label-9a6b03bc { - min-height: var(--fds-sizing-7); - } - - .fds-switch-large-9a6b03bc, - .fds-switch-large-9a6b03bc .fds-switch-label-9a6b03bc { - min-height: var(--fds-sizing-8); - } - - .fds-switch-small-9a6b03bc { - --fds-switch-height: var(--fds-sizing-6); - --fds-switch-width: var(--fds-sizing-11); - } - - .fds-switch-small-9a6b03bc .fds-switch-input-9a6b03bc { - left: -0.25rem; - top: -0.25rem; - } - - .fds-switch-medium-9a6b03bc { - --fds-switch-height: var(--fds-sizing-7); - --fds-switch-width: var(--fds-sizing-13); - } - - .fds-switch-medium-9a6b03bc .fds-switch-input-9a6b03bc { - left: 0; - top: 0; - } - - .fds-switch-large-9a6b03bc { - --fds-switch-height: var(--fds-sizing-8); - --fds-switch-width: var(--fds-sizing-15); - } - - .fds-switch-large-9a6b03bc .fds-switch-input-9a6b03bc { - left: 0; - top: 0.25rem; - } - - .fds-switch-label-9a6b03bc:has(.fds-switch-track-9a6b03bc:only-child) { - grid-template-columns: auto; - } - - .fds-switch-label-9a6b03bc:has(.fds-switch-track-9a6b03bc:only-child) .fds-switch-track-9a6b03bc { - margin-right: 0; - } - - .fds-switch-input-9a6b03bc:focus-visible + .fds-switch-label-9a6b03bc .fds-switch-track-9a6b03bc { - outline: var(--fds-switch-focus-border-width) solid var(--fds-semantic-border-focus-outline); - box-shadow: inset 0 0 0 var(--fds-switch-focus-border-width) var(--fds-semantic-border-focus-boxshadow); - } - - .fds-switch-input-9a6b03bc:not([readonly]):checked + .fds-switch-label-9a6b03bc .fds-switch-track-9a6b03bc { - background-color: var(--fds-semantic-surface-success-default); - } - - .fds-switch-thumb-9a6b03bc { - scale: 0.8; - position: absolute; - height: var(--fds-switch-height); - width: var(--fds-switch-height); - border-radius: var(--fds-border_radius-full); - background-color: var(--fds-semantic-background-default); - transition: transform var(--fds-transition) ease; - } - - .fds-switch-input-9a6b03bc:checked + .fds-switch-label-9a6b03bc .fds-switch-track-9a6b03bc .fds-switch-thumb-9a6b03bc { - transform: translateX(calc((var(--fds-switch-width) - var(--fds-switch-height)) * 1.2)); - background-image: url("data:image/svg+xml,%3Csvg viewBox='-3 -3 17 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M10.1339 2.86612C10.622 3.35427 10.622 4.14573 10.1339 4.63388L5.88388 8.88388C5.39573 9.37204 4.60427 9.37204 4.11612 8.88388L1.86612 6.63388C1.37796 6.14573 1.37796 5.35427 1.86612 4.86612C2.35427 4.37796 3.14573 4.37796 3.63388 4.86612L5 6.23223L8.36612 2.86612C8.85427 2.37796 9.64573 2.37796 10.1339 2.86612Z' fill='%23118849' /%3E%3C/svg%3E"); - } - - .fds-switch-readonly-9a6b03bc .fds-switch-input-9a6b03bc[readonly] + .fds-switch-label-9a6b03bc .fds-switch-track-9a6b03bc { - box-shadow: inset 0 0 0 2px var(--fds-semantic-border-neutral-subtle); - background-color: var(--fds-semantic-background-subtle); - } - - .fds-switch-readonly-9a6b03bc .fds-switch-input-9a6b03bc[readonly] + .fds-switch-label-9a6b03bc .fds-switch-track-9a6b03bc > .fds-switch-thumb-9a6b03bc { - background-color: var(--fds-semantic-border-neutral-default); - } - - .fds-switch-readonly-9a6b03bc .fds-switch-input-9a6b03bc[readonly]:checked + .fds-switch-label-9a6b03bc .fds-switch-track-9a6b03bc .fds-switch-thumb-9a6b03bc { - background-image: url("data:image/svg+xml,%3Csvg viewBox='-3 -3 17 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M10.1339 2.86612C10.622 3.35427 10.622 4.14573 10.1339 4.63388L5.88388 8.88388C5.39573 9.37204 4.60427 9.37204 4.11612 8.88388L1.86612 6.63388C1.37796 6.14573 1.37796 5.35427 1.86612 4.86612C2.35427 4.37796 3.14573 4.37796 3.63388 4.86612L5 6.23223L8.36612 2.86612C8.85427 2.37796 9.64573 2.37796 10.1339 2.86612Z' fill='%23f4f5f6' /%3E%3C/svg%3E"); - } - - @media (hover: hover) and (pointer: fine) { - .fds-switch-input-9a6b03bc:not([readonly], :disabled):hover + .fds-switch-label-9a6b03bc .fds-switch-track-9a6b03bc > .fds-switch-thumb-9a6b03bc { - transform: translateX(calc((var(--fds-switch-width) - var(--fds-switch-height)) * 0.2)); - } - - .fds-switch-input-9a6b03bc:not([readonly], :disabled):hover + .fds-switch-label-9a6b03bc { - color: var(--fds-semantic-border-input-hover); - } - - .fds-switch-input-9a6b03bc:not(:disabled, [readonly]):checked:hover + .fds-switch-label-9a6b03bc .fds-switch-track-9a6b03bc > .fds-switch-thumb-9a6b03bc { - transform: translateX(calc((var(--fds-switch-width) - var(--fds-switch-height)))); - background-image: url("data:image/svg+xml,%3Csvg viewBox='-3 -3 17 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M10.1339 2.86612C10.622 3.35427 10.622 4.14573 10.1339 4.63388L5.88388 8.88388C5.39573 9.37204 4.60427 9.37204 4.11612 8.88388L1.86612 6.63388C1.37796 6.14573 1.37796 5.35427 1.86612 4.86612C2.35427 4.37796 3.14573 4.37796 3.63388 4.86612L5 6.23223L8.36612 2.86612C8.85427 2.37796 9.64573 2.37796 10.1339 2.86612Z' fill='%230c6536' /%3E%3C/svg%3E"); - } - - .fds-switch-input-9a6b03bc:not(:checked, :disabled, [readonly]):hover + .fds-switch-label-9a6b03bc .fds-switch-track-9a6b03bc { - background-color: var(--fds-semantic-surface-neutral-dark-hover); - } - - .fds-switch-input-9a6b03bc:not(:disabled, [readonly]):checked:hover + .fds-switch-label-9a6b03bc .fds-switch-track-9a6b03bc { - background-color: var(--fds-semantic-surface-success-hover); - } - } -} - @layer fds.textfield { .fds-textfield-formField-d98267a0 { display: grid; diff --git a/packages/css/Switch.module.css b/packages/css/switch.css similarity index 64% rename from packages/css/Switch.module.css rename to packages/css/switch.css index 92d2b82863..051f0ef359 100644 --- a/packages/css/Switch.module.css +++ b/packages/css/switch.css @@ -1,6 +1,6 @@ @layer fds.switch { - .switch { - --fds-transition: 200ms; + .fds-switch { + --fds-switch--transition: 200ms; --fds-switch-height: 1.75rem; --fds-switch-focus-border-width: 3px; @@ -9,11 +9,11 @@ @media (prefers-reduced-motion) { .switch { - --fds-transition: 0; + --fds-switch--transition: 0; } } - .label { + .fds-switch__label { min-height: var(--fds-sizing-10); min-width: min-content; display: grid; @@ -23,7 +23,7 @@ cursor: pointer; } - .track { + .fds-switch__track { position: relative; display: inline-block; pointer-events: none; @@ -33,36 +33,36 @@ overflow: visible; border-radius: var(--fds-border_radius-full); background-color: var(--fds-semantic-surface-neutral-dark); - transition: background-color var(--fds-transition) ease; + transition: background-color var(--fds-switch--transition) ease; margin-right: var(--fds-spacing-1); } - .description { + .fds-switch__description { padding-left: calc(var(--fds-switch-width) + var(--fds-spacing-2)); margin-top: calc(var(--fds-spacing-2) * -1); color: var(--fds-semantic-text-neutral-subtle); } - .padlock { + .fds-switch__readonly__icon { height: 1.2em; width: 1.2em; } - .right { + .fds-switch__label--right { grid-template-columns: 1fr auto; grid-auto-flow: dense; } - .right .track { + .fds-switch__label--right .fds-switch__track { order: 1; margin-right: 0; } - .right + .description { + .fds-switch__label--right + .fds-switch__description { padding-left: 0; } - .input { + .fds-switch__input { position: absolute; width: 2.75rem; height: 2.75rem; @@ -72,144 +72,144 @@ margin: 0; } - .readonly > .label { + .fds-switch--readonly > .fds-switch__label { grid-template-columns: auto min-content 1fr; } - .readonly > .label:where(.right) { + .fds-switch--readonly > .fds-switch__label:where(.fds-switch__label--right) { grid-template-columns: min-content 1fr auto; } - .readonly > .input, - .readonly > .label { + .fds-switch--readonly > .fds-switch__input, + .fds-switch--readonly > .fds-switch__label { cursor: default; } - .disabled > .input, - .disabled > .label, - .disabled > .track { + .fds-switch--disabled > .fds-switch__input, + .fds-switch--disabled > .fds-switch__label, + .fds-switch--disabled > .fds-switch__track { cursor: not-allowed; } - .disabled > .label, - .disabled > .track, - .disabled > .description { + .fds-switch--disabled > .fds-switch__label, + .fds-switch--disabled > .fds-switch__track, + .fds-switch--disabled > .fds-switch__description { opacity: var(--fds-opacity-disabled); } - .readonly > .description { + .fds-switch--readonly > .fds-switch__description { margin-left: var(--fds-spacing-1); } - .small, - .small .label { + .fds-switch--small, + .fds-switch--small .fds-switch__label { min-height: var(--fds-sizing-6); } - .medium, - .medium .label { + .fds-switch--medium, + .fds-switch--medium .fds-switch__label { min-height: var(--fds-sizing-7); } - .large, - .large .label { + .fds-switch--large, + .fds-switch--large .fds-switch__label { min-height: var(--fds-sizing-8); } - .small { + .fds-switch--small { --fds-switch-height: var(--fds-sizing-6); --fds-switch-width: var(--fds-sizing-11); } - .small .input { + .fds-switch--small .fds-switch__input { left: -0.25rem; top: -0.25rem; } - .medium { + .fds-switch--medium { --fds-switch-height: var(--fds-sizing-7); --fds-switch-width: var(--fds-sizing-13); } - .medium .input { + .fds-switch--medium .fds-switch__input { left: 0; top: 0; } - .large { + .fds-switch--large { --fds-switch-height: var(--fds-sizing-8); --fds-switch-width: var(--fds-sizing-15); } - .large .input { + .fds-switch--large .fds-switch__input { left: 0; top: 0.25rem; } - .label:has(.track:only-child) { + .fds-switch__label:has(.fds-switch__track:only-child) { grid-template-columns: auto; } - .label:has(.track:only-child) .track { + .fds-switch__label:has(.fds-switch__track:only-child) .fds-switch__track { margin-right: 0; } - .input:focus-visible + .label .track { + .fds-switch__input:focus-visible + .fds-switch__label .fds-switch__track { outline: var(--fds-switch-focus-border-width) solid var(--fds-semantic-border-focus-outline); box-shadow: inset 0 0 0 var(--fds-switch-focus-border-width) var(--fds-semantic-border-focus-boxshadow); } - .input:not([readonly]):checked + .label .track { + .fds-switch__input:not([readonly]):checked + .fds-switch__label .fds-switch__track { background-color: var(--fds-semantic-surface-success-default); } - .thumb { + .fds-switch__thumb { scale: 0.8; position: absolute; height: var(--fds-switch-height); width: var(--fds-switch-height); border-radius: var(--fds-border_radius-full); background-color: var(--fds-semantic-background-default); - transition: transform var(--fds-transition) ease; + transition: transform var(--fds-switch--transition) ease; } - .input:checked + .label .track .thumb { + .fds-switch__input:checked + .fds-switch__label .fds-switch__track .fds-switch__thumb { transform: translateX(calc((var(--fds-switch-width) - var(--fds-switch-height)) * 1.2)); background-image: url("data:image/svg+xml,%3Csvg viewBox='-3 -3 17 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M10.1339 2.86612C10.622 3.35427 10.622 4.14573 10.1339 4.63388L5.88388 8.88388C5.39573 9.37204 4.60427 9.37204 4.11612 8.88388L1.86612 6.63388C1.37796 6.14573 1.37796 5.35427 1.86612 4.86612C2.35427 4.37796 3.14573 4.37796 3.63388 4.86612L5 6.23223L8.36612 2.86612C8.85427 2.37796 9.64573 2.37796 10.1339 2.86612Z' fill='%23118849' /%3E%3C/svg%3E"); } - .readonly .input[readonly] + .label .track { + .fds-switch--readonly .fds-switch__input[readonly] + .fds-switch__label .fds-switch__track { box-shadow: inset 0 0 0 2px var(--fds-semantic-border-neutral-subtle); background-color: var(--fds-semantic-background-subtle); } - .readonly .input[readonly] + .label .track > .thumb { + .fds-switch--readonly .fds-switch__input[readonly] + .fds-switch__label .fds-switch__track > .fds-switch__thumb { background-color: var(--fds-semantic-border-neutral-default); } - .readonly .input[readonly]:checked + .label .track .thumb { + .fds-switch--readonly .fds-switch__input[readonly]:checked + .fds-switch__label .fds-switch__track .fds-switch__thumb { background-image: url("data:image/svg+xml,%3Csvg viewBox='-3 -3 17 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M10.1339 2.86612C10.622 3.35427 10.622 4.14573 10.1339 4.63388L5.88388 8.88388C5.39573 9.37204 4.60427 9.37204 4.11612 8.88388L1.86612 6.63388C1.37796 6.14573 1.37796 5.35427 1.86612 4.86612C2.35427 4.37796 3.14573 4.37796 3.63388 4.86612L5 6.23223L8.36612 2.86612C8.85427 2.37796 9.64573 2.37796 10.1339 2.86612Z' fill='%23f4f5f6' /%3E%3C/svg%3E"); } @media (hover: hover) and (pointer: fine) { - .input:not([readonly], :disabled):hover + .label .track > .thumb { + .fds-switch__input:not([readonly], :disabled):hover + .fds-switch__label .fds-switch__track > .fds-switch__thumb { transform: translateX(calc((var(--fds-switch-width) - var(--fds-switch-height)) * 0.2)); } - .input:not([readonly], :disabled):hover + .label { + .fds-switch__input:not([readonly], :disabled):hover + .fds-switch__label { color: var(--fds-semantic-border-input-hover); } - .input:not(:disabled, [readonly]):checked:hover + .label .track > .thumb { + .fds-switch__input:not(:disabled, [readonly]):checked:hover + .fds-switch__label .fds-switch__track > .fds-switch__thumb { transform: translateX(calc((var(--fds-switch-width) - var(--fds-switch-height)))); background-image: url("data:image/svg+xml,%3Csvg viewBox='-3 -3 17 17' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M10.1339 2.86612C10.622 3.35427 10.622 4.14573 10.1339 4.63388L5.88388 8.88388C5.39573 9.37204 4.60427 9.37204 4.11612 8.88388L1.86612 6.63388C1.37796 6.14573 1.37796 5.35427 1.86612 4.86612C2.35427 4.37796 3.14573 4.37796 3.63388 4.86612L5 6.23223L8.36612 2.86612C8.85427 2.37796 9.64573 2.37796 10.1339 2.86612Z' fill='%230c6536' /%3E%3C/svg%3E"); } - .input:not(:checked, :disabled, [readonly]):hover + .label .track { + .fds-switch__input:not(:checked, :disabled, [readonly]):hover + .fds-switch__label .fds-switch__track { background-color: var(--fds-semantic-surface-neutral-dark-hover); } - .input:not(:disabled, [readonly]):checked:hover + .label .track { + .fds-switch__input:not(:disabled, [readonly]):checked:hover + .fds-switch__label .fds-switch__track { background-color: var(--fds-semantic-surface-success-hover); } } diff --git a/packages/react/src/components/form/Switch/Switch.tsx b/packages/react/src/components/form/Switch/Switch.tsx index 56b7802fb0..2d86916866 100644 --- a/packages/react/src/components/form/Switch/Switch.tsx +++ b/packages/react/src/components/form/Switch/Switch.tsx @@ -1,13 +1,12 @@ import type { InputHTMLAttributes, ReactNode } from 'react'; import { forwardRef } from 'react'; -import cl from 'clsx'; +import cl from 'clsx/lite'; import { PadlockLockedFillIcon } from '@navikt/aksel-icons'; import { omit } from '../../../utilities'; import { Label, Paragraph } from '../../Typography'; import type { FormFieldProps } from '../useFormField'; -import classes from './Switch.module.css'; import { useSwitch } from './useSwitch'; export type SwitchProps = { @@ -45,33 +44,36 @@ export const Switch = forwardRef( >