import React from 'react' import { useClickOutside, text, spacingPx, states, useEscapeListener, } from '@planview/pv-utilities' import { Radio } 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 StyledRadio = styled(Radio)` * { 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 GridEditorRadio = ({ columnId, rowId, tabIndex, value, mode, onCancel, onConfirm, }: CellEditorParams) => { const ref = React.useRef(null) const column = useGridColumn(columnId) const columnLabel = column?.data?.label const { editable } = useGridEditor() const readOnly = !editable 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', }) return } if ( e.key === 'ArrowUp' || e.key === 'ArrowDown' || e.key === 'ArrowLeft' || e.key === 'ArrowRight' ) { e.preventDefault() e.stopPropagation() } }, [onConfirm, mode, value] ) const handleChange = React.useCallback(() => { onConfirm(true, { continueEditing: 'current', }) }, [onConfirm]) const disabledProps = React.useMemo( () => readOnly ? { role: 'radio' as const, tabIndex, 'aria-disabled': true, 'aria-checked': !!value, 'aria-label': columnLabel, } : {}, [columnLabel, readOnly, tabIndex, value] ) return ( ) }