@dcg-overseas/number-line 0.1.4 → 0.1.6

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 DELETED
@@ -1,753 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const jsxRuntime = require("react/jsx-runtime");
4
- const React = require("react");
5
- function useHistory() {
6
- const stackRef = React.useRef([]);
7
- const [stackLen, setStackLen] = React.useState(0);
8
- const push = React.useCallback((op) => {
9
- stackRef.current = [...stackRef.current, op];
10
- setStackLen(stackRef.current.length);
11
- }, []);
12
- const undo = React.useCallback((strokes) => {
13
- if (stackRef.current.length === 0) return { strokes: null, arcIndices: [] };
14
- const op = stackRef.current[stackRef.current.length - 1];
15
- stackRef.current = stackRef.current.slice(0, -1);
16
- setStackLen(stackRef.current.length);
17
- switch (op.type) {
18
- case "add":
19
- return {
20
- strokes: strokes.filter((s) => !op.strokes.some((os) => os.id === s.id)),
21
- arcIndices: []
22
- };
23
- case "delete":
24
- return {
25
- strokes: op.strokesBefore,
26
- arcIndices: op.arcIndices
27
- };
28
- }
29
- }, []);
30
- const clear = React.useCallback(() => {
31
- stackRef.current = [];
32
- setStackLen(0);
33
- }, []);
34
- return { push, undo, clear, canUndo: stackLen > 0 };
35
- }
36
- function useDrawing() {
37
- const [strokes, setStrokes] = React.useState([]);
38
- const [tool, setTool] = React.useState("none");
39
- const drawing = React.useRef(false);
40
- const pointCount = React.useRef(0);
41
- const currentD = React.useRef("");
42
- const currentId = React.useRef("");
43
- const toggleTool = React.useCallback((t) => {
44
- setTool((prev) => {
45
- if (prev === t) return "none";
46
- return t;
47
- });
48
- setStrokes((prev) => prev.map((s) => ({ ...s, selected: false })));
49
- }, []);
50
- const startStroke = React.useCallback((x, y, w, h) => {
51
- drawing.current = true;
52
- pointCount.current = 1;
53
- const xN = w > 0 ? x / w : 0;
54
- const yN = h > 0 ? y / h : 0;
55
- currentD.current = `M ${xN} ${yN}`;
56
- currentId.current = `${Date.now()}-${Math.random()}`;
57
- }, []);
58
- const continueStroke = React.useCallback((x, y, w, h) => {
59
- if (!drawing.current) return null;
60
- pointCount.current++;
61
- const xN = w > 0 ? x / w : 0;
62
- const yN = h > 0 ? y / h : 0;
63
- currentD.current += ` L ${xN} ${yN}`;
64
- return {
65
- id: currentId.current,
66
- d: currentD.current,
67
- selected: false
68
- };
69
- }, []);
70
- const endStroke = React.useCallback(() => {
71
- if (!drawing.current) return null;
72
- drawing.current = false;
73
- if (pointCount.current < 2) {
74
- currentD.current = "";
75
- pointCount.current = 0;
76
- return null;
77
- }
78
- const stroke = {
79
- id: currentId.current,
80
- d: currentD.current,
81
- selected: false
82
- };
83
- currentD.current = "";
84
- pointCount.current = 0;
85
- return stroke;
86
- }, []);
87
- const toggleSelect = React.useCallback((id) => {
88
- setStrokes(
89
- (prev) => prev.map((s) => s.id === id ? { ...s, selected: !s.selected } : s)
90
- );
91
- }, []);
92
- const eraseStroke = React.useCallback((id) => {
93
- setStrokes((prev) => prev.filter((s) => s.id !== id));
94
- }, []);
95
- const addStroke = React.useCallback((stroke) => {
96
- setStrokes((prev) => [...prev, stroke]);
97
- }, []);
98
- const deleteSelected = React.useCallback(() => {
99
- setStrokes((prev) => prev.filter((s) => !s.selected));
100
- }, []);
101
- const resetStrokes = React.useCallback(() => {
102
- setStrokes([]);
103
- }, []);
104
- const restoreStrokes = React.useCallback((restored) => {
105
- setStrokes(restored);
106
- }, []);
107
- return {
108
- strokes,
109
- tool,
110
- toggleTool,
111
- startStroke,
112
- continueStroke,
113
- endStroke,
114
- toggleSelect,
115
- eraseStroke,
116
- addStroke,
117
- deleteSelected,
118
- resetStrokes,
119
- restoreStrokes
120
- };
121
- }
122
- function useContainerSize() {
123
- const ref = React.useRef(null);
124
- const [size, setSize] = React.useState({ width: 600, height: 200 });
125
- React.useLayoutEffect(() => {
126
- const el = ref.current;
127
- if (!el) return;
128
- const rect = el.getBoundingClientRect();
129
- if (rect.width > 0 && rect.height > 0) {
130
- setSize({ width: rect.width, height: rect.height });
131
- }
132
- }, []);
133
- React.useEffect(() => {
134
- const el = ref.current;
135
- if (!el) return;
136
- const ro = new ResizeObserver((entries) => {
137
- var _a;
138
- const rect = (_a = entries[0]) == null ? void 0 : _a.contentRect;
139
- if (rect && rect.width > 0 && rect.height > 0) {
140
- setSize({ width: rect.width, height: rect.height });
141
- }
142
- });
143
- ro.observe(el);
144
- return () => ro.disconnect();
145
- }, []);
146
- return { ref, width: size.width, height: size.height };
147
- }
148
- const NumberLineContext = React.createContext(null);
149
- function useNumberLineContext() {
150
- const ctx = React.useContext(NumberLineContext);
151
- if (!ctx) throw new Error("Must be used inside <NumberLineProvider>");
152
- return ctx;
153
- }
154
- function NumberLineProvider({
155
- min,
156
- max,
157
- groupSize,
158
- groupCount,
159
- tickStep,
160
- arcColors,
161
- showGroupTicks = true,
162
- showMajorTicks = true,
163
- showMinorTicks = false,
164
- children
165
- }) {
166
- const [selectedArcIndices, setSelectedArcIndices] = React.useState(/* @__PURE__ */ new Set());
167
- const [deletedArcIndices, setDeletedArcIndices] = React.useState(/* @__PURE__ */ new Set());
168
- const { ref: svgRef, width: containerWidth, height: containerHeight } = useContainerSize();
169
- const history = useHistory();
170
- const drawing = useDrawing();
171
- const [liveStroke, setLiveStroke] = React.useState(null);
172
- const svgPoint = React.useRef(null);
173
- React.useEffect(() => {
174
- setDeletedArcIndices(/* @__PURE__ */ new Set());
175
- setSelectedArcIndices(/* @__PURE__ */ new Set());
176
- }, [min, max, groupSize, groupCount]);
177
- const getLocalCoords = React.useCallback(
178
- (e) => {
179
- const svg = svgRef.current;
180
- if (!svg) return null;
181
- const ctm = svg.getScreenCTM();
182
- if (!ctm) return null;
183
- if (!svgPoint.current) svgPoint.current = svg.createSVGPoint();
184
- svgPoint.current.x = e.clientX;
185
- svgPoint.current.y = e.clientY;
186
- const pt = svgPoint.current.matrixTransform(ctm.inverse());
187
- return [pt.x, pt.y];
188
- },
189
- [svgRef]
190
- );
191
- const onPointerDown = React.useCallback(
192
- (e) => {
193
- e.currentTarget.focus();
194
- if (drawing.tool !== "pen") return;
195
- e.currentTarget.setPointerCapture(e.pointerId);
196
- const coords = getLocalCoords(e);
197
- if (!coords) return;
198
- drawing.startStroke(coords[0], coords[1], containerWidth, containerHeight);
199
- },
200
- [drawing, getLocalCoords, containerWidth, containerHeight]
201
- );
202
- const onPointerMove = React.useCallback(
203
- (e) => {
204
- if (drawing.tool !== "pen") return;
205
- const coords = getLocalCoords(e);
206
- if (!coords) return;
207
- const live = drawing.continueStroke(coords[0], coords[1], containerWidth, containerHeight);
208
- if (live) setLiveStroke(live);
209
- },
210
- [drawing, getLocalCoords, containerWidth, containerHeight]
211
- );
212
- const onPointerUp = React.useCallback(() => {
213
- if (drawing.tool !== "pen") return;
214
- const stroke = drawing.endStroke();
215
- setLiveStroke(null);
216
- if (stroke) {
217
- drawing.addStroke(stroke);
218
- history.push({ type: "add", strokes: [stroke] });
219
- }
220
- }, [drawing, history]);
221
- const onStrokeClick = React.useCallback(
222
- (id, e) => {
223
- e.stopPropagation();
224
- if (drawing.tool === "eraser") {
225
- const target = drawing.strokes.find((s) => s.id === id);
226
- if (target) {
227
- const strokesBefore = drawing.strokes;
228
- drawing.eraseStroke(id);
229
- history.push({ type: "delete", strokesBefore, arcIndices: [] });
230
- }
231
- } else if (drawing.tool === "none") {
232
- drawing.toggleSelect(id);
233
- }
234
- },
235
- [drawing, history]
236
- );
237
- const onArcClick = React.useCallback(
238
- (groupIndex, e) => {
239
- e.stopPropagation();
240
- if (drawing.tool === "eraser") {
241
- const strokesBefore = drawing.strokes;
242
- setDeletedArcIndices((prev) => /* @__PURE__ */ new Set([...prev, groupIndex]));
243
- history.push({ type: "delete", strokesBefore, arcIndices: [groupIndex] });
244
- } else if (drawing.tool === "none") {
245
- setSelectedArcIndices((prev) => {
246
- const next = new Set(prev);
247
- if (next.has(groupIndex)) next.delete(groupIndex);
248
- else next.add(groupIndex);
249
- return next;
250
- });
251
- }
252
- },
253
- [drawing.tool, drawing.strokes, history]
254
- );
255
- const clearArcSelection = React.useCallback(() => setSelectedArcIndices(/* @__PURE__ */ new Set()), []);
256
- const onDelete = React.useCallback(() => {
257
- const strokesBefore = drawing.strokes;
258
- const deletedStrokes = drawing.strokes.filter((s) => s.selected);
259
- const deletedArcs = [...selectedArcIndices];
260
- if (deletedStrokes.length === 0 && deletedArcs.length === 0) return;
261
- if (deletedStrokes.length > 0) drawing.deleteSelected();
262
- if (deletedArcs.length > 0) {
263
- setDeletedArcIndices((prev) => /* @__PURE__ */ new Set([...prev, ...deletedArcs]));
264
- setSelectedArcIndices(/* @__PURE__ */ new Set());
265
- }
266
- history.push({ type: "delete", strokesBefore, arcIndices: deletedArcs });
267
- }, [drawing, history, selectedArcIndices]);
268
- const onReset = React.useCallback(() => {
269
- drawing.resetStrokes();
270
- history.clear();
271
- setDeletedArcIndices(/* @__PURE__ */ new Set());
272
- setSelectedArcIndices(/* @__PURE__ */ new Set());
273
- }, [drawing, history]);
274
- const onUndo = React.useCallback(() => {
275
- const result = history.undo(drawing.strokes);
276
- if (result.strokes !== null) drawing.restoreStrokes(result.strokes);
277
- if (result.arcIndices.length > 0) {
278
- setDeletedArcIndices((prev) => {
279
- const next = new Set(prev);
280
- result.arcIndices.forEach((i) => next.delete(i));
281
- return next;
282
- });
283
- }
284
- }, [history, drawing]);
285
- const onTogglePen = React.useCallback(
286
- () => {
287
- drawing.toggleTool("pen");
288
- clearArcSelection();
289
- },
290
- [drawing, clearArcSelection]
291
- );
292
- const onToggleEraser = React.useCallback(
293
- () => {
294
- drawing.toggleTool("eraser");
295
- clearArcSelection();
296
- },
297
- [drawing, clearArcSelection]
298
- );
299
- const canDelete = drawing.strokes.some((s) => s.selected) || selectedArcIndices.size > 0;
300
- React.useEffect(() => {
301
- setSelectedArcIndices(/* @__PURE__ */ new Set());
302
- }, [drawing.tool]);
303
- const keyHandlers = React.useRef({ toggleTool: drawing.toggleTool, clearArcSelection, canDelete, onDelete, onUndo });
304
- keyHandlers.current = { toggleTool: drawing.toggleTool, clearArcSelection, canDelete, onDelete, onUndo };
305
- React.useEffect(() => {
306
- const svg = svgRef.current;
307
- if (!svg) return;
308
- const onKey = (e) => {
309
- const h = keyHandlers.current;
310
- if (e.key === "Escape") {
311
- h.toggleTool("none");
312
- h.clearArcSelection();
313
- } else if ((e.key === "Delete" || e.key === "Backspace") && h.canDelete) {
314
- e.preventDefault();
315
- h.onDelete();
316
- } else if (e.key === "z" && (e.ctrlKey || e.metaKey)) {
317
- e.preventDefault();
318
- h.onUndo();
319
- }
320
- };
321
- svg.addEventListener("keydown", onKey);
322
- return () => svg.removeEventListener("keydown", onKey);
323
- }, [svgRef]);
324
- const svgCursor = drawing.tool === "pen" ? "crosshair" : drawing.tool === "eraser" ? "cell" : "default";
325
- return /* @__PURE__ */ jsxRuntime.jsx(
326
- NumberLineContext.Provider,
327
- {
328
- value: {
329
- svgRef,
330
- containerWidth,
331
- containerHeight,
332
- svgCursor,
333
- min,
334
- max,
335
- groupSize,
336
- groupCount,
337
- tickStep,
338
- arcColors,
339
- showGroupTicks,
340
- showMajorTicks,
341
- showMinorTicks,
342
- tool: drawing.tool,
343
- strokes: drawing.strokes,
344
- liveStroke,
345
- selectedArcIndices,
346
- deletedArcIndices,
347
- onPointerDown,
348
- onPointerMove,
349
- onPointerUp,
350
- onStrokeClick,
351
- onArcClick,
352
- canDelete,
353
- canUndo: history.canUndo,
354
- onTogglePen,
355
- onToggleEraser,
356
- onDelete,
357
- onReset,
358
- onUndo
359
- },
360
- children
361
- }
362
- );
363
- }
364
- function buildArcPath({ x1, x2, y, rx, ry }) {
365
- return `M ${x1} ${y} A ${rx} ${ry} 0 0 1 ${x2} ${y}`;
366
- }
367
- function computeLabelStep(containerWidth, range) {
368
- const maxLabels = Math.floor(containerWidth / 40);
369
- if (maxLabels <= 0) return range;
370
- const raw = range / maxLabels;
371
- const candidates = [1, 2, 5, 10, 20, 25, 50, 100, 200, 500];
372
- return candidates.find((c) => c >= raw) ?? candidates[candidates.length - 1];
373
- }
374
- const ARC_COLORS = [
375
- "#7c3aed",
376
- "#0891b2",
377
- "#d97706",
378
- "#be185d",
379
- "#16a34a"
380
- ];
381
- function gcd(a, b) {
382
- let x = Math.max(1, Math.abs(Math.round(a)));
383
- let y = Math.max(1, Math.abs(Math.round(b)));
384
- while (y !== 0) [x, y] = [y, x % y];
385
- return x;
386
- }
387
- const AxisLayer = React.memo(function AxisLayer2({
388
- min,
389
- max,
390
- axisY,
391
- padLeft,
392
- padRight,
393
- viewWidth,
394
- containerWidth,
395
- groupSize,
396
- tickStep,
397
- showGroupTicks,
398
- showMajorTicks,
399
- showMinorTicks
400
- }) {
401
- const range = max - min;
402
- if (range <= 0) return null;
403
- const usable = viewWidth - padLeft - padRight;
404
- const toX = (v) => padLeft + (v - min) / range * usable;
405
- const step = Math.max(1, Math.round(tickStep));
406
- const rawLabelStep = computeLabelStep(containerWidth, range);
407
- const labelStep = Math.max(step, Math.ceil(rawLabelStep / step) * step);
408
- const MAX_TICKS = 500;
409
- const capStep = Math.max(1, Math.ceil(range / MAX_TICKS));
410
- const visibleStep = groupSize > 0 ? gcd(step, groupSize) : step;
411
- const iterStep = showMinorTicks ? capStep : Math.max(capStep, visibleStep);
412
- const allTicks = [];
413
- for (let v = min; v <= max; v += iterStep) allTicks.push(v);
414
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { className: "nl-axis-layer", children: [
415
- /* @__PURE__ */ jsxRuntime.jsx(
416
- "line",
417
- {
418
- x1: padLeft - 4,
419
- y1: axisY,
420
- x2: viewWidth - padRight,
421
- y2: axisY,
422
- stroke: "#374151",
423
- strokeWidth: 2
424
- }
425
- ),
426
- allTicks.map((v) => {
427
- const x = toX(v);
428
- const offset = v - min;
429
- const isMajor = offset % step === 0;
430
- const isGroupBoundary = groupSize > 0 && offset % groupSize === 0;
431
- const visible = isGroupBoundary && showGroupTicks || isMajor && showMajorTicks || !isGroupBoundary && !isMajor && showMinorTicks;
432
- if (!visible) return null;
433
- const renderAsGroup = isGroupBoundary && showGroupTicks;
434
- const renderAsMajor = !renderAsGroup && isMajor && showMajorTicks;
435
- const showLabel = (renderAsGroup || renderAsMajor) && offset % labelStep === 0;
436
- const tickH = renderAsGroup ? 7 : renderAsMajor ? 10 : 4;
437
- const strokeW = renderAsGroup ? 1.5 : renderAsMajor ? 1 : 0.5;
438
- const color = renderAsGroup || renderAsMajor ? "#374151" : "#9ca3af";
439
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
440
- /* @__PURE__ */ jsxRuntime.jsx(
441
- "line",
442
- {
443
- x1: x,
444
- y1: axisY - tickH,
445
- x2: x,
446
- y2: axisY + tickH,
447
- stroke: color,
448
- strokeWidth: strokeW
449
- }
450
- ),
451
- showLabel && /* @__PURE__ */ jsxRuntime.jsx(
452
- "text",
453
- {
454
- x,
455
- y: axisY + 22,
456
- textAnchor: "middle",
457
- fontSize: 11,
458
- fill: "#374151",
459
- pointerEvents: "none",
460
- style: { userSelect: "none", WebkitUserSelect: "none" },
461
- children: v
462
- }
463
- )
464
- ] }, v);
465
- })
466
- ] });
467
- });
468
- const GroupArcsLayer = React.memo(function GroupArcsLayer2({
469
- min,
470
- max,
471
- groupSize,
472
- groupCount,
473
- axisY,
474
- padLeft,
475
- padRight,
476
- viewWidth,
477
- arcMaxHeight,
478
- tool,
479
- selectedArcIndices,
480
- deletedArcIndices,
481
- onArcClick,
482
- arcColors = ARC_COLORS
483
- }) {
484
- if (groupSize <= 0 || groupCount <= 0) return null;
485
- const range = max - min;
486
- const usable = viewWidth - padLeft - padRight;
487
- const toX = (v) => padLeft + (v - min) / range * usable;
488
- const arcs = [];
489
- for (let g = 0; g < groupCount; g++) {
490
- if (deletedArcIndices.has(g)) continue;
491
- const start = min + g * groupSize;
492
- const end = start + groupSize;
493
- if (end > max) break;
494
- const x1 = toX(start);
495
- const x2 = toX(end);
496
- const rx = (x2 - x1) / 2;
497
- const ry = Math.min(rx * 0.7, arcMaxHeight);
498
- const color = arcColors[g % arcColors.length];
499
- const arrowHeadH = 7;
500
- const arrowHeadHW = 4;
501
- const MIN_ARROW_SPAN = 18;
502
- const textY = Math.min(axisY - ry - 6, axisY - MIN_ARROW_SPAN);
503
- const arcPath = buildArcPath({ x1, x2, y: axisY, rx, ry });
504
- const isSelected = selectedArcIndices.has(g);
505
- const hitCursor = tool === "eraser" ? "cell" : tool === "none" ? "pointer" : "default";
506
- arcs.push(
507
- /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
508
- isSelected && /* @__PURE__ */ jsxRuntime.jsx(
509
- "path",
510
- {
511
- d: arcPath,
512
- fill: "none",
513
- stroke: "rgba(0,0,0,0.15)",
514
- strokeWidth: 14,
515
- strokeLinecap: "round",
516
- pointerEvents: "none"
517
- }
518
- ),
519
- /* @__PURE__ */ jsxRuntime.jsx(
520
- "path",
521
- {
522
- d: arcPath,
523
- fill: "none",
524
- stroke: isSelected ? "#1d4ed8" : color,
525
- strokeWidth: isSelected ? 3 : 2,
526
- pointerEvents: "none"
527
- }
528
- ),
529
- /* @__PURE__ */ jsxRuntime.jsx(
530
- "path",
531
- {
532
- d: arcPath,
533
- fill: "none",
534
- stroke: "transparent",
535
- strokeWidth: 20,
536
- strokeLinecap: "round",
537
- pointerEvents: "stroke",
538
- style: { cursor: hitCursor },
539
- onPointerDown: (e) => {
540
- if (tool === "eraser" || tool === "none") {
541
- e.stopPropagation();
542
- onArcClick(g, e);
543
- }
544
- }
545
- }
546
- ),
547
- /* @__PURE__ */ jsxRuntime.jsx(
548
- "text",
549
- {
550
- x: x2,
551
- y: textY,
552
- textAnchor: "middle",
553
- fontSize: 10,
554
- fill: isSelected ? "#1d4ed8" : color,
555
- fontWeight: "600",
556
- pointerEvents: "none",
557
- style: { userSelect: "none", WebkitUserSelect: "none" },
558
- children: end
559
- }
560
- ),
561
- /* @__PURE__ */ jsxRuntime.jsx(
562
- "line",
563
- {
564
- x1: x2,
565
- y1: textY + 4,
566
- x2,
567
- y2: axisY - arrowHeadH,
568
- stroke: isSelected ? "#1d4ed8" : color,
569
- strokeWidth: 1.5,
570
- pointerEvents: "none"
571
- }
572
- ),
573
- /* @__PURE__ */ jsxRuntime.jsx(
574
- "polygon",
575
- {
576
- points: `${x2},${axisY} ${x2 - arrowHeadHW},${axisY - arrowHeadH} ${x2 + arrowHeadHW},${axisY - arrowHeadH}`,
577
- fill: isSelected ? "#1d4ed8" : color,
578
- pointerEvents: "none"
579
- }
580
- )
581
- ] }, g)
582
- );
583
- }
584
- return /* @__PURE__ */ jsxRuntime.jsx("g", { className: "nl-arcs-layer", children: arcs });
585
- });
586
- function DrawingLayer({ strokes, liveStroke, tool, width, height, onStrokeClick }) {
587
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { className: "nl-drawing-layer", transform: `scale(${width} ${height})`, children: [
588
- strokes.map((s) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
589
- s.selected && /* @__PURE__ */ jsxRuntime.jsx(
590
- "path",
591
- {
592
- d: s.d,
593
- fill: "none",
594
- stroke: "rgba(0,0,0,0.15)",
595
- strokeWidth: 18,
596
- strokeLinecap: "round",
597
- strokeLinejoin: "round",
598
- vectorEffect: "non-scaling-stroke",
599
- pointerEvents: "none"
600
- }
601
- ),
602
- /* @__PURE__ */ jsxRuntime.jsx(
603
- "path",
604
- {
605
- d: s.d,
606
- fill: "none",
607
- stroke: "transparent",
608
- strokeWidth: tool === "eraser" ? 32 : 28,
609
- strokeLinecap: "round",
610
- strokeLinejoin: "round",
611
- vectorEffect: "non-scaling-stroke",
612
- pointerEvents: "stroke",
613
- style: { cursor: tool === "eraser" ? "cell" : tool === "none" ? "pointer" : "default" },
614
- onPointerDown: (e) => {
615
- if (tool === "eraser" || tool === "none") {
616
- e.stopPropagation();
617
- onStrokeClick(s.id, e);
618
- }
619
- }
620
- }
621
- ),
622
- /* @__PURE__ */ jsxRuntime.jsx(
623
- "path",
624
- {
625
- d: s.d,
626
- fill: "none",
627
- stroke: "#7c3aed",
628
- strokeWidth: 2.5,
629
- strokeLinecap: "round",
630
- strokeLinejoin: "round",
631
- vectorEffect: "non-scaling-stroke",
632
- pointerEvents: "none"
633
- }
634
- )
635
- ] }, s.id)),
636
- liveStroke && /* @__PURE__ */ jsxRuntime.jsx(
637
- "path",
638
- {
639
- d: liveStroke.d,
640
- fill: "none",
641
- stroke: "#7c3aed",
642
- strokeWidth: 2.5,
643
- strokeLinecap: "round",
644
- strokeLinejoin: "round",
645
- vectorEffect: "non-scaling-stroke",
646
- pointerEvents: "none",
647
- opacity: 0.7
648
- }
649
- )
650
- ] });
651
- }
652
- const PAD_LEFT = 30;
653
- const PAD_RIGHT = 40;
654
- const AXIS_BOTTOM_OFFSET = 50;
655
- const ARC_TOP_PADDING = 16;
656
- const MIN_ARC_HEIGHT = 24;
657
- function NumberLine({ className }) {
658
- const {
659
- svgRef,
660
- containerWidth,
661
- containerHeight,
662
- svgCursor,
663
- min,
664
- max,
665
- groupSize,
666
- groupCount,
667
- tickStep,
668
- arcColors,
669
- showGroupTicks,
670
- showMajorTicks,
671
- showMinorTicks,
672
- tool,
673
- strokes,
674
- liveStroke,
675
- selectedArcIndices,
676
- deletedArcIndices,
677
- onPointerDown,
678
- onPointerMove,
679
- onPointerUp,
680
- onStrokeClick,
681
- onArcClick
682
- } = useNumberLineContext();
683
- const w = containerWidth;
684
- const h = containerHeight;
685
- const axisY = Math.max(MIN_ARC_HEIGHT + ARC_TOP_PADDING, h - AXIS_BOTTOM_OFFSET);
686
- const arcMaxHeight = Math.max(MIN_ARC_HEIGHT, axisY - ARC_TOP_PADDING);
687
- return /* @__PURE__ */ jsxRuntime.jsxs(
688
- "svg",
689
- {
690
- ref: svgRef,
691
- tabIndex: 0,
692
- className: className ? `nl-svg ${className}` : "nl-svg",
693
- viewBox: `0 0 ${w} ${h}`,
694
- preserveAspectRatio: "none",
695
- style: { width: "100%", height: "100%", display: "block", outline: "none", cursor: svgCursor, touchAction: "none" },
696
- onPointerDown,
697
- onPointerMove,
698
- onPointerUp,
699
- children: [
700
- /* @__PURE__ */ jsxRuntime.jsx(
701
- AxisLayer,
702
- {
703
- min,
704
- max,
705
- axisY,
706
- padLeft: PAD_LEFT,
707
- padRight: PAD_RIGHT,
708
- viewWidth: w,
709
- containerWidth: w,
710
- groupSize,
711
- tickStep,
712
- showGroupTicks,
713
- showMajorTicks,
714
- showMinorTicks
715
- }
716
- ),
717
- /* @__PURE__ */ jsxRuntime.jsx(
718
- GroupArcsLayer,
719
- {
720
- min,
721
- max,
722
- groupSize,
723
- groupCount,
724
- axisY,
725
- padLeft: PAD_LEFT,
726
- padRight: PAD_RIGHT,
727
- viewWidth: w,
728
- arcMaxHeight,
729
- tool,
730
- selectedArcIndices,
731
- deletedArcIndices,
732
- onArcClick,
733
- arcColors
734
- }
735
- ),
736
- /* @__PURE__ */ jsxRuntime.jsx(
737
- DrawingLayer,
738
- {
739
- strokes,
740
- liveStroke,
741
- tool,
742
- width: w,
743
- height: h,
744
- onStrokeClick
745
- }
746
- )
747
- ]
748
- }
749
- );
750
- }
751
- exports.NumberLine = NumberLine;
752
- exports.NumberLineProvider = NumberLineProvider;
753
- exports.useNumberLineContext = useNumberLineContext;