import type { PopoverProps } from '@blueprintjs/core'; import { Popover } from '@blueprintjs/core'; import styled from '@emotion/styled'; import { yupResolver } from '@hookform/resolvers/yup'; import type { MouseEvent, ReactNode } from 'react'; import { useState } from 'react'; import { useForm } from 'react-hook-form'; import * as Yup from 'yup'; import { Input2Controller } from '../elements/Input2Controller.js'; import { NumberInput2Controller } from '../elements/NumberInput2Controller.js'; const StyledPopover = styled(Popover)` .field-edition-popover { border-radius: 5px; } `; type InputType = 'number' | 'text'; interface FieldProps { value: number | string; inputType?: InputType; onChange: (value: any) => void; } interface FieldEditionsProps extends FieldProps { children: ReactNode; PopoverProps?: PopoverProps; } const InputDimension = { height: 28, width: 100 }; const validationSchema = (inputType: 'number' | 'text') => Yup.object({ value: (inputType === 'number' ? Yup.number() : Yup.string()).required(), }); function stopPropagation(e: MouseEvent) { e.stopPropagation(); } export function FieldEdition(props: FieldEditionsProps) { const { value, inputType = 'text', onChange, children, PopoverProps } = props; const [isOpen, setIsOpen] = useState(false); function handleChange({ value: newValue, }: { value: FieldEditionsProps['value']; }) { onChange(newValue); setIsOpen(false); } return ( setIsOpen(false)} onInteraction={() => setIsOpen(true)} content={ } {...PopoverProps} > {children} ); } function Field(props: FieldProps) { const { value, inputType = 'text', onChange } = props; const { control, handleSubmit } = useForm({ defaultValues: { value }, resolver: yupResolver(validationSchema(inputType)), }); function handleKeyDown(event: React.KeyboardEvent) { if (event.key === 'Enter') { void handleSubmit(onChange)(); } } const style = { height: `${InputDimension.height}px`, outline: 'none', }; if (inputType === 'number') { return ( ); } return ( ); }