diff --git a/package-lock.json b/package-lock.json
index ad0a1526a..edd06acc2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,8 +16,8 @@
"@tanstack/react-store": "^0.11.0",
"@tanstack/react-table": "^8.21.3",
"@zakodium/nmr-types": "^0.5.18",
- "@zakodium/nmrium-core": "^0.7.37",
- "@zakodium/nmrium-core-plugins": "^0.7.50",
+ "@zakodium/nmrium-core": "^0.7.40",
+ "@zakodium/nmrium-core-plugins": "^0.7.53",
"@zakodium/pdnd-esm": "^1.1.0",
"@zakodium/utils": "^0.2.0",
"@zip.js/zip.js": "^2.8.26",
@@ -3970,9 +3970,9 @@
}
},
"node_modules/@zakodium/nmrium-core": {
- "version": "0.7.37",
- "resolved": "https://registry.npmjs.org/@zakodium/nmrium-core/-/nmrium-core-0.7.37.tgz",
- "integrity": "sha512-jlehjYSNiuvYTcoMi2jgihmCC/PMQqorUYlnrlSN1zUMvWHlMXMrB9a+nfHRlCXnMNkPNCEINLTwacGKqiWhLg==",
+ "version": "0.7.40",
+ "resolved": "https://registry.npmjs.org/@zakodium/nmrium-core/-/nmrium-core-0.7.40.tgz",
+ "integrity": "sha512-dyy4MsGWDbXA4/yCnpCgj7aIp31+IEWjGafJNeAIsv7vRbv1Sus5FkPCyLP/fubI2sfaJxPoHboJ/aOVybQjug==",
"license": "CC-BY-NC-SA-4.0",
"dependencies": {
"@zakodium/utils": "^0.2.0",
@@ -3989,24 +3989,24 @@
}
},
"node_modules/@zakodium/nmrium-core-plugins": {
- "version": "0.7.50",
- "resolved": "https://registry.npmjs.org/@zakodium/nmrium-core-plugins/-/nmrium-core-plugins-0.7.50.tgz",
- "integrity": "sha512-n+ypOorejkk/6MFhnjIo/5qUKRYssxyy1QBDRwPKlq0g2MuG+f9QXxpEBs7IENdYr3GYatJdYHkrIbtf9pHwXQ==",
+ "version": "0.7.53",
+ "resolved": "https://registry.npmjs.org/@zakodium/nmrium-core-plugins/-/nmrium-core-plugins-0.7.53.tgz",
+ "integrity": "sha512-bX0UoCMfDHnFOyrD0PdaQIvxZGisWGST4/qABefWwHa+5b/VJuKcpLR5FIMDzgEm8IcmqFoCev4OT31aNC1CbA==",
"license": "CC-BY-NC-SA-4.0",
"dependencies": {
"@date-fns/utc": "^2.1.1",
- "@zakodium/nmrium-core": "^0.7.37",
+ "@zakodium/nmrium-core": "^0.7.40",
"cheminfo-types": "^1.15.0",
"convert-to-jcamp": "^7.0.0",
"date-fns": "^4.4.0",
"file-collection": "^6.6.1",
"gyromagnetic-ratio": "^2.0.0",
"is-any-array": "^3.0.0",
- "jcampconverter": "^12.5.0",
+ "jcampconverter": "^12.5.1",
"linear-sum-assignment": "^1.0.9",
"lodash.merge": "^4.6.2",
"ml-spectra-processing": "^14.29.1",
- "nmr-processing": "^22.19.0",
+ "nmr-processing": "^22.19.1",
"openchemlib": "^9.23.0",
"openchemlib-utils": "^8.17.0",
"sdf-parser": "^9.0.0",
@@ -8432,9 +8432,9 @@
}
},
"node_modules/jcampconverter": {
- "version": "12.5.0",
- "resolved": "https://registry.npmjs.org/jcampconverter/-/jcampconverter-12.5.0.tgz",
- "integrity": "sha512-aEHivNTxqZFMPSR7HHA+37KlqLUMlLwAjtmwgq72jM1VolZ9k1/tEwvDALFbu5RdtP8sMITPcaGl2UhJ+rP4NQ==",
+ "version": "12.5.1",
+ "resolved": "https://registry.npmjs.org/jcampconverter/-/jcampconverter-12.5.1.tgz",
+ "integrity": "sha512-vTYX9xcDBkPRK1qeGd2ejtEQmNKs+qXG7EOEFDgyoH0BKC+PQUmERp/GQAI0Xat0Ro/So+IgGfRLJ+kHA9stOw==",
"license": "CC-BY-NC-SA-4.0",
"dependencies": {
"cheminfo-types": "^1.15.0",
@@ -9680,9 +9680,9 @@
}
},
"node_modules/nmr-processing": {
- "version": "22.19.0",
- "resolved": "https://registry.npmjs.org/nmr-processing/-/nmr-processing-22.19.0.tgz",
- "integrity": "sha512-GUJVa6ZrdPshoxeVRhvq9rkNEM0ILkjnLQO1MgGVYRNrAoqHM28ykyLF0UFNp8U+5OKN54cpZ8rnTLvkzC0M3A==",
+ "version": "22.19.1",
+ "resolved": "https://registry.npmjs.org/nmr-processing/-/nmr-processing-22.19.1.tgz",
+ "integrity": "sha512-xNTa3A+mqoVOXwm73o39japJlpQaeLyl7iK+FXkkLteiP4BOvbwjm+mkc7vou/QIid8XbP1m3+hyb9MWuo+iAQ==",
"license": "CC-BY-NC-SA-4.0",
"dependencies": {
"binary-search": "^1.3.6",
diff --git a/package.json b/package.json
index 1bd813bf3..6b31cff3e 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,7 @@
"clean-lib": "rimraf lib",
"cspell": "cspell lint \"**/*.tsx\"",
"dev": "vite --host localhost --port 3000 --open",
- "eslint": "eslint . --cache --max-warnings=102",
+ "eslint": "eslint . --cache --max-warnings=103",
"eslint-fix": "node --run eslint -- --fix",
"install:clean": "rm -rf node_modules/ && rm -rf package-lock.json && npm install && npm start",
"knip": "knip",
@@ -70,8 +70,8 @@
"@tanstack/react-store": "^0.11.0",
"@tanstack/react-table": "^8.21.3",
"@zakodium/nmr-types": "^0.5.18",
- "@zakodium/nmrium-core": "^0.7.37",
- "@zakodium/nmrium-core-plugins": "^0.7.50",
+ "@zakodium/nmrium-core": "^0.7.40",
+ "@zakodium/nmrium-core-plugins": "^0.7.53",
"@zakodium/pdnd-esm": "^1.1.0",
"@zakodium/utils": "^0.2.0",
"@zip.js/zip.js": "^2.8.26",
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/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/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 }) => }
-
-
+ <>
+
+
+
+
+
+
+
+
+ {({ 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/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,