import React from 'react' import { useClickOutside, text, spacingPx, states, useEscapeListener, } from '@planview/pv-utilities' import { Switch } from '@planview/pv-uikit' import styled from 'styled-components' import type { CellEditorParams, GridRowData } from '../types' import { useGridColumn } from '../context/grid-context' import { useGridEditor } from '../context/grid-editor-context' const StyledSwitch = styled(Switch)` * { outline: none; } ` const CCell = styled.div<{ $focusVisible: boolean }>` ${text.regular}; height: 100%; width: 100%; padding: 0 ${spacingPx.small}; display: flex; flex-direction: row; align-items: center; min-width: 0; overflow: hidden; outline: none; ${(props) => states.focus({ focusVisible: props.$focusVisible })} ` export const GridEditorSwitch = ({ columnId, tabIndex, value, mode, onCancel, onConfirm, }: CellEditorParams) => { const ref = React.useRef(null) const column = useGridColumn(columnId) const columnLabel = column?.data?.label const { editable } = useGridEditor() const handleOnClickOutside = React.useCallback(() => { if (mode === 'editing') { onCancel() } }, [onCancel, mode]) useClickOutside(ref, handleOnClickOutside) React.useEffect(() => { if (mode === 'editing') { ref.current?.focus() } }, [mode]) const handleClick = React.useCallback( (e) => e.stopPropagation(), [] ) const handleEscape = React.useCallback(() => { onCancel() }, [onCancel]) useEscapeListener({ onEscape: handleEscape, enabled: mode === 'editing', stack: true, }) const onKeyDown = React.useCallback( (e) => { if (mode === 'navigation') { return } if (e.key === 'Tab') { e.stopPropagation() e.preventDefault() onConfirm(value, { continueEditing: e.shiftKey ? 'previous' : 'next', }) } }, [onConfirm, mode, value] ) const handleChange = React.useCallback( (val: boolean) => { onConfirm(val, { continueEditing: 'current', }) }, [onConfirm] ) /** * These attributes are added in case the Switch is disabled in which * case the wrapper takes over the focus and adds descriptive attributes for * assistive technology. */ const disabledProps = React.useMemo( () => !editable ? { role: 'checkbox', tabIndex, 'aria-disabled': true, 'aria-checked': !!value, 'aria-label': columnLabel, } : {}, [columnLabel, editable, tabIndex, value] ) return ( ) }