Skip to content

Commit ab739dd

Browse files
committed
fix: fix ref props issue.
1 parent 6913d27 commit ab739dd

File tree

6 files changed

+47
-47
lines changed

6 files changed

+47
-47
lines changed

core/README.md

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,7 @@ import Signature from '@uiw/react-signature';
2222

2323
export default function App() {
2424
const $svg = useRef(null);
25-
const handle = (evn) => {
26-
const parentElement = $svg.current
27-
while (parentElement.firstChild) {
28-
parentElement.removeChild(parentElement.firstChild);
29-
}
30-
}
25+
const handle = (evn) => $svg.current?.clear();
3126
return (
3227
<>
3328
<Signature ref={$svg} />
@@ -65,16 +60,11 @@ import Signature from '@uiw/react-signature';
6560

6661
export default function App() {
6762
const $svg = useRef(null);
68-
const handle = (evn) => {
69-
const parentElement = $svg.current
70-
while (parentElement.firstChild) {
71-
parentElement.removeChild(parentElement.firstChild);
72-
}
73-
}
63+
const handle = (evn) => $svg.current?.clear();
7464
return (
7565
<>
7666
<Signature ref={$svg} fill="red" style={{ "--w-signature-background": "#e4e6ef" }} />
77-
<button onClick={() => handle()}>Clear</button>
67+
<button onClick={handle}>Clear</button>
7868
</>
7969
);
8070
}
@@ -90,10 +80,7 @@ export default function App() {
9080
const $svg = useRef(null);
9181
const [points, setPoints] = useState([])
9282
const handle = (evn) => {
93-
const parentElement = $svg.current
94-
while (parentElement.firstChild) {
95-
parentElement.removeChild(parentElement.firstChild);
96-
}
83+
$svg.current?.clear();
9784
setPoints([])
9885
}
9986
const handlePoints = (data) => {
@@ -146,13 +133,19 @@ export default function App() {
146133
```ts
147134
import React from 'react';
148135
import { type StrokeOptions } from 'perfect-freehand';
136+
import { type Dispatch } from '@uiw/react-signature';
149137
export interface SignatureProps extends React.SVGProps<SVGSVGElement> {
150138
prefixCls?: string;
151139
options?: StrokeOptions;
152140
readonly?: boolean;
153141
defaultPoints?: Record<string, number[][]>;
154142
onPointer?: (points: number[][]) => void;
155143
}
144+
export type SignatureRef = {
145+
svg: SVGSVGElement | null;
146+
dispatch: Dispatch;
147+
clear: () => void;
148+
};
156149
export default function Signature(props?: SignatureProps): React.JSX.Element;
157150
```
158151

core/src/Signature.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import React, { useEffect, useRef, useId, forwardRef, useImperativeHandle } from 'react';
2-
import { getStroke, type StrokeOptions } from 'perfect-freehand';
2+
import { type StrokeOptions } from 'perfect-freehand';
33
import { getBoundingClientRect, getClinetXY, defaultStyle, useEvent } from './utils';
44

55
import { useDispatch } from './store';
6+
import { SignatureRef } from './';
67

78
export interface SignatureProps extends React.SVGProps<SVGSVGElement> {
89
prefixCls?: string;
@@ -11,7 +12,7 @@ export interface SignatureProps extends React.SVGProps<SVGSVGElement> {
1112
onPointer?: (points: number[][]) => void;
1213
}
1314

14-
export const Signature = forwardRef<SVGSVGElement, SignatureProps>((props, ref) => {
15+
export const Signature = forwardRef<SignatureRef, SignatureProps>((props, ref) => {
1516
const {
1617
className,
1718
prefixCls = 'w-signature',
@@ -28,9 +29,12 @@ export const Signature = forwardRef<SVGSVGElement, SignatureProps>((props, ref)
2829
const pointsRef = useRef<number[][]>();
2930
const pointCount = useRef<number>(0);
3031
const pointId = useId();
31-
const distpatch = useDispatch();
32-
33-
useImperativeHandle<SVGSVGElement | null, SVGSVGElement | null>(ref, () => $svg.current, [$svg.current]);
32+
const dispatch = useDispatch();
33+
useImperativeHandle<SignatureRef, SignatureRef>(
34+
ref,
35+
() => ({ svg: $svg.current, dispatch, clear: () => dispatch({}) }),
36+
[$svg.current, dispatch],
37+
);
3438

3539
const handlePointerDown = useEvent((e: React.PointerEvent<SVGSVGElement>) => {
3640
if (readonly) return;
@@ -42,7 +46,7 @@ export const Signature = forwardRef<SVGSVGElement, SignatureProps>((props, ref)
4246
const pathElm = document.createElementNS('http://www.w3.org/2000/svg', 'path');
4347
$path.current = pathElm;
4448
$svg.current!.appendChild(pathElm);
45-
distpatch({
49+
dispatch({
4650
[pointId + pointCount.current]: pointsRef.current,
4751
});
4852
});
@@ -52,7 +56,7 @@ export const Signature = forwardRef<SVGSVGElement, SignatureProps>((props, ref)
5256
const { offsetY, offsetX } = getBoundingClientRect($svg.current);
5357
const { clientX, clientY } = getClinetXY(e);
5458
pointsRef.current = [...pointsRef.current!, [clientX - offsetX, clientY - offsetY]];
55-
distpatch({
59+
dispatch({
5660
[pointId + pointCount.current]: pointsRef.current,
5761
});
5862
}

core/src/index.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
import React, { useReducer, forwardRef, useEffect } from 'react';
22
import { type StrokeOptions } from 'perfect-freehand';
3-
import { PointerContext, PointerDispatchContext, reducer } from './store';
3+
import { PointerContext, PointerDispatchContext, reducer, type Dispatch } from './store';
44
import { OptionContext, OptionDispatchContext, reducerOption, defaultOptions } from './options';
55
import { Signature as Container } from './Signature';
66
import { Paths } from './Paths';
77

88
export * from 'perfect-freehand';
99
export * from './utils';
1010
export * from './options';
11+
export * from './store';
12+
13+
export type SignatureRef = {
14+
svg: SVGSVGElement | null;
15+
dispatch: Dispatch;
16+
clear: () => void;
17+
};
1118

1219
export interface SignatureProps extends React.SVGProps<SVGSVGElement> {
1320
prefixCls?: string;
@@ -18,7 +25,7 @@ export interface SignatureProps extends React.SVGProps<SVGSVGElement> {
1825
onPointer?: (points: number[][]) => void;
1926
}
2027

21-
const Signature = forwardRef<SVGSVGElement, SignatureProps>(
28+
const Signature = forwardRef<SignatureRef, SignatureProps>(
2229
({ children, options, renderPath, defaultPoints, ...props }, ref) => {
2330
const [state, dispatch] = useReducer(reducer, Object.assign({}, defaultPoints));
2431
const [stateOption, dispatchOption] = useReducer(

core/src/store.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ export const initialState: InitialState = {};
55
export const PointerContext = createContext<InitialState>(initialState);
66
export const PointerDispatchContext = createContext<Dispatch>(() => {});
77

8-
type Dispatch = React.Dispatch<InitialState>;
9-
8+
export type Dispatch = React.Dispatch<InitialState>;
109
type InitialState = Record<string, number[][]>;
1110

1211
export function reducer(tasks: InitialState, action: InitialState) {
12+
if (action && Object.keys(action).length === 0) return initialState;
1313
return { ...tasks, ...action };
1414
}
1515

package.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@
22
"private": true,
33
"scripts": {
44
"⬇️⬇️⬇️⬇️⬇️ package ⬇️⬇️⬇️⬇️⬇️": "▼▼▼▼▼ package ▼▼▼▼▼",
5-
"build": "lerna exec --scope @uiw/* -- tsbb build src/*.tsx --use-babel --cjs cjs --bail && npm run css:build && npm run css:build:dist",
6-
"watch": "lerna exec \"tsbb watch src/*.tsx --use-babel --cjs cjs\" --scope @uiw/* & npm run css:watch",
7-
"css:build": "lerna exec --scope @uiw/* -- compile-less -d src -o esm",
8-
"css:watch": "lerna exec --scope @uiw/* -- compile-less -d src -o esm --watch",
9-
"css:build:dist": "lerna exec --scope @uiw/* -- compile-less -d src -o lib --combine=dist.css",
5+
"build": "lerna exec --scope @uiw/* -- tsbb build src/*.tsx --use-babel --cjs cjs --bail",
6+
"watch": "lerna exec \"tsbb watch src/*.tsx --use-babel --cjs cjs\" --scope @uiw/*",
107
"bundle": "lerna exec --scope @uiw/* -- ncc build src/index.tsx --target web --filename dist",
118
"bundle:min": "lerna exec --scope @uiw/* -- ncc build src/index.tsx --target web --filename dist --minify",
129
"⬆️⬆️⬆️⬆️⬆️ package ⬆️⬆️⬆️⬆️⬆️": "▲▲▲▲▲ package ▲▲▲▲▲",

website/src/Example.tsx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useRef, useState } from 'react';
2-
import Signature, { defaultOptions, StrokeOptions } from '@uiw/react-signature';
2+
import Signature, { defaultOptions, type StrokeOptions, type SignatureRef } from '@uiw/react-signature';
33
import copyTextToClipboard from '@uiw/copy-to-clipboard';
44
import styled from 'styled-components';
55

@@ -101,6 +101,7 @@ const points1 = [
101101
[422.6171875, 174.94921875],
102102
[423.01953125, 175.1484375],
103103
];
104+
104105
const points2 = [
105106
[277.48828125, 62.6015625],
106107
[277.4453125, 62.64453125],
@@ -119,22 +120,18 @@ const points2 = [
119120
const points = { points1, points2 };
120121

121122
export const ExampleSignature = () => {
122-
const $svg = useRef<SVGSVGElement>(null);
123+
const $svg = useRef<SignatureRef>(null);
123124
const [options, setOptions] = useState<StrokeOptions>(defaultOptions);
124-
125125
const handle = (evn: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
126-
const parentElement = $svg.current as SVGSVGElement;
127-
while (parentElement.firstChild) {
128-
parentElement.removeChild(parentElement.firstChild);
129-
}
126+
$svg.current?.clear();
130127
};
131128

132129
const resetOption = () => setOptions(defaultOptions);
133130
const handleCopy = () => copyTextToClipboard(JSON.stringify(options, null, 2));
134131
const handleSVGCopy = () => {
135-
const svgelm = $svg.current?.cloneNode(true) as SVGSVGElement;
136-
const clientWidth = $svg.current?.clientWidth;
137-
const clientHeight = $svg.current?.clientHeight;
132+
const svgelm = $svg.current?.svg?.cloneNode(true) as SVGSVGElement;
133+
const clientWidth = $svg.current?.svg?.clientWidth;
134+
const clientHeight = $svg.current?.svg?.clientHeight;
138135
svgelm.removeAttribute('style');
139136
svgelm.setAttribute('width', `${clientWidth}px`);
140137
svgelm.setAttribute('height', `${clientHeight}px`);
@@ -150,10 +147,12 @@ export const ExampleSignature = () => {
150147
options={options}
151148
defaultPoints={points}
152149
/>
153-
<button onClick={handle}>Clear</button>
154-
<button onClick={resetOption}>Reset Options</button>
155-
<button onClick={handleCopy}>Copy Options</button>
156-
<button onClick={handleSVGCopy}>Copy to SVG</button>
150+
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '1rem', paddingTop: '0.46rem' }}>
151+
<button onClick={handle}>Clear</button>
152+
<button onClick={resetOption}>Reset Options</button>
153+
<button onClick={handleCopy}>Copy Options</button>
154+
<button onClick={handleSVGCopy}>Copy to SVG</button>
155+
</div>
157156
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '1rem', paddingTop: '1rem' }}>
158157
<label>
159158
<div>Size: {options.size}</div>

0 commit comments

Comments
 (0)