@omer-x/svg-viewport 0.3.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ default: () => index_default
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/components/SvgViewport.tsx
29
+ var import_react = require("react");
30
+
31
+ // src/core/matrix.ts
32
+ function transform(matrix) {
33
+ if (!matrix) return void 0;
34
+ const { a, b, c, d, e, f } = matrix;
35
+ return `matrix(${a}, ${b}, ${c}, ${d}, ${e}, ${f})`;
36
+ }
37
+ function focusTo(matrix, { x, y }, width, height, zoom) {
38
+ return matrix.translate(
39
+ width / 2 / zoom - x - matrix.m41 / zoom,
40
+ height / 2 / zoom - y - matrix.m42 / zoom
41
+ );
42
+ }
43
+ function adjustWithZoom(matrix, scale, svgElement, eX, eY) {
44
+ const rect = svgElement.getBoundingClientRect();
45
+ const focusPoint = new DOMPoint(eX - rect.left, eY - rect.top);
46
+ const relativePoint = focusPoint.matrixTransform(matrix.inverse());
47
+ const modifier = new DOMMatrix().translate(relativePoint.x, relativePoint.y).scale(scale).translate(-relativePoint.x, -relativePoint.y);
48
+ return matrix.multiply(modifier);
49
+ }
50
+
51
+ // src/core/initial-focus.ts
52
+ function getFocusedMatrix(focusPoint, width, height) {
53
+ switch (focusPoint) {
54
+ case "center":
55
+ return focusTo(new DOMMatrix(), { x: 0, y: 0 }, width, height, 1);
56
+ case "top-left":
57
+ return focusTo(new DOMMatrix(), { x: 0, y: 0 }, 0, 0, 1);
58
+ }
59
+ }
60
+
61
+ // src/components/SvgViewport.tsx
62
+ var import_jsx_runtime = require("react/jsx-runtime");
63
+ var SvgViewport = ({
64
+ width,
65
+ height,
66
+ pannable = false,
67
+ zoomable = false,
68
+ minZoom = 0.5,
69
+ maxZoom = 2,
70
+ transformation: externalTransformation,
71
+ onTransformationChange,
72
+ initialFocusPoint = "center",
73
+ style,
74
+ children,
75
+ ...otherProps
76
+ }) => {
77
+ const isControlled = externalTransformation !== void 0;
78
+ const [internalTransformation, setInternalTransformation] = (0, import_react.useState)(() => {
79
+ if (isControlled) return null;
80
+ return {
81
+ zoom: 1,
82
+ matrix: getFocusedMatrix(initialFocusPoint, width, height)
83
+ };
84
+ });
85
+ const transformation = isControlled ? externalTransformation : internalTransformation;
86
+ const transformationRef = (0, import_react.useRef)(transformation);
87
+ (0, import_react.useEffect)(() => {
88
+ transformationRef.current = transformation;
89
+ }, [transformation]);
90
+ const pointer = (0, import_react.useRef)({ x: 0, y: 0 });
91
+ const [grabbing, setGrabbing] = (0, import_react.useState)(false);
92
+ const [isPanning, setIsPanning] = (0, import_react.useState)(false);
93
+ const setTransformation = (0, import_react.useCallback)((value) => {
94
+ if (!isControlled) {
95
+ setInternalTransformation(value);
96
+ }
97
+ onTransformationChange?.(value);
98
+ }, [isControlled, onTransformationChange]);
99
+ const stopGrabbing = () => {
100
+ setGrabbing(false);
101
+ };
102
+ const down = (e) => {
103
+ if (e.button !== 0) return;
104
+ pointer.current = { x: e.clientX, y: e.clientY };
105
+ setIsPanning(true);
106
+ setGrabbing(true);
107
+ };
108
+ const move = (0, import_react.useCallback)((e) => {
109
+ const currentTrans = transformationRef.current;
110
+ if (currentTrans) {
111
+ const x = (e.clientX - pointer.current.x) / currentTrans.zoom;
112
+ const y = (e.clientY - pointer.current.y) / currentTrans.zoom;
113
+ pointer.current = { x: e.clientX, y: e.clientY };
114
+ setTransformation({
115
+ ...currentTrans,
116
+ matrix: currentTrans.matrix.translate(x, y)
117
+ });
118
+ }
119
+ }, [setTransformation]);
120
+ const up = (0, import_react.useCallback)(() => {
121
+ setIsPanning(false);
122
+ setGrabbing(false);
123
+ }, []);
124
+ (0, import_react.useEffect)(() => {
125
+ if (isPanning) {
126
+ document.addEventListener("mousemove", move);
127
+ document.addEventListener("mouseup", up);
128
+ }
129
+ return () => {
130
+ document.removeEventListener("mousemove", move);
131
+ document.removeEventListener("mouseup", up);
132
+ };
133
+ }, [isPanning, move, up]);
134
+ const adjustZoom = (e) => {
135
+ if (!zoomable) return;
136
+ e.preventDefault();
137
+ const scale = e.deltaY < 0 ? 1.25 : 0.8;
138
+ const eventTarget = e.currentTarget;
139
+ const { clientX, clientY } = e;
140
+ if (transformation && transformation.zoom * scale > minZoom && transformation.zoom * scale < maxZoom) {
141
+ setTransformation({
142
+ zoom: transformation.zoom * scale,
143
+ matrix: adjustWithZoom(transformation.matrix, scale, eventTarget, clientX, clientY)
144
+ });
145
+ }
146
+ };
147
+ const cursor = pannable ? grabbing ? "grabbing" : "grab" : "auto";
148
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
149
+ "svg",
150
+ {
151
+ width,
152
+ height,
153
+ onMouseDown: pannable ? down : void 0,
154
+ onMouseUp: pannable ? stopGrabbing : void 0,
155
+ onMouseLeave: pannable ? stopGrabbing : void 0,
156
+ onWheel: zoomable ? adjustZoom : void 0,
157
+ onContextMenu: (e) => e.preventDefault(),
158
+ style: { ...style, cursor },
159
+ ...otherProps,
160
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: transform(transformation?.matrix), children: transformation && children })
161
+ }
162
+ );
163
+ };
164
+ var SvgViewport_default = SvgViewport;
165
+
166
+ // src/index.ts
167
+ var index_default = SvgViewport_default;
@@ -0,0 +1,57 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ComponentProps } from 'react';
3
+
4
+ type FocusPoint = "center" | "top-left";
5
+
6
+ type ViewportTransformation = {
7
+ zoom: number;
8
+ matrix: DOMMatrix;
9
+ };
10
+
11
+ /**
12
+ * Props for the SvgViewport component.
13
+ */
14
+ type SvgViewportProps = ComponentProps<"svg"> & {
15
+ /**
16
+ * Width of the SVG viewport.
17
+ */
18
+ width: number;
19
+ /**
20
+ * Height of the SVG viewport.
21
+ */
22
+ height: number;
23
+ /**
24
+ * Enable or disable panning functionality.
25
+ */
26
+ pannable?: boolean;
27
+ /**
28
+ * Enable or disable zooming functionality.
29
+ */
30
+ zoomable?: boolean;
31
+ /**
32
+ * Minimum zoom level.
33
+ */
34
+ minZoom?: number;
35
+ /**
36
+ * Maximum zoom level.
37
+ */
38
+ maxZoom?: number;
39
+ /**
40
+ * Current transformation state of the viewport.
41
+ */
42
+ transformation?: ViewportTransformation | null;
43
+ /**
44
+ * Callback to update the transformation state.
45
+ */
46
+ onTransformationChange?: (tranformation: ViewportTransformation) => void;
47
+ /**
48
+ * Initial focus point of the viewport.
49
+ */
50
+ initialFocusPoint?: FocusPoint;
51
+ };
52
+ /**
53
+ * SVG Viewport component that supports panning and zooming.
54
+ */
55
+ declare const SvgViewport: ({ width, height, pannable, zoomable, minZoom, maxZoom, transformation: externalTransformation, onTransformationChange, initialFocusPoint, style, children, ...otherProps }: SvgViewportProps) => react_jsx_runtime.JSX.Element;
56
+
57
+ export { SvgViewport as default };
package/dist/index.d.ts CHANGED
@@ -1,27 +1,57 @@
1
- import React, { Dispatch, SetStateAction, ReactNode } from 'react';
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ComponentProps } from 'react';
2
3
 
