@activecollab/components 2.0.397 → 2.0.399

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.
Files changed (61) hide show
  1. package/dist/cjs/presentation/whiteboard/bottomDock.js +194 -0
  2. package/dist/cjs/presentation/whiteboard/bottomDock.js.map +1 -0
  3. package/dist/cjs/presentation/whiteboard/canvasElements.js +877 -0
  4. package/dist/cjs/presentation/whiteboard/canvasElements.js.map +1 -0
  5. package/dist/cjs/presentation/whiteboard/elements.js +816 -0
  6. package/dist/cjs/presentation/whiteboard/elements.js.map +1 -0
  7. package/dist/cjs/presentation/whiteboard/fileElement.js +457 -0
  8. package/dist/cjs/presentation/whiteboard/fileElement.js.map +1 -0
  9. package/dist/cjs/presentation/whiteboard/glyphs.js +67 -0
  10. package/dist/cjs/presentation/whiteboard/glyphs.js.map +1 -0
  11. package/dist/cjs/presentation/whiteboard/inspector.js +884 -0
  12. package/dist/cjs/presentation/whiteboard/inspector.js.map +1 -0
  13. package/dist/cjs/presentation/whiteboard/linkElement.js +357 -0
  14. package/dist/cjs/presentation/whiteboard/linkElement.js.map +1 -0
  15. package/dist/cjs/presentation/whiteboard/outline.js +966 -0
  16. package/dist/cjs/presentation/whiteboard/outline.js.map +1 -0
  17. package/dist/cjs/presentation/whiteboard/peopleMenu.js +516 -0
  18. package/dist/cjs/presentation/whiteboard/peopleMenu.js.map +1 -0
  19. package/dist/cjs/presentation/whiteboard/settingsMenu.js +177 -0
  20. package/dist/cjs/presentation/whiteboard/settingsMenu.js.map +1 -0
  21. package/dist/esm/presentation/whiteboard/bottomDock.d.ts +51 -0
  22. package/dist/esm/presentation/whiteboard/bottomDock.d.ts.map +1 -0
  23. package/dist/esm/presentation/whiteboard/bottomDock.js +162 -0
  24. package/dist/esm/presentation/whiteboard/bottomDock.js.map +1 -0
  25. package/dist/esm/presentation/whiteboard/canvasElements.d.ts +61 -0
  26. package/dist/esm/presentation/whiteboard/canvasElements.d.ts.map +1 -0
  27. package/dist/esm/presentation/whiteboard/canvasElements.js +746 -0
  28. package/dist/esm/presentation/whiteboard/canvasElements.js.map +1 -0
  29. package/dist/esm/presentation/whiteboard/elements.d.ts +180 -0
  30. package/dist/esm/presentation/whiteboard/elements.d.ts.map +1 -0
  31. package/dist/esm/presentation/whiteboard/elements.js +736 -0
  32. package/dist/esm/presentation/whiteboard/elements.js.map +1 -0
  33. package/dist/esm/presentation/whiteboard/fileElement.d.ts +113 -0
  34. package/dist/esm/presentation/whiteboard/fileElement.d.ts.map +1 -0
  35. package/dist/esm/presentation/whiteboard/fileElement.js +430 -0
  36. package/dist/esm/presentation/whiteboard/fileElement.js.map +1 -0
  37. package/dist/esm/presentation/whiteboard/glyphs.d.ts +32 -0
  38. package/dist/esm/presentation/whiteboard/glyphs.d.ts.map +1 -0
  39. package/dist/esm/presentation/whiteboard/glyphs.js +50 -0
  40. package/dist/esm/presentation/whiteboard/glyphs.js.map +1 -0
  41. package/dist/esm/presentation/whiteboard/inspector.d.ts +100 -0
  42. package/dist/esm/presentation/whiteboard/inspector.d.ts.map +1 -0
  43. package/dist/esm/presentation/whiteboard/inspector.js +753 -0
  44. package/dist/esm/presentation/whiteboard/inspector.js.map +1 -0
  45. package/dist/esm/presentation/whiteboard/linkElement.d.ts +97 -0
  46. package/dist/esm/presentation/whiteboard/linkElement.d.ts.map +1 -0
  47. package/dist/esm/presentation/whiteboard/linkElement.js +327 -0
  48. package/dist/esm/presentation/whiteboard/linkElement.js.map +1 -0
  49. package/dist/esm/presentation/whiteboard/outline.d.ts +89 -0
  50. package/dist/esm/presentation/whiteboard/outline.d.ts.map +1 -0
  51. package/dist/esm/presentation/whiteboard/outline.js +870 -0
  52. package/dist/esm/presentation/whiteboard/outline.js.map +1 -0
  53. package/dist/esm/presentation/whiteboard/peopleMenu.d.ts +44 -0
  54. package/dist/esm/presentation/whiteboard/peopleMenu.d.ts.map +1 -0
  55. package/dist/esm/presentation/whiteboard/peopleMenu.js +440 -0
  56. package/dist/esm/presentation/whiteboard/peopleMenu.js.map +1 -0
  57. package/dist/esm/presentation/whiteboard/settingsMenu.d.ts +13 -0
  58. package/dist/esm/presentation/whiteboard/settingsMenu.d.ts.map +1 -0
  59. package/dist/esm/presentation/whiteboard/settingsMenu.js +155 -0
  60. package/dist/esm/presentation/whiteboard/settingsMenu.js.map +1 -0
  61. package/package.json +1 -1
