@pie-lib/tools 2.0.2-next.1 → 2.0.3-next.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/_virtual/_rolldown/runtime.js +11 -0
- package/dist/anchor-utils.d.ts +60 -0
- package/dist/anchor-utils.js +87 -0
- package/dist/anchor.d.ts +13 -0
- package/dist/anchor.js +17 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +5 -0
- package/dist/node_modules/.bun/assert@1.5.1/node_modules/assert/assert.js +174 -0
- package/dist/node_modules/.bun/call-bind-apply-helpers@1.0.2/node_modules/call-bind-apply-helpers/actualApply.js +13 -0
- package/dist/node_modules/.bun/call-bind-apply-helpers@1.0.2/node_modules/call-bind-apply-helpers/functionApply.js +8 -0
- package/dist/node_modules/.bun/call-bind-apply-helpers@1.0.2/node_modules/call-bind-apply-helpers/functionCall.js +8 -0
- package/dist/node_modules/.bun/call-bind-apply-helpers@1.0.2/node_modules/call-bind-apply-helpers/index.js +16 -0
- package/dist/node_modules/.bun/call-bind-apply-helpers@1.0.2/node_modules/call-bind-apply-helpers/reflectApply.js +8 -0
- package/dist/node_modules/.bun/call-bound@1.0.4/node_modules/call-bound/index.js +14 -0
- package/dist/node_modules/.bun/degrees-radians@1.0.3/node_modules/degrees-radians/index.js +12 -0
- package/dist/node_modules/.bun/dunder-proto@1.0.1/node_modules/dunder-proto/get.js +19 -0
- package/dist/node_modules/.bun/es-define-property@1.0.1/node_modules/es-define-property/index.js +14 -0
- package/dist/node_modules/.bun/es-errors@1.3.0/node_modules/es-errors/eval.js +8 -0
- package/dist/node_modules/.bun/es-errors@1.3.0/node_modules/es-errors/index.js +8 -0
- package/dist/node_modules/.bun/es-errors@1.3.0/node_modules/es-errors/range.js +8 -0
- package/dist/node_modules/.bun/es-errors@1.3.0/node_modules/es-errors/ref.js +8 -0
- package/dist/node_modules/.bun/es-errors@1.3.0/node_modules/es-errors/syntax.js +8 -0
- package/dist/node_modules/.bun/es-errors@1.3.0/node_modules/es-errors/type.js +8 -0
- package/dist/node_modules/.bun/es-errors@1.3.0/node_modules/es-errors/uri.js +8 -0
- package/dist/node_modules/.bun/es-object-atoms@1.1.2/node_modules/es-object-atoms/index.js +8 -0
- package/dist/node_modules/.bun/function-bind@1.1.2/node_modules/function-bind/implementation.js +34 -0
- package/dist/node_modules/.bun/function-bind@1.1.2/node_modules/function-bind/index.js +10 -0
- package/dist/node_modules/.bun/get-intrinsic@1.3.0/node_modules/get-intrinsic/index.js +283 -0
- package/dist/node_modules/.bun/get-proto@1.0.1/node_modules/get-proto/Object.getPrototypeOf.js +9 -0
- package/dist/node_modules/.bun/get-proto@1.0.1/node_modules/get-proto/Reflect.getPrototypeOf.js +8 -0
- package/dist/node_modules/.bun/get-proto@1.0.1/node_modules/get-proto/index.js +19 -0
- package/dist/node_modules/.bun/gopd@1.2.0/node_modules/gopd/gOPD.js +8 -0
- package/dist/node_modules/.bun/gopd@1.2.0/node_modules/gopd/index.js +15 -0
- package/dist/node_modules/.bun/has-symbols@1.1.0/node_modules/has-symbols/index.js +12 -0
- package/dist/node_modules/.bun/has-symbols@1.1.0/node_modules/has-symbols/shams.js +23 -0
- package/dist/node_modules/.bun/hasown@2.0.4/node_modules/hasown/index.js +10 -0
- package/dist/node_modules/.bun/inherits@2.0.3/node_modules/inherits/inherits_browser.js +19 -0
- package/dist/node_modules/.bun/math-intrinsics@1.1.0/node_modules/math-intrinsics/abs.js +8 -0
- package/dist/node_modules/.bun/math-intrinsics@1.1.0/node_modules/math-intrinsics/floor.js +8 -0
- package/dist/node_modules/.bun/math-intrinsics@1.1.0/node_modules/math-intrinsics/isNaN.js +10 -0
- package/dist/node_modules/.bun/math-intrinsics@1.1.0/node_modules/math-intrinsics/max.js +8 -0
- package/dist/node_modules/.bun/math-intrinsics@1.1.0/node_modules/math-intrinsics/min.js +8 -0
- package/dist/node_modules/.bun/math-intrinsics@1.1.0/node_modules/math-intrinsics/pow.js +8 -0
- package/dist/node_modules/.bun/math-intrinsics@1.1.0/node_modules/math-intrinsics/round.js +8 -0
- package/dist/node_modules/.bun/math-intrinsics@1.1.0/node_modules/math-intrinsics/sign.js +12 -0
- package/dist/node_modules/.bun/object-keys@1.1.1/node_modules/object-keys/implementation.js +77 -0
- package/dist/node_modules/.bun/object-keys@1.1.1/node_modules/object-keys/index.js +20 -0
- package/dist/node_modules/.bun/object-keys@1.1.1/node_modules/object-keys/isArguments.js +12 -0
- package/dist/node_modules/.bun/object.assign@4.1.7/node_modules/object.assign/implementation.js +29 -0
- package/dist/node_modules/.bun/object.assign@4.1.7/node_modules/object.assign/polyfill.js +27 -0
- package/dist/node_modules/.bun/radians-degrees@1.0.0/node_modules/radians-degrees/index.js +11 -0
- package/dist/node_modules/.bun/react-portal@4.3.0_6dbf9a050bc9aadb/node_modules/react-portal/es/LegacyPortal.js +77 -0
- package/dist/node_modules/.bun/react-portal@4.3.0_6dbf9a050bc9aadb/node_modules/react-portal/es/Portal.js +55 -0
- package/dist/node_modules/.bun/react-portal@4.3.0_6dbf9a050bc9aadb/node_modules/react-portal/es/PortalCompat.js +9 -0
- package/dist/node_modules/.bun/react-portal@4.3.0_6dbf9a050bc9aadb/node_modules/react-portal/es/utils.js +4 -0
- package/dist/node_modules/.bun/trigonometry-calculator@2.0.0/node_modules/trigonometry-calculator/lib/index.js +53 -0
- package/dist/node_modules/.bun/trigonometry-equations@2.0.1/node_modules/trigonometry-equations/lib/index.js +129 -0
- package/dist/node_modules/.bun/util@0.10.4/node_modules/util/support/isBufferBrowser.js +10 -0
- package/dist/node_modules/.bun/util@0.10.4/node_modules/util/util.js +262 -0
- package/dist/protractor/graphic.d.ts +13 -0
- package/dist/protractor/graphic.js +85 -0
- package/dist/protractor/index.d.ts +29 -0
- package/dist/protractor/index.js +56 -0
- package/dist/rotatable.d.ts +56 -0
- package/dist/rotatable.js +210 -0
- package/dist/ruler/graphic.d.ts +20 -0
- package/dist/ruler/graphic.js +53 -0
- package/dist/ruler/index.d.ts +32 -0
- package/dist/ruler/index.js +77 -0
- package/dist/ruler/unit-type.d.ts +30 -0
- package/dist/ruler/unit-type.js +38 -0
- package/dist/ruler/unit.d.ts +21 -0
- package/dist/ruler/unit.js +69 -0
- package/dist/style-utils.d.ts +12 -0
- package/dist/style-utils.js +5 -0
- package/dist/transform-origin.d.ts +18 -0
- package/dist/transform-origin.js +21 -0
- package/package.json +31 -25
- package/CHANGELOG.json +0 -1
- package/CHANGELOG.md +0 -622
- package/LICENSE.md +0 -5
- package/lib/anchor-utils.js +0 -193
- package/lib/anchor-utils.js.map +0 -1
- package/lib/anchor.js +0 -33
- package/lib/anchor.js.map +0 -1
- package/lib/index.js +0 -33
- package/lib/index.js.map +0 -1
- package/lib/protractor/graphic.js +0 -147
- package/lib/protractor/graphic.js.map +0 -1
- package/lib/protractor/index.js +0 -90
- package/lib/protractor/index.js.map +0 -1
- package/lib/rotatable.js +0 -335
- package/lib/rotatable.js.map +0 -1
- package/lib/ruler/graphic.js +0 -89
- package/lib/ruler/graphic.js.map +0 -1
- package/lib/ruler/index.js +0 -114
- package/lib/ruler/index.js.map +0 -1
- package/lib/ruler/unit-type.js +0 -55
- package/lib/ruler/unit-type.js.map +0 -1
- package/lib/ruler/unit.js +0 -124
- package/lib/ruler/unit.js.map +0 -1
- package/lib/style-utils.js +0 -21
- package/lib/style-utils.js.map +0 -1
- package/lib/transform-origin.js +0 -71
- package/lib/transform-origin.js.map +0 -1
- package/src/__tests__/anchor-utils.test.js +0 -131
- package/src/__tests__/rotatable.test.jsx +0 -263
- package/src/__tests__/transform-origin.test.jsx +0 -24
- package/src/anchor-utils.js +0 -153
- package/src/anchor.jsx +0 -20
- package/src/index.js +0 -6
- package/src/protractor/__tests__/graphic.test.jsx +0 -64
- package/src/protractor/__tests__/index.test.jsx +0 -65
- package/src/protractor/graphic.jsx +0 -82
- package/src/protractor/index.jsx +0 -67
- package/src/rotatable.jsx +0 -290
- package/src/ruler/__tests__/graphic.test.jsx +0 -64
- package/src/ruler/__tests__/index.test.jsx +0 -85
- package/src/ruler/__tests__/unit-type.test.jsx +0 -66
- package/src/ruler/__tests__/unit.test.jsx +0 -68
- package/src/ruler/graphic.jsx +0 -48
- package/src/ruler/index.jsx +0 -78
- package/src/ruler/unit-type.jsx +0 -39
- package/src/ruler/unit.jsx +0 -83
- package/src/style-utils.js +0 -7
- package/src/transform-origin.jsx +0 -60
package/src/protractor/index.jsx
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { styled } from '@mui/material/styles';
|
|
3
|
-
import PropTypes from 'prop-types';
|
|
4
|
-
import Graphic from './graphic';
|
|
5
|
-
import Anchor from '../anchor';
|
|
6
|
-
import Rotatable from '../rotatable';
|
|
7
|
-
|
|
8
|
-
const StyledProtractor = styled('div')(() => ({
|
|
9
|
-
position: 'relative',
|
|
10
|
-
}));
|
|
11
|
-
|
|
12
|
-
const StyledLeftAnchor = styled(Anchor)(() => ({
|
|
13
|
-
position: 'absolute',
|
|
14
|
-
left: 0,
|
|
15
|
-
bottom: 0,
|
|
16
|
-
}));
|
|
17
|
-
|
|
18
|
-
const StyledRightAnchor = styled(Anchor)(() => ({
|
|
19
|
-
position: 'absolute',
|
|
20
|
-
right: 0,
|
|
21
|
-
bottom: 0,
|
|
22
|
-
}));
|
|
23
|
-
|
|
24
|
-
export class Protractor extends React.Component {
|
|
25
|
-
static propTypes = {
|
|
26
|
-
width: PropTypes.number.isRequired,
|
|
27
|
-
className: PropTypes.string,
|
|
28
|
-
startPosition: PropTypes.shape({
|
|
29
|
-
left: PropTypes.number,
|
|
30
|
-
top: PropTypes.number,
|
|
31
|
-
}),
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
static defaultProps = {
|
|
35
|
-
width: 450,
|
|
36
|
-
startPosition: { left: 0, top: 0 },
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
render() {
|
|
40
|
-
const { width, startPosition } = this.props;
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<Rotatable
|
|
44
|
-
startPosition={startPosition}
|
|
45
|
-
handle={[
|
|
46
|
-
{
|
|
47
|
-
class: 'leftAnchor',
|
|
48
|
-
origin: `${width * 0.495}px ${width * 0.49}px`,
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
class: 'rightAnchor',
|
|
52
|
-
origin: `${width * 0.495}px ${width * 0.49}px`,
|
|
53
|
-
},
|
|
54
|
-
]}
|
|
55
|
-
>
|
|
56
|
-
<StyledProtractor style={{ width: `${width}px` }}>
|
|
57
|
-
<Graphic />
|
|
58
|
-
|
|
59
|
-
<StyledLeftAnchor className="leftAnchor" />
|
|
60
|
-
<StyledRightAnchor className="rightAnchor" />
|
|
61
|
-
</StyledProtractor>
|
|
62
|
-
</Rotatable>
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export default Protractor;
|
package/src/rotatable.jsx
DELETED
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import { styled } from '@mui/material/styles';
|
|
4
|
-
import { arctangent, distanceBetween, getAnchor as calcAnchor } from './anchor-utils';
|
|
5
|
-
import { Portal } from 'react-portal';
|
|
6
|
-
import Point from '@mapbox/point-geometry';
|
|
7
|
-
import { parse as parseOrigin } from './transform-origin';
|
|
8
|
-
|
|
9
|
-
const AnchorSvg = styled('svg')({
|
|
10
|
-
position: 'absolute',
|
|
11
|
-
zIndex: 100,
|
|
12
|
-
width: '200px',
|
|
13
|
-
height: '80px',
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
const Anchor = ({ left, top, color, fill }) => {
|
|
17
|
-
color = color || 'green';
|
|
18
|
-
fill = fill || 'white';
|
|
19
|
-
return (
|
|
20
|
-
<Portal>
|
|
21
|
-
<AnchorSvg
|
|
22
|
-
style={{
|
|
23
|
-
left: left - 10,
|
|
24
|
-
top: top - 10,
|
|
25
|
-
}}
|
|
26
|
-
>
|
|
27
|
-
<circle cx={10} cy={10} r={8} strokeWidth={1} stroke={color} fill={fill} />
|
|
28
|
-
</AnchorSvg>
|
|
29
|
-
</Portal>
|
|
30
|
-
);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Tip o' the hat to:
|
|
35
|
-
* https://bl.ocks.org/joyrexus/7207044
|
|
36
|
-
*/
|
|
37
|
-
const RotatableContainer = styled('div')({
|
|
38
|
-
position: 'relative',
|
|
39
|
-
display: 'inline-block',
|
|
40
|
-
cursor: 'move',
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
export class Rotatable extends React.Component {
|
|
44
|
-
static propTypes = {
|
|
45
|
-
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
|
|
46
|
-
showAnchor: PropTypes.bool,
|
|
47
|
-
handle: PropTypes.arrayOf(
|
|
48
|
-
PropTypes.shape({
|
|
49
|
-
class: PropTypes.string.isRequired,
|
|
50
|
-
origin: PropTypes.string,
|
|
51
|
-
}),
|
|
52
|
-
),
|
|
53
|
-
startPosition: PropTypes.shape({
|
|
54
|
-
left: PropTypes.number,
|
|
55
|
-
top: PropTypes.number,
|
|
56
|
-
}),
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
static defaultProps = {
|
|
60
|
-
showAnchor: false,
|
|
61
|
-
startPosition: { left: 0, top: 0 },
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
constructor(props) {
|
|
65
|
-
super(props);
|
|
66
|
-
this.state = {
|
|
67
|
-
isRotating: false,
|
|
68
|
-
rotation: 0,
|
|
69
|
-
startAngle: 0,
|
|
70
|
-
angle: 0,
|
|
71
|
-
position: {
|
|
72
|
-
left: props.startPosition.left,
|
|
73
|
-
top: props.startPosition.top,
|
|
74
|
-
},
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
componentWillUnmount() {
|
|
79
|
-
document.removeEventListener('mouseup', this.rotateStop);
|
|
80
|
-
document.removeEventListener('mousemove', this.drag);
|
|
81
|
-
document.removeEventListener('mousemove', this.rotate);
|
|
82
|
-
|
|
83
|
-
this.handles.forEach((h) => {
|
|
84
|
-
h.el.removeEventListener('mousedown', h.mousedownHandler);
|
|
85
|
-
h.el.removeEventListener('mouseup', this.rotateStop);
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
componentDidMount() {
|
|
90
|
-
this.addMouseUpHandler();
|
|
91
|
-
this.initHandles();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
initHandles = () => {
|
|
95
|
-
const { handle } = this.props;
|
|
96
|
-
|
|
97
|
-
if (Array.isArray(handle)) {
|
|
98
|
-
this.handles = [];
|
|
99
|
-
handle.forEach((h) => {
|
|
100
|
-
const el = this.rotatable.querySelector(`.${h.class}`);
|
|
101
|
-
|
|
102
|
-
if (el) {
|
|
103
|
-
const mousedownHandler = this.rotateStart(h.origin);
|
|
104
|
-
el.addEventListener('mousedown', mousedownHandler);
|
|
105
|
-
el.addEventListener('mouseup', this.rotateStop);
|
|
106
|
-
this.handles.push({ el, mousedownHandler });
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
addMouseUpHandler = () => {
|
|
113
|
-
document.addEventListener('mouseup', this.rotateStop);
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
originToXY = (origin) => {
|
|
117
|
-
const { clientWidth: width, clientHeight: height } = this.rotatable;
|
|
118
|
-
return parseOrigin({ width, height }, origin);
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Get the anchor point for the given element, origin and rotation.
|
|
123
|
-
* @returns {{left:number, top: number}} - the co-ordinates of the anchor point relative to the whole page.
|
|
124
|
-
*/
|
|
125
|
-
getAnchor = (origin) => {
|
|
126
|
-
const { rotation } = this.state;
|
|
127
|
-
const { clientWidth, clientHeight } = this.rotatable;
|
|
128
|
-
const { top, left } = this.rotatable.getBoundingClientRect();
|
|
129
|
-
const xy = this.originToXY(origin);
|
|
130
|
-
const { top: anchorTop, left: anchorLeft } = calcAnchor(
|
|
131
|
-
{
|
|
132
|
-
width: clientWidth,
|
|
133
|
-
height: clientHeight,
|
|
134
|
-
},
|
|
135
|
-
xy,
|
|
136
|
-
rotation,
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
return {
|
|
140
|
-
top: top + anchorTop,
|
|
141
|
-
left: left + anchorLeft,
|
|
142
|
-
};
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
rotateStart = (origin) => (e) => {
|
|
146
|
-
const { isRotating } = this.state;
|
|
147
|
-
if (isRotating) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
e.preventDefault();
|
|
152
|
-
|
|
153
|
-
const anchor = this.getAnchor(origin);
|
|
154
|
-
const { rotation } = this.state;
|
|
155
|
-
const { angle: startAngle } = this.getAngle(anchor, e);
|
|
156
|
-
|
|
157
|
-
let diff = { x: 0, y: 0 };
|
|
158
|
-
if (origin !== this.state.origin) {
|
|
159
|
-
const { clientWidth: width, clientHeight: height } = this.rotatable;
|
|
160
|
-
diff = distanceBetween({ width, height }, rotation, this.state.origin, origin);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
this.setState(
|
|
164
|
-
{
|
|
165
|
-
origin,
|
|
166
|
-
isRotating: true,
|
|
167
|
-
startAngle,
|
|
168
|
-
anchor,
|
|
169
|
-
position: {
|
|
170
|
-
left: this.state.position.left + diff.x,
|
|
171
|
-
top: this.state.position.top + diff.y,
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
() => {
|
|
175
|
-
document.addEventListener('mousemove', this.rotate);
|
|
176
|
-
},
|
|
177
|
-
);
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
rotateStop = (e) => {
|
|
181
|
-
const { isRotating } = this.state;
|
|
182
|
-
|
|
183
|
-
if (!isRotating) {
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
e.preventDefault();
|
|
188
|
-
|
|
189
|
-
this.setState(
|
|
190
|
-
{
|
|
191
|
-
isRotating: false,
|
|
192
|
-
angle: this.state.rotation,
|
|
193
|
-
anchor: null,
|
|
194
|
-
current: null,
|
|
195
|
-
},
|
|
196
|
-
() => {
|
|
197
|
-
document.removeEventListener('mousemove', this.rotate);
|
|
198
|
-
document.removeEventListener('mousemove', this.drag);
|
|
199
|
-
},
|
|
200
|
-
);
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
getAngle(anchor, e) {
|
|
204
|
-
const x = e.clientX - anchor.left;
|
|
205
|
-
const y = (e.clientY - anchor.top) * -1;
|
|
206
|
-
return { angle: arctangent(x, y), x, y };
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
rotate = (e) => {
|
|
210
|
-
const { isRotating } = this.state;
|
|
211
|
-
if (!isRotating) {
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
e.preventDefault();
|
|
216
|
-
|
|
217
|
-
const { startAngle, angle, anchor } = this.state;
|
|
218
|
-
const { angle: current, x, y } = this.getAngle(anchor, e);
|
|
219
|
-
const computedAnchor = { x, y };
|
|
220
|
-
const diff = current - startAngle;
|
|
221
|
-
const rotation = angle + diff;
|
|
222
|
-
this.setState({ rotation, diff, current, computedAnchor });
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
mouseDown = (e) => {
|
|
226
|
-
const handle = this.handles.find((h) => h.el === e.target);
|
|
227
|
-
|
|
228
|
-
if (!handle) {
|
|
229
|
-
this.dragStart(e);
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
dragStart = (e) => {
|
|
234
|
-
const dragPoint = new Point(e.pageX, e.pageY);
|
|
235
|
-
this.setState({ dragPoint }, () => {
|
|
236
|
-
document.addEventListener('mousemove', this.drag);
|
|
237
|
-
});
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
drag = (e) => {
|
|
241
|
-
e.preventDefault();
|
|
242
|
-
const current = new Point(e.pageX, e.pageY);
|
|
243
|
-
const translate = current.sub(this.state.dragPoint);
|
|
244
|
-
this.setState({ translate });
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
mouseUp = () => {
|
|
248
|
-
if (!this.state.translate) {
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const { position: lastPosition, translate } = this.state;
|
|
253
|
-
|
|
254
|
-
const position = {
|
|
255
|
-
left: lastPosition.left + translate.x,
|
|
256
|
-
top: lastPosition.top + translate.y,
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
document.removeEventListener('mousemove', this.drag);
|
|
260
|
-
this.setState({ position, dragPoint: null, translate: null });
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
render() {
|
|
264
|
-
const { children, showAnchor } = this.props;
|
|
265
|
-
const { rotation, anchor, origin, translate, position } = this.state;
|
|
266
|
-
|
|
267
|
-
const t = translate ? `translate(${translate.x}px, ${translate.y}px)` : '';
|
|
268
|
-
|
|
269
|
-
const style = {
|
|
270
|
-
left: position.left,
|
|
271
|
-
top: position.top,
|
|
272
|
-
transformOrigin: origin,
|
|
273
|
-
transform: `${t} rotate(${rotation}deg)`,
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
return (
|
|
277
|
-
<RotatableContainer
|
|
278
|
-
style={style}
|
|
279
|
-
ref={(r) => (this.rotatable = r)}
|
|
280
|
-
onMouseDown={this.mouseDown}
|
|
281
|
-
onMouseUp={this.mouseUp}
|
|
282
|
-
>
|
|
283
|
-
{anchor && showAnchor && <Anchor {...anchor} />}
|
|
284
|
-
{children}
|
|
285
|
-
</RotatableContainer>
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
export default Rotatable;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { render } from '@testing-library/react';
|
|
2
|
-
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
|
3
|
-
import { Graphic } from '../graphic';
|
|
4
|
-
import React from 'react';
|
|
5
|
-
|
|
6
|
-
describe('graphic', () => {
|
|
7
|
-
const theme = createTheme();
|
|
8
|
-
|
|
9
|
-
const renderComponent = (props = {}) => {
|
|
10
|
-
const defaultProps = {
|
|
11
|
-
width: 300,
|
|
12
|
-
height: 100,
|
|
13
|
-
units: 12,
|
|
14
|
-
unit: {
|
|
15
|
-
type: 'in',
|
|
16
|
-
ticks: 16,
|
|
17
|
-
},
|
|
18
|
-
...props,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
return render(
|
|
22
|
-
<ThemeProvider theme={theme}>
|
|
23
|
-
<Graphic {...defaultProps} />
|
|
24
|
-
</ThemeProvider>,
|
|
25
|
-
);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
describe('rendering', () => {
|
|
29
|
-
it('renders svg with correct viewBox', () => {
|
|
30
|
-
const { container } = renderComponent({ width: 300, height: 100 });
|
|
31
|
-
const svg = container.querySelector('svg');
|
|
32
|
-
expect(svg).toBeInTheDocument();
|
|
33
|
-
expect(svg).toHaveAttribute('viewBox', '0 0 300 100');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('renders background rect with correct dimensions', () => {
|
|
37
|
-
const { container } = renderComponent({ width: 300, height: 100 });
|
|
38
|
-
const rect = container.querySelector('rect');
|
|
39
|
-
expect(rect).toBeInTheDocument();
|
|
40
|
-
expect(rect).toHaveAttribute('width', '300');
|
|
41
|
-
expect(rect).toHaveAttribute('height', '100');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('renders correct number of unit markers', () => {
|
|
45
|
-
const { container } = renderComponent({ units: 12 });
|
|
46
|
-
const svg = container.querySelector('svg');
|
|
47
|
-
// Each unit renders as a group element with a specific structure
|
|
48
|
-
const groups = svg.querySelectorAll('g');
|
|
49
|
-
expect(groups.length).toBeGreaterThan(0);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('renders with different unit types', () => {
|
|
53
|
-
const { container } = renderComponent({ unit: { type: 'cm', ticks: 10 } });
|
|
54
|
-
const svg = container.querySelector('svg');
|
|
55
|
-
expect(svg).toBeInTheDocument();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('renders with custom dimensions', () => {
|
|
59
|
-
const { container } = renderComponent({ width: 480, height: 60, units: 10 });
|
|
60
|
-
const svg = container.querySelector('svg');
|
|
61
|
-
expect(svg).toHaveAttribute('viewBox', '0 0 480 60');
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
});
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
|
3
|
-
import { Ruler } from '../index';
|
|
4
|
-
import React from 'react';
|
|
5
|
-
|
|
6
|
-
// Mock the Rotatable component to avoid complex DOM interactions
|
|
7
|
-
jest.mock('../../rotatable', () => {
|
|
8
|
-
return function MockRotatable({ children }) {
|
|
9
|
-
return <div data-testid="rotatable">{children}</div>;
|
|
10
|
-
};
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
// Mock the RulerGraphic component to verify props
|
|
14
|
-
jest.mock('../graphic', () => {
|
|
15
|
-
return function MockRulerGraphic(props) {
|
|
16
|
-
return <div data-testid="ruler-graphic" data-unit={JSON.stringify(props.unit)} />;
|
|
17
|
-
};
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
describe('ruler', () => {
|
|
21
|
-
const theme = createTheme();
|
|
22
|
-
|
|
23
|
-
const renderComponent = (props = {}) => {
|
|
24
|
-
const defaultProps = {
|
|
25
|
-
units: 12,
|
|
26
|
-
measure: 'imperial',
|
|
27
|
-
...props,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
return render(
|
|
31
|
-
<ThemeProvider theme={theme}>
|
|
32
|
-
<Ruler {...defaultProps} />
|
|
33
|
-
</ThemeProvider>,
|
|
34
|
-
);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
describe('rendering', () => {
|
|
38
|
-
it('renders ruler component', () => {
|
|
39
|
-
renderComponent();
|
|
40
|
-
expect(screen.getByTestId('rotatable')).toBeInTheDocument();
|
|
41
|
-
expect(screen.getByTestId('ruler-graphic')).toBeInTheDocument();
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('renders with default props', () => {
|
|
45
|
-
renderComponent();
|
|
46
|
-
const graphic = screen.getByTestId('ruler-graphic');
|
|
47
|
-
expect(graphic).toBeInTheDocument();
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('renders with custom startPosition', () => {
|
|
51
|
-
renderComponent({ startPosition: { left: 100, top: 200 } });
|
|
52
|
-
expect(screen.getByTestId('ruler-graphic')).toBeInTheDocument();
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
describe('logic', () => {
|
|
57
|
-
it('sets unit for imperial', () => {
|
|
58
|
-
renderComponent({ measure: 'imperial', label: 'in' });
|
|
59
|
-
const graphic = screen.getByTestId('ruler-graphic');
|
|
60
|
-
const unit = JSON.parse(graphic.getAttribute('data-unit'));
|
|
61
|
-
expect(unit).toEqual({ ticks: 16, type: 'in' });
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('sets unit for metric', () => {
|
|
65
|
-
renderComponent({ measure: 'metric', label: 'cm' });
|
|
66
|
-
const graphic = screen.getByTestId('ruler-graphic');
|
|
67
|
-
const unit = JSON.parse(graphic.getAttribute('data-unit'));
|
|
68
|
-
expect(unit).toEqual({ ticks: 10, type: 'cm' });
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('sets custom tick count for imperial when divisible by 4', () => {
|
|
72
|
-
renderComponent({ measure: 'imperial', label: 'in', tickCount: 8 });
|
|
73
|
-
const graphic = screen.getByTestId('ruler-graphic');
|
|
74
|
-
const unit = JSON.parse(graphic.getAttribute('data-unit'));
|
|
75
|
-
expect(unit).toEqual({ ticks: 8, type: 'in' });
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('defaults to 16 ticks for imperial when tickCount not divisible by 4', () => {
|
|
79
|
-
renderComponent({ measure: 'imperial', label: 'in', tickCount: 7 });
|
|
80
|
-
const graphic = screen.getByTestId('ruler-graphic');
|
|
81
|
-
const unit = JSON.parse(graphic.getAttribute('data-unit'));
|
|
82
|
-
expect(unit).toEqual({ ticks: 16, type: 'in' });
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
});
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { render } from '@testing-library/react';
|
|
2
|
-
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
|
3
|
-
import { UnitType } from '../unit-type';
|
|
4
|
-
import React from 'react';
|
|
5
|
-
|
|
6
|
-
describe('unit-type', () => {
|
|
7
|
-
const theme = createTheme();
|
|
8
|
-
|
|
9
|
-
const renderComponent = (props = {}) => {
|
|
10
|
-
const defaultProps = {
|
|
11
|
-
label: 'cm',
|
|
12
|
-
...props,
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
return render(
|
|
16
|
-
<ThemeProvider theme={theme}>
|
|
17
|
-
<svg>
|
|
18
|
-
<UnitType {...defaultProps} />
|
|
19
|
-
</svg>
|
|
20
|
-
</ThemeProvider>,
|
|
21
|
-
);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
describe('rendering', () => {
|
|
25
|
-
it('renders text element with label', () => {
|
|
26
|
-
const { container } = renderComponent({ label: 'cm' });
|
|
27
|
-
const text = container.querySelector('text');
|
|
28
|
-
expect(text).toBeInTheDocument();
|
|
29
|
-
expect(text).toHaveTextContent('cm');
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('renders with default position', () => {
|
|
33
|
-
const { container } = renderComponent();
|
|
34
|
-
const text = container.querySelector('text');
|
|
35
|
-
expect(text).toHaveAttribute('x', '8');
|
|
36
|
-
expect(text).toHaveAttribute('y', '14');
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('renders with custom position', () => {
|
|
40
|
-
const { container } = renderComponent({ x: 20, y: 30 });
|
|
41
|
-
const text = container.querySelector('text');
|
|
42
|
-
expect(text).toHaveAttribute('x', '20');
|
|
43
|
-
expect(text).toHaveAttribute('y', '30');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('renders with custom fontSize', () => {
|
|
47
|
-
const { container } = renderComponent({ fontSize: 16 });
|
|
48
|
-
const text = container.querySelector('text');
|
|
49
|
-
expect(text).toBeInTheDocument();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('renders with different labels', () => {
|
|
53
|
-
const { container, rerender } = renderComponent({ label: 'in' });
|
|
54
|
-
expect(container.querySelector('text')).toHaveTextContent('in');
|
|
55
|
-
|
|
56
|
-
rerender(
|
|
57
|
-
<ThemeProvider theme={theme}>
|
|
58
|
-
<svg>
|
|
59
|
-
<UnitType label="mm" />
|
|
60
|
-
</svg>
|
|
61
|
-
</ThemeProvider>,
|
|
62
|
-
);
|
|
63
|
-
expect(container.querySelector('text')).toHaveTextContent('mm');
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
});
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { render } from '@testing-library/react';
|
|
2
|
-
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
|
3
|
-
import { Unit } from '../unit';
|
|
4
|
-
import React from 'react';
|
|
5
|
-
|
|
6
|
-
describe('unit', () => {
|
|
7
|
-
const theme = createTheme();
|
|
8
|
-
|
|
9
|
-
const renderComponent = (props = {}) => {
|
|
10
|
-
const defaultProps = {
|
|
11
|
-
index: 2,
|
|
12
|
-
width: 30,
|
|
13
|
-
height: 20,
|
|
14
|
-
last: false,
|
|
15
|
-
config: { ticks: 10 },
|
|
16
|
-
...props,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
return render(
|
|
20
|
-
<ThemeProvider theme={theme}>
|
|
21
|
-
<svg>
|
|
22
|
-
<Unit {...defaultProps} />
|
|
23
|
-
</svg>
|
|
24
|
-
</ThemeProvider>,
|
|
25
|
-
);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
describe('rendering', () => {
|
|
29
|
-
it('renders group element with correct transform', () => {
|
|
30
|
-
const { container } = renderComponent({ index: 2, width: 30 });
|
|
31
|
-
const group = container.querySelector('g');
|
|
32
|
-
expect(group).toBeInTheDocument();
|
|
33
|
-
expect(group).toHaveStyle({ transform: 'translate(30px, 0px)' });
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('renders label with index value', () => {
|
|
37
|
-
const { container } = renderComponent({ index: 5 });
|
|
38
|
-
const text = container.querySelector('text');
|
|
39
|
-
expect(text).toHaveTextContent('5');
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('renders end tick when not last unit', () => {
|
|
43
|
-
const { container } = renderComponent({ last: false });
|
|
44
|
-
const lines = container.querySelectorAll('line');
|
|
45
|
-
// Should have end tick plus ticks based on config
|
|
46
|
-
expect(lines.length).toBeGreaterThan(0);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('does not render end tick when last unit', () => {
|
|
50
|
-
const { container } = renderComponent({ last: true });
|
|
51
|
-
const group = container.querySelector('g');
|
|
52
|
-
expect(group).toBeInTheDocument();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('renders correct number of tick marks', () => {
|
|
56
|
-
const { container } = renderComponent({ config: { ticks: 16 } });
|
|
57
|
-
const lines = container.querySelectorAll('line');
|
|
58
|
-
// Should render ticks based on config (16 ticks - 1 for range + 1 end tick = 16 total)
|
|
59
|
-
expect(lines.length).toBeGreaterThan(10);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('renders with different width', () => {
|
|
63
|
-
const { container } = renderComponent({ index: 3, width: 40 });
|
|
64
|
-
const group = container.querySelector('g');
|
|
65
|
-
expect(group).toHaveStyle({ transform: 'translate(80px, 0px)' });
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
});
|
package/src/ruler/graphic.jsx
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import { styled } from '@mui/material/styles';
|
|
4
|
-
import UnitType from './unit-type';
|
|
5
|
-
import { range } from 'lodash-es';
|
|
6
|
-
import Unit from './unit';
|
|
7
|
-
import { fillColor, strokeColor } from '../style-utils';
|
|
8
|
-
|
|
9
|
-
const StyledBg = styled('rect')(({ theme }) => ({
|
|
10
|
-
stroke: strokeColor(theme),
|
|
11
|
-
strokeWidth: '2px',
|
|
12
|
-
fill: fillColor(theme),
|
|
13
|
-
}));
|
|
14
|
-
|
|
15
|
-
const Bg = ({ width, height }) => <StyledBg width={width} height={height} cx={0} cy={0} />;
|
|
16
|
-
|
|
17
|
-
Bg.propTypes = {
|
|
18
|
-
width: PropTypes.number.isRequired,
|
|
19
|
-
height: PropTypes.number.isRequired,
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export class Graphic extends React.PureComponent {
|
|
23
|
-
static propTypes = {
|
|
24
|
-
width: PropTypes.number.isRequired,
|
|
25
|
-
height: PropTypes.number.isRequired,
|
|
26
|
-
units: PropTypes.number.isRequired,
|
|
27
|
-
unit: PropTypes.object.isRequired,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
render() {
|
|
31
|
-
const { width, height, units, unit } = this.props;
|
|
32
|
-
const viewBox = `0 0 ${width} ${height}`;
|
|
33
|
-
const unitWidth = width / units;
|
|
34
|
-
const unitHeight = height;
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<svg viewBox={viewBox}>
|
|
38
|
-
<Bg width={width} height={height} />
|
|
39
|
-
<UnitType label={unit.type} />
|
|
40
|
-
{range(1, units + 1).map((r) => (
|
|
41
|
-
<Unit width={unitWidth} height={unitHeight} key={r} index={r} config={unit} last={r === units} />
|
|
42
|
-
))}
|
|
43
|
-
</svg>
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export default Graphic;
|