import { ChangeEvent, SessionDataTestId, SyntheticEvent } from 'react'; import styled, { CSSProperties } from 'styled-components'; import { Flex } from './Flex'; const StyledButton = styled.button<{ disabled: boolean }>` cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')}; min-height: 30px; background-color: var(--transparent-color); `; const StyledInput = styled.input<{ filledSize: number; outlineOffset: number; selectedColor?: string; }>` opacity: 0; position: absolute; width: ${props => props.filledSize + props.outlineOffset}px; height: ${props => props.filledSize + props.outlineOffset}px; &:checked + label:before { background: ${props => props.disabled ? 'var(--disabled-color)' : props.selectedColor ? props.selectedColor : 'var(--primary-color)'}; } `; // NOTE (Will): We don't use a transition because it's too slow and creates flickering when changing buttons. const StyledLabel = styled.label<{ disabled: boolean; filledSize: number; outlineOffset: number; beforeMargins?: string; }>` cursor: pointer; color: ${props => (props.disabled ? 'var(--disabled-color)' : 'var(--text-primary-color)')}; &:before { content: ''; display: inline-block; border-radius: 100%; padding: ${props => props.filledSize}px; border: none; outline: 1px solid currentColor; /* CSS variables don't work here */ outline-offset: ${props => props.outlineOffset}px; ${props => props.beforeMargins && `margin: ${props.beforeMargins};`}; } `; type SessionRadioProps = { label: string; value: string; active: boolean; inputName?: string; beforeMargins?: string; onClick?: (value: string) => void; disabled?: boolean; radioPosition?: 'left' | 'right'; style?: CSSProperties; labelDataTestId?: SessionDataTestId; inputDataTestId?: SessionDataTestId; }; export const SessionRadio = (props: SessionRadioProps) => { const { label, inputName, value, active, onClick, beforeMargins, disabled = false, radioPosition = 'left', style, labelDataTestId, inputDataTestId, } = props; const clickHandler = (e: SyntheticEvent) => { if (!disabled && onClick) { // let something else catch the event if our click handler is not set e.stopPropagation(); onClick(value); } }; const filledSize = 15 / 2; const outlineOffset = 2; return ( { if (e.code === 'Space') { clickHandler(e); } }} onClick={clickHandler} disabled={disabled} > {label} ); }; const StyledInputOutlineSelected = styled(StyledInput)` color: ${props => (props.disabled ? 'var(--disabled-color)' : 'var(--text-primary-color)')}; label:before, label:before { outline: none; } &:checked + label:before { outline: 1px solid currentColor; } `; const StyledLabelOutlineSelected = styled(StyledLabel)<{ selectedColor: string }>` &:before { background: ${props => props.disabled ? 'var(--disabled-color)' : props.selectedColor ? props.selectedColor : 'var(--primary-color)'}; outline: 1px solid transparent; /* CSS variables don't work here */ } `; /** * Keeping this component here so we can reuse the `StyledInput` and `StyledLabel` defined locally rather than exporting them */ export const SessionRadioPrimaryColors = (props: { value: string; active: boolean; inputName?: string; onClick: (value: string) => void; ariaLabel?: string; color: string; // by default, we use the theme accent color but for the settings screen we need to be able to force it disabled?: boolean; }) => { const { inputName, value, active, onClick, color, ariaLabel, disabled = false } = props; function clickHandler(e: ChangeEvent) { e.stopPropagation(); onClick(value); } const filledSize = 31 / 2; const outlineOffset = 5; return ( {''} ); };