@crewlethq/ui 0.31.0 → 0.32.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/README.md +25 -1
- package/dist/Canvas/Canvas.d.ts +48 -2
- package/dist/Canvas/ShortcutTip.d.ts +22 -0
- package/dist/Canvas/geometry.d.ts +13 -3
- package/dist/Canvas/index.d.ts +3 -1
- package/dist/Canvas/index.js +3 -1
- package/dist/{Canvas-YVXHMWLN.css → Canvas-LRVNW7XN.css} +39 -3
- package/dist/CanvasBoard/CanvasBoard.d.ts +75 -12
- package/dist/CanvasBoard/index.d.ts +2 -2
- package/dist/CanvasBoard/index.js +6 -2
- package/dist/{CanvasBoard-ZLPDINSM.css → CanvasBoard-MBZVBWDO.css} +135 -30
- package/dist/CanvasToolbar/CanvasToolbar.d.ts +48 -0
- package/dist/CanvasToolbar/index.d.ts +3 -0
- package/dist/CanvasToolbar/index.js +12 -0
- package/dist/CanvasToolbar-AE5MXH7T.css +32 -0
- package/dist/DataView/index.js +3 -3
- package/dist/EditingStatus/index.js +1 -1
- package/dist/{EditingStatus-NFADEPSX.css → EditingStatus-L6THUAN7.css} +21 -0
- package/dist/PresenterView/index.js +2 -2
- package/dist/RichEditor/index.js +1 -1
- package/dist/SheetGrid/index.js +3 -3
- package/dist/SlideCompare/index.js +2 -2
- package/dist/SlideFilmstrip/index.js +2 -2
- package/dist/SlideGrid/index.js +2 -2
- package/dist/SlideStage/SlideStage.d.ts +6 -1
- package/dist/SlideStage/index.js +1 -1
- package/dist/TreeCanvas/index.js +4 -2
- package/dist/{chunk-ALMSY7RL.js → chunk-CRKFL423.js} +1 -1
- package/dist/{chunk-O63MWA4G.js → chunk-E6CR5PEV.js} +2 -1
- package/dist/chunk-E6EWK5YY.js +33 -0
- package/dist/{chunk-3DPIU2Q7.js → chunk-FPS3JIPQ.js} +1 -1
- package/dist/{chunk-OGAAHVF6.js → chunk-MBNFJSZS.js} +1 -1
- package/dist/{chunk-OJ45PPCV.js → chunk-OTN35CI4.js} +113 -30
- package/dist/{chunk-JODJS7MR.js → chunk-PJD2KFHX.js} +243 -39
- package/dist/{chunk-LR5QTFOE.js → chunk-RV7SZAHR.js} +1 -1
- package/dist/{chunk-VOX3YRFO.js → chunk-V5IGUXMZ.js} +1 -1
- package/dist/{chunk-3C3BRIMY.js → chunk-VS3KOOOL.js} +1 -1
- package/dist/{chunk-S6VG5ZFZ.js → chunk-WTNUVQVI.js} +1 -1
- package/dist/generated/index.d.ts +1 -0
- package/dist/generated/index.js +49 -48
- package/dist/index.js +49 -48
- package/dist/styles.css +233 -36
- package/package.json +3 -3
- package/dist/{Editor-YZ7KG2RD.js → Editor-YWBUJAQU.js} +1 -1
- package/dist/{chunk-UVJ5FF5V.js → chunk-3ZAFJ4GK.js} +2 -2
- package/dist/{chunk-CT4EZF62.js → chunk-LWXRD6L6.js} +2 -2
- /package/dist/{chunk-OC46246T.js → chunk-TF2P3OPS.js} +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Note } from './chunk-CJKMURZO.js';
|
|
2
|
-
import {
|
|
2
|
+
import { CanvasToolbar, toolForKey } from './chunk-E6EWK5YY.js';
|
|
3
|
+
import { IDENTITY_VIEW, Canvas } from './chunk-OTN35CI4.js';
|
|
3
4
|
import { IconButton } from './chunk-4FQT6ZAY.js';
|
|
4
5
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
5
|
-
import './CanvasBoard-
|
|
6
|
-
import { useState, useCallback, useMemo,
|
|
7
|
-
import { MaximizeGlyph, PencilGlyph, TrashGlyph } from '@crewlethq/icons/glyphs';
|
|
6
|
+
import './CanvasBoard-MBZVBWDO.css';
|
|
7
|
+
import { useState, useRef, useImperativeHandle, useCallback, useMemo, useEffect } from 'react';
|
|
8
|
+
import { MaximizeGlyph, PencilGlyph, TrashGlyph, MousePointer2Glyph, HandGlyph, TypeGlyph, StickyNoteGlyph } from '@crewlethq/icons/glyphs';
|
|
8
9
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
10
|
|
|
10
11
|
// src/CanvasBoard/budget.ts
|
|
@@ -41,6 +42,11 @@ var NOTE_TONES = {
|
|
|
41
42
|
green: "green",
|
|
42
43
|
purple: "purple"
|
|
43
44
|
};
|
|
45
|
+
function titleSize(note) {
|
|
46
|
+
const chars = Math.max(1, Array.from(note.text.trim()).length);
|
|
47
|
+
return Math.max(1, Math.min(note.h * 0.6, note.w / (chars * TITLE_GLYPH_EM)));
|
|
48
|
+
}
|
|
49
|
+
var TITLE_GLYPH_EM = 0.58;
|
|
44
50
|
function noteName(note) {
|
|
45
51
|
const words = note.text.trim().replace(/\s+/g, " ");
|
|
46
52
|
return words.length > 40 ? `${words.slice(0, 39)}\u2026` : words;
|
|
@@ -54,8 +60,21 @@ var LABELS = {
|
|
|
54
60
|
removeNote: "Delete note",
|
|
55
61
|
noteText: "Note text",
|
|
56
62
|
paused: "Zoom in to run this board",
|
|
57
|
-
active: "Press Escape to return to the canvas"
|
|
63
|
+
active: "Press Escape to return to the canvas",
|
|
64
|
+
interact: "Double-click to use this board",
|
|
65
|
+
tools: "Tools",
|
|
66
|
+
moveTool: "Move",
|
|
67
|
+
handTool: "Hand",
|
|
68
|
+
textTool: "Text",
|
|
69
|
+
stickyTool: "Sticky note"
|
|
70
|
+
};
|
|
71
|
+
var TOOL_CURSOR = {
|
|
72
|
+
move: "pointer",
|
|
73
|
+
hand: "hand",
|
|
74
|
+
text: "text",
|
|
75
|
+
sticky: "crosshair"
|
|
58
76
|
};
|
|
77
|
+
var CANVAS_BOARD_MIN_ZOOM = 0.02;
|
|
59
78
|
var KEY_STEP = 8;
|
|
60
79
|
var KEY_STEP_LARGE = 64;
|
|
61
80
|
var CONTENT_MARGIN = 160;
|
|
@@ -80,23 +99,37 @@ function contentOf(boards, notes) {
|
|
|
80
99
|
};
|
|
81
100
|
}
|
|
82
101
|
var clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
|
|
102
|
+
var CONTROL = "button, a[href], input, select, textarea, [contenteditable='true']";
|
|
103
|
+
var POINTER_CORNERS = ["resize-nw", "resize-ne", "resize-sw"];
|
|
83
104
|
function useFrameGestures(zoom, minSide, maxSide, commit) {
|
|
84
105
|
const [preview, setPreview] = useState(null);
|
|
85
106
|
const drag = useRef(null);
|
|
86
107
|
const next = useCallback(
|
|
87
|
-
(d, dx, dy) =>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
108
|
+
(d, dx, dy) => {
|
|
109
|
+
const { from } = d;
|
|
110
|
+
if (d.mode === "move") return { ...from, x: Math.round(from.x + dx), y: Math.round(from.y + dy) };
|
|
111
|
+
const west = d.mode === "resize-nw" || d.mode === "resize-sw";
|
|
112
|
+
const north = d.mode === "resize-nw" || d.mode === "resize-ne";
|
|
113
|
+
const w = clamp(Math.round(from.w + (west ? -dx : dx)), minSide, maxSide);
|
|
114
|
+
const h = clamp(Math.round(from.h + (north ? -dy : dy)), minSide, maxSide);
|
|
115
|
+
return {
|
|
116
|
+
x: west ? from.x + from.w - w : from.x,
|
|
117
|
+
y: north ? from.y + from.h - h : from.y,
|
|
118
|
+
w,
|
|
119
|
+
h
|
|
120
|
+
};
|
|
91
121
|
},
|
|
92
122
|
[minSide, maxSide]
|
|
93
123
|
);
|
|
94
|
-
const
|
|
124
|
+
const pointer = (id, mode, item) => {
|
|
95
125
|
const from = { x: item.x, y: item.y, w: item.w, h: item.h };
|
|
96
126
|
return {
|
|
97
127
|
onPointerDown: (event) => {
|
|
98
128
|
if (event.pointerType === "mouse" && event.button !== 0) return;
|
|
129
|
+
const control = event.target instanceof Element ? event.target.closest(CONTROL) : null;
|
|
130
|
+
if (control !== null && control !== event.currentTarget) return;
|
|
99
131
|
event.preventDefault();
|
|
132
|
+
event.stopPropagation();
|
|
100
133
|
try {
|
|
101
134
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
102
135
|
} catch {
|
|
@@ -135,7 +168,12 @@ function useFrameGestures(zoom, minSide, maxSide, commit) {
|
|
|
135
168
|
onPointerCancel: () => {
|
|
136
169
|
drag.current = null;
|
|
137
170
|
setPreview(null);
|
|
138
|
-
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
const keys = (id, mode, item) => {
|
|
175
|
+
const from = { x: item.x, y: item.y, w: item.w, h: item.h };
|
|
176
|
+
return {
|
|
139
177
|
onKeyDown: (event) => {
|
|
140
178
|
const step = event.shiftKey ? KEY_STEP_LARGE : KEY_STEP;
|
|
141
179
|
const delta = {
|
|
@@ -159,8 +197,13 @@ function useFrameGestures(zoom, minSide, maxSide, commit) {
|
|
|
159
197
|
}
|
|
160
198
|
};
|
|
161
199
|
};
|
|
162
|
-
|
|
200
|
+
const handle = (id, mode, item) => ({
|
|
201
|
+
...pointer(id, mode, item),
|
|
202
|
+
...keys(id, mode, item)
|
|
203
|
+
});
|
|
204
|
+
return { preview, handle, pointer };
|
|
163
205
|
}
|
|
206
|
+
var TYPING = "input, textarea, select, [contenteditable='true']";
|
|
164
207
|
function CanvasBoard({
|
|
165
208
|
label,
|
|
166
209
|
boards,
|
|
@@ -174,9 +217,11 @@ function CanvasBoard({
|
|
|
174
217
|
onBoardChange,
|
|
175
218
|
onNoteChange,
|
|
176
219
|
onNoteRemove,
|
|
220
|
+
onNoteCreate,
|
|
177
221
|
onOpen,
|
|
178
222
|
onActivate,
|
|
179
223
|
controlsExtra,
|
|
224
|
+
toolbar = true,
|
|
180
225
|
labels,
|
|
181
226
|
canvasLabels,
|
|
182
227
|
canvasRef,
|
|
@@ -187,6 +232,22 @@ function CanvasBoard({
|
|
|
187
232
|
const [viewport, setViewport] = useState({ width: 0, height: 0 });
|
|
188
233
|
const [active, setActive] = useState(null);
|
|
189
234
|
const [editing, setEditing] = useState(null);
|
|
235
|
+
const [selected, setSelected] = useState(null);
|
|
236
|
+
const [chosenTool, setTool] = useState("move");
|
|
237
|
+
const [spaceHeld, setSpaceHeld] = useState(false);
|
|
238
|
+
const canvas = useRef(null);
|
|
239
|
+
useImperativeHandle(canvasRef, () => canvas.current, []);
|
|
240
|
+
const creates = editable && onNoteCreate !== void 0;
|
|
241
|
+
const tools = [
|
|
242
|
+
{ id: "move", label: text.moveTool, icon: /* @__PURE__ */ jsx(MousePointer2Glyph, {}), shortcut: "V" },
|
|
243
|
+
{ id: "hand", label: text.handTool, icon: /* @__PURE__ */ jsx(HandGlyph, {}), shortcut: "H" },
|
|
244
|
+
...creates ? [
|
|
245
|
+
{ id: "text", label: text.textTool, icon: /* @__PURE__ */ jsx(TypeGlyph, {}), shortcut: "T" },
|
|
246
|
+
{ id: "sticky", label: text.stickyTool, icon: /* @__PURE__ */ jsx(StickyNoteGlyph, {}), shortcut: "S" }
|
|
247
|
+
] : []
|
|
248
|
+
];
|
|
249
|
+
const tool = tools.some((t) => t.id === chosenTool) ? chosenTool : "move";
|
|
250
|
+
const acting = spaceHeld ? "hand" : tool;
|
|
190
251
|
const activate = (id) => {
|
|
191
252
|
setActive(id);
|
|
192
253
|
onActivate?.(id);
|
|
@@ -215,15 +276,77 @@ function CanvasBoard({
|
|
|
215
276
|
);
|
|
216
277
|
const largest = boards.reduce((w, b) => Math.max(w, b.w), 0);
|
|
217
278
|
const live = new Set(liveBoards(drawnBoards, view, viewport, maxLive, minLiveWidth));
|
|
279
|
+
const shownSelection = selected !== null && (selected.kind === "board" ? boards : notes).some((item) => item.id === selected.id) ? selected : null;
|
|
280
|
+
const isSelected = (kind, id) => shownSelection?.kind === kind && shownSelection.id === id;
|
|
281
|
+
useEffect(() => {
|
|
282
|
+
if (!spaceHeld) return;
|
|
283
|
+
const release = (event) => {
|
|
284
|
+
if (event instanceof KeyboardEvent && event.key !== " ") return;
|
|
285
|
+
setSpaceHeld(false);
|
|
286
|
+
};
|
|
287
|
+
window.addEventListener("keyup", release);
|
|
288
|
+
window.addEventListener("blur", release);
|
|
289
|
+
return () => {
|
|
290
|
+
window.removeEventListener("keyup", release);
|
|
291
|
+
window.removeEventListener("blur", release);
|
|
292
|
+
};
|
|
293
|
+
}, [spaceHeld]);
|
|
218
294
|
const onKeyDown = (event) => {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
295
|
+
const target = event.target instanceof Element ? event.target : null;
|
|
296
|
+
if (event.key === "Escape") {
|
|
297
|
+
if (active !== null) {
|
|
298
|
+
event.stopPropagation();
|
|
299
|
+
activate(null);
|
|
300
|
+
} else if (shownSelection !== null) {
|
|
301
|
+
event.stopPropagation();
|
|
302
|
+
setSelected(null);
|
|
303
|
+
}
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (event.defaultPrevented || target?.closest(TYPING)) return;
|
|
307
|
+
if (event.key === " ") {
|
|
308
|
+
if (target?.closest(CONTROL)) return;
|
|
309
|
+
event.preventDefault();
|
|
310
|
+
if (!event.repeat) setSpaceHeld(true);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if ((event.key === "Delete" || event.key === "Backspace") && editable && shownSelection?.kind === "note") {
|
|
314
|
+
event.preventDefault();
|
|
315
|
+
onNoteRemove?.(shownSelection.id);
|
|
316
|
+
setSelected(null);
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
const picked = toolForKey(tools, event);
|
|
320
|
+
if (picked !== void 0) {
|
|
321
|
+
event.preventDefault();
|
|
322
|
+
setTool(picked);
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
const onClick = (event) => {
|
|
326
|
+
const target = event.target instanceof Element ? event.target : null;
|
|
327
|
+
if (!target?.closest(".crewlet-canvas__viewport")) return;
|
|
328
|
+
if (target.closest(".crewlet-canvas-board__board, .crewlet-canvas-board__note")) return;
|
|
329
|
+
if ((acting === "text" || acting === "sticky") && onNoteCreate && canvas.current) {
|
|
330
|
+
const at = canvas.current.worldAt({ x: event.clientX, y: event.clientY });
|
|
331
|
+
const id = onNoteCreate(acting === "text" ? "title" : "sticky", {
|
|
332
|
+
x: Math.round(at.x),
|
|
333
|
+
y: Math.round(at.y)
|
|
334
|
+
});
|
|
335
|
+
setTool("move");
|
|
336
|
+
if (id !== void 0) {
|
|
337
|
+
setSelected({ kind: "note", id });
|
|
338
|
+
setEditing(id);
|
|
339
|
+
}
|
|
340
|
+
return;
|
|
222
341
|
}
|
|
342
|
+
if (acting === "move") setSelected(null);
|
|
223
343
|
};
|
|
224
344
|
const zoomVar = { "--crewlet-canvas-board-zoom": String(view.k) };
|
|
345
|
+
const activeBoard = boards.find((b) => b.id === active && live.has(b.id));
|
|
346
|
+
const chosenBoard = shownSelection?.kind === "board" ? shownSelection.id : null;
|
|
347
|
+
const hint = !editable && activeBoard ? text.active : !editable && chosenBoard !== null && live.has(chosenBoard) ? text.interact : "";
|
|
225
348
|
return (
|
|
226
|
-
// The wrapper
|
|
349
|
+
// The wrapper hears keys and clicks bubbling from inside the canvas; the
|
|
227
350
|
// canvas's own viewport is the focusable, labelled control.
|
|
228
351
|
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
229
352
|
/* @__PURE__ */ jsx(
|
|
@@ -231,7 +354,9 @@ function CanvasBoard({
|
|
|
231
354
|
{
|
|
232
355
|
className: cx("crewlet-canvas-board", className),
|
|
233
356
|
"data-editable": editable || void 0,
|
|
357
|
+
"data-tool": acting,
|
|
234
358
|
onKeyDown,
|
|
359
|
+
onClick,
|
|
235
360
|
children: /* @__PURE__ */ jsx(
|
|
236
361
|
Canvas,
|
|
237
362
|
{
|
|
@@ -239,23 +364,31 @@ function CanvasBoard({
|
|
|
239
364
|
content,
|
|
240
365
|
largestItemWidth: largest || void 0,
|
|
241
366
|
ground: "dotted",
|
|
367
|
+
cursor: TOOL_CURSOR[acting],
|
|
368
|
+
minZoom: CANVAS_BOARD_MIN_ZOOM,
|
|
369
|
+
refitOnResize: true,
|
|
370
|
+
controlsActualSize: true,
|
|
242
371
|
controlsExtra,
|
|
372
|
+
hint,
|
|
243
373
|
labels: canvasLabels,
|
|
374
|
+
overlay: toolbar ? /* @__PURE__ */ jsx("div", { className: "crewlet-canvas-board__tools", children: /* @__PURE__ */ jsx(CanvasToolbar, { label: text.tools, tools, value: tool, onChange: setTool }) }) : void 0,
|
|
244
375
|
onViewChange: (nextView, size) => {
|
|
245
376
|
setView(nextView);
|
|
246
377
|
setViewport(size);
|
|
247
378
|
},
|
|
248
|
-
ref:
|
|
379
|
+
ref: canvas,
|
|
249
380
|
children: /* @__PURE__ */ jsxs("div", { className: "crewlet-canvas-board__layer", style: zoomVar, children: [
|
|
250
381
|
drawnBoards.map((b) => {
|
|
251
382
|
const isLive = live.has(b.id);
|
|
252
383
|
const isActive = !editable && active === b.id && isLive;
|
|
384
|
+
const chosen = isSelected("board", b.id);
|
|
253
385
|
return /* @__PURE__ */ jsxs(
|
|
254
386
|
"section",
|
|
255
387
|
{
|
|
256
388
|
className: "crewlet-canvas-board__board",
|
|
257
389
|
"data-live": isLive || void 0,
|
|
258
390
|
"data-active": isActive || void 0,
|
|
391
|
+
"data-selected": chosen || void 0,
|
|
259
392
|
"aria-label": `${b.title}, ${text.size(b.w, b.h)}`,
|
|
260
393
|
style: { left: b.x, top: b.y, width: b.w, height: b.h },
|
|
261
394
|
children: [
|
|
@@ -266,10 +399,25 @@ function CanvasBoard({
|
|
|
266
399
|
type: "button",
|
|
267
400
|
className: "crewlet-canvas-board__title crewlet-canvas-board__handle",
|
|
268
401
|
"aria-label": text.move(b.title),
|
|
402
|
+
"aria-pressed": chosen,
|
|
403
|
+
onFocus: () => setSelected({ kind: "board", id: b.id }),
|
|
269
404
|
...boardGestures.handle(b.id, "move", b),
|
|
270
405
|
children: b.title
|
|
271
406
|
}
|
|
272
|
-
) :
|
|
407
|
+
) : (
|
|
408
|
+
// The name selects its board, as a press on the board
|
|
409
|
+
// does; the board's keyboard route is its own page and
|
|
410
|
+
// its open control, so the name is pointer only.
|
|
411
|
+
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
|
|
412
|
+
/* @__PURE__ */ jsx(
|
|
413
|
+
"span",
|
|
414
|
+
{
|
|
415
|
+
className: "crewlet-canvas-board__title",
|
|
416
|
+
onClick: () => setSelected({ kind: "board", id: b.id }),
|
|
417
|
+
children: b.title
|
|
418
|
+
}
|
|
419
|
+
)
|
|
420
|
+
),
|
|
273
421
|
onOpen && /* @__PURE__ */ jsx(
|
|
274
422
|
IconButton,
|
|
275
423
|
{
|
|
@@ -287,27 +435,29 @@ function CanvasBoard({
|
|
|
287
435
|
/* @__PURE__ */ jsx("span", { children: text.size(b.w, b.h) }),
|
|
288
436
|
/* @__PURE__ */ jsx("span", { children: text.paused })
|
|
289
437
|
] }) }),
|
|
290
|
-
|
|
291
|
-
// a click
|
|
292
|
-
// The board's page stays
|
|
293
|
-
// its own frame, so the
|
|
294
|
-
//
|
|
438
|
+
!isActive && // A press here pans the canvas like the field around it;
|
|
439
|
+
// a click selects the board and a double-click hands a
|
|
440
|
+
// live board the pointer. The board's page stays
|
|
441
|
+
// reachable by keyboard through its own frame, so the
|
|
442
|
+
// shield is pointer only.
|
|
443
|
+
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
|
|
295
444
|
/* @__PURE__ */ jsx(
|
|
296
445
|
"div",
|
|
297
446
|
{
|
|
298
447
|
className: "crewlet-canvas-board__shield",
|
|
299
|
-
onClick:
|
|
448
|
+
onClick: () => setSelected({ kind: "board", id: b.id }),
|
|
449
|
+
onDoubleClick: editable || !isLive ? void 0 : () => activate(b.id)
|
|
300
450
|
}
|
|
301
451
|
)
|
|
302
452
|
] }),
|
|
303
|
-
isActive && /* @__PURE__ */ jsx("p", { className: "crewlet-canvas-board__hint", children: text.active }),
|
|
304
453
|
editable && /* @__PURE__ */ jsx(
|
|
305
|
-
|
|
454
|
+
Corners,
|
|
306
455
|
{
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
456
|
+
title: b.title,
|
|
457
|
+
selected: chosen,
|
|
458
|
+
text,
|
|
459
|
+
keyed: boardGestures.handle(b.id, "resize-se", b),
|
|
460
|
+
pointer: (mode) => boardGestures.pointer(b.id, mode, b)
|
|
311
461
|
}
|
|
312
462
|
)
|
|
313
463
|
]
|
|
@@ -321,9 +471,13 @@ function CanvasBoard({
|
|
|
321
471
|
note: n,
|
|
322
472
|
editable,
|
|
323
473
|
editing: editing === n.id,
|
|
474
|
+
selected: isSelected("note", n.id),
|
|
324
475
|
text,
|
|
325
476
|
moveHandle: noteGestures.handle(n.id, "move", n),
|
|
326
|
-
|
|
477
|
+
dragPaper: noteGestures.pointer(n.id, "move", n),
|
|
478
|
+
resizeHandle: noteGestures.handle(n.id, "resize-se", n),
|
|
479
|
+
resizePointer: (mode) => noteGestures.pointer(n.id, mode, n),
|
|
480
|
+
onSelect: () => setSelected({ kind: "note", id: n.id }),
|
|
327
481
|
onEdit: () => setEditing(n.id),
|
|
328
482
|
onDone: (value) => {
|
|
329
483
|
setEditing(null);
|
|
@@ -345,13 +499,47 @@ function CanvasBoard({
|
|
|
345
499
|
)
|
|
346
500
|
);
|
|
347
501
|
}
|
|
502
|
+
function Corners({
|
|
503
|
+
title,
|
|
504
|
+
selected,
|
|
505
|
+
text,
|
|
506
|
+
keyed,
|
|
507
|
+
pointer
|
|
508
|
+
}) {
|
|
509
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
510
|
+
selected && POINTER_CORNERS.map((mode) => /* @__PURE__ */ jsx(
|
|
511
|
+
"span",
|
|
512
|
+
{
|
|
513
|
+
"aria-hidden": true,
|
|
514
|
+
className: "crewlet-canvas-board__resize",
|
|
515
|
+
"data-corner": mode,
|
|
516
|
+
...pointer(mode)
|
|
517
|
+
},
|
|
518
|
+
mode
|
|
519
|
+
)),
|
|
520
|
+
/* @__PURE__ */ jsx(
|
|
521
|
+
"button",
|
|
522
|
+
{
|
|
523
|
+
type: "button",
|
|
524
|
+
className: "crewlet-canvas-board__resize",
|
|
525
|
+
"data-corner": "resize-se",
|
|
526
|
+
"aria-label": text.resize(title),
|
|
527
|
+
...keyed
|
|
528
|
+
}
|
|
529
|
+
)
|
|
530
|
+
] });
|
|
531
|
+
}
|
|
348
532
|
function NoteView({
|
|
349
533
|
note,
|
|
350
534
|
editable,
|
|
351
535
|
editing,
|
|
536
|
+
selected,
|
|
352
537
|
text,
|
|
353
538
|
moveHandle,
|
|
539
|
+
dragPaper,
|
|
354
540
|
resizeHandle,
|
|
541
|
+
resizePointer,
|
|
542
|
+
onSelect,
|
|
355
543
|
onEdit,
|
|
356
544
|
onDone,
|
|
357
545
|
onCancel,
|
|
@@ -365,6 +553,7 @@ function NoteView({
|
|
|
365
553
|
"aria-label": text.noteText,
|
|
366
554
|
defaultValue: note.text,
|
|
367
555
|
autoFocus: true,
|
|
556
|
+
onFocus: (event) => event.currentTarget.select(),
|
|
368
557
|
onBlur: (event) => onDone(event.currentTarget.value),
|
|
369
558
|
onKeyDown: (event) => {
|
|
370
559
|
if (event.key === "Escape") {
|
|
@@ -377,7 +566,14 @@ function NoteView({
|
|
|
377
566
|
}
|
|
378
567
|
}
|
|
379
568
|
}
|
|
380
|
-
) : /* @__PURE__ */ jsx(
|
|
569
|
+
) : /* @__PURE__ */ jsx(
|
|
570
|
+
"p",
|
|
571
|
+
{
|
|
572
|
+
className: "crewlet-canvas-board__note-text",
|
|
573
|
+
style: note.kind === "title" ? { fontSize: titleSize(note) } : void 0,
|
|
574
|
+
children: note.text
|
|
575
|
+
}
|
|
576
|
+
),
|
|
381
577
|
editable && !editing && /* @__PURE__ */ jsxs("div", { className: "crewlet-canvas-board__note-tools", children: [
|
|
382
578
|
/* @__PURE__ */ jsx(
|
|
383
579
|
"button",
|
|
@@ -385,6 +581,7 @@ function NoteView({
|
|
|
385
581
|
type: "button",
|
|
386
582
|
className: "crewlet-canvas-board__handle crewlet-canvas-board__note-move",
|
|
387
583
|
"aria-label": text.move(noteName(note)),
|
|
584
|
+
onFocus: onSelect,
|
|
388
585
|
...moveHandle
|
|
389
586
|
}
|
|
390
587
|
),
|
|
@@ -410,16 +607,22 @@ function NoteView({
|
|
|
410
607
|
)
|
|
411
608
|
] }),
|
|
412
609
|
editable && !editing && /* @__PURE__ */ jsx(
|
|
413
|
-
|
|
610
|
+
Corners,
|
|
414
611
|
{
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
612
|
+
title: noteName(note),
|
|
613
|
+
selected,
|
|
614
|
+
text,
|
|
615
|
+
keyed: resizeHandle,
|
|
616
|
+
pointer: resizePointer
|
|
419
617
|
}
|
|
420
618
|
)
|
|
421
619
|
] });
|
|
422
620
|
const frame = { left: note.x, top: note.y, width: note.w, height: note.h };
|
|
621
|
+
const paper = {
|
|
622
|
+
"data-selected": selected || void 0,
|
|
623
|
+
onClick: onSelect,
|
|
624
|
+
...editable && !editing ? { ...dragPaper, onDoubleClick: onEdit } : {}
|
|
625
|
+
};
|
|
423
626
|
if (note.kind === "sticky") {
|
|
424
627
|
return /* @__PURE__ */ jsx(
|
|
425
628
|
Note,
|
|
@@ -428,11 +631,12 @@ function NoteView({
|
|
|
428
631
|
className: "crewlet-canvas-board__note",
|
|
429
632
|
"data-kind": "sticky",
|
|
430
633
|
style: frame,
|
|
634
|
+
...paper,
|
|
431
635
|
children: body
|
|
432
636
|
}
|
|
433
637
|
);
|
|
434
638
|
}
|
|
435
|
-
return /* @__PURE__ */ jsx("div", { className: "crewlet-canvas-board__note", "data-kind": "title", style: frame, children: body });
|
|
639
|
+
return /* @__PURE__ */ jsx("div", { className: "crewlet-canvas-board__note", "data-kind": "title", style: frame, ...paper, children: body });
|
|
436
640
|
}
|
|
437
641
|
|
|
438
|
-
export { CANVAS_BOARD_MAX_LIVE, CANVAS_BOARD_MIN_LIVE_WIDTH, CANVAS_NOTE_COLORS, CanvasBoard, liveBoards };
|
|
642
|
+
export { CANVAS_BOARD_MAX_LIVE, CANVAS_BOARD_MIN_LIVE_WIDTH, CANVAS_BOARD_MIN_ZOOM, CANVAS_NOTE_COLORS, CanvasBoard, TITLE_GLYPH_EM, liveBoards, titleSize };
|
|
@@ -9,7 +9,7 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
9
9
|
var engine = null;
|
|
10
10
|
var loading = null;
|
|
11
11
|
function loadEngine() {
|
|
12
|
-
loading ??= import('./Editor-
|
|
12
|
+
loading ??= import('./Editor-YWBUJAQU.js').then(
|
|
13
13
|
(module) => {
|
|
14
14
|
engine = module.Editor;
|
|
15
15
|
return engine;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useTreeState, useMeasuredSizes, layoutForest, treeAncestors, useLayoutAnchor, treeExpandable, layoutConnectors, treeItemAction, treeStep, treePosInSet, treeSetSize, treeLevel, placeGroups } from './chunk-MY374UUD.js';
|
|
2
|
-
import { CANVAS_COMPOSE_CONTEXT, CANVAS_FIT_MAX_ZOOM, Canvas } from './chunk-
|
|
2
|
+
import { CANVAS_COMPOSE_CONTEXT, CANVAS_FIT_MAX_ZOOM, Canvas } from './chunk-OTN35CI4.js';
|
|
3
3
|
import { focusables } from './chunk-R25RGPUB.js';
|
|
4
4
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
5
5
|
import './TreeCanvas-L2XYONWL.css';
|
|
@@ -24,6 +24,7 @@ export * from '../Callout/index.js';
|
|
|
24
24
|
export * from '../Canvas/index.js';
|
|
25
25
|
export * from '../CanvasBoard/index.js';
|
|
26
26
|
export * from '../CanvasSchematic/index.js';
|
|
27
|
+
export * from '../CanvasToolbar/index.js';
|
|
27
28
|
export * from '../Card/index.js';
|
|
28
29
|
export * from '../ChangeMark/index.js';
|
|
29
30
|
export * from '../CharacterPicker/index.js';
|