From 4e5310c87eb10d84acf82b09792dc570bfee48bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Thu, 10 Oct 2024 15:01:01 +0200 Subject: [PATCH] feat: make module native ESM BREAKING-CHANGE: the module is now ESM-only --- .eslintrc.yml | 1 - .nvmrc | 2 +- .storybook/main.js | 2 +- eslint.config.js | 4 ++ package.json | 37 +++++++++---------- src/components/AlignGroup.tsx | 4 +- src/components/ResponsiveChart.tsx | 3 +- src/hooks/useBBoxObserver.ts | 2 +- src/hooks/useLinearPrimaryTicks.ts | 17 +++------ src/hooks/useLogTicks.ts | 16 ++++---- src/hooks/useTick.ts | 18 ++++----- src/hooks/useTimeTicks.ts | 10 ++--- src/index.ts | 12 +++--- src/utils.ts | 2 +- stories/components/AlignGroup.stories.tsx | 8 +++- .../components/ResponsiveChart.stories.tsx | 6 +-- .../hooks/LinearPrimaryExamples.stories.tsx | 4 +- stories/hooks/LinearPrimaryTicks.stories.tsx | 4 +- stories/hooks/LogExamples.stories.tsx | 4 +- stories/hooks/LogTicks.stories.tsx | 4 +- stories/hooks/TestAxis.tsx | 18 +++++---- stories/hooks/TimeExamples.stories.tsx | 4 +- stories/hooks/TimeTicks.stories.tsx | 4 +- tsconfig.cjs.json => tsconfig.build.json | 0 tsconfig.esm.json | 9 ----- tsconfig.json | 23 ++++++------ 26 files changed, 106 insertions(+), 112 deletions(-) delete mode 100644 .eslintrc.yml create mode 100644 eslint.config.js rename tsconfig.cjs.json => tsconfig.build.json (100%) delete mode 100644 tsconfig.esm.json diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index 7ccd66c..0000000 --- a/.eslintrc.yml +++ /dev/null @@ -1 +0,0 @@ -extends: '@zakodium/eslint-config/typescript-react' diff --git a/.nvmrc b/.nvmrc index 209e3ef..2bd5a0a 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20 +22 diff --git a/.storybook/main.js b/.storybook/main.js index a2ebd22..f9b532a 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,4 +1,4 @@ -module.exports = { +export default { stories: ['../stories/**/*.stories.@(js|jsx|ts|tsx)'], addons: [ diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..6f93af3 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,4 @@ +import react from 'eslint-config-zakodium/react'; +import ts from 'eslint-config-zakodium/ts'; + +export default [...react, ...ts]; diff --git a/package.json b/package.json index 484a38e..0d5f096 100644 --- a/package.json +++ b/package.json @@ -2,27 +2,26 @@ "name": "react-d3-utils", "version": "1.0.0", "description": "Low-level utilities to build charts with React and D3", - "main": "lib/index.js", - "module": "lib-esm/index.js", - "types": "lib-esm/index.d.ts", + "type": "module", + "exports": "./lib/index.js", "files": [ "lib", - "lib-esm" + "src" ], "scripts": { "build": "npm run clean && npm run build-ts", - "build-ts": "tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json", + "build-ts": "tsc -p tsconfig.build.json", "build-storybook": "storybook build", "check-types": "tsc --noEmit", - "clean": "rimraf lib lib-esm", + "clean": "rimraf lib", "dev": "storybook dev -p 6006", "eslint": "eslint src stories", "eslint-fix": "npm run eslint -- --fix", + "prepack": "npm run build", "prettier": "prettier --check .", "prettier-write": "prettier --write .", - "prepublishOnly": "npm run build", "start": "npm run dev", - "test": "npm run eslint && npm run check-types" + "test": "npm run eslint && npm run prettier && npm run check-types" }, "repository": { "type": "git", @@ -35,19 +34,19 @@ }, "homepage": "https://github.com/zakodium-oss/react-d3-utils#readme", "devDependencies": { - "@simbathesailor/use-what-changed": "^2.0.0", - "@storybook/addon-essentials": "^8.2.8", - "@storybook/addon-links": "^8.2.8", - "@storybook/addon-storysource": "^8.2.8", - "@storybook/react": "^8.2.8", - "@storybook/react-vite": "^8.2.8", - "@types/react": "^18.3.3", - "@zakodium/eslint-config": "^6.0.0", - "eslint": "^8.27.0", + "@storybook/addon-essentials": "^8.3.5", + "@storybook/addon-links": "^8.3.5", + "@storybook/addon-storysource": "^8.3.5", + "@storybook/react": "^8.3.5", + "@storybook/react-vite": "^8.3.5", + "@types/react": "^18.3.11", + "eslint": "^9.12.0", + "eslint-config-zakodium": "^13.0.0", "prettier": "^3.3.3", "react": "^18.3.1", "react-dom": "^18.3.1", - "typescript": "^5.5.4" + "rimraf": "^6.0.1", + "typescript": "^5.6.3" }, "dependencies": { "@types/d3-scale": "^4.0.8", @@ -55,6 +54,6 @@ "use-resize-observer": "^9.1.0" }, "volta": { - "node": "20.16.0" + "node": "22.9.0" } } diff --git a/src/components/AlignGroup.tsx b/src/components/AlignGroup.tsx index 290beae..9fc94b1 100644 --- a/src/components/AlignGroup.tsx +++ b/src/components/AlignGroup.tsx @@ -1,6 +1,6 @@ -import { useMemo, ReactNode, CSSProperties } from 'react'; +import { type CSSProperties, type ReactNode, useMemo } from 'react'; -import { useBBoxObserver } from '../hooks/useBBoxObserver'; +import { useBBoxObserver } from '../hooks/useBBoxObserver.js'; export type Align = 'start' | 'middle' | 'end' | 'none'; diff --git a/src/components/ResponsiveChart.tsx b/src/components/ResponsiveChart.tsx index 1c34011..2278685 100644 --- a/src/components/ResponsiveChart.tsx +++ b/src/components/ResponsiveChart.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import type { ReactNode } from 'react'; import useResizeObserver from 'use-resize-observer'; export interface ResponsiveChartProps { @@ -15,6 +15,7 @@ export function ResponsiveChart(props: ResponsiveChartProps) { const { width, height, minWidth, minHeight, maxWidth, maxHeight, children } = props; + // @ts-expect-error Default import is correct. const observed = useResizeObserver(); return ( diff --git a/src/hooks/useBBoxObserver.ts b/src/hooks/useBBoxObserver.ts index bcfd84c..9b74165 100644 --- a/src/hooks/useBBoxObserver.ts +++ b/src/hooks/useBBoxObserver.ts @@ -1,4 +1,4 @@ -import { RefCallback, useCallback, useRef, useState } from 'react'; +import { type RefCallback, useCallback, useRef, useState } from 'react'; const initialSize = { x: 0, y: 0, width: 0, height: 0 }; diff --git a/src/hooks/useLinearPrimaryTicks.ts b/src/hooks/useLinearPrimaryTicks.ts index c4f2286..9748be0 100644 --- a/src/hooks/useLinearPrimaryTicks.ts +++ b/src/hooks/useLinearPrimaryTicks.ts @@ -1,7 +1,7 @@ import type { ScaleContinuousNumeric } from 'd3-scale'; -import { MutableRefObject, useState } from 'react'; +import { type MutableRefObject, useState } from 'react'; -import { useTicks } from './useTick'; +import { useTicks } from './useTick.js'; type Directions = 'horizontal' | 'vertical'; @@ -16,21 +16,14 @@ interface Options { minSpace?: number; } -export function useLinearPrimaryTicks< - Scale extends ScaleContinuousNumeric, ->( - scale: Scale, +export function useLinearPrimaryTicks( + scale: ScaleContinuousNumeric, direction: Directions, ref: MutableRefObject, options: Options = {}, ): PrimaryLinearTicks[] { const [ticks, setTicks] = useState([]); const { tickFormat = String } = options; - useTicks>( - scale, - direction, - ref, - { ...options, tickFormat, setTicks }, - ); + useTicks(scale, direction, ref, { ...options, tickFormat, setTicks }); return ticks; } diff --git a/src/hooks/useLogTicks.ts b/src/hooks/useLogTicks.ts index bb9b126..1d422c1 100644 --- a/src/hooks/useLogTicks.ts +++ b/src/hooks/useLogTicks.ts @@ -1,13 +1,13 @@ import type { ScaleContinuousNumeric } from 'd3-scale'; import { - MutableRefObject, + type MutableRefObject, useCallback, useEffect, useMemo, useState, } from 'react'; -import { textDimensions } from '../utils'; +import { textDimensions } from '../utils.js'; type Directions = 'horizontal' | 'vertical'; @@ -25,13 +25,13 @@ interface Options { const TEST_HEIGHT = '+1234567890'; function isMainTick(value: number): number { - const index = value / Math.pow(10, Math.round(Math.log10(value))); + const index = value / 10 ** Math.round(Math.log10(value)); return Math.floor(index < 1 ? index * 10 : index); } -function formatTicks>( +function formatTicks( ticks: number[], - scale: Scale, + scale: ScaleContinuousNumeric, format: (d: number) => string, maxWordSpace: number, minSpace: number, @@ -53,10 +53,8 @@ function formatTicks>( }); } -export function useLogTicks< - Scale extends ScaleContinuousNumeric, ->( - scale: Scale, +export function useLogTicks( + scale: ScaleContinuousNumeric, direction: Directions, ref: MutableRefObject, options: Options = {}, diff --git a/src/hooks/useTick.ts b/src/hooks/useTick.ts index 8d1d430..64d1aba 100644 --- a/src/hooks/useTick.ts +++ b/src/hooks/useTick.ts @@ -1,7 +1,12 @@ import type { ScaleContinuousNumeric, ScaleTime } from 'd3-scale'; -import { Dispatch, MutableRefObject, SetStateAction, useEffect } from 'react'; +import { + type Dispatch, + type MutableRefObject, + type SetStateAction, + useEffect, +} from 'react'; -import { textDimensions } from '../utils'; +import { textDimensions } from '../utils.js'; type Directions = 'horizontal' | 'vertical'; @@ -20,13 +25,8 @@ interface Options { } const TEST_HEIGHT = '+1234567890'; -export function useTicks< - T extends number | Date, - Scale extends - | ScaleContinuousNumeric - | ScaleTime, ->( - scale: Scale, +export function useTicks( + scale: ScaleContinuousNumeric | ScaleTime, direction: Directions, ref: MutableRefObject, options: Options, diff --git a/src/hooks/useTimeTicks.ts b/src/hooks/useTimeTicks.ts index 51b6bea..3b01c41 100644 --- a/src/hooks/useTimeTicks.ts +++ b/src/hooks/useTimeTicks.ts @@ -1,7 +1,7 @@ import type { ScaleTime } from 'd3-scale'; -import { MutableRefObject, useState } from 'react'; +import { type MutableRefObject, useState } from 'react'; -import { useTicks } from './useTick'; +import { useTicks } from './useTick.js'; type Directions = 'horizontal' | 'vertical'; @@ -16,15 +16,15 @@ interface Options { minSpace?: number; } -export function useTimeTicks>( - scale: Scale, +export function useTimeTicks( + scale: ScaleTime, direction: Directions, ref: MutableRefObject, options: Options, ): TimeTicks[] { const { tickFormat = scale.tickFormat() } = options; const [ticks, setTicks] = useState([]); - useTicks>(scale, direction, ref, { + useTicks(scale, direction, ref, { ...options, setTicks, tickFormat, diff --git a/src/index.ts b/src/index.ts index a1b5245..03ded9d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ -export * from './components/AlignGroup'; -export * from './components/ResponsiveChart'; +export * from './components/AlignGroup.js'; +export * from './components/ResponsiveChart.js'; -export * from './hooks/useBBoxObserver'; -export * from './hooks/useLinearPrimaryTicks'; -export * from './hooks/useLogTicks'; -export * from './hooks/useTimeTicks'; +export * from './hooks/useBBoxObserver.js'; +export * from './hooks/useLinearPrimaryTicks.js'; +export * from './hooks/useLogTicks.js'; +export * from './hooks/useTimeTicks.js'; diff --git a/src/utils.ts b/src/utils.ts index 385a8ce..d7756bd 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -import { MutableRefObject } from 'react'; +import type { MutableRefObject } from 'react'; export function textDimensions( word: string, diff --git a/stories/components/AlignGroup.stories.tsx b/stories/components/AlignGroup.stories.tsx index 64bcdc0..75686e1 100644 --- a/stories/components/AlignGroup.stories.tsx +++ b/stories/components/AlignGroup.stories.tsx @@ -1,7 +1,11 @@ -import { Meta } from '@storybook/react'; +import type { Meta } from '@storybook/react'; import { useEffect, useState } from 'react'; -import { AlignGroup, AlignGroupProps, useBBoxObserver } from '../../src'; +import { + AlignGroup, + type AlignGroupProps, + useBBoxObserver, +} from '../../src/index.js'; const DEBUG_COLOR = 'yellow'; diff --git a/stories/components/ResponsiveChart.stories.tsx b/stories/components/ResponsiveChart.stories.tsx index 82e329e..c07c6e2 100644 --- a/stories/components/ResponsiveChart.stories.tsx +++ b/stories/components/ResponsiveChart.stories.tsx @@ -1,7 +1,7 @@ -import { Meta } from '@storybook/react'; -import { ReactNode, useEffect, useState } from 'react'; +import type { Meta } from '@storybook/react'; +import { type ReactNode, useEffect, useState } from 'react'; -import { ResponsiveChart, ResponsiveChartProps } from '../../src'; +import { ResponsiveChart, type ResponsiveChartProps } from '../../src/index.js'; export default { title: 'components/ResponsiveChart', diff --git a/stories/hooks/LinearPrimaryExamples.stories.tsx b/stories/hooks/LinearPrimaryExamples.stories.tsx index 9d63ce1..d9bbe24 100644 --- a/stories/hooks/LinearPrimaryExamples.stories.tsx +++ b/stories/hooks/LinearPrimaryExamples.stories.tsx @@ -1,7 +1,7 @@ -import { Meta } from '@storybook/react'; +import type { Meta } from '@storybook/react'; import { useState } from 'react'; -import { HorizontalExample, VerticalExample } from './TestAxis'; +import { HorizontalExample, VerticalExample } from './TestAxis.js'; export default { title: 'Hooks/static/useLinearPrimaryTicks', diff --git a/stories/hooks/LinearPrimaryTicks.stories.tsx b/stories/hooks/LinearPrimaryTicks.stories.tsx index 14a4334..8da8414 100644 --- a/stories/hooks/LinearPrimaryTicks.stories.tsx +++ b/stories/hooks/LinearPrimaryTicks.stories.tsx @@ -1,6 +1,6 @@ -import { Meta } from '@storybook/react'; +import type { Meta } from '@storybook/react'; -import { AutomaticHorizontalAxis, AutomaticVerticalAxis } from './TestAxis'; +import { AutomaticHorizontalAxis, AutomaticVerticalAxis } from './TestAxis.js'; interface Props { minSize: number; diff --git a/stories/hooks/LogExamples.stories.tsx b/stories/hooks/LogExamples.stories.tsx index bce154c..6de0d45 100644 --- a/stories/hooks/LogExamples.stories.tsx +++ b/stories/hooks/LogExamples.stories.tsx @@ -1,6 +1,6 @@ -import { Meta } from '@storybook/react'; +import type { Meta } from '@storybook/react'; -import { HorizontalExample, VerticalExample } from './TestAxis'; +import { HorizontalExample, VerticalExample } from './TestAxis.js'; export default { title: 'Hooks/static/useLogTicks', diff --git a/stories/hooks/LogTicks.stories.tsx b/stories/hooks/LogTicks.stories.tsx index d9b10fe..ee0930a 100644 --- a/stories/hooks/LogTicks.stories.tsx +++ b/stories/hooks/LogTicks.stories.tsx @@ -1,6 +1,6 @@ -import { Meta } from '@storybook/react'; +import type { Meta } from '@storybook/react'; -import { AutomaticHorizontalAxis, AutomaticVerticalAxis } from './TestAxis'; +import { AutomaticHorizontalAxis, AutomaticVerticalAxis } from './TestAxis.js'; interface Props { minSize: number; diff --git a/stories/hooks/TestAxis.tsx b/stories/hooks/TestAxis.tsx index 272e6fe..0470e54 100644 --- a/stories/hooks/TestAxis.tsx +++ b/stories/hooks/TestAxis.tsx @@ -1,14 +1,18 @@ import { - ScaleTime, - ScaleLinear, + type ScaleLinear, scaleLinear, scaleLog, - ScaleLogarithmic, + type ScaleLogarithmic, + type ScaleTime, scaleTime, } from 'd3-scale'; -import React, { forwardRef, useMemo, useRef, useEffect, useState } from 'react'; +import React, { forwardRef, useEffect, useMemo, useRef, useState } from 'react'; -import { useLinearPrimaryTicks, useLogTicks, useTimeTicks } from '../../src'; +import { + useLinearPrimaryTicks, + useLogTicks, + useTimeTicks, +} from '../../src/index.js'; interface BaseAxis { x: number; @@ -338,7 +342,7 @@ export function HorizontalExample({ } }, [domain, type]); useEffect(() => { - let state = []; + const state = []; for (let i = MIN; i <= MAX; i += 50) { const scale = scaleType(i); state.push({ scale, width: i }); @@ -385,7 +389,7 @@ export function VerticalExample({ } }, [domain, type]); useEffect(() => { - let state = []; + const state = []; for (let i = MIN; i <= MAX; i += 50) { const scale = scaleType(i); state.push({ scale, height: i }); diff --git a/stories/hooks/TimeExamples.stories.tsx b/stories/hooks/TimeExamples.stories.tsx index 9673a03..b62e66c 100644 --- a/stories/hooks/TimeExamples.stories.tsx +++ b/stories/hooks/TimeExamples.stories.tsx @@ -1,6 +1,6 @@ -import { Meta } from '@storybook/react'; +import type { Meta } from '@storybook/react'; -import { HorizontalExample, VerticalExample } from './TestAxis'; +import { HorizontalExample, VerticalExample } from './TestAxis.js'; export default { title: 'Hooks/static/useTimeTicks', diff --git a/stories/hooks/TimeTicks.stories.tsx b/stories/hooks/TimeTicks.stories.tsx index 230e7cb..938c5e5 100644 --- a/stories/hooks/TimeTicks.stories.tsx +++ b/stories/hooks/TimeTicks.stories.tsx @@ -1,6 +1,6 @@ -import { Meta } from '@storybook/react'; +import type { Meta } from '@storybook/react'; -import { AutomaticHorizontalAxis, AutomaticVerticalAxis } from './TestAxis'; +import { AutomaticHorizontalAxis, AutomaticVerticalAxis } from './TestAxis.js'; interface Props { minSize: number; diff --git a/tsconfig.cjs.json b/tsconfig.build.json similarity index 100% rename from tsconfig.cjs.json rename to tsconfig.build.json diff --git a/tsconfig.esm.json b/tsconfig.esm.json deleted file mode 100644 index 746c836..0000000 --- a/tsconfig.esm.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.cjs.json", - "compilerOptions": { - "declaration": true, - "module": "esnext", - "sourceMap": true, - "outDir": "lib-esm" - } -} diff --git a/tsconfig.json b/tsconfig.json index 82db5b1..b56e111 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,18 +1,19 @@ { "compilerOptions": { - "baseUrl": ".", - "declaration": false, - "esModuleInterop": true, - "jsx": "react-jsx", - "lib": ["dom", "esnext"], - "module": "commonjs", - "moduleResolution": "node", - "resolveJsonModule": true, + "lib": ["DOM", "ES2022"], + "types": [], + "target": "ES2022", "outDir": "lib", - "removeComments": false, - "sourceMap": false, + "jsx": "react-jsx", + "module": "NodeNext", "strict": true, - "target": "es2019" + "skipLibCheck": true, + "resolveJsonModule": false, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "sourceMap": true, + "declaration": true, + "declarationMap": true }, "include": ["src/**/*", "stories/**/*"], "exclude": ["node_modules"]