UNPKG

@sanity/ui

Version:

The Sanity UI components.

174 lines (150 loc) 4.74 kB
import {getTheme_v2} from '@sanity/ui/theme' import {css} from 'styled-components' import {rem, ThemeProps} from '../../styles' import {focusRingStyle} from '../../styles/internal' /* Root */ export function switchBaseStyles(): ReturnType<typeof css> { return css` position: relative; &:not([hidden]) { display: inline-block; } ` } /* Input */ export function switchInputStyles(): ReturnType<typeof css> { // Visually hide the input element while keeping it interactive return css` position: absolute; top: 0; right: 0; bottom: 0; left: 0; opacity: 0; height: 100%; width: 100%; outline: none; padding: 0; margin: 0; /* Place the input element above the representation element */ z-index: 1; ` } /* Representation */ export function switchRepresentationStyles(props: ThemeProps): ReturnType<typeof css> { const {color, input} = getTheme_v2(props.theme) return css` --switch-bg-color: ${color.input.default.enabled.border}; --switch-fg-color: ${color.input.default.enabled.bg}; --switch-box-shadow: none; &:not([hidden]) { display: block; } position: relative; width: ${rem(input.switch.width)}; height: ${rem(input.switch.height)}; border-radius: ${rem(input.switch.height / 2)}; /* Make sure it’s not possible to interact with the wrapper element */ pointer-events: none; &:after { content: ''; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: 1; box-shadow: var(--switch-box-shadow); border-radius: inherit; } /* Focus styles */ input:focus + && { --switch-box-shadow: ${focusRingStyle({focusRing: input.switch.focusRing})}; } input:focus:not(:focus-visible) + && { --switch-box-shadow: none; } input:checked + && { --switch-bg-color: ${color.input.default.enabled.fg}; --switch-fg-color: ${color.input.default.enabled.bg}; } @media (hover: hover) { input:not(:disabled):hover + && { --switch-bg-color: ${color.input.default.hovered.border}; --switch-fg-color: ${color.input.default.hovered.bg}; } input:not(:disabled):checked:hover + && { --switch-bg-color: ${color.input.default.enabled.fg}; --switch-fg-color: ${color.input.default.enabled.bg}; } } input:not([data-read-only]):disabled + && { --switch-bg-color: ${color.input.default.disabled.border}; --switch-fg-color: ${color.input.default.disabled.bg}; } input[data-read-only]:disabled + && { --switch-bg-color: ${color.input.default.readOnly.border}; --switch-fg-color: ${color.input.default.readOnly.bg}; } input:checked[data-read-only]:disabled + && { --switch-bg-color: ${color.input.default.readOnly.fg}; --switch-fg-color: ${color.input.default.readOnly.bg}; } ` } /* Track */ export function switchTrackStyles(props: ThemeProps): ReturnType<typeof css> { const {input} = getTheme_v2(props.theme) return css` &:not([hidden]) { display: block; } background-color: var(--switch-bg-color); position: absolute; left: 0; top: 0; width: ${rem(input.switch.width)}; height: ${rem(input.switch.height)}; border-radius: ${rem(input.switch.height / 2)}; ` } /* Thumb */ export function switchThumbStyles( props: {$checked?: boolean; $indeterminate?: boolean} & ThemeProps, ): ReturnType<typeof css> { const {$indeterminate} = props const {input} = getTheme_v2(props.theme) const trackWidth = input.switch.width const trackHeight = input.switch.height const trackPadding = input.switch.padding const size = trackHeight - input.switch.padding * 2 const checkedOffset = trackWidth - trackPadding * 2 - size const indeterminateOffset = trackWidth / 2 - size / 2 - trackPadding const checked = $indeterminate !== true && props.$checked === true return css` &:not([hidden]) { display: block; } position: absolute; left: ${rem(trackPadding)}; top: ${rem(trackPadding)}; height: ${rem(size)}; width: ${rem(size)}; border-radius: ${rem(size / 2)}; transition-property: transform; transition-duration: ${input.switch.transitionDurationMs}ms; transition-timing-function: ${input.switch.transitionTimingFunction}; background: var(--switch-fg-color); transform: translate3d(0, 0, 0); box-shadow: 0px 1px 0px 0px rgba(0, 0, 0, 0.05); ${checked && css` transform: translate3d(${checkedOffset}px, 0, 0); `} ${$indeterminate && css` transform: translate3d(${indeterminateOffset}px, 0, 0); `} ` }