3
4
  type FocusPoint = "center" | "top-left";
4
5
 
5
- type ViewportTransform = {
6
- zoom: number,
7
- matrix: DOMMatrix,
6
+ type ViewportTransformation = {
7
+ zoom: number;
8
+ matrix: DOMMatrix;
8
9
  };
9
10
 
10
- type SvgViewportProps = {
11
+ /**
12
+ * Props for the SvgViewport component.
13
+ */
14
+ type SvgViewportProps = ComponentProps<"svg"> & {
15
+ /**
16
+ * Width of the SVG viewport.
17
+ */
11
18
  width: number;
19
+ /**
20
+ * Height of the SVG viewport.
21
+ */
12
22
  height: number;
23
+ /**
24
+ * Enable or disable panning functionality.
25
+ */
13
26
  pannable?: boolean;
27
+ /**
28
+ * Enable or disable zooming functionality.
29
+ */
14
30
  zoomable?: boolean;
31
+ /**
32
+ * Minimum zoom level.
33
+ */
15
34
  minZoom?: number;
35
+ /**
36
+ * Maximum zoom level.
37
+ */
16
38
  maxZoom?: number;
17
- panning?: boolean;
18
- setPanning?: Dispatch<SetStateAction<boolean>>;
19
- transformation?: ViewportTransform | null;
20
- setTransformation?: Dispatch<SetStateAction<ViewportTransform | null>>;
39
+ /**
40
+ * Current transformation state of the viewport.
41
+ */
42
+ transformation?: ViewportTransformation | null;
43
+ /**
44
+ * Callback to update the transformation state.
45
+ */
46
+ onTransformationChange?: (tranformation: ViewportTransformation) => void;
47
+ /**
48
+ * Initial focus point of the viewport.
49
+ */
21
50
  initialFocusPoint?: FocusPoint;
22
- className?: string;
23
- children: ReactNode;
24
51
  };
25
- declare const SvgViewport: ({ width, height, pannable, zoomable, minZoom, maxZoom, panning, setPanning, transformation, setTransformation, initialFocusPoint, className, children, }: SvgViewportProps) => React.JSX.Element;
52
+ /**
53
+ * SVG Viewport component that supports panning and zooming.
54
+ */
55
+ declare const SvgViewport: ({ width, height, pannable, zoomable, minZoom, maxZoom, transformation: externalTransformation, onTransformationChange, initialFocusPoint, style, children, ...otherProps }: SvgViewportProps) => react_jsx_runtime.JSX.Element;
26
56
 
27
57
  export { SvgViewport as default };
package/dist/index.js CHANGED
@@ -1,110 +1,145 @@
1
1
  "use client";
2
- import React, { useState, useRef, useEffect, useCallback } from 'react';
3
2
 
3
+ // src/components/SvgViewport.tsx
4
+ import { useCallback, useEffect, useRef, useState } from "react";
5
+
6
+ // src/core/matrix.ts
4
7
  function transform(matrix) {
5
- if (!matrix)
6
- return undefined;
7
- const { a, b, c, d, e, f } = matrix;
8
- return `matrix(${a}, ${b}, ${c}, ${d}, ${e}, ${f})`;
8
+ if (!matrix) return void 0;
9
+ const { a, b, c, d, e, f } = matrix;
10
+ return `matrix(${a}, ${b}, ${c}, ${d}, ${e}, ${f})`;
9
11
  }
10
12
  function focusTo(matrix, { x, y }, width, height, zoom) {
11
- return matrix.translate(((width / 2) / zoom) - x - (matrix.m41 / zoom), ((height / 2) / zoom) - y - (matrix.m42 / zoom));
13
+ return matrix.translate(
14
+ width / 2 / zoom - x - matrix.m41 / zoom,
15
+ height / 2 / zoom - y - matrix.m42 / zoom
16
+ );
12
17
  }
13
18
  function adjustWithZoom(matrix, scale, svgElement, eX, eY) {
14
- const rect = svgElement.getBoundingClientRect();
15
- const focusPoint = new DOMPoint(eX - rect.left, eY - rect.top);
16
- const relativePoint = focusPoint.matrixTransform(matrix.inverse());
17
- const modifier = new DOMMatrix()
18
- .translate(relativePoint.x, relativePoint.y)
19
- .scale(scale)
20
- .translate(-relativePoint.x, -relativePoint.y);
21
- return matrix.multiply(modifier);
19
+ const rect = svgElement.getBoundingClientRect();
20
+ const focusPoint = new DOMPoint(eX - rect.left, eY - rect.top);
21
+ const relativePoint = focusPoint.matrixTransform(matrix.inverse());
22
+ const modifier = new DOMMatrix().translate(relativePoint.x, relativePoint.y).scale(scale).translate(-relativePoint.x, -relativePoint.y);
23
+ return matrix.multiply(modifier);
22
24
  }
23
25
 
26
+ // src/core/initial-focus.ts
24
27
  function getFocusedMatrix(focusPoint, width, height) {
25
- switch (focusPoint) {
26
- case "center":
27
- return focusTo(new DOMMatrix(), { x: 0, y: 0 }, width, height, 1);
28
- case "top-left":
29
- return focusTo(new DOMMatrix(), { x: 0, y: 0 }, 0, 0, 1);
30
- }
31
- }
32
-
33
- function usePolyfillState(state, dispatch) {
34
- const [polyfill, setPolyfill] = useState(state);
35
- if (dispatch) {
36
- return [state, dispatch];
37
- }
38
- return [polyfill, setPolyfill];
28
+ switch (focusPoint) {
29
+ case "center":
30
+ return focusTo(new DOMMatrix(), { x: 0, y: 0 }, width, height, 1);
31
+ case "top-left":
32
+ return focusTo(new DOMMatrix(), { x: 0, y: 0 }, 0, 0, 1);
33
+ }
39
34
  }
40
35
 
41
- const SvgViewport = ({ width, height, pannable = false, zoomable = false, minZoom = 0.5, maxZoom = 2, panning = false, setPanning, transformation = null, setTransformation, initialFocusPoint = "center", className, children, }) => {
42
- const pointer = useRef({ x: 0, y: 0 });
43
- const [grabbing, setGrabbing] = useState(false);
44
- const [activeTransformation, activeSetTransformation] = usePolyfillState(transformation, setTransformation);
45
- const [activePanning, setActivePanning] = usePolyfillState(panning, setPanning);
46
- const stopGrabbing = () => {
47
- setGrabbing(false);
48
- };
49
- useEffect(() => {
50
- if (setTransformation)
51
- return;
52
- activeSetTransformation({
53
- zoom: 1,
54
- matrix: getFocusedMatrix(initialFocusPoint, width, height),
55
- });
56
- }, [setTransformation]);
57
- // panning
58
- const down = (e) => {
59
- if (e.button === 0) {
60
- pointer.current = {
61
- x: e.clientX,
62
- y: e.clientY,
63
- };
64
- setActivePanning(true);
65
- }
66
- setGrabbing(true);
36
+ // src/components/SvgViewport.tsx
37
+ import { jsx } from "react/jsx-runtime";
38
+ var SvgViewport = ({
39
+ width,
40
+ height,
41
+ pannable = false,
42
+ zoomable = false,
43
+ minZoom = 0.5,
44
+ maxZoom = 2,
45
+ transformation: externalTransformation,
46
+ onTransformationChange,
47
+ initialFocusPoint = "center",
48
+ style,
49
+ children,
50
+ ...otherProps
51
+ }) => {
52
+ const isControlled = externalTransformation !== void 0;
53
+ const [internalTransformation, setInternalTransformation] = useState(() => {
54
+ if (isControlled) return null;
55
+ return {
56
+ zoom: 1,
57
+ matrix: getFocusedMatrix(initialFocusPoint, width, height)
67
58
  };
68
- const move = useCallback((e) => {
69
- if (activePanning && activeTransformation) {
70
- const x = (e.clientX - pointer.current.x) / activeTransformation.zoom;
71
- const y = (e.clientY - pointer.current.y) / activeTransformation.zoom;
72
- pointer.current = {
73
- x: e.clientX,
74
- y: e.clientY,
75
- };
76
- activeSetTransformation(t => (t ? Object.assign(Object.assign({}, t), { matrix: t.matrix.translate(x, y) }) : t));
77
- }
78
- }, [activePanning, activeTransformation]);
79
- const up = useCallback(() => {
80
- setActivePanning(false);
81
- }, []);
82
- useEffect(() => {
83
- if (activePanning) {
84
- document.addEventListener("mousemove", move);
85
- document.addEventListener("mouseup", up);
86
- }
87
- return () => {
88
- document.removeEventListener("mousemove", move);
89
- document.removeEventListener("mouseup", up);
90
- };
91
- }, [activePanning]);
92
- // zooming
93
- const adjustZoom = (e) => {
94
- const scale = e.deltaY < 0 ? 1.25 : 0.8;
95
- const eventTarget = e.currentTarget;
96
- const eventClientX = e.clientX;
97
- const eventClientY = e.clientY;
98
- activeSetTransformation(t => {
99
- if (t && t.zoom * scale > minZoom && t.zoom * scale < maxZoom) {
100
- return Object.assign(Object.assign({}, t), { zoom: t.zoom * scale, matrix: adjustWithZoom(t.matrix, scale, eventTarget, eventClientX, eventClientY) });
101
- }
102
- return t;
103
- });
59
+ });
60
+ const transformation = isControlled ? externalTransformation : internalTransformation;
61
+ const transformationRef = useRef(transformation);
62
+ useEffect(() => {
63
+ transformationRef.current = transformation;
64
+ }, [transformation]);
65
+ const pointer = useRef({ x: 0, y: 0 });
66
+ const [grabbing, setGrabbing] = useState(false);
67
+ const [isPanning, setIsPanning] = useState(false);
68
+ const setTransformation = useCallback((value) => {
69
+ if (!isControlled) {
70
+ setInternalTransformation(value);
71
+ }
72
+ onTransformationChange?.(value);
73
+ }, [isControlled, onTransformationChange]);
74
+ const stopGrabbing = () => {
75
+ setGrabbing(false);
76
+ };
77
+ const down = (e) => {
78
+ if (e.button !== 0) return;
79
+ pointer.current = { x: e.clientX, y: e.clientY };
80
+ setIsPanning(true);
81
+ setGrabbing(true);
82
+ };
83
+ const move = useCallback((e) => {
84
+ const currentTrans = transformationRef.current;
85
+ if (currentTrans) {
86
+ const x = (e.clientX - pointer.current.x) / currentTrans.zoom;
87
+ const y = (e.clientY - pointer.current.y) / currentTrans.zoom;
88
+ pointer.current = { x: e.clientX, y: e.clientY };
89
+ setTransformation({
90
+ ...currentTrans,
91
+ matrix: currentTrans.matrix.translate(x, y)
92
+ });
93
+ }
94
+ }, [setTransformation]);
95
+ const up = useCallback(() => {
96
+ setIsPanning(false);
97
+ setGrabbing(false);
98
+ }, []);
99
+ useEffect(() => {
100
+ if (isPanning) {
101
+ document.addEventListener("mousemove", move);
102
+ document.addEventListener("mouseup", up);
103
+ }
104
+ return () => {
105
+ document.removeEventListener("mousemove", move);
106
+ document.removeEventListener("mouseup", up);
104
107
  };
105
- const cursor = pannable ? ((grabbing || panning) ? "grabbing" : "grab") : "auto";
106
- return (React.createElement("svg", { width: width, height: height, onMouseDown: pannable ? down : undefined, onMouseUp: pannable ? stopGrabbing : undefined, onMouseLeave: pannable ? stopGrabbing : undefined, onWheel: zoomable ? adjustZoom : undefined, onContextMenu: e => e.preventDefault(), className: className, style: { cursor } },
107
- React.createElement("g", { transform: transform(activeTransformation === null || activeTransformation === void 0 ? void 0 : activeTransformation.matrix) }, activeTransformation && children)));
108
+ }, [isPanning, move, up]);
109
+ const adjustZoom = (e) => {
110
+ if (!zoomable) return;
111
+ e.preventDefault();
112
+ const scale = e.deltaY < 0 ? 1.25 : 0.8;
113
+ const eventTarget = e.currentTarget;
114
+ const { clientX, clientY } = e;
115
+ if (transformation && transformation.zoom * scale > minZoom && transformation.zoom * scale < maxZoom) {
116
+ setTransformation({
117
+ zoom: transformation.zoom * scale,
118
+ matrix: adjustWithZoom(transformation.matrix, scale, eventTarget, clientX, clientY)
119
+ });
120
+ }
121
+ };
122
+ const cursor = pannable ? grabbing ? "grabbing" : "grab" : "auto";
123
+ return /* @__PURE__ */ jsx(
124
+ "svg",
125
+ {
126
+ width,
127
+ height,
128
+ onMouseDown: pannable ? down : void 0,
129
+ onMouseUp: pannable ? stopGrabbing : void 0,
130
+ onMouseLeave: pannable ? stopGrabbing : void 0,
131
+ onWheel: zoomable ? adjustZoom : void 0,
132
+ onContextMenu: (e) => e.preventDefault(),
133
+ style: { ...style, cursor },
134
+ ...otherProps,
135
+ children: /* @__PURE__ */ jsx("g", { transform: transform(transformation?.matrix), children: transformation && children })
136
+ }
137
+ );
108
138
  };
139
+ var SvgViewport_default = SvgViewport;
109
140
 
110
- export { SvgViewport as default };
141
+ // src/index.ts
142
+ var index_default = SvgViewport_default;
143
+ export {
144
+ index_default as default
145
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omer-x/svg-viewport",
3
- "version": "0.3.1",
3
+ "version": "2.0.0",
4
4
  "description": "Provides a simple React component for displaying SVG content with zooming and panning capabilities",
5
5
  "keywords": [
6
6
  "react",
@@ -23,9 +23,6 @@
23
23
  "publishConfig": {
24
24
  "access": "public"
25
25
  },
26
- "files": [
27
- "dist/"
28
- ],
29
26
  "author": {
30
27
  "name": "Omer Mecitoglu",
31
28
  "email": "omer.mecitoglu@gmail.com",
@@ -33,28 +30,35 @@
33
30
  },
34
31
  "license": "MIT",
35
32
  "type": "module",
36
- "main": "./dist/index.js",
37
- "types": "./dist/index.d.ts",
33
+ "files": [
34
+ "dist/"
35
+ ],
36
+ "exports": {
37
+ ".": {
38
+ "types": "./dist/index.d.ts",
39
+ "import": "./dist/index.js",
40
+ "require": "./dist/index.cjs"
41
+ }
42
+ },
38
43
  "scripts": {
39
- "check-unused-exports": "ts-unused-exports tsconfig.json --excludePathsFromReport='src/index'",
40
- "prebuild": "npm run check-unused-exports && tsc",
41
- "postbuild": "rimraf dist/build",
42
- "build": "rollup --config"
44
+ "lint": "eslint --flag unstable_native_nodejs_ts_config",
45
+ "lint:fix": "eslint --fix --flag unstable_native_nodejs_ts_config",
46
+ "test": "vitest run --coverage",
47
+ "test:watch": "vitest --coverage",
48
+ "dev": "tsup --watch",
49
+ "build": "tsup"
43
50
  },
44
- "dependencies": {
45
- "react": "^18.2.0"
51
+ "peerDependencies": {
52
+ "react": "^19"
46
53
  },
47
54
  "devDependencies": {
48
- "@omer-x/eslint-config": "^1.0.5",
49
- "@rollup/plugin-alias": "^5.1.0",
50
- "@rollup/plugin-typescript": "^11.1.6",
51
- "@types/react": "^18.2.55",
52
- "eslint": "^8.56.0",
53
- "rollup": "^4.12.0",
54
- "rollup-plugin-banner2": "^1.2.2",
55
- "rollup-plugin-dts": "^6.1.0",
56
- "ts-unused-exports": "^10.0.1",
57
- "tslib": "^2.6.2",
58
- "typescript": "^5.3.3"
55
+ "@omer-x/eslint-config": "^2.2.6",
56
+ "@types/react": "^19.2.10",
57
+ "@vitest/coverage-v8": "^4.0.18",
58
+ "eslint": "^9.39.2",
59
+ "semantic-release": "^25.0.3",
60
+ "tsup": "^8.5.1",
61
+ "typescript": "^5.9.3",
62
+ "vitest": "^4.0.18"
59
63
  }
60
64
  }