import { Dialog as BPDialog } from '@blueprintjs/core'; import styled from '@emotion/styled'; import { revalidateLogic } from '@tanstack/react-form'; import type { Workspace } from '@zakodium/nmrium-core'; import { ErrorBoundary } from 'react-error-boundary'; import { Form, assert, assertUnreachable, useForm } from 'react-science/ui'; import { usePreferences } from '../../../context/PreferencesContext.js'; import ErrorOverlay from '../../../main/ErrorOverlay.tsx'; import { GeneralSettingsDialogBody } from './general_settings_dialog_body.js'; import { GeneralSettingsDialogFooter } from './general_settings_dialog_footer.js'; import { GeneralSettingsDialogHeader } from './general_settings_dialog_header.js'; import { formValueToWorkspace, useDefaultValues, } from './hooks/use_safe_workspace.ts'; import { workspaceValidation } from './validation.js'; interface GeneralSettingsDialogProps { isOpen: boolean; close: () => void; onSave: (values?: Partial) => void; height?: number; } const Dialog = styled(BPDialog)` max-width: 1000px; width: 50vw; min-width: 800px; /* * Fix: Blueprint NumericInput text selection bug inside Dialog * https://github.com/palantir/blueprint/issues/3004#issuecomment-432853498 * * Clicking the up/down buttons of a NumericInput selects the surrounding text. * Recommended way to fix this is to set user-select with initial. */ user-select: initial !important; `; export function GeneralSettingsDialog(props: GeneralSettingsDialogProps) { const { isOpen, close } = props; return ( ); } interface GeneralSettingsProps extends Omit< GeneralSettingsDialogProps, 'isOpen' > { onSave: (values?: Partial) => void; } type FormMeta = 'apply' | 'save'; function GeneralSettings(props: GeneralSettingsProps) { const { close, height, onSave } = props; const { current: currentWorkspace, dispatch } = usePreferences(); const defaultValues = useDefaultValues(); const form = useForm({ validators: { onDynamic: workspaceValidation, }, validationLogic: revalidateLogic({ mode: 'change' }), defaultValues, onSubmitMeta: 'apply' satisfies FormMeta as FormMeta, onSubmit: ({ value, meta }) => { const mergedValues = formValueToWorkspace(value, currentWorkspace); switch (meta) { case 'apply': dispatch({ type: 'APPLY_GENERAL_PREFERENCES', payload: { data: mergedValues }, }); break; case 'save': onSave(mergedValues); break; default: assertUnreachable(meta); } close(); }, }); return (
{ event.preventDefault(); const nativeEvent = event.nativeEvent as SubmitEvent; const submitter = nativeEvent.submitter as HTMLButtonElement | null; assert(submitter, 'form event should have a submitter'); const action = submitter.dataset.action; void form.handleSubmit(action as FormMeta); }} > ); } const InvisibleButton = styled.button` display: none; `; /** * In this form there are inputs with datalist, the complete event with the `Enter` key also triggers the form submission. * The previous version of this form did not use a proper Submit button, so there was no implicit form submission. * * @see https://stackoverflow.com/a/51507806 */ function PreventImplicitSubmit() { return