UNPKG

@adaptabletools/adaptable

Version:

Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

162 lines (161 loc) 8.07 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import * as React from 'react'; import { cn } from '../../../lib/utils'; import { Box, Flex } from '../../../components/Flex'; import SimpleButton from '../../../components/SimpleButton'; import { capturePlusMinusTriggerFromEvent, plusMinusKeyLabel, plusMinusTriggerDisplayParts, } from '../../../Utilities/Helpers/PlusMinusHelper'; import { targetOwn } from '../../../components/twUtils'; const Kbd = ({ children }) => (_jsx(Box, { as: "kbd", className: "twa:px-2 twa:py-[2px] twa:rounded-standard twa:bg-primary twa:text-2 twa:leading-none twa:font-medium twa:whitespace-nowrap", children: children })); const renderTokens = (tokens) => tokens.map((token, index) => (_jsxs(React.Fragment, { children: [index > 0 ? _jsx(Box, { className: "twa:opacity-50 twa:text-2", children: "+" }) : null, _jsx(Kbd, { children: token })] }, `${token}-${index}`))); export const KeyComboCaptureInput = (props) => { const { value, isUsingDefault, placeholder, disabled, onCapture, onReset, validateCapture } = props; const ref = React.useRef(null); const [focused, setFocused] = React.useState(false); const [editing, setEditing] = React.useState(false); const [pendingModifiers, setPendingModifiers] = React.useState([]); const [staged, setStaged] = React.useState(undefined); const [error, setError] = React.useState(undefined); const stopEditing = React.useCallback(() => { setEditing(false); setPendingModifiers([]); setStaged(undefined); }, []); const handleKeyDown = (event) => { if (disabled) { return; } if (!editing) { if (event.key === 'Enter') { event.preventDefault(); event.stopPropagation(); setError(undefined); setPendingModifiers([]); setStaged(undefined); setEditing(true); } return; } if (event.key === 'Escape') { event.preventDefault(); event.stopPropagation(); setError(undefined); stopEditing(); return; } if (event.key === 'Tab') { if (staged && !validateCapture?.(staged)) { onCapture(staged); } stopEditing(); setError(undefined); return; } event.preventDefault(); event.stopPropagation(); const noModifiers = !event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey; if (event.key === 'Enter' && noModifiers) { if (!staged) { return; } const validationError = validateCapture?.(staged); if (validationError) { setError(validationError); return; } const confirmed = staged; setError(undefined); stopEditing(); onCapture(confirmed); return; } const result = capturePlusMinusTriggerFromEvent({ key: event.key, ctrlKey: event.ctrlKey, altKey: event.altKey, metaKey: event.metaKey, shiftKey: event.shiftKey, }); if (result.kind === 'pending') { setPendingModifiers(result.modifiers); setError(undefined); return; } if (result.kind === 'invalid') { setPendingModifiers([]); setStaged(undefined); setError(result.reason); return; } const validationError = validateCapture?.(result.trigger); if (validationError) { setPendingModifiers([]); setStaged(undefined); setError(validationError); return; } setPendingModifiers([]); setError(undefined); setStaged(result.trigger); }; const handleReset = (event) => { event.preventDefault(); event.stopPropagation(); setError(undefined); stopEditing(); onReset?.(); }; const handleEnterEdit = (event) => { event.preventDefault(); event.stopPropagation(); setError(undefined); setPendingModifiers([]); setStaged(undefined); setEditing(true); ref.current?.focus(); }; const valueParts = plusMinusTriggerDisplayParts(value); let content; if (editing) { if (staged) { content = (_jsx(Flex, { className: "twa:items-center twa:gap-1", children: renderTokens(plusMinusTriggerDisplayParts(staged)) })); } else if (pendingModifiers.length) { content = (_jsxs(Flex, { className: "twa:items-center twa:gap-1", children: [renderTokens(pendingModifiers.map(plusMinusKeyLabel)), _jsx(Box, { className: "twa:opacity-50 twa:text-2", children: "+ \u2026" })] })); } else { content = _jsx(Box, { className: "twa:opacity-60 twa:text-2", children: "Press a key combination\u2026" }); } } else if (valueParts.length) { content = (_jsxs(Flex, { className: "twa:items-center twa:gap-1", children: [renderTokens(valueParts), isUsingDefault ? (_jsx(Box, { className: "twa:opacity-60 twa:text-2 twa:ml-1", children: "(default)" })) : null] })); } else { content = _jsx(Box, { className: "twa:opacity-60 twa:text-2", children: placeholder ?? 'Hit Enter to edit' }); } return (_jsxs(Flex, { flexDirection: "column", className: "twa:gap-1 twa:max-w-[300px] twa:w-full", children: [_jsxs(Flex, { ref: ref, role: "button", tabIndex: disabled ? -1 : 0, "data-name": props['data-name'], "aria-label": "Record keyboard shortcut", onFocus: () => { if (!disabled) { setFocused(true); } }, onBlur: (event) => { if (ref.current && event.relatedTarget && ref.current.contains(event.relatedTarget)) { return; } if (editing && staged && !validateCapture?.(staged)) { onCapture(staged); } setFocused(false); stopEditing(); setError(undefined); }, onClick: () => ref.current?.focus(), onKeyDown: handleKeyDown, className: cn('twa:min-h-input twa:rounded-input twa:px-2 twa:items-center twa:gap-2 twa:w-full', 'twa:border-input twa:border', targetOwn.focusWithinOutline, disabled ? 'twa:opacity-60 twa:cursor-not-allowed' : 'twa:cursor-pointer twa:bg-input-background', editing ? 'twa:border-accent' : '', error ? 'twa:border-destructive' : ''), children: [_jsx(Flex, { className: "twa:flex-1 twa:flex-wrap twa:items-center twa:gap-1 twa:py-1", children: content }), !disabled && !editing ? (onReset && !isUsingDefault ? (_jsx(SimpleButton, { variant: "text", icon: "undo", tooltip: "Revert to default", "data-name": "plus-minus-reset-key", tabIndex: -1, onMouseDown: handleReset, onKeyDown: (event) => { if (event.key === 'Enter') { handleReset(event); ref.current?.focus(); } } })) : (_jsx(SimpleButton, { variant: "text", icon: "edit", tooltip: "Edit keyboard shortcut", "data-name": "plus-minus-edit-key", tabIndex: -1, onMouseDown: handleEnterEdit, onKeyDown: (event) => { if (event.key === 'Enter') { handleEnterEdit(event); } } }))) : null] }), _jsx(Box, { "data-name": error ? 'key-capture-error' : 'key-capture-hint', className: cn('twa:text-2', error ? 'twa:text-destructive' : 'twa:opacity-60', !focused && !error ? 'twa:invisible' : ''), children: error ? error : editing ? 'ENTER to confirm, ESCAPE to cancel' : 'Hit Enter to edit' })] })); };