@@ -0,0 +1,877 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.NO_DRAG_SELECTOR = exports.DRAG_THROUGH_SELECTOR = exports.CanvasElements = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _bottomDock = require("./bottomDock");
9
+ var _elements = require("./elements");
10
+ var _fileElement = require("./fileElement");
11
+ var _linkElement = require("./linkElement");
12
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
13
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
14
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
15
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
16
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
17
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
18
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
19
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
20
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
21
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
22
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
23
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
24
+ /**
25
+ * A card is full of its own controls — the URL field, the display toggle, the
26
+ * retry button, the toolbar. A mousedown on any of them selects the element but
27
+ * must not start a board drag.
28
+ *
29
+ * The resize grip needs no entry here: the shipped handle calls
30
+ * `preventDefault()` on pointerdown, which suppresses the compatibility mouse
31
+ * events entirely, so a grip press never reaches this at all.
32
+ */
33
+ var NO_DRAG_SELECTOR = exports.NO_DRAG_SELECTOR = "a, button, input, textarea, [data-no-drag]";
34
+
35
+ /**
36
+ * …except a control that IS the whole card.
37
+ *
38
+ * A placeholder is one big button filling its card, so treating it as a control
39
+ * left no surface to grab and the card could not be moved at all. Marked
40
+ * drag-through, it does both: moving the pointer drags the card, and releasing
41
+ * without moving is still a click that opens the editor or the file picker.
42
+ * (Atlassian's rule — make a handle draggable, not the whole element — assumes
43
+ * the element has some non-interactive surface. This one has none.)
44
+ */
45
+ var DRAG_THROUGH_SELECTOR = exports.DRAG_THROUGH_SELECTOR = "[data-drag-through]";
46
+ /* The canvas elements + selection state. The rounded rectangle starts
47
+ selected; clicking an element selects it, clicking the canvas deselects,
48
+ Delete on the shape toolbar removes the element. Toolbar submenus really
49
+ edit the per-element state. Elements are draggable, and snap to the grid
50
+ when the board's Snap to Grid setting is on.
51
+
52
+ Link elements are created here too — by drawing a box with the Link tool
53
+ armed, or by pasting a URL onto the canvas. */
54
+ var CanvasElements = exports.CanvasElements = function CanvasElements(_ref) {
55
+ var gridSize = _ref.gridSize,
56
+ snapToGrid = _ref.snapToGrid,
57
+ activeTool = _ref.activeTool,
58
+ onToolUsed = _ref.onToolUsed,
59
+ selectedId = _ref.selectedId,
60
+ setSelectedId = _ref.onSelectedIdChange,
61
+ positions = _ref.positions,
62
+ setPositions = _ref.setPositions,
63
+ shapes = _ref.shapes,
64
+ setShapes = _ref.setShapes,
65
+ stickyStyle = _ref.stickyStyle,
66
+ setStickyStyle = _ref.setStickyStyle,
67
+ links = _ref.links,
68
+ setLinks = _ref.setLinks,
69
+ files = _ref.files,
70
+ setFiles = _ref.setFiles,
71
+ createdShapes = _ref.createdShapes,
72
+ setCreatedShapes = _ref.setCreatedShapes,
73
+ sizes = _ref.sizes,
74
+ rotations = _ref.rotations,
75
+ locks = _ref.locks,
76
+ setLocks = _ref.setLocks;
77
+ var toggleLock = function toggleLock(id) {
78
+ return setLocks(function (current) {
79
+ var _current$id;
80
+ return _objectSpread(_objectSpread({}, current), {}, {
81
+ [id]: !((_current$id = current[id]) !== null && _current$id !== void 0 ? _current$id : false)
82
+ });
83
+ });
84
+ };
85
+ var _useState = (0, _react.useState)([]),
86
+ _useState2 = _slicedToArray(_useState, 2),
87
+ removedIds = _useState2[0],
88
+ setRemovedIds = _useState2[1];
89
+ var _useState3 = (0, _react.useState)(null),
90
+ _useState4 = _slicedToArray(_useState3, 2),
91
+ autoEditId = _useState4[0],
92
+ setAutoEditId = _useState4[1];
93
+ var _useState5 = (0, _react.useState)(null),
94
+ _useState6 = _slicedToArray(_useState5, 2),
95
+ autoOpenId = _useState6[0],
96
+ setAutoOpenId = _useState6[1];
97
+ var _useState7 = (0, _react.useState)(null),
98
+ _useState8 = _slicedToArray(_useState7, 2),
99
+ draft = _useState8[0],
100
+ setDraft = _useState8[1];
101
+ // The active drag and the live snap step are held in refs so the document
102
+ // listeners stay stable and always read the current Board Settings.
103
+ var dragRef = (0, _react.useRef)(null);
104
+ var snapStepRef = (0, _react.useRef)(null);
105
+ snapStepRef.current = snapToGrid ? (0, _elements.gridLevel)(gridSize).snapStep : null;
106
+ /* Set once a press turns into a move, so the click that ends the gesture can
107
+ be swallowed before it reaches a drag-through control. */
108
+ var suppressClickRef = (0, _react.useRef)(false);
109
+
110
+ /* Runs in the capture phase, so it can stop the click before the placeholder
111
+ button underneath ever sees it. It must stay a no-op otherwise — stopping
112
+ propagation on the way down would keep every ordinary click from reaching
113
+ the control it was aimed at. */
114
+ var handleElementClickCapture = (0, _react.useCallback)(function (event) {
115
+ if (!suppressClickRef.current) {
116
+ return;
117
+ }
118
+ suppressClickRef.current = false;
119
+ event.preventDefault();
120
+ event.stopPropagation();
121
+ }, []);
122
+ var handleDragMove = (0, _react.useCallback)(function (event) {
123
+ var drag = dragRef.current;
124
+ if (!drag) {
125
+ return;
126
+ }
127
+ var dx = event.clientX - drag.startX;
128
+ var dy = event.clientY - drag.startY;
129
+ if (!drag.moved && Math.abs(dx) + Math.abs(dy) < 3) {
130
+ return;
131
+ }
132
+ // Past the threshold this gesture is a move, so the click it ends with must
133
+ // not also activate whatever was under the pointer.
134
+ drag.moved = true;
135
+ suppressClickRef.current = true;
136
+ var step = snapStepRef.current;
137
+ var x = (0, _elements.snapValue)(drag.originX + dx, step);
138
+ var y = (0, _elements.snapValue)(drag.originY + dy, step);
139
+ setPositions(function (current) {
140
+ return _objectSpread(_objectSpread({}, current), {}, {
141
+ [drag.id]: {
142
+ x,
143
+ y
144
+ }
145
+ });
146
+ });
147
+ }, [setPositions]);
148
+ var handleDragEnd = (0, _react.useCallback)(function () {
149
+ dragRef.current = null;
150
+ window.removeEventListener("mousemove", handleDragMove);
151
+ window.removeEventListener("mouseup", handleDragEnd);
152
+ }, [handleDragMove]);
153
+
154
+ /* A native HTML5 drag (an <img>, a text selection) swallows the mouseup this
155
+ drag ends on, which would leave the element following the pointer with no
156
+ button held. Ending the board drag on `dragstart` closes that hole; the
157
+ cover's media is also marked undraggable in the design system, so the case
158
+ should not arise from a card in the first place. */
159
+ (0, _react.useEffect)(function () {
160
+ var handleNativeDragStart = function handleNativeDragStart(event) {
161
+ event.preventDefault();
162
+ handleDragEnd();
163
+ };
164
+ window.addEventListener("dragstart", handleNativeDragStart);
165
+ return function () {
166
+ return window.removeEventListener("dragstart", handleNativeDragStart);
167
+ };
168
+ }, [handleDragEnd]);
169
+ var handleElementMouseDown = (0, _react.useCallback)(function (event, id) {
170
+ if (event.button !== 0) {
171
+ return;
172
+ }
173
+
174
+ // An armed tool owns the canvas: let the press through to the layer so a
175
+ // box can be drawn over an existing element instead of moving it.
176
+ if (activeToolRef.current !== "select") {
177
+ return;
178
+ }
179
+ event.stopPropagation();
180
+ setSelectedId(id);
181
+
182
+ // A fresh press starts a fresh gesture: whatever the last one decided
183
+ // about swallowing its click no longer applies.
184
+ suppressClickRef.current = false;
185
+ var target = event.target;
186
+ if (target.closest(NO_DRAG_SELECTOR) && !target.closest(DRAG_THROUGH_SELECTOR)) {
187
+ return;
188
+ }
189
+ var origin = positions[id];
190
+ dragRef.current = {
191
+ id,
192
+ startX: event.clientX,
193
+ startY: event.clientY,
194
+ originX: origin.x,
195
+ originY: origin.y,
196
+ moved: false
197
+ };
198
+ window.addEventListener("mousemove", handleDragMove);
199
+ window.addEventListener("mouseup", handleDragEnd);
200
+ }, [positions, handleDragMove, handleDragEnd, setSelectedId]);
201
+ var updateShape = (0, _react.useCallback)(function (id, partial) {
202
+ return setShapes(function (current) {
203
+ return _objectSpread(_objectSpread({}, current), {}, {
204
+ [id]: _objectSpread(_objectSpread({}, current[id]), partial)
205
+ });
206
+ });
207
+ }, [setShapes]);
208
+ var handleDelete = (0, _react.useCallback)(function () {
209
+ setSelectedId(function (current) {
210
+ if (current) {
211
+ setRemovedIds(function (removed) {
212
+ return [...removed, current];
213
+ });
214
+ }
215
+ return null;
216
+ });
217
+ }, [setSelectedId]);
218
+
219
+ /* ---- link elements ------------------------------------------------ */
220
+
221
+ var layerRef = (0, _react.useRef)(null);
222
+ var linkCounterRef = (0, _react.useRef)(0);
223
+ // Where a pasted card lands: the pointer's last canvas position.
224
+ var pointerRef = (0, _react.useRef)({
225
+ x: 160,
226
+ y: 160
227
+ });
228
+ /* The width each live resize gesture started from. The grip reports deltas
229
+ measured from the gesture START and brackets the stream with
230
+ `onResizeStart` / `onResizeCommit`, so this is a snapshot taken when a
231
+ gesture opens and dropped when it closes — not a running accumulator. That
232
+ is what lets a slow, few-pixels-at-a-time drag keep growing: the delta
233
+ itself grows, so it crosses grid lines instead of rounding each hop away.
234
+ Having a defined gesture end also means nothing is ever left over to make
235
+ the next gesture jump. */
236
+ var resizeStartRef = (0, _react.useRef)({});
237
+
238
+ // Mirrors so the stable document/window handlers always read current state.
239
+ var activeToolRef = (0, _react.useRef)(activeTool);
240
+ activeToolRef.current = activeTool;
241
+ var linksRef = (0, _react.useRef)(links);
242
+ linksRef.current = links;
243
+ var filesRef = (0, _react.useRef)(files);
244
+ filesRef.current = files;
245
+ var canvasPoint = (0, _react.useCallback)(function (clientX, clientY) {
246
+ var _layerRef$current, _rect$left, _rect$top;
247
+ var rect = (_layerRef$current = layerRef.current) === null || _layerRef$current === void 0 ? void 0 : _layerRef$current.getBoundingClientRect();
248
+ return {
249
+ x: clientX - ((_rect$left = rect === null || rect === void 0 ? void 0 : rect.left) !== null && _rect$left !== void 0 ? _rect$left : 0),
250
+ y: clientY - ((_rect$top = rect === null || rect === void 0 ? void 0 : rect.top) !== null && _rect$top !== void 0 ? _rect$top : 0)
251
+ };
252
+ }, []);
253
+
254
+ /* ---- shape elements ------------------------------------------------ */
255
+
256
+ var shapeCounterRef = (0, _react.useRef)(0);
257
+
258
+ /* Create a shape element. A plain click drops the tool's default size at the
259
+ (snapped) point; a real drag creates the drawn box. */
260
+ var addShape = (0, _react.useCallback)(function (point, tool, size) {
261
+ shapeCounterRef.current += 1;
262
+ var id = "shape-created-".concat(shapeCounterRef.current);
263
+ var step = snapStepRef.current;
264
+ setPositions(function (current) {
265
+ return _objectSpread(_objectSpread({}, current), {}, {
266
+ [id]: {
267
+ x: (0, _elements.snapValue)(point.x, step),
268
+ y: (0, _elements.snapValue)(point.y, step)
269
+ }
270
+ });
271
+ });
272
+ setShapes(function (current) {
273
+ return _objectSpread(_objectSpread({}, current), {}, {
274
+ [id]: (0, _elements.defaultShapeState)(tool)
275
+ });
276
+ });
277
+ setCreatedShapes(function (current) {
278
+ return [...current, {
279
+ id,
280
+ kind: "shape",
281
+ initialType: tool,
282
+ x: point.x,
283
+ y: point.y,
284
+ width: size.width,
285
+ height: size.height
286
+ }];
287
+ });
288
+ setSelectedId(id);
289
+ }, [setPositions, setShapes, setCreatedShapes, setSelectedId]);
290
+
291
+ /* Create a link element. `url` null lands a placeholder (the draw gesture);
292
+ a URL goes straight to the unfurl (the paste gesture, where the address is
293
+ already known). */
294
+ var addLink = (0, _react.useCallback)(function (point, width, url) {
295
+ linkCounterRef.current += 1;
296
+ var id = "link-".concat(linkCounterRef.current);
297
+ var step = snapStepRef.current;
298
+ setPositions(function (current) {
299
+ return _objectSpread(_objectSpread({}, current), {}, {
300
+ [id]: {
301
+ x: (0, _elements.snapValue)(point.x, step),
302
+ y: (0, _elements.snapValue)(point.y, step)
303
+ }
304
+ });
305
+ });
306
+ setLinks(function (current) {
307
+ return [...current, {
308
+ id,
309
+ width: (0, _linkElement.clampCardWidth)(width),
310
+ url
311
+ }];
312
+ });
313
+ setSelectedId(id);
314
+ setAutoEditId(url == null ? id : null);
315
+ }, [setSelectedId, setPositions, setLinks]);
316
+ var commitLinkUrl = (0, _react.useCallback)(function (id, url) {
317
+ setLinks(function (current) {
318
+ return current.map(function (link) {
319
+ return link.id === id ? _objectSpread(_objectSpread({}, link), {}, {
320
+ url
321
+ }) : link;
322
+ });
323
+ });
324
+ }, [setLinks]);
325
+ var deleteLink = (0, _react.useCallback)(function (id) {
326
+ setLinks(function (current) {
327
+ return current.filter(function (link) {
328
+ return link.id !== id;
329
+ });
330
+ });
331
+ delete resizeStartRef.current[id];
332
+ setSelectedId(null);
333
+ }, [setSelectedId, setLinks]);
334
+
335
+ /* ---- file elements ------------------------------------------------ */
336
+
337
+ var fileCounterRef = (0, _react.useRef)(0);
338
+
339
+ /* Create a file element. `file` null lands a placeholder and opens the picker
340
+ (the draw gesture); a file goes straight to the upload (the paste and drop
341
+ gestures, where the bytes are already in hand). */
342
+ var addFile = (0, _react.useCallback)(function (point, width, file) {
343
+ fileCounterRef.current += 1;
344
+ var id = "file-".concat(fileCounterRef.current);
345
+ var step = snapStepRef.current;
346
+
347
+ /* `describeFile` allocates an object URL, so it must run HERE and not
348
+ inside the updater: a state updater has to be pure, and a double-invoked
349
+ one would mint a second URL that nothing holds a reference to and that
350
+ therefore could never be revoked. */
351
+ var described = file ? (0, _fileElement.describeFile)(file) : null;
352
+ setPositions(function (current) {
353
+ return _objectSpread(_objectSpread({}, current), {}, {
354
+ [id]: {
355
+ x: (0, _elements.snapValue)(point.x, step),
356
+ y: (0, _elements.snapValue)(point.y, step)
357
+ }
358
+ });
359
+ });
360
+ setFiles(function (current) {
361
+ return [...current, {
362
+ id,
363
+ width: (0, _linkElement.clampCardWidth)(width),
364
+ file: described
365
+ }];
366
+ });
367
+ setSelectedId(id);
368
+ setAutoOpenId(file == null ? id : null);
369
+ }, [setSelectedId, setPositions, setFiles]);
370
+ var attachFile = (0, _react.useCallback)(function (id, picked) {
371
+ var _filesRef$current$fin, _filesRef$current$fin2;
372
+ var described = (0, _fileElement.describeFile)(picked);
373
+ // Replacing a file releases the one it replaces.
374
+ (0, _fileElement.revokeThumbnail)((_filesRef$current$fin = (_filesRef$current$fin2 = filesRef.current.find(function (entry) {
375
+ return entry.id === id;
376
+ })) === null || _filesRef$current$fin2 === void 0 ? void 0 : _filesRef$current$fin2.file) !== null && _filesRef$current$fin !== void 0 ? _filesRef$current$fin : null);
377
+ setFiles(function (current) {
378
+ return current.map(function (entry) {
379
+ return entry.id === id ? _objectSpread(_objectSpread({}, entry), {}, {
380
+ file: described
381
+ }) : entry;
382
+ });
383
+ });
384
+ }, [setFiles]);
385
+
386
+ /* Cancelling an upload keeps the card and drops the file, so the placeholder
387
+ is what you land back on — the same place Esc leaves you. */
388
+ var detachFile = (0, _react.useCallback)(function (id) {
389
+ var _filesRef$current$fin3, _filesRef$current$fin4;
390
+ (0, _fileElement.revokeThumbnail)((_filesRef$current$fin3 = (_filesRef$current$fin4 = filesRef.current.find(function (entry) {
391
+ return entry.id === id;
392
+ })) === null || _filesRef$current$fin4 === void 0 ? void 0 : _filesRef$current$fin4.file) !== null && _filesRef$current$fin3 !== void 0 ? _filesRef$current$fin3 : null);
393
+ setFiles(function (current) {
394
+ return current.map(function (entry) {
395
+ return entry.id === id ? _objectSpread(_objectSpread({}, entry), {}, {
396
+ file: null
397
+ }) : entry;
398
+ });
399
+ });
400
+ setAutoOpenId(null);
401
+ }, [setFiles]);
402
+ var deleteFile = (0, _react.useCallback)(function (id) {
403
+ var _filesRef$current$fin5, _filesRef$current$fin6;
404
+ (0, _fileElement.revokeThumbnail)((_filesRef$current$fin5 = (_filesRef$current$fin6 = filesRef.current.find(function (entry) {
405
+ return entry.id === id;
406
+ })) === null || _filesRef$current$fin6 === void 0 ? void 0 : _filesRef$current$fin6.file) !== null && _filesRef$current$fin5 !== void 0 ? _filesRef$current$fin5 : null);
407
+ setFiles(function (current) {
408
+ return current.filter(function (entry) {
409
+ return entry.id !== id;
410
+ });
411
+ });
412
+ delete resizeStartRef.current[id];
413
+ setSelectedId(null);
414
+ }, [setSelectedId, setFiles]);
415
+ var resizeFile = (0, _react.useCallback)(function (id, dx) {
416
+ var from = resizeStartRef.current[id];
417
+ if (from == null) {
418
+ return;
419
+ }
420
+ var width = (0, _linkElement.clampCardWidth)((0, _elements.snapValue)(from + dx, snapStepRef.current));
421
+ setFiles(function (all) {
422
+ return all.map(function (entry) {
423
+ return entry.id === id ? _objectSpread(_objectSpread({}, entry), {}, {
424
+ width
425
+ }) : entry;
426
+ });
427
+ });
428
+ }, [setFiles]);
429
+
430
+ // Object URLs outlive React, so release every one still held on unmount.
431
+ (0, _react.useEffect)(function () {
432
+ return function () {
433
+ return filesRef.current.forEach(function (entry) {
434
+ return (0, _fileElement.revokeThumbnail)(entry.file);
435
+ });
436
+ };
437
+ }, []);
438
+
439
+ /* The gesture brackets. `beginResize` snapshots the width the gesture opened
440
+ on; `endResize` is where a real board would push its single undo entry, the
441
+ previews before it being live feedback only (spec §7e). */
442
+ var beginResize = (0, _react.useCallback)(function (id, width) {
443
+ resizeStartRef.current[id] = width;
444
+ }, []);
445
+ var endResize = (0, _react.useCallback)(function (id) {
446
+ delete resizeStartRef.current[id];
447
+ }, []);
448
+
449
+ /* Width-only resize: the card reports the delta from the gesture start, the
450
+ board decides what it means — clamp to the link bounds, then land on the
451
+ board grid. Resolving against the snapshot rather than the last value makes
452
+ this idempotent, so a double-invoked updater cannot count a delta twice. */
453
+ var resizeLink = (0, _react.useCallback)(function (id, dx) {
454
+ var from = resizeStartRef.current[id];
455
+ if (from == null) {
456
+ return;
457
+ }
458
+ var width = (0, _linkElement.clampCardWidth)((0, _elements.snapValue)(from + dx, snapStepRef.current));
459
+ setLinks(function (all) {
460
+ return all.map(function (link) {
461
+ return link.id === id ? _objectSpread(_objectSpread({}, link), {}, {
462
+ width
463
+ }) : link;
464
+ });
465
+ });
466
+ }, [setLinks]);
467
+
468
+ /* ---- draw-to-place ------------------------------------------------ */
469
+
470
+ var drawRef = (0, _react.useRef)(null);
471
+ /* A completed draw is followed by a click on the canvas layer, whose job is
472
+ to deselect — which would drop the selection off the card just created.
473
+ This swallows exactly that one click. */
474
+ var drawEndedRef = (0, _react.useRef)(false);
475
+ var handleDrawMove = (0, _react.useCallback)(function (event) {
476
+ var origin = drawRef.current;
477
+ if (!origin) {
478
+ return;
479
+ }
480
+ var point = canvasPoint(event.clientX, event.clientY);
481
+ setDraft({
482
+ x: Math.min(origin.x, point.x),
483
+ y: Math.min(origin.y, point.y),
484
+ width: Math.abs(point.x - origin.x),
485
+ height: Math.abs(point.y - origin.y),
486
+ tool: origin.tool
487
+ });
488
+ }, [canvasPoint]);
489
+ var handleDrawEnd = (0, _react.useCallback)(function (event) {
490
+ var origin = drawRef.current;
491
+ drawRef.current = null;
492
+ window.removeEventListener("mousemove", handleDrawMove);
493
+ window.removeEventListener("mouseup", handleDrawEnd);
494
+ setDraft(null);
495
+ if (!origin) {
496
+ return;
497
+ }
498
+
499
+ // Swallow the click that follows this mouseup, so the layer's deselect
500
+ // does not drop the selection off the card we are about to create. The
501
+ // click may never arrive (a release over the dock retargets it), so it
502
+ // expires on a timer rather than waiting to be consumed.
503
+ drawEndedRef.current = true;
504
+ window.setTimeout(function () {
505
+ drawEndedRef.current = false;
506
+ }, 0);
507
+ var point = canvasPoint(event.clientX, event.clientY);
508
+ var width = Math.abs(point.x - origin.x);
509
+ var height = Math.abs(point.y - origin.y);
510
+ // A click (or a nudge) means "default element here"; a real drag sets
511
+ // the size.
512
+ var drawn = Math.max(width, height) >= _linkElement.CARD_DRAW_THRESHOLD;
513
+ var at = drawn ? {
514
+ x: Math.min(origin.x, point.x),
515
+ y: Math.min(origin.y, point.y)
516
+ } : origin;
517
+ if ((0, _bottomDock.isShapeTool)(origin.tool)) {
518
+ addShape(at, origin.tool, drawn ? {
519
+ width,
520
+ height
521
+ } : _bottomDock.SHAPE_DEFAULT_SIZES[origin.tool]);
522
+ } else if (origin.tool === "file") {
523
+ addFile(at, drawn ? width : _fileElement.FILE_DEFAULT_WIDTH, null);
524
+ } else {
525
+ addLink(at, drawn ? width : _linkElement.LINK_DEFAULT_WIDTH, null);
526
+ }
527
+ onToolUsed();
528
+ }, [addFile, addLink, addShape, canvasPoint, handleDrawMove, onToolUsed]);
529
+ var handleLayerMouseDown = (0, _react.useCallback)(function (event) {
530
+ var tool = activeToolRef.current;
531
+ if (event.button !== 0 || tool === "select") {
532
+ return;
533
+ }
534
+
535
+ // Without this the draw drag also runs the browser's text selection and
536
+ // highlights everything it sweeps across.
537
+ event.preventDefault();
538
+ var point = canvasPoint(event.clientX, event.clientY);
539
+ // The tool is captured with the gesture: disarming mid-drag must not
540
+ // change what the release creates.
541
+ drawRef.current = _objectSpread(_objectSpread({}, point), {}, {
542
+ tool
543
+ });
544
+ setHoverPoint(null);
545
+ setDraft(_objectSpread(_objectSpread({}, point), {}, {
546
+ width: 0,
547
+ height: 0,
548
+ tool
549
+ }));
550
+ window.addEventListener("mousemove", handleDrawMove);
551
+ window.addEventListener("mouseup", handleDrawEnd);
552
+ }, [canvasPoint, handleDrawMove, handleDrawEnd]);
553
+
554
+ /* Where the armed tool's hover preview sits — cleared while a draw gesture
555
+ runs (the rubber band takes over) and whenever the tool disarms. */
556
+ var _useState9 = (0, _react.useState)(null),
557
+ _useState0 = _slicedToArray(_useState9, 2),
558
+ hoverPoint = _useState0[0],
559
+ setHoverPoint = _useState0[1];
560
+ (0, _react.useEffect)(function () {
561
+ if (activeTool === "select") {
562
+ setHoverPoint(null);
563
+ }
564
+ }, [activeTool]);
565
+ var handleLayerMouseMove = (0, _react.useCallback)(function (event) {
566
+ pointerRef.current = canvasPoint(event.clientX, event.clientY);
567
+ if (activeTool !== "select" && !drawRef.current) {
568
+ setHoverPoint(pointerRef.current);
569
+ }
570
+ }, [activeTool, canvasPoint]);
571
+ var handleLayerMouseLeave = (0, _react.useCallback)(function () {
572
+ setHoverPoint(null);
573
+ }, []);
574
+ var handleLayerClick = (0, _react.useCallback)(function () {
575
+ if (drawEndedRef.current) {
576
+ drawEndedRef.current = false;
577
+ return;
578
+ }
579
+ setSelectedId(null);
580
+ }, [setSelectedId]);
581
+
582
+ /* ---- drop-to-place ------------------------------------------------ */
583
+
584
+ /**
585
+ * The whole board is a drop target, which the dock hint already promises.
586
+ *
587
+ * This also has to exist for safety, not just for the feature: a file dropped
588
+ * anywhere the app does not handle makes the browser NAVIGATE to it, throwing
589
+ * the board away. So the document swallows every file drag, and a drop on the
590
+ * canvas lands a card at the pointer.
591
+ */
592
+ (0, _react.useEffect)(function () {
593
+ var isFileDrag = function isFileDrag(event) {
594
+ var _event$dataTransfer$t, _event$dataTransfer;
595
+ return Array.from((_event$dataTransfer$t = (_event$dataTransfer = event.dataTransfer) === null || _event$dataTransfer === void 0 ? void 0 : _event$dataTransfer.types) !== null && _event$dataTransfer$t !== void 0 ? _event$dataTransfer$t : []).includes("Files");
596
+ };
597
+ var handleDragOver = function handleDragOver(event) {
598
+ if (!isFileDrag(event)) {
599
+ return;
600
+ }
601
+ // Both of these are required: without the dragover default prevented the
602
+ // drop event never fires at all.
603
+ event.preventDefault();
604
+ if (event.dataTransfer) {
605
+ event.dataTransfer.dropEffect = "copy";
606
+ }
607
+ };
608
+ var handleDrop = function handleDrop(event) {
609
+ if (!isFileDrag(event)) {
610
+ return;
611
+ }
612
+ event.preventDefault();
613
+ var target = event.target;
614
+ // A drop onto an empty placeholder is that card's own business.
615
+ if (target !== null && target !== void 0 && target.closest("[data-file-dropzone]")) {
616
+ return;
617
+ }
618
+ var dropped = (0, _fileElement.binaryFrom)(event.dataTransfer);
619
+ if (!dropped) {
620
+ return;
621
+ }
622
+ addFile(canvasPoint(event.clientX, event.clientY), _fileElement.FILE_DEFAULT_WIDTH, dropped);
623
+ onToolUsed();
624
+ };
625
+ document.addEventListener("dragover", handleDragOver);
626
+ document.addEventListener("drop", handleDrop);
627
+ return function () {
628
+ document.removeEventListener("dragover", handleDragOver);
629
+ document.removeEventListener("drop", handleDrop);
630
+ };
631
+ }, [addFile, canvasPoint, onToolUsed]);
632
+
633
+ /* ---- paste-to-place ----------------------------------------------- */
634
+
635
+ (0, _react.useEffect)(function () {
636
+ var handlePaste = function handlePaste(event) {
637
+ var _layerRef$current2, _event$clipboardData$, _event$clipboardData;
638
+ /* Only the board may claim a paste, and two different things can take it
639
+ away: a focused field keeps its own paste (the card's URL editor is
640
+ INSIDE the canvas, so "on the board" is not sufficient), and a dialog
641
+ keeps its own too — otherwise pasting with Add Users open would quietly
642
+ drop a card behind the modal. With nothing focused the target is
643
+ <body>, which is the board's own case. */
644
+ var target = event.target;
645
+ if (target !== null && target !== void 0 && target.closest("input, textarea, [contenteditable='true']")) {
646
+ return;
647
+ }
648
+ var onTheBoard = target === document.body || target != null && ((_layerRef$current2 = layerRef.current) === null || _layerRef$current2 === void 0 ? void 0 : _layerRef$current2.contains(target)) === true;
649
+ if (!onTheBoard) {
650
+ return;
651
+ }
652
+
653
+ /* Binary wins over text. A screenshot or a copied file carries both — the
654
+ bytes as an item and often a filename as text — and the bytes are the
655
+ thing the user meant. Only once there is nothing binary do we read the
656
+ clipboard as a URL. */
657
+ var binary = (0, _fileElement.binaryFrom)(event.clipboardData);
658
+ if (binary) {
659
+ event.preventDefault();
660
+ // The bytes are in hand, so the card skips the placeholder and the
661
+ // picker: it goes straight to uploading them.
662
+ addFile(pointerRef.current, _fileElement.FILE_DEFAULT_WIDTH, binary);
663
+ onToolUsed();
664
+ return;
665
+ }
666
+ var text = (_event$clipboardData$ = (_event$clipboardData = event.clipboardData) === null || _event$clipboardData === void 0 ? void 0 : _event$clipboardData.getData("text/plain")) !== null && _event$clipboardData$ !== void 0 ? _event$clipboardData$ : "";
667
+ if (!(0, _linkElement.isValidLinkUrl)(text)) {
668
+ return;
669
+ }
670
+ event.preventDefault();
671
+ // The address is already known, so this card skips the placeholder and
672
+ // the editor: it drops straight into the unfurl.
673
+ addLink(pointerRef.current, _linkElement.LINK_DEFAULT_WIDTH, text.trim());
674
+ onToolUsed();
675
+ };
676
+ document.addEventListener("paste", handlePaste);
677
+ return function () {
678
+ return document.removeEventListener("paste", handlePaste);
679
+ };
680
+ }, [addFile, addLink, onToolUsed]);
681
+ return /*#__PURE__*/_react.default.createElement(_elements.StyledCanvasLayer, {
682
+ ref: layerRef,
683
+ className: activeTool === "select" ? undefined : "drawing",
684
+ onClick: handleLayerClick,
685
+ onMouseDown: handleLayerMouseDown,
686
+ onMouseMove: handleLayerMouseMove,
687
+ onMouseLeave: handleLayerMouseLeave
688
+ }, [..._elements.CANVAS_ELEMENTS, ...createdShapes].filter(function (element) {
689
+ return !removedIds.includes(element.id);
690
+ }).map(function (element) {
691
+ var _sizes$element$id$wid, _sizes$element$id, _sizes$element$id$hei, _sizes$element$id2, _rotations$element$id, _locks$element$id, _locks$element$id2;
692
+ var selected = element.id === selectedId;
693
+ var shape = element.kind === "shape" ? shapes[element.id] : null;
694
+ var width = (_sizes$element$id$wid = (_sizes$element$id = sizes[element.id]) === null || _sizes$element$id === void 0 ? void 0 : _sizes$element$id.width) !== null && _sizes$element$id$wid !== void 0 ? _sizes$element$id$wid : element.width;
695
+ var height = (_sizes$element$id$hei = (_sizes$element$id2 = sizes[element.id]) === null || _sizes$element$id2 === void 0 ? void 0 : _sizes$element$id2.height) !== null && _sizes$element$id$hei !== void 0 ? _sizes$element$id$hei : element.height;
696
+ var rotation = (_rotations$element$id = rotations[element.id]) !== null && _rotations$element$id !== void 0 ? _rotations$element$id : 0;
697
+ return /*#__PURE__*/_react.default.createElement(_elements.StyledCanvasElement, {
698
+ key: element.id,
699
+ className: selected ? "selected" : undefined,
700
+ style: {
701
+ left: positions[element.id].x,
702
+ top: positions[element.id].y,
703
+ width,
704
+ height,
705
+ transform: rotation ? "rotate(".concat(rotation, "deg)") : undefined
706
+ },
707
+ onMouseDown: function onMouseDown(event) {
708
+ return handleElementMouseDown(event, element.id);
709
+ },
710
+ onClick: function onClick(event) {
711
+ return event.stopPropagation();
712
+ }
713
+ }, shape ? (0, _elements.renderShapeBody)(element, shape, width, height) : null, element.kind === "sticky" ? /*#__PURE__*/_react.default.createElement(_elements.StyledSticky, {
714
+ style: {
715
+ background: (0, _elements.stickyGradient)(stickyStyle.color, stickyStyle.fillOpacity),
716
+ color: stickyStyle.textColor,
717
+ fontSize: stickyStyle.fontSize,
718
+ fontWeight: stickyStyle.bold ? "bold" : "normal",
719
+ fontStyle: stickyStyle.italic ? "italic" : "normal",
720
+ textDecoration: [stickyStyle.underline ? "underline" : "", stickyStyle.strikethrough ? "line-through" : ""].filter(Boolean).join(" ") || undefined,
721
+ textAlign: stickyStyle.align
722
+ }
723
+ }, "Retro: what went well?") : null, selected && shape ? /*#__PURE__*/_react.default.createElement(_elements.ShapeFormattingToolbar, {
724
+ element: shape,
725
+ onUpdate: function onUpdate(partial) {
726
+ return updateShape(element.id, partial);
727
+ },
728
+ onDelete: handleDelete,
729
+ locked: (_locks$element$id = locks[element.id]) !== null && _locks$element$id !== void 0 ? _locks$element$id : false,
730
+ onToggleLock: function onToggleLock() {
731
+ return toggleLock(element.id);
732
+ }
733
+ }) : null, selected && element.kind === "sticky" ? /*#__PURE__*/_react.default.createElement(_elements.PostitFormattingToolbar, {
734
+ value: stickyStyle,
735
+ onChange: setStickyStyle,
736
+ onDelete: handleDelete,
737
+ locked: (_locks$element$id2 = locks[element.id]) !== null && _locks$element$id2 !== void 0 ? _locks$element$id2 : false,
738
+ onToggleLock: function onToggleLock() {
739
+ return toggleLock(element.id);
740
+ }
741
+ }) : null, selected ? /*#__PURE__*/_react.default.createElement(_elements.ResizeHandles, null) : null);
742
+ }), links.map(function (link) {
743
+ var _positions$link$id$x, _positions$link$id, _positions$link$id$y, _positions$link$id2;
744
+ var selected = link.id === selectedId;
745
+ return /*#__PURE__*/_react.default.createElement(_elements.StyledCanvasElement, {
746
+ key: link.id,
747
+ className: selected ? "is-card selected" : "is-card",
748
+ style: {
749
+ left: (_positions$link$id$x = (_positions$link$id = positions[link.id]) === null || _positions$link$id === void 0 ? void 0 : _positions$link$id.x) !== null && _positions$link$id$x !== void 0 ? _positions$link$id$x : 0,
750
+ top: (_positions$link$id$y = (_positions$link$id2 = positions[link.id]) === null || _positions$link$id2 === void 0 ? void 0 : _positions$link$id2.y) !== null && _positions$link$id$y !== void 0 ? _positions$link$id$y : 0,
751
+ width: link.width
752
+ },
753
+ onMouseDown: function onMouseDown(event) {
754
+ return handleElementMouseDown(event, link.id);
755
+ },
756
+ onClickCapture: handleElementClickCapture,
757
+ onClick: function onClick(event) {
758
+ return event.stopPropagation();
759
+ }
760
+ }, /*#__PURE__*/_react.default.createElement(_linkElement.LinkElement, {
761
+ element: link,
762
+ selected: selected,
763
+ autoEdit: link.id === autoEditId,
764
+ onCommitUrl: function onCommitUrl(url) {
765
+ return commitLinkUrl(link.id, url);
766
+ },
767
+ resize: {
768
+ onResizeStart: function onResizeStart() {
769
+ return beginResize(link.id, link.width);
770
+ },
771
+ onResizeDelta: function onResizeDelta(dx) {
772
+ return resizeLink(link.id, dx);
773
+ },
774
+ onResizeCommit: function onResizeCommit() {
775
+ return endResize(link.id);
776
+ }
777
+ },
778
+ onDelete: function onDelete() {
779
+ return deleteLink(link.id);
780
+ }
781
+ }));
782
+ }), files.map(function (entry) {
783
+ var _positions$entry$id$x, _positions$entry$id, _positions$entry$id$y, _positions$entry$id2;
784
+ var selected = entry.id === selectedId;
785
+ return /*#__PURE__*/_react.default.createElement(_elements.StyledCanvasElement, {
786
+ key: entry.id,
787
+ className: selected ? "is-card selected" : "is-card",
788
+ style: {
789
+ left: (_positions$entry$id$x = (_positions$entry$id = positions[entry.id]) === null || _positions$entry$id === void 0 ? void 0 : _positions$entry$id.x) !== null && _positions$entry$id$x !== void 0 ? _positions$entry$id$x : 0,
790
+ top: (_positions$entry$id$y = (_positions$entry$id2 = positions[entry.id]) === null || _positions$entry$id2 === void 0 ? void 0 : _positions$entry$id2.y) !== null && _positions$entry$id$y !== void 0 ? _positions$entry$id$y : 0,
791
+ width: entry.width
792
+ },
793
+ onMouseDown: function onMouseDown(event) {
794
+ return handleElementMouseDown(event, entry.id);
795
+ },
796
+ onClickCapture: handleElementClickCapture,
797
+ onClick: function onClick(event) {
798
+ return event.stopPropagation();
799
+ }
800
+ }, /*#__PURE__*/_react.default.createElement(_fileElement.FileElement, {
801
+ element: entry,
802
+ selected: selected,
803
+ autoOpen: entry.id === autoOpenId,
804
+ onPickFile: function onPickFile(picked) {
805
+ return attachFile(entry.id, picked);
806
+ },
807
+ resize: {
808
+ onResizeStart: function onResizeStart() {
809
+ return beginResize(entry.id, entry.width);
810
+ },
811
+ onResizeDelta: function onResizeDelta(dx) {
812
+ return resizeFile(entry.id, dx);
813
+ },
814
+ onResizeCommit: function onResizeCommit() {
815
+ return endResize(entry.id);
816
+ }
817
+ },
818
+ onCancel: function onCancel() {
819
+ return detachFile(entry.id);
820
+ },
821
+ onDelete: function onDelete() {
822
+ return deleteFile(entry.id);
823
+ }
824
+ }));
825
+ }), draft && !(0, _bottomDock.isShapeTool)(draft.tool) ? /*#__PURE__*/_react.default.createElement(_linkElement.StyledLinkDraft, {
826
+ style: {
827
+ left: draft.x,
828
+ top: draft.y,
829
+ width: Math.max(draft.width, 1),
830
+ height: Math.max(draft.height, 1)
831
+ }
832
+ }, /*#__PURE__*/_react.default.createElement("span", {
833
+ className: "draft-width"
834
+ }, "W", " ", draft.width >= _linkElement.CARD_DRAW_THRESHOLD ? (0, _linkElement.clampCardWidth)(draft.width) : draft.tool === "file" ? _fileElement.FILE_DEFAULT_WIDTH : _linkElement.LINK_DEFAULT_WIDTH, " ", "\xB7 height follows content")) : null, draft && (0, _bottomDock.isShapeTool)(draft.tool) ? /*#__PURE__*/_react.default.createElement(_linkElement.StyledShapePreview, {
835
+ style: {
836
+ left: draft.x,
837
+ top: draft.y,
838
+ width: Math.max(draft.width, 1),
839
+ height: Math.max(draft.height, 1)
840
+ }
841
+ }, (0, _linkElement.shapePreviewGlyph)(draft.tool, Math.max(draft.width, 1), Math.max(draft.height, 1))) : null, hoverPoint && !draft && activeTool !== "select" ? function () {
842
+ var step = snapStepRef.current;
843
+ var at = {
844
+ x: (0, _elements.snapValue)(hoverPoint.x, step),
845
+ y: (0, _elements.snapValue)(hoverPoint.y, step)
846
+ };
847
+ if ((0, _bottomDock.isShapeTool)(activeTool)) {
848
+ var size = _bottomDock.SHAPE_DEFAULT_SIZES[activeTool];
849
+ return /*#__PURE__*/_react.default.createElement(_linkElement.StyledShapePreview, {
850
+ style: _objectSpread({
851
+ left: at.x,
852
+ top: at.y
853
+ }, size)
854
+ }, (0, _linkElement.shapePreviewGlyph)(activeTool, size.width, size.height));
855
+ }
856
+ var width = activeTool === "file" ? _fileElement.FILE_DEFAULT_WIDTH : _linkElement.LINK_DEFAULT_WIDTH;
857
+ return /*#__PURE__*/_react.default.createElement(_linkElement.StyledShapePreview, {
858
+ style: {
859
+ left: at.x,
860
+ top: at.y,
861
+ width,
862
+ height: _bottomDock.CARD_PREVIEW_HEIGHT
863
+ }
864
+ }, /*#__PURE__*/_react.default.createElement("svg", {
865
+ width: "100%",
866
+ height: "100%"
867
+ }, /*#__PURE__*/_react.default.createElement("rect", {
868
+ x: "0",
869
+ y: "0",
870
+ width: "100%",
871
+ height: "100%",
872
+ rx: 8,
873
+ ry: 8
874
+ })));
875
+ }() : null);
876
+ };
877
+ //# sourceMappingURL=canvasElements.js.map