diff --git a/src/component/1d/HorizontalAxis1D.tsx b/src/component/1d/HorizontalAxis1D.tsx index efa58ee1b..4d8086cc4 100644 --- a/src/component/1d/HorizontalAxis1D.tsx +++ b/src/component/1d/HorizontalAxis1D.tsx @@ -1,5 +1,6 @@ import { useMemo, useRef } from 'react'; import { useLinearPrimaryTicks } from 'react-d3-utils'; +import { SVGStyledText } from 'react-science/ui'; import { AxisUnitPicker } from '../1d-2d/components/axis_unit_picker.tsx'; import { useChartData } from '../context/ChartContext.js'; @@ -11,6 +12,7 @@ import { useHorizontalAxisUnit, } from '../hooks/use_axis_unit.ts'; import { useGridline1DConfig } from '../hooks/use_gridlines_config.ts'; +import { useTicksConfig } from '../hooks/use_ticks_config.ts'; import { useIsInset } from './inset/InsetProvider.js'; @@ -33,6 +35,7 @@ export function HorizontalAxis1D() { 'horizontal', refAxis, ); + const { labelStyle } = useTicksConfig(); const gridConfig = useGridline1DConfig(); if (!width || !height) { @@ -59,9 +62,16 @@ export function HorizontalAxis1D() { allowedUnits={allowedUnits} onChange={setUnit} > - + {unitLabel} - + )} diff --git a/src/component/2d/DirectAxis2D.tsx b/src/component/2d/DirectAxis2D.tsx index 9fc3be363..3acf61cd1 100644 --- a/src/component/2d/DirectAxis2D.tsx +++ b/src/component/2d/DirectAxis2D.tsx @@ -1,5 +1,6 @@ import { memo, useRef } from 'react'; import { useLinearPrimaryTicks } from 'react-d3-utils'; +import { SVGStyledText } from 'react-science/ui'; import { useIsInset } from '../1d/inset/InsetProvider.tsx'; import { AxisUnitPicker } from '../1d-2d/components/axis_unit_picker.tsx'; @@ -8,6 +9,7 @@ import { D3Axis } from '../elements/D3Axis.js'; import { useCheckExportStatus } from '../hooks/useViewportSize.tsx'; import { axisUnitToLabel, useDirectAxisUnit } from '../hooks/use_axis_unit.ts'; import { useGridline2DConfig } from '../hooks/use_gridlines_config.ts'; +import { useTicksConfig } from '../hooks/use_ticks_config.ts'; import { useScale2DX } from './utilities/scale.js'; @@ -93,11 +95,18 @@ interface UnitLabelProps { } function UnitLabel(props: UnitLabelProps) { const { width, children } = props; - + const { labelStyle } = useTicksConfig(); return ( - + {children} - + ); } diff --git a/src/component/2d/IndirectAxis2D.tsx b/src/component/2d/IndirectAxis2D.tsx index 88845069d..8e6668a28 100644 --- a/src/component/2d/IndirectAxis2D.tsx +++ b/src/component/2d/IndirectAxis2D.tsx @@ -1,5 +1,6 @@ import { memo, useRef } from 'react'; import { useLinearPrimaryTicks } from 'react-d3-utils'; +import { SVGStyledText } from 'react-science/ui'; import { useIsInset } from '../1d/inset/InsetProvider.tsx'; import { AxisUnitPicker } from '../1d-2d/components/axis_unit_picker.tsx'; @@ -13,6 +14,7 @@ import { useIndirectAxisUnit, } from '../hooks/use_axis_unit.ts'; import { useGridline2DConfig } from '../hooks/use_gridlines_config.ts'; +import { useTicksConfig } from '../hooks/use_ticks_config.ts'; import { useScale2DY } from './utilities/scale.js'; @@ -108,8 +110,8 @@ interface UnitLabelProps { } function UnitLabel(props: UnitLabelProps) { const { children } = props; - - const { getTextWidth } = useTextMetrics({ labelSize: 10 }); + const { labelStyle } = useTicksConfig(); + const { getTextWidth } = useTextMetrics({ labelSize: labelStyle.fontSize }); const labelHeight = getTextWidth(children); return ( @@ -124,14 +126,16 @@ function UnitLabel(props: UnitLabelProps) { y={-5} opacity={0.8} /> - {children} - + ); } diff --git a/src/component/elements/D3Axis.tsx b/src/component/elements/D3Axis.tsx index e8770b165..1c838edfa 100644 --- a/src/component/elements/D3Axis.tsx +++ b/src/component/elements/D3Axis.tsx @@ -51,6 +51,8 @@ function isVerticalAxis(axisPosition: AxisPosition) { function BaseLine(props: BaseLineProps) { const { axisPosition, tickLength = 6, scale } = props; + const { primaryTicks } = useTicksConfig(); + const [x1, x2] = scale.range(); const sign = ['left', 'top'].includes(axisPosition) ? -1 : 1; @@ -60,12 +62,20 @@ function BaseLine(props: BaseLineProps) { path = `M${sign * tickLength},${x2} H0 V${x1} H${sign * tickLength}`; } - return ; + return ( + + ); } function Tickets(props: TicketsProps) { const { ticks, tickLength = 6, axisPosition } = props; - const config = useTicksConfig(); + const { primaryTicks, secondaryTicks } = useTicksConfig(); if (!Array.isArray(ticks) || ticks.length === 0) return null; @@ -127,19 +137,31 @@ function Tickets(props: TicketsProps) { transform={`translate(${isVertical ? `0,${position}` : `${position},0`})`} className="tick" > - {config.isSecondaryEnabled && isFirst && ( - + {secondaryTicks.enabled && isFirst && ( + )} - - - {config.isSecondaryEnabled && ( - + + + {secondaryTicks.enabled && ( + )} {label} diff --git a/src/component/hooks/usePanelPreferences.ts b/src/component/hooks/usePanelPreferences.ts index c3771f11c..b66025078 100644 --- a/src/component/hooks/usePanelPreferences.ts +++ b/src/component/hooks/usePanelPreferences.ts @@ -2,8 +2,8 @@ import type { MatrixGenerationOptions, MultipleSpectraAnalysisPreferences, PanelsPreferences, - WorkSpacePanelPreferences, Workspace, + WorkspacePanelPreferences, } from '@zakodium/nmrium-core'; import has from 'lodash/has.js'; import { useMemo } from 'react'; @@ -128,15 +128,15 @@ export function usePanelPreferences( ? MatrixGenerationOptions : T extends 'multipleSpectraAnalysis' ? MultipleSpectraAnalysisPreferences - : WorkSpacePanelPreferences[T]; + : WorkspacePanelPreferences[T]; export function usePanelPreferences( panelKey: T, -): WorkSpacePanelPreferences[T]; +): WorkspacePanelPreferences[T]; export function usePanelPreferences( panelKey: T, nucleus?: string, -): WorkSpacePanelPreferences[T] { +): WorkspacePanelPreferences[T] { const { current } = usePreferences(); return useMemo(() => { return getPanelPreferences(current, panelKey, nucleus); diff --git a/src/component/hooks/use_ticks_config.ts b/src/component/hooks/use_ticks_config.ts index 21915ade4..f5d23f941 100644 --- a/src/component/hooks/use_ticks_config.ts +++ b/src/component/hooks/use_ticks_config.ts @@ -5,11 +5,5 @@ export function useTicksConfig() { const { current } = usePreferences(); const axis = current.axis ?? workspaceDefaultProperties.axis; - const { textStyle } = axis.primaryTicks; - const { enabled } = axis.secondaryTicks; - - return { - textStyle, - isSecondaryEnabled: enabled, - }; + return axis; } diff --git a/src/component/modal/setting/WorkspaceItem.tsx b/src/component/modal/setting/WorkspaceItem.tsx index 90d745630..b3eaf1217 100644 --- a/src/component/modal/setting/WorkspaceItem.tsx +++ b/src/component/modal/setting/WorkspaceItem.tsx @@ -1,4 +1,4 @@ -import type { WorkSpaceSource } from '@zakodium/nmrium-core'; +import type { WorkspaceSource } from '@zakodium/nmrium-core'; import type { CSSProperties, ChangeEvent, MouseEvent } from 'react'; import { useState } from 'react'; import { Button } from 'react-science/ui'; @@ -115,7 +115,7 @@ const style = { alignItems: 'center', }; -const WorkspaceIndicator = (props: { source: WorkSpaceSource }) => { +const WorkspaceIndicator = (props: { source: WorkspaceSource }) => { let letter = ''; let backgroundColor = 'red'; diff --git a/src/component/modal/setting/tanstack_general_settings/tabs/axis_tab.tsx b/src/component/modal/setting/tanstack_general_settings/tabs/axis_tab.tsx index 1fff99a75..3dbfffed7 100644 --- a/src/component/modal/setting/tanstack_general_settings/tabs/axis_tab.tsx +++ b/src/component/modal/setting/tanstack_general_settings/tabs/axis_tab.tsx @@ -1,3 +1,4 @@ +import styled from '@emotion/styled'; import { FieldGroupSVGLineStyleFields, FieldGroupSVGTextStyleFields, @@ -9,6 +10,18 @@ import type { z } from 'zod'; import type { gridlineValidation } from '../validation/axis_tab_validation.ts'; import { defaultGeneralSettingsFormValues } from '../validation.ts'; +// TODO: Expose the Fieldset and Legend components in react-science/ui package +const Fieldset = styled.fieldset` + display: block; + border-top: 1px lightgrey groove; + min-inline-size: min-content; +`; + +const Legend = styled.legend` + display: block; + padding-inline-end: 5px; +`; + export const AxisTab = withForm({ defaultValues: defaultGeneralSettingsFormValues, render: ({ form }) => { @@ -28,18 +41,69 @@ const TicksSection = withFieldGroup({ const { AppField, Section } = group; return ( -
- -
- - {({ Checkbox }) => } - -
+ <> +
+ +
+
+ +
+ Line style + + {(field) => } + + + {(field) => ( + + )} + + + {(field) => } + +
+
+ +
+ + {({ Checkbox }) => } + + + {(field) => } + + + {(field) => ( + + )} + + + {(field) => } + +
+ ); }, }); diff --git a/src/component/modal/setting/tanstack_general_settings/validation/axis_tab_validation.ts b/src/component/modal/setting/tanstack_general_settings/validation/axis_tab_validation.ts index a4bb03df0..c6f707f59 100644 --- a/src/component/modal/setting/tanstack_general_settings/validation/axis_tab_validation.ts +++ b/src/component/modal/setting/tanstack_general_settings/validation/axis_tab_validation.ts @@ -14,10 +14,24 @@ const gridlinesValidation = z.object({ secondary: gridlineValidation, }); +const primaryTicksValidation = z.object({ + textStyle: svgTextStyleFieldsSchema, + tickStyle: svgLineStyleFieldsSchema.omit({ + strokeDasharray: true, + }), +}); +const secondaryTicksValidation = z.object({ + enabled: z.boolean(), + tickStyle: svgLineStyleFieldsSchema.omit({ + strokeDasharray: true, + }), +}); + export const axisValidation = z .object({ - primaryTicks: z.object({ textStyle: svgTextStyleFieldsSchema }), - secondaryTicks: z.object({ enabled: z.boolean() }), + labelStyle: svgTextStyleFieldsSchema, + primaryTicks: primaryTicksValidation, + secondaryTicks: secondaryTicksValidation, gridlines1D: gridlinesValidation, gridlines2D: gridlinesValidation, }) diff --git a/src/component/panels/RangesPanel/RangesPanel.tsx b/src/component/panels/RangesPanel/RangesPanel.tsx index 27378e2e9..a5a3bcf60 100644 --- a/src/component/panels/RangesPanel/RangesPanel.tsx +++ b/src/component/panels/RangesPanel/RangesPanel.tsx @@ -1,7 +1,7 @@ import type { Info1D, Range, Ranges } from '@zakodium/nmr-types'; import type { Spectrum1D, - WorkSpacePanelPreferences, + WorkspacePanelPreferences, } from '@zakodium/nmrium-core'; import type { NmrData1D } from 'cheminfo-types'; import { xGetFromToIndex } from 'ml-spectra-processing'; @@ -37,7 +37,7 @@ interface RangesTablePanelInnerProps { info: Info1D; xDomain: number[]; activeTab: string; - preferences: WorkSpacePanelPreferences['ranges']; + preferences: WorkspacePanelPreferences['ranges']; } export interface RangesTableDataMetaInfo { diff --git a/src/component/panels/RangesPanel/RangesTable.tsx b/src/component/panels/RangesPanel/RangesTable.tsx index 022ed517d..3b39036ee 100644 --- a/src/component/panels/RangesPanel/RangesTable.tsx +++ b/src/component/panels/RangesPanel/RangesTable.tsx @@ -1,6 +1,6 @@ import styled from '@emotion/styled'; import type { Info1D } from '@zakodium/nmr-types'; -import type { WorkSpacePanelPreferences } from '@zakodium/nmrium-core'; +import type { WorkspacePanelPreferences } from '@zakodium/nmrium-core'; import { FaLink } from 'react-icons/fa'; import { withDialog } from '../../elements/DialogManager.js'; @@ -61,7 +61,7 @@ const Table = styled.table` `; interface RangesTableProps extends TableContextMenuProps { - preferences: WorkSpacePanelPreferences['ranges']; + preferences: WorkspacePanelPreferences['ranges']; tableData: RangesTableDataRow[]; activeTab: string; info: Info1D; diff --git a/src/component/panels/RangesPanel/RangesTableRow.tsx b/src/component/panels/RangesPanel/RangesTableRow.tsx index 01471d5a0..b47f5aba8 100644 --- a/src/component/panels/RangesPanel/RangesTableRow.tsx +++ b/src/component/panels/RangesPanel/RangesTableRow.tsx @@ -1,5 +1,5 @@ import type { Info1D } from '@zakodium/nmr-types'; -import type { WorkSpacePanelPreferences } from '@zakodium/nmrium-core'; +import type { WorkspacePanelPreferences } from '@zakodium/nmrium-core'; import type { CSSProperties, MouseEvent } from 'react'; import { useCallback, useMemo } from 'react'; @@ -35,7 +35,7 @@ const ConstantlyHighlightedRowStyle = { interface RangesTableRowProps extends TableContextMenuProps { rowData: RangeData; - preferences: WorkSpacePanelPreferences['ranges']; + preferences: WorkspacePanelPreferences['ranges']; info: Info1D; } diff --git a/src/component/panels/multipleAnalysisPanel/AnalysisChart.tsx b/src/component/panels/multipleAnalysisPanel/AnalysisChart.tsx index a9a384443..b838cbe2c 100644 --- a/src/component/panels/multipleAnalysisPanel/AnalysisChart.tsx +++ b/src/component/panels/multipleAnalysisPanel/AnalysisChart.tsx @@ -3,7 +3,7 @@ import { css } from '@emotion/react'; import type { JpathTableColumn, Spectrum, - WorkSpacePanelPreferences, + WorkspacePanelPreferences, } from '@zakodium/nmrium-core'; import dlv from 'dlv'; import type { ChangeEvent } from 'react'; @@ -82,7 +82,7 @@ function getPlotDataAsString( options: { plotOptions: PlotOptions; spectra: Spectrum[]; - spectraPanelPreferences: WorkSpacePanelPreferences['spectra']; + spectraPanelPreferences: WorkspacePanelPreferences['spectra']; }, ) { const { plotOptions, spectra, spectraPanelPreferences } = options; diff --git a/src/component/reducer/preferences/preferencesReducer.ts b/src/component/reducer/preferences/preferencesReducer.ts index c635a6823..449432276 100644 --- a/src/component/reducer/preferences/preferencesReducer.ts +++ b/src/component/reducer/preferences/preferencesReducer.ts @@ -9,8 +9,8 @@ import type { PanelPreferencesType, PanelsPreferences, PrintPageOptions, - WorkSpaceSource, Workspace, + WorkspaceSource, } from '@zakodium/nmrium-core'; import { CURRENT_EXPORT_VERSION, migrateSettings } from '@zakodium/nmrium-core'; import type { Draft } from 'immer'; @@ -223,7 +223,7 @@ export type PreferencesActions = | CutSpectraAnalysisAction | ToggleSplitPanelAction; -export type WorkspaceWithSource = Workspace & { source: WorkSpaceSource }; +export type WorkspaceWithSource = Workspace & { source: WorkspaceSource }; type WorkspacesWithSource = Record; export interface PreferencesState { diff --git a/src/component/reducer/preferences/utilities/initWorkspace.ts b/src/component/reducer/preferences/utilities/initWorkspace.ts index 535fb0b4b..d50331b7a 100644 --- a/src/component/reducer/preferences/utilities/initWorkspace.ts +++ b/src/component/reducer/preferences/utilities/initWorkspace.ts @@ -1,4 +1,4 @@ -import type { WorkSpaceSource } from '@zakodium/nmrium-core'; +import type { WorkspaceSource } from '@zakodium/nmrium-core'; import lodashMerge from 'lodash/merge.js'; import { workspaceDefaultProperties } from '../../../workspaces/workspaceDefaultProperties.js'; @@ -6,7 +6,7 @@ import type { WorkspaceWithSource } from '../preferencesReducer.js'; export function initWorkspace( preferences: any, - data: { source: WorkSpaceSource; label: string }, + data: { source: WorkspaceSource; label: string }, ): WorkspaceWithSource { return lodashMerge({}, workspaceDefaultProperties, preferences, data); } diff --git a/src/component/reducer/preferences/utilities/mapWorkspaces.ts b/src/component/reducer/preferences/utilities/mapWorkspaces.ts index 7d046d8a6..9f539874a 100644 --- a/src/component/reducer/preferences/utilities/mapWorkspaces.ts +++ b/src/component/reducer/preferences/utilities/mapWorkspaces.ts @@ -1,7 +1,7 @@ import type { - WorkSpaceSource, Workspace, WorkspacePreferences, + WorkspaceSource, } from '@zakodium/nmrium-core'; import lodashMerge from 'lodash/merge.js'; @@ -10,7 +10,7 @@ import { workspaceDefaultProperties } from '../../../workspaces/workspaceDefault interface MapWorkspacesOptions { ignoreKeys?: object; mergeWithDefaultProperties?: boolean; - source?: WorkSpaceSource; + source?: WorkspaceSource; } export function mapWorkspaces( diff --git a/src/component/toolbar/ToolTypes.ts b/src/component/toolbar/ToolTypes.ts index 1335d41f8..cc7ae044a 100644 --- a/src/component/toolbar/ToolTypes.ts +++ b/src/component/toolbar/ToolTypes.ts @@ -1,5 +1,5 @@ import type { Info1D, Info2D } from '@zakodium/nmr-types'; -import type { NMRiumToolBarPreferences } from '@zakodium/nmrium-core'; +import type { NMRiumToolbarPreferences } from '@zakodium/nmrium-core'; import { Filters1D, Filters2D } from 'nmr-processing'; import type { DisplayerMode } from '../reducer/Reducer.js'; @@ -32,7 +32,7 @@ export interface ToolOptionItem { isExperimental?: true; } -export type MainTool = keyof NMRiumToolBarPreferences; +export type MainTool = keyof NMRiumToolbarPreferences; /** * Tools that are selectable in panels, not in the main toolbar. diff --git a/src/component/workspaces/workspaceDefaultProperties.ts b/src/component/workspaces/workspaceDefaultProperties.ts index 5749a4744..a4b9e2ecb 100644 --- a/src/component/workspaces/workspaceDefaultProperties.ts +++ b/src/component/workspaces/workspaceDefaultProperties.ts @@ -77,8 +77,25 @@ export const workspaceDefaultProperties: RequiredWorkspacePreferences = { } satisfies Required, axis: { - secondaryTicks: { enabled: true }, - primaryTicks: { textStyle: { fontSize: 10 } }, + labelStyle: { + fontSize: 10, + }, + secondaryTicks: { + enabled: true, + tickStyle: { + strokeWidth: 1, + strokeOpacity: 1, + stroke: '#000000', + }, + }, + primaryTicks: { + textStyle: { fontSize: 10 }, + tickStyle: { + strokeWidth: 1, + strokeOpacity: 1, + stroke: '#000000', + }, + }, gridlines1D: { primary: { enabled: true, diff --git a/src/data/data1d/multipleSpectraAnalysis.ts b/src/data/data1d/multipleSpectraAnalysis.ts index 7a57a1a90..6ce06db43 100644 --- a/src/data/data1d/multipleSpectraAnalysis.ts +++ b/src/data/data1d/multipleSpectraAnalysis.ts @@ -8,7 +8,7 @@ import type { SpectraAnalysisColumns, Spectrum1D, Spectrum, - WorkSpacePanelPreferences, + WorkspacePanelPreferences, } from '@zakodium/nmrium-core'; import { ANALYSIS_COLUMN_TYPES, @@ -314,7 +314,7 @@ function calculate( export function getDataAsString( spectraAnalysis: SpectraAnalysisData, spectra: Spectrum1D[], - spectraPanelPreferences: WorkSpacePanelPreferences['spectra'], + spectraPanelPreferences: WorkspacePanelPreferences['spectra'], ) { const spectraData = convertSpectraArrayToObject(spectra); if (spectraAnalysis) {