|
- import { css } from '@tesseract-design/goofy-goober'
-
- export enum CheckControlAppearance {
- TICK_BOX = 'tick-box',
- BUTTON = 'button',
- SWITCH = 'switch',
- }
-
- export enum CheckControlType {
- /**
- * One or more of this component within its group can be selected.
- */
- CHECKBOX = 'checkbox',
- /**
- * At most one of this component within its group can be selected.
- */
- RADIO = 'radio',
- }
-
- export type CheckControlBaseArgs = {
- /**
- * Will the component conserve visual space?
- */
- compact: boolean,
- /**
- * Appearance of the component.
- */
- appearance: CheckControlAppearance,
- /**
- * Will the component occupy the whole width of its container?
- */
- block: boolean,
- /**
- * Type of the component defining its behavior.
- */
- type: CheckControlType,
- /**
- * Label to display signifying the component's unselected state.
- */
- uncheckedLabel: boolean,
- }
-
- export const CheckStateContainer = ({
- appearance,
- type,
- }: CheckControlBaseArgs): string => css.cx(
- css`
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- white-space: nowrap;
- border-width: 0;
- &:disabled + * {
- cursor: not-allowed;
- }
- &:first-child + * > :first-child + * + * {
- align-items: flex-start;
- text-align: left;
- }
- &:checked + * {
- --color-accent: var(--color-active, Highlight);
- outline: 0;
- }
- &:indeterminate[type="checkbox"] + * {
- --color-accent: var(--color-active, Highlight);
- outline: 0;
- }
- &:indeterminate[type="checkbox"] + * > :first-child + * > * > :first-child {
- display: none;
- }
- &:checked + * > :first-child + * > * > :first-child + * {
- display: none;
- }
- &:focus + * {
- --color-accent: var(--color-hover, red);
- outline: 0;
- }
- &:focus[type="checkbox"] + * {
- --color-accent: var(--color-hover, red);
- outline: 0;
- }
- &:focus + * > :first-child::before {
- box-shadow: 0 0 0 0.375rem var(--color-accent, blue);
- }
- `,
- css.nest('&:checked + * > :first-child + * > *') (
- css.if (
- appearance === CheckControlAppearance.TICK_BOX
- || appearance === CheckControlAppearance.BUTTON
- ) (
- css.if (type === 'checkbox') (
- css`
- width: 1.5em;
- height: 1.5em;
- `
- ),
- css.if (type === 'radio') (
- css`
- width: 1em;
- height: 1em;
- `
- ),
- ),
- css.if (appearance === CheckControlAppearance.SWITCH) (
- css`
- width: 1em;
- height: 1em;
- margin-right: 0;
- margin-left: 1em;
- `
- ),
- ),
- css.nest('&:first-child + *') (
- css`
- cursor: pointer;
- `,
- css.if (appearance === CheckControlAppearance.BUTTON) (
- css`
- display: flex;
- `,
- ),
- css.if (appearance === CheckControlAppearance.SWITCH) (
- css`
- width: 1em;
- height: 1em;
- `,
- ),
- ),
- css.nest('&:indeterminate[type="checkbox"] + * > :first-child + * > *') (
- css.if (
- appearance === CheckControlAppearance.BUTTON
- || appearance === CheckControlAppearance.TICK_BOX
- ) (
- css`
- width: 1.5em;
- height: 1.5em;
- `
- ),
- css.if (appearance === CheckControlAppearance.SWITCH) (
- css`
- width: 1em;
- height: 1em;
- margin-right: 0.5em;
- margin-left: 0.5em;
- `
- )
- ),
- css.nest('&:indeterminate[type="checkbox"] + * > :first-child + * > * > :first-child + *') (
- css.if (
- appearance === CheckControlAppearance.BUTTON
- || appearance === CheckControlAppearance.TICK_BOX
- ) (
- css`
- display: block;
- `
- ),
- ),
- css.nest('&:checked + * > :first-child + * > * > :first-child') (
- css.if (
- appearance === CheckControlAppearance.BUTTON
- || appearance === CheckControlAppearance.TICK_BOX
- ) (
- css`
- display: block;
- `
- ),
- ),
- );
-
- export const ClickArea = (): string => css.cx(
- css`
- display: contents;
- `
- );
-
- export const CheckIndicatorArea = ({
- compact,
- appearance,
- type,
- uncheckedLabel,
- }: CheckControlBaseArgs): string => css.cx(
- css`
- display: inline-grid;
- vertical-align: middle;
- place-content: center;
- position: relative;
- background-color: var(--color-bg, white);
- box-shadow: 0 0 0 0.125rem var(--color-bg, white);
- color: var(--color-accent, blue);
- overflow: hidden;
- &::before {
- content: '';
- width: 100%;
- height: 100%;
- position: absolute;
- top: 0;
- left: 0;
- border-radius: inherit;
- border-width: 0.125rem;
- border-style: solid;
- box-sizing: border-box;
- }
- `,
- css.if (appearance === CheckControlAppearance.TICK_BOX) (
- css`
- width: 1.5em;
- height: 1.5em;
- `,
- css.if (type === CheckControlType.CHECKBOX) (
- css`
- border-radius: 0.25rem;
- `
- ),
- css.if (type === CheckControlType.RADIO) (
- css`
- border-radius: 50%;
- `
- ),
- ),
- css.if (appearance === CheckControlAppearance.BUTTON) (
- css`
- width: 1.5em;
- height: 1.5em;
- `,
- css.if (!compact) (
- css`
- margin-left: -0.25rem;
- `
- ),
- css.if (type === CheckControlType.CHECKBOX) (
- css`
- border-radius: 0.25rem;
- `
- ),
- css.if (type === CheckControlType.RADIO) (
- css`
- border-radius: 50%;
- `
- ),
- ),
- css.if (appearance === CheckControlAppearance.SWITCH) (
- css`
- width: 2.5em;
- height: 1.5em;
- border-radius: 0.75em;
- `,
- css.if(uncheckedLabel) (
- css.dynamic({
- 'margin-left': compact ? '0.375rem' : '0.75rem',
- })
- ),
- ),
- css.nest('& + *') (
- css.dynamic({
- 'margin-left': compact ? '0.375rem' : '0.75rem',
- })
- )
- );
-
- export const CheckIndicatorWrapper = ({
- appearance,
- }: CheckControlBaseArgs): string => css.cx(
- css`
- flex-shrink: 0;
- display: grid;
- position: relative;
- background-color: var(--color-accent, blue);
- overflow: hidden;
- border-radius: inherit;
- `,
- css.if(
- appearance === CheckControlAppearance.TICK_BOX
- || appearance === CheckControlAppearance.BUTTON
- ) (
- css`
- width: 0;
- height: 0;
- `
- ),
- css.if(appearance === CheckControlAppearance.SWITCH) (
- css`
- width: 1em;
- height: 1em;
- margin-right: 1em;
- transition-property: margin-left, margin-right;
- transition-duration: 150ms;
- transition-timing-function: ease-out;
- `,
- ),
- );
-
- export const CheckIndicator = ({
- appearance,
- }: CheckControlBaseArgs) => css.cx(
- css`
- fill: none;
- stroke: var(--color-bg, white);
- stroke-width: 2;
- stroke-linecap: round;
- stroke-linejoin: round;
- width: 1.5em;
- height: 1.5em;
- `,
- css.if(appearance === CheckControlAppearance.SWITCH) (
- css`
- display: none;
- `
- )
- );
-
- export const ClickAreaWrapper = ({
- block,
- appearance,
- uncheckedLabel,
- }: CheckControlBaseArgs) => css.cx(
- css`
- vertical-align: middle;
- `,
- css.dynamic({
- display: block ? 'block' : 'inline-block',
- }),
- css.if (appearance === CheckControlAppearance.TICK_BOX) (
- css`
- padding-left: 2.25rem;
- text-indent: -2.25rem;
- `
- ),
- css.if (appearance === CheckControlAppearance.SWITCH) (
- css.if (!uncheckedLabel) (
- css`
- padding-left: 3.25rem;
- text-indent: -3.25rem;
- `
- ),
- ),
- );
-
- export const Subtext = () => css.cx(
- css`
- font-size: 0.875em;
- `
- );
|