From c61df6bb857d2d9ef059f273715c20745cb250c3 Mon Sep 17 00:00:00 2001 From: Sebastien Ahkrin <30870051+Sebastien-Ahkrin@users.noreply.github.com> Date: Wed, 8 Jul 2026 14:53:58 +0200 Subject: [PATCH 1/2] refactor: use new form on RangesPickingOptionPanel closes: https://github.com/cheminfo/nmrium/issues/4175 --- .../header/RangesPickingOptionPanel.tsx | 145 +++++++++++------- 1 file changed, 87 insertions(+), 58 deletions(-) diff --git a/src/component/header/RangesPickingOptionPanel.tsx b/src/component/header/RangesPickingOptionPanel.tsx index 6bd78d467..c3805e7f2 100644 --- a/src/component/header/RangesPickingOptionPanel.tsx +++ b/src/component/header/RangesPickingOptionPanel.tsx @@ -1,51 +1,44 @@ -import { Button, Checkbox } from '@blueprintjs/core'; -import { yupResolver } from '@hookform/resolvers/yup'; -import { useForm } from 'react-hook-form'; -import * as Yup from 'yup'; +import { Checkbox, FormGroup, NumericInput } from '@blueprintjs/core'; +import styled from '@emotion/styled'; +import { revalidateLogic } from '@tanstack/react-form'; +import type { FormEvent } from 'react'; +import { useCallback } from 'react'; +import { useForm } from 'react-science/ui'; +import { z } from 'zod'; import { useDispatch } from '../context/DispatchContext.js'; import { useToaster } from '../context/ToasterContext.js'; -import Label from '../elements/Label.js'; -import { NumberInput2Controller } from '../elements/NumberInput2Controller.js'; import { MIN_AREA_POINTS, useCheckPointsNumberInWindowArea, } from '../hooks/useCheckPointsNumberInWindowArea.js'; -import { headerLabelStyle } from './Header.js'; -import { HeaderWrapper } from './HeaderWrapper.js'; - -interface AutoRangesOptions { - minMaxRatio: number; - lookNegative: boolean; -} - -const validationSchema = Yup.object().shape({ - minMaxRatio: Yup.number().min(0).required(), - lookNegative: Yup.boolean().required(), +const validationZodSchema = z.object({ + minMaxRatio: z.number().min(0), + lookNegative: z.boolean(), }); -const initialValues: AutoRangesOptions = { +type AutoRangesOptions = z.infer; + +const defaultValues: AutoRangesOptions = { minMaxRatio: 0.05, lookNegative: false, }; +const FormContainer = styled.div` + display: flex; + flex-direction: row; + gap: 10px; + align-items: center; +`; + function RangesPickingOptionPanel() { const dispatch = useDispatch(); - const { - handleSubmit, - register, - control, - formState: { isValid }, - } = useForm({ - defaultValues: initialValues, - resolver: yupResolver(validationSchema), - mode: 'onChange', - }); + const hasEnoughPoints = useCheckPointsNumberInWindowArea(); const toaster = useToaster(); - function handleRangesPicking(values: any) { + function handleRangesPicking(values: AutoRangesOptions) { if (hasEnoughPoints) { dispatch({ type: 'AUTO_RANGES_DETECTION', @@ -59,37 +52,73 @@ function RangesPickingOptionPanel() { } } + const form = useForm({ + defaultValues, + validationLogic: revalidateLogic({ modeAfterSubmission: 'change' }), + validators: { + onDynamic: validationZodSchema, + }, + onSubmit: ({ value }) => { + const parsedValues = validationZodSchema.parse(value); + handleRangesPicking(parsedValues); + }, + }); + + const onSubmit = useCallback( + (event: FormEvent) => { + event.preventDefault(); + void form.handleSubmit(event); + }, + [form], + ); + return ( - - - +
+ + + + {(field) => ( + + field.handleChange(checked) + } + /> + )} + + + + {(field) => ( + + { + field.handleChange(valueAsNumber); + }} + /> + + )} + - - +
+ + Auto ranges picking + +
+
+
+
); } From b5807a945829d7e50563d1d7f88b7d953b5c97df Mon Sep 17 00:00:00 2001 From: Sebastien Ahkrin <30870051+Sebastien-Ahkrin@users.noreply.github.com> Date: Wed, 8 Jul 2026 16:12:24 +0200 Subject: [PATCH 2/2] fix: make changes according to reviewer --- .../header/RangesPickingOptionPanel.tsx | 103 +++++++----------- 1 file changed, 42 insertions(+), 61 deletions(-) diff --git a/src/component/header/RangesPickingOptionPanel.tsx b/src/component/header/RangesPickingOptionPanel.tsx index c3805e7f2..25b098d3e 100644 --- a/src/component/header/RangesPickingOptionPanel.tsx +++ b/src/component/header/RangesPickingOptionPanel.tsx @@ -1,9 +1,7 @@ import { Checkbox, FormGroup, NumericInput } from '@blueprintjs/core'; import styled from '@emotion/styled'; import { revalidateLogic } from '@tanstack/react-form'; -import type { FormEvent } from 'react'; -import { useCallback } from 'react'; -import { useForm } from 'react-science/ui'; +import { AppForm, useForm } from 'react-science/ui'; import { z } from 'zod'; import { useDispatch } from '../context/DispatchContext.js'; @@ -14,24 +12,25 @@ import { } from '../hooks/useCheckPointsNumberInWindowArea.js'; const validationZodSchema = z.object({ - minMaxRatio: z.number().min(0), + minMaxRatio: z.coerce.number().min(0), lookNegative: z.boolean(), }); -type AutoRangesOptions = z.infer; - -const defaultValues: AutoRangesOptions = { - minMaxRatio: 0.05, +const defaultValues: AutoRangesOptionsInput = { + minMaxRatio: '0.05', lookNegative: false, }; -const FormContainer = styled.div` +const AppFormContainer = styled(AppForm)` display: flex; flex-direction: row; gap: 10px; align-items: center; `; +type AutoRangesOptionsInput = z.input; +type AutoRangesOptions = z.output; + function RangesPickingOptionPanel() { const dispatch = useDispatch(); @@ -64,61 +63,43 @@ function RangesPickingOptionPanel() { }, }); - const onSubmit = useCallback( - (event: FormEvent) => { - event.preventDefault(); - void form.handleSubmit(event); - }, - [form], - ); - return ( -
- - - - {(field) => ( - - field.handleChange(checked) - } - /> - )} - + + + {(field) => ( + field.handleChange(checked)} + /> + )} + - - {(field) => ( - - { - field.handleChange(valueAsNumber); - }} - /> - - )} - + + {(field) => ( + + { + field.handleChange(valueAsString); + }} + /> + + )} + -
- - Auto ranges picking - -
-
-
-
+
+ + Auto ranges picking + +
+ ); }