tldraw 5.2.3 → 5.2.5

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/DOCS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # tldraw Documentation
2
2
 
3
- Version: `5.2.3`
3
+ Version: `5.2.5`
4
4
 
5
5
  This file is generated during package publishing from the tldraw docs content for this exact package version.
6
6
 
package/RELEASE_NOTES.md CHANGED
@@ -1,12 +1,49 @@
1
1
  # Releases
2
2
 
3
- Version: `5.2.3`
3
+ Version: `5.2.5`
4
4
 
5
5
  This file is generated during package publishing from the tldraw release notes content for this exact package version.
6
6
 
7
- ## v5.2.3
7
+ ## v5.2.5
8
8
 
9
+ This release adds snapping and symmetric resizing while cropping images, a reactive `Editor.getIsMounted()` with a new `unmount` event, and faster viewport culling on large pages. It also fixes a batch of crashes and interaction bugs across arrows, groups, and text.
9
10
 
11
+ ### What's new
12
+
13
+ #### Snapping and symmetric resize while cropping ([#9424](https://github.com/tldraw/tldraw/pull/9424))
14
+
15
+ When cropping an image, crop edges now snap to other shapes and the grid, with the usual snapping guidelines. Holding option resizes the crop region symmetrically from its center.
16
+
17
+ ### API changes
18
+
19
+ - Add an `unmount` event to `TLEventMap` and make `Editor.getIsMounted()` a reactive value that tracks whether the editor's component is currently mounted. ([#9472](https://github.com/tldraw/tldraw/pull/9472), [#9483](https://github.com/tldraw/tldraw/pull/9483))
20
+ - Make the shape hit-test margin pointer-aware and add a `coarseHitTestMargin` option: fine pointers (mouse and trackpad) use a tighter 3px default, coarse pointers (touch and pen) use 4px. ([#9492](https://github.com/tldraw/tldraw/pull/9492))
21
+
22
+ ### Improvements
23
+
24
+ - Improve viewport culling performance on large pages: the spatial index now rechecks only the shapes affected by a change instead of every shape on the page. Custom shapes whose geometry depends on unrelated shapes (outside parent/child and binding relationships) are no longer automatically rechecked for culling when those shapes change; built-in shapes and standard patterns are unaffected. ([#9093](https://github.com/tldraw/tldraw/pull/9093))
25
+ - Improve performance when deleting many shapes at once by batching page state cleanup. ([#9456](https://github.com/tldraw/tldraw/pull/9456))
26
+ - Make long toast and dialog content wrap instead of overflowing, so long strings like URLs stay within the toast or dialog. ([#9546](https://github.com/tldraw/tldraw/pull/9546))
27
+ - Delay the appearance of the "back to content" button by about a second so it no longer flickers during normal panning and zooming. Hiding stays immediate. ([#9448](https://github.com/tldraw/tldraw/pull/9448))
28
+ - Remove the unnecessary ellipsis from the "Keyboard shortcuts" menu item. ([#9570](https://github.com/tldraw/tldraw/pull/9570))
29
+
30
+ ### Bug fixes
31
+
32
+ - Fix rich text headings (H1–H6) rendering with their line-height too tight, causing overlapping lines. ([#9543](https://github.com/tldraw/tldraw/pull/9543))
33
+ - Fix the style panel not highlighting the active fill correctly when the current fill lives in the overflow dropdown. ([#9509](https://github.com/tldraw/tldraw/pull/9509)) (contributed by [@meg-an31](https://github.com/meg-an31))
34
+ - Fix the style panel Shape, Line, and spline dropdown popovers so they open with the same gap as the other dropdowns. ([#9491](https://github.com/tldraw/tldraw/pull/9491))
35
+ - Fix double-clicking a shape inside an unfocused group immediately editing it; a double-click now drills one level into the group. ([#9488](https://github.com/tldraw/tldraw/pull/9488))
36
+ - Fix selected clipped arrows so they can be dragged when their geometry extends outside a clipping parent. ([#9479](https://github.com/tldraw/tldraw/pull/9479))
37
+ - Fix arrows bound to frames so they duplicate and delete with the frame without being clipped. ([#9470](https://github.com/tldraw/tldraw/pull/9470))
38
+ - Fix a shape dragged from the toolbar to a frame beneath the toolbar not being parented to the frame. ([#9458](https://github.com/tldraw/tldraw/pull/9458))
39
+ - Fix a missing `onChildrenChange` call when creating a shape directly within a parent shape. ([#9455](https://github.com/tldraw/tldraw/pull/9455))
40
+ - Fix the reactive Meta (Cmd) key state not clearing on keyup until a pointer event on macOS, which affected `getMetaKey()` and `getAccelKey()`. ([#9404](https://github.com/tldraw/tldraw/pull/9404))
41
+ - Fix a crash when dragging a handle on a line whose point keys differed from their indices. ([#9299](https://github.com/tldraw/tldraw/pull/9299))
42
+ - Fix arrow bindings floating outside a geo shape after changing its geo type; precise bindings now re-snap to the nearest point on the new shape. ([#9281](https://github.com/tldraw/tldraw/pull/9281))
43
+ - Fix an occasional crash in text measurement by iterating over grapheme clusters instead of individual characters, keeping emoji, flags, and accented characters intact. ([#9266](https://github.com/tldraw/tldraw/pull/9266))
44
+ - Fix a crash ("Shape not found") when dragging a tool from the toolbar in a read-only room. ([#9225](https://github.com/tldraw/tldraw/pull/9225))
45
+ - Fix sync clients not recovering from a malformed WebSocket message; they now restart the connection so a corrupt frame can no longer silently leave the client out of sync. ([#9380](https://github.com/tldraw/tldraw/pull/9380))
46
+ - Fix uploaded asset handling for invalid R2 object names. ([#9495](https://github.com/tldraw/tldraw/pull/9495))
10
47
 
11
48
  ## v5.2.0
12
49
 
package/dist-cjs/index.js CHANGED
@@ -648,7 +648,7 @@ var import_buildFromV1Document = require("./lib/utils/tldr/buildFromV1Document")
648
648
  var import_file = require("./lib/utils/tldr/file");
649
649
  (0, import_editor.registerTldrawLibraryVersion)(
650
650
  "tldraw",
651
- "5.2.3",
651
+ "5.2.5",
652
652
  "cjs"
653
653
  );
654
654
  //# sourceMappingURL=index.js.map
@@ -262,8 +262,8 @@ function DrawShapeSvg({
262
262
  }
263
263
  const strokePoints = (0, import_getStrokePoints.getStrokePoints)(allPointsFromSegments, options);
264
264
  const isDot = strokePoints.length < 2;
265
- const solidStrokePath = isDot ? getDot(allPointsFromSegments[0], 0) : (0, import_svg.getSvgPathFromStrokePoints)(strokePoints, shape.props.isClosed);
266
265
  const fill = isDot || shape.props.isClosed ? shape.props.fill : "none";
266
+ const solidStrokePath = isDot ? getDot(allPointsFromSegments[0], 0) : (0, import_svg.getSvgPathFromStrokePoints)(strokePoints, shape.props.isClosed && fill !== "none");
267
267
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
268
268
  isDot || !shape.props.isClosed || fill === "none" ? null : fill === "pattern" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
269
269
  import_PatternFill.PatternFill,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/draw/DrawShapeUtil.tsx"],
4
- "sourcesContent": ["import {\n\tBox,\n\tCircle2d,\n\tPolygon2d,\n\tPolyline2d,\n\tSVGContainer,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLDrawShape,\n\tTLDrawShapeProps,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVecLike,\n\tb64Vecs,\n\tdrawShapeMigrations,\n\tdrawShapeProps,\n\tgetColorValue,\n\tlast,\n\tlerp,\n\trng,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { STROKE_SIZES } from '../shared/default-shape-constants'\nimport { DEFAULT_FILL_COLOR_NAMES } from '../shared/defaultFills'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { svgInk } from '../shared/freehand/svgInk'\nimport { ShapeOptionsWithDisplayValues, getDisplayValues } from '../shared/getDisplayValues'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { PatternFill } from '../shared/PatternFill'\nimport {\n\tgetDrawShapeStrokeDashArray,\n\tgetFreehandOptions,\n\tgetPointsFromDrawSegments,\n} from './getPath'\n\n/** @public */\nexport interface DrawShapeUtilDisplayValues {\n\tstrokeColor: string\n\tstrokeWidth: number\n\tfillColor: string\n\tpatternFillFallbackColor: string\n}\n\n/** @public */\nexport interface DrawShapeOptions extends ShapeOptionsWithDisplayValues<\n\tTLDrawShape,\n\tDrawShapeUtilDisplayValues\n> {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n}\n\n/** @public */\nexport class DrawShapeUtil extends ShapeUtil<TLDrawShape> {\n\tstatic override type = 'draw' as const\n\tstatic override props = drawShapeProps\n\tstatic override migrations = drawShapeMigrations\n\n\toverride options: DrawShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t\tgetDefaultDisplayValues(_editor, shape, theme, colorMode): DrawShapeUtilDisplayValues {\n\t\t\tconst { color, fill, size } = shape.props\n\t\t\tconst colors = theme.colors[colorMode]\n\t\t\treturn {\n\t\t\t\tstrokeColor: getColorValue(colors, color, 'solid'),\n\t\t\t\tstrokeWidth: theme.strokeWidth * STROKE_SIZES[size],\n\t\t\t\tfillColor:\n\t\t\t\t\tfill === 'none'\n\t\t\t\t\t\t? 'transparent'\n\t\t\t\t\t\t: fill === 'semi'\n\t\t\t\t\t\t\t? colors.solid\n\t\t\t\t\t\t\t: getColorValue(colors, color, DEFAULT_FILL_COLOR_NAMES[fill]),\n\t\t\t\tpatternFillFallbackColor: getColorValue(colors, color, 'semi'),\n\t\t\t}\n\t\t},\n\t\tgetCustomDisplayValues(): Partial<DrawShapeUtilDisplayValues> {\n\t\t\treturn {}\n\t\t},\n\t}\n\n\toverride hideResizeHandles(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLDrawShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tfill: 'none',\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisClosed: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t\tscaleX: 1,\n\t\t\tscaleY: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLDrawShape) {\n\t\tconst points = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tconst sw = (getDisplayValues(this, shape).strokeWidth + 1) * shape.props.scale\n\n\t\t// A dot\n\t\tif (shape.props.segments.length === 1) {\n\t\t\tconst box = Box.FromPoints(points)\n\t\t\tif (box.width < sw * 2 && box.height < sw * 2) {\n\t\t\t\treturn new Circle2d({\n\t\t\t\t\tx: -sw,\n\t\t\t\t\ty: -sw,\n\t\t\t\t\tradius: sw,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst strokePoints = getStrokePoints(\n\t\t\tpoints,\n\t\t\tgetFreehandOptions(shape.props, sw, shape.props.isPen, true)\n\t\t).map((p) => p.point)\n\n\t\t// A closed draw stroke\n\t\tif (shape.props.isClosed && strokePoints.length > 2) {\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: strokePoints,\n\t\t\t\tisFilled: shape.props.fill !== 'none',\n\t\t\t})\n\t\t}\n\n\t\tif (strokePoints.length === 1) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -sw,\n\t\t\t\ty: -sw,\n\t\t\t\tradius: sw,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\t// An open draw stroke\n\t\treturn new Polyline2d({\n\t\t\tpoints: strokePoints,\n\t\t})\n\t}\n\n\tcomponent(shape: TLDrawShape) {\n\t\tconst dv = getDisplayValues(this, shape)\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DrawShapeSvg\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tstrokeColor={dv.strokeColor}\n\t\t\t\t\tstrokeWidth={dv.strokeWidth}\n\t\t\t\t\tfillColor={dv.fillColor}\n\t\t\t\t\tpatternFillFallbackColor={dv.patternFillFallbackColor}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\toverride getIndicatorPath(shape: TLDrawShape): Path2D {\n\t\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tlet sw = (getDisplayValues(this, shape).strokeWidth + 1) * shape.props.scale\n\n\t\tconst zoomLevel = this.editor.getEfficientZoomLevel()\n\t\tconst forceSolid = zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\n\t\tif (\n\t\t\t!forceSolid &&\n\t\t\t!shape.props.isPen &&\n\t\t\tshape.props.dash === 'draw' &&\n\t\t\tallPointsFromSegments.length === 1\n\t\t) {\n\t\t\tsw += rng(shape.id)() * (sw / 6)\n\t\t}\n\n\t\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\t\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, true)\n\t\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\t\tconst solidStrokePath =\n\t\t\tstrokePoints.length > 1\n\t\t\t\t? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\t\t\t\t: getDot(allPointsFromSegments[0], sw)\n\n\t\treturn new Path2D(solidStrokePath)\n\t}\n\n\toverride toSvg(shape: TLDrawShape, ctx: SvgExportContext) {\n\t\tctx.addExportDef(getFillDefForExport(shape.props.fill))\n\t\tconst dv = getDisplayValues(this, shape, ctx.colorMode)\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<DrawShapeSvg\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tzoomOverride={1}\n\t\t\t\t\tstrokeColor={dv.strokeColor}\n\t\t\t\t\tstrokeWidth={dv.strokeWidth}\n\t\t\t\t\tfillColor={dv.fillColor}\n\t\t\t\t\tpatternFillFallbackColor={dv.patternFillFallbackColor}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(shape: TLDrawShape, info: TLResizeInfo<TLDrawShape>) {\n\t\tconst newScaleX = info.scaleX * shape.props.scaleX\n\t\tconst newScaleY = info.scaleY * shape.props.scaleY\n\t\tif (newScaleX === 0 || newScaleY === 0) return\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tscaleX: newScaleX,\n\t\t\t\tscaleY: newScaleY,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride expandSelectionOutlinePx(shape: TLDrawShape): number {\n\t\tconst multiplier = shape.props.dash === 'draw' ? 1.6 : 1\n\t\treturn ((getDisplayValues(this, shape).strokeWidth * multiplier) / 2) * shape.props.scale\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLDrawShape,\n\t\tendShape: TLDrawShape,\n\t\tt: number\n\t): TLDrawShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getDot(point: VecLike, sw: number) {\n\tconst r = (sw + 1) * 0.5\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIsDot(shape: TLDrawShape) {\n\t// A dot is a single-point segment. isSinglePoint knows the per-encoding length\n\t// (and takes the segment's dim), so this stays correct for both 2D and 3D paths.\n\t// A bare length threshold can't: a 2-point 2D path is the same length as a 1-point\n\t// 3D path, so only the dim disambiguates them.\n\tconst segment = shape.props.segments[0]\n\treturn shape.props.segments.length === 1 && b64Vecs.isSinglePoint(segment.path, segment.dim)\n}\n\nfunction DrawShapeSvg({\n\tshape,\n\tzoomOverride,\n\tstrokeColor,\n\tstrokeWidth: baseStrokeWidth,\n\tfillColor,\n\tpatternFillFallbackColor,\n}: {\n\tshape: TLDrawShape\n\tzoomOverride?: number\n\tstrokeColor: string\n\tstrokeWidth: number\n\tfillColor: string\n\tpatternFillFallbackColor: string\n}) {\n\tconst editor = useEditor()\n\n\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\tshape.props.segments,\n\t\tshape.props.scaleX,\n\t\tshape.props.scaleY\n\t)\n\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = (baseStrokeWidth + 1) * shape.props.scale\n\tconst forceSolid = useValue(\n\t\t'force solid',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel()\n\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t},\n\t\t[editor, sw, zoomOverride]\n\t)\n\n\tconst dotAdjustment = useValue(\n\t\t'dot adjustment',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel()\n\t\t\t// If we're zoomed way out (10%), then we need to make the dotted line go to 9 instead 0.1\n\t\t\t// Chrome doesn't render anything otherwise.\n\t\t\treturn zoomLevel < 0.2 ? 9 : 0.1\n\t\t},\n\t\t[editor, zoomOverride]\n\t)\n\n\tif (\n\t\t!forceSolid &&\n\t\t!shape.props.isPen &&\n\t\tshape.props.dash === 'draw' &&\n\t\tallPointsFromSegments.length === 1\n\t) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, forceSolid)\n\n\tif (!forceSolid && shape.props.dash === 'draw') {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{shape.props.isClosed &&\n\t\t\t\t\tshape.props.fill !== 'none' &&\n\t\t\t\t\tallPointsFromSegments.length > 1 &&\n\t\t\t\t\t(shape.props.fill === 'pattern' ? (\n\t\t\t\t\t\t<PatternFill\n\t\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tfillColor={fillColor}\n\t\t\t\t\t\t\tpatternFillFallbackColor={patternFillFallbackColor}\n\t\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\tfill={fillColor}\n\t\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t<path d={svgInk(allPointsFromSegments, options)} strokeLinecap=\"round\" fill={strokeColor} />\n\t\t\t</>\n\t\t)\n\t}\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\tconst isDot = strokePoints.length < 2\n\tconst solidStrokePath = isDot\n\t\t? getDot(allPointsFromSegments[0], 0)\n\t\t: getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\n\tconst fill = isDot || shape.props.isClosed ? shape.props.fill : 'none'\n\n\treturn (\n\t\t<>\n\t\t\t{isDot || !shape.props.isClosed || fill === 'none' ? null : fill === 'pattern' ? (\n\t\t\t\t<PatternFill\n\t\t\t\t\td={solidStrokePath}\n\t\t\t\t\tfillColor={fillColor}\n\t\t\t\t\tpatternFillFallbackColor={patternFillFallbackColor}\n\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<path fill={fillColor} d={solidStrokePath} />\n\t\t\t)}\n\t\t\t{shape.props.dash !== 'none' && (\n\t\t\t\t<path\n\t\t\t\t\td={solidStrokePath}\n\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\tfill={isDot ? strokeColor : 'none'}\n\t\t\t\t\tstroke={strokeColor}\n\t\t\t\t\tstrokeWidth={sw}\n\t\t\t\t\tstrokeDasharray={isDot ? 'none' : getDrawShapeStrokeDashArray(shape, sw, dotAdjustment)}\n\t\t\t\t\tstrokeDashoffset=\"0\"\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tBox,\n\tCircle2d,\n\tPolygon2d,\n\tPolyline2d,\n\tSVGContainer,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLDrawShape,\n\tTLDrawShapeProps,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVecLike,\n\tb64Vecs,\n\tdrawShapeMigrations,\n\tdrawShapeProps,\n\tgetColorValue,\n\tlast,\n\tlerp,\n\trng,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { STROKE_SIZES } from '../shared/default-shape-constants'\nimport { DEFAULT_FILL_COLOR_NAMES } from '../shared/defaultFills'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { svgInk } from '../shared/freehand/svgInk'\nimport { ShapeOptionsWithDisplayValues, getDisplayValues } from '../shared/getDisplayValues'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { PatternFill } from '../shared/PatternFill'\nimport {\n\tgetDrawShapeStrokeDashArray,\n\tgetFreehandOptions,\n\tgetPointsFromDrawSegments,\n} from './getPath'\n\n/** @public */\nexport interface DrawShapeUtilDisplayValues {\n\tstrokeColor: string\n\tstrokeWidth: number\n\tfillColor: string\n\tpatternFillFallbackColor: string\n}\n\n/** @public */\nexport interface DrawShapeOptions extends ShapeOptionsWithDisplayValues<\n\tTLDrawShape,\n\tDrawShapeUtilDisplayValues\n> {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n}\n\n/** @public */\nexport class DrawShapeUtil extends ShapeUtil<TLDrawShape> {\n\tstatic override type = 'draw' as const\n\tstatic override props = drawShapeProps\n\tstatic override migrations = drawShapeMigrations\n\n\toverride options: DrawShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t\tgetDefaultDisplayValues(_editor, shape, theme, colorMode): DrawShapeUtilDisplayValues {\n\t\t\tconst { color, fill, size } = shape.props\n\t\t\tconst colors = theme.colors[colorMode]\n\t\t\treturn {\n\t\t\t\tstrokeColor: getColorValue(colors, color, 'solid'),\n\t\t\t\tstrokeWidth: theme.strokeWidth * STROKE_SIZES[size],\n\t\t\t\tfillColor:\n\t\t\t\t\tfill === 'none'\n\t\t\t\t\t\t? 'transparent'\n\t\t\t\t\t\t: fill === 'semi'\n\t\t\t\t\t\t\t? colors.solid\n\t\t\t\t\t\t\t: getColorValue(colors, color, DEFAULT_FILL_COLOR_NAMES[fill]),\n\t\t\t\tpatternFillFallbackColor: getColorValue(colors, color, 'semi'),\n\t\t\t}\n\t\t},\n\t\tgetCustomDisplayValues(): Partial<DrawShapeUtilDisplayValues> {\n\t\t\treturn {}\n\t\t},\n\t}\n\n\toverride hideResizeHandles(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLDrawShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tfill: 'none',\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisClosed: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t\tscaleX: 1,\n\t\t\tscaleY: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLDrawShape) {\n\t\tconst points = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tconst sw = (getDisplayValues(this, shape).strokeWidth + 1) * shape.props.scale\n\n\t\t// A dot\n\t\tif (shape.props.segments.length === 1) {\n\t\t\tconst box = Box.FromPoints(points)\n\t\t\tif (box.width < sw * 2 && box.height < sw * 2) {\n\t\t\t\treturn new Circle2d({\n\t\t\t\t\tx: -sw,\n\t\t\t\t\ty: -sw,\n\t\t\t\t\tradius: sw,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst strokePoints = getStrokePoints(\n\t\t\tpoints,\n\t\t\tgetFreehandOptions(shape.props, sw, shape.props.isPen, true)\n\t\t).map((p) => p.point)\n\n\t\t// A closed draw stroke\n\t\tif (shape.props.isClosed && strokePoints.length > 2) {\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: strokePoints,\n\t\t\t\tisFilled: shape.props.fill !== 'none',\n\t\t\t})\n\t\t}\n\n\t\tif (strokePoints.length === 1) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -sw,\n\t\t\t\ty: -sw,\n\t\t\t\tradius: sw,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\t// An open draw stroke\n\t\treturn new Polyline2d({\n\t\t\tpoints: strokePoints,\n\t\t})\n\t}\n\n\tcomponent(shape: TLDrawShape) {\n\t\tconst dv = getDisplayValues(this, shape)\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DrawShapeSvg\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tstrokeColor={dv.strokeColor}\n\t\t\t\t\tstrokeWidth={dv.strokeWidth}\n\t\t\t\t\tfillColor={dv.fillColor}\n\t\t\t\t\tpatternFillFallbackColor={dv.patternFillFallbackColor}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\toverride getIndicatorPath(shape: TLDrawShape): Path2D {\n\t\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tlet sw = (getDisplayValues(this, shape).strokeWidth + 1) * shape.props.scale\n\n\t\tconst zoomLevel = this.editor.getEfficientZoomLevel()\n\t\tconst forceSolid = zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\n\t\tif (\n\t\t\t!forceSolid &&\n\t\t\t!shape.props.isPen &&\n\t\t\tshape.props.dash === 'draw' &&\n\t\t\tallPointsFromSegments.length === 1\n\t\t) {\n\t\t\tsw += rng(shape.id)() * (sw / 6)\n\t\t}\n\n\t\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\t\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, true)\n\t\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\t\tconst solidStrokePath =\n\t\t\tstrokePoints.length > 1\n\t\t\t\t? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\t\t\t\t: getDot(allPointsFromSegments[0], sw)\n\n\t\treturn new Path2D(solidStrokePath)\n\t}\n\n\toverride toSvg(shape: TLDrawShape, ctx: SvgExportContext) {\n\t\tctx.addExportDef(getFillDefForExport(shape.props.fill))\n\t\tconst dv = getDisplayValues(this, shape, ctx.colorMode)\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<DrawShapeSvg\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tzoomOverride={1}\n\t\t\t\t\tstrokeColor={dv.strokeColor}\n\t\t\t\t\tstrokeWidth={dv.strokeWidth}\n\t\t\t\t\tfillColor={dv.fillColor}\n\t\t\t\t\tpatternFillFallbackColor={dv.patternFillFallbackColor}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(shape: TLDrawShape, info: TLResizeInfo<TLDrawShape>) {\n\t\tconst newScaleX = info.scaleX * shape.props.scaleX\n\t\tconst newScaleY = info.scaleY * shape.props.scaleY\n\t\tif (newScaleX === 0 || newScaleY === 0) return\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tscaleX: newScaleX,\n\t\t\t\tscaleY: newScaleY,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride expandSelectionOutlinePx(shape: TLDrawShape): number {\n\t\tconst multiplier = shape.props.dash === 'draw' ? 1.6 : 1\n\t\treturn ((getDisplayValues(this, shape).strokeWidth * multiplier) / 2) * shape.props.scale\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLDrawShape,\n\t\tendShape: TLDrawShape,\n\t\tt: number\n\t): TLDrawShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getDot(point: VecLike, sw: number) {\n\tconst r = (sw + 1) * 0.5\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIsDot(shape: TLDrawShape) {\n\t// A dot is a single-point segment. isSinglePoint knows the per-encoding length\n\t// (and takes the segment's dim), so this stays correct for both 2D and 3D paths.\n\t// A bare length threshold can't: a 2-point 2D path is the same length as a 1-point\n\t// 3D path, so only the dim disambiguates them.\n\tconst segment = shape.props.segments[0]\n\treturn shape.props.segments.length === 1 && b64Vecs.isSinglePoint(segment.path, segment.dim)\n}\n\nfunction DrawShapeSvg({\n\tshape,\n\tzoomOverride,\n\tstrokeColor,\n\tstrokeWidth: baseStrokeWidth,\n\tfillColor,\n\tpatternFillFallbackColor,\n}: {\n\tshape: TLDrawShape\n\tzoomOverride?: number\n\tstrokeColor: string\n\tstrokeWidth: number\n\tfillColor: string\n\tpatternFillFallbackColor: string\n}) {\n\tconst editor = useEditor()\n\n\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\tshape.props.segments,\n\t\tshape.props.scaleX,\n\t\tshape.props.scaleY\n\t)\n\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = (baseStrokeWidth + 1) * shape.props.scale\n\tconst forceSolid = useValue(\n\t\t'force solid',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel()\n\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t},\n\t\t[editor, sw, zoomOverride]\n\t)\n\n\tconst dotAdjustment = useValue(\n\t\t'dot adjustment',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel()\n\t\t\t// If we're zoomed way out (10%), then we need to make the dotted line go to 9 instead 0.1\n\t\t\t// Chrome doesn't render anything otherwise.\n\t\t\treturn zoomLevel < 0.2 ? 9 : 0.1\n\t\t},\n\t\t[editor, zoomOverride]\n\t)\n\n\tif (\n\t\t!forceSolid &&\n\t\t!shape.props.isPen &&\n\t\tshape.props.dash === 'draw' &&\n\t\tallPointsFromSegments.length === 1\n\t) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, forceSolid)\n\n\tif (!forceSolid && shape.props.dash === 'draw') {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{shape.props.isClosed &&\n\t\t\t\t\tshape.props.fill !== 'none' &&\n\t\t\t\t\tallPointsFromSegments.length > 1 &&\n\t\t\t\t\t(shape.props.fill === 'pattern' ? (\n\t\t\t\t\t\t<PatternFill\n\t\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tfillColor={fillColor}\n\t\t\t\t\t\t\tpatternFillFallbackColor={patternFillFallbackColor}\n\t\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\tfill={fillColor}\n\t\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t<path d={svgInk(allPointsFromSegments, options)} strokeLinecap=\"round\" fill={strokeColor} />\n\t\t\t</>\n\t\t)\n\t}\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\tconst isDot = strokePoints.length < 2\n\tconst fill = isDot || shape.props.isClosed ? shape.props.fill : 'none'\n\n\tconst solidStrokePath = isDot\n\t\t? getDot(allPointsFromSegments[0], 0)\n\t\t: getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed && fill !== 'none')\n\n\treturn (\n\t\t<>\n\t\t\t{isDot || !shape.props.isClosed || fill === 'none' ? null : fill === 'pattern' ? (\n\t\t\t\t<PatternFill\n\t\t\t\t\td={solidStrokePath}\n\t\t\t\t\tfillColor={fillColor}\n\t\t\t\t\tpatternFillFallbackColor={patternFillFallbackColor}\n\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<path fill={fillColor} d={solidStrokePath} />\n\t\t\t)}\n\t\t\t{shape.props.dash !== 'none' && (\n\t\t\t\t<path\n\t\t\t\t\td={solidStrokePath}\n\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\tfill={isDot ? strokeColor : 'none'}\n\t\t\t\t\tstroke={strokeColor}\n\t\t\t\t\tstrokeWidth={sw}\n\t\t\t\t\tstrokeDasharray={isDot ? 'none' : getDrawShapeStrokeDashArray(shape, sw, dotAdjustment)}\n\t\t\t\t\tstrokeDashoffset=\"0\"\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -22,10 +22,10 @@ __export(version_exports, {
22
22
  version: () => version
23
23
  });
24
24
  module.exports = __toCommonJS(version_exports);
25
- const version = "5.2.3";
25
+ const version = "5.2.5";
26
26
  const publishDates = {
27
27
  major: "2026-05-06T16:28:18.473Z",
28
28
  minor: "2026-07-01T09:20:01.735Z",
29
- patch: "2026-07-06T16:50:48.696Z"
29
+ patch: "2026-07-15T23:10:03.621Z"
30
30
  };
31
31
  //# sourceMappingURL=version.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/ui/version.ts"],
4
- "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '5.2.3'\nexport const publishDates = {\n\tmajor: '2026-05-06T16:28:18.473Z',\n\tminor: '2026-07-01T09:20:01.735Z',\n\tpatch: '2026-07-06T16:50:48.696Z',\n}\n"],
4
+ "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '5.2.5'\nexport const publishDates = {\n\tmajor: '2026-05-06T16:28:18.473Z',\n\tminor: '2026-07-01T09:20:01.735Z',\n\tpatch: '2026-07-15T23:10:03.621Z',\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -634,7 +634,7 @@ import {
634
634
  } from "./lib/utils/tldr/file.mjs";
635
635
  registerTldrawLibraryVersion(
636
636
  "tldraw",
637
- "5.2.3",
637
+ "5.2.5",
638
638
  "esm"
639
639
  );
640
640
  export {
@@ -259,8 +259,8 @@ function DrawShapeSvg({
259
259
  }
260
260
  const strokePoints = getStrokePoints(allPointsFromSegments, options);
261
261
  const isDot = strokePoints.length < 2;
262
- const solidStrokePath = isDot ? getDot(allPointsFromSegments[0], 0) : getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed);
263
262
  const fill = isDot || shape.props.isClosed ? shape.props.fill : "none";
263
+ const solidStrokePath = isDot ? getDot(allPointsFromSegments[0], 0) : getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed && fill !== "none");
264
264
  return /* @__PURE__ */ jsxs(Fragment, { children: [
265
265
  isDot || !shape.props.isClosed || fill === "none" ? null : fill === "pattern" ? /* @__PURE__ */ jsx(
266
266
  PatternFill,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/draw/DrawShapeUtil.tsx"],
4
- "sourcesContent": ["import {\n\tBox,\n\tCircle2d,\n\tPolygon2d,\n\tPolyline2d,\n\tSVGContainer,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLDrawShape,\n\tTLDrawShapeProps,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVecLike,\n\tb64Vecs,\n\tdrawShapeMigrations,\n\tdrawShapeProps,\n\tgetColorValue,\n\tlast,\n\tlerp,\n\trng,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { STROKE_SIZES } from '../shared/default-shape-constants'\nimport { DEFAULT_FILL_COLOR_NAMES } from '../shared/defaultFills'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { svgInk } from '../shared/freehand/svgInk'\nimport { ShapeOptionsWithDisplayValues, getDisplayValues } from '../shared/getDisplayValues'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { PatternFill } from '../shared/PatternFill'\nimport {\n\tgetDrawShapeStrokeDashArray,\n\tgetFreehandOptions,\n\tgetPointsFromDrawSegments,\n} from './getPath'\n\n/** @public */\nexport interface DrawShapeUtilDisplayValues {\n\tstrokeColor: string\n\tstrokeWidth: number\n\tfillColor: string\n\tpatternFillFallbackColor: string\n}\n\n/** @public */\nexport interface DrawShapeOptions extends ShapeOptionsWithDisplayValues<\n\tTLDrawShape,\n\tDrawShapeUtilDisplayValues\n> {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n}\n\n/** @public */\nexport class DrawShapeUtil extends ShapeUtil<TLDrawShape> {\n\tstatic override type = 'draw' as const\n\tstatic override props = drawShapeProps\n\tstatic override migrations = drawShapeMigrations\n\n\toverride options: DrawShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t\tgetDefaultDisplayValues(_editor, shape, theme, colorMode): DrawShapeUtilDisplayValues {\n\t\t\tconst { color, fill, size } = shape.props\n\t\t\tconst colors = theme.colors[colorMode]\n\t\t\treturn {\n\t\t\t\tstrokeColor: getColorValue(colors, color, 'solid'),\n\t\t\t\tstrokeWidth: theme.strokeWidth * STROKE_SIZES[size],\n\t\t\t\tfillColor:\n\t\t\t\t\tfill === 'none'\n\t\t\t\t\t\t? 'transparent'\n\t\t\t\t\t\t: fill === 'semi'\n\t\t\t\t\t\t\t? colors.solid\n\t\t\t\t\t\t\t: getColorValue(colors, color, DEFAULT_FILL_COLOR_NAMES[fill]),\n\t\t\t\tpatternFillFallbackColor: getColorValue(colors, color, 'semi'),\n\t\t\t}\n\t\t},\n\t\tgetCustomDisplayValues(): Partial<DrawShapeUtilDisplayValues> {\n\t\t\treturn {}\n\t\t},\n\t}\n\n\toverride hideResizeHandles(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLDrawShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tfill: 'none',\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisClosed: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t\tscaleX: 1,\n\t\t\tscaleY: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLDrawShape) {\n\t\tconst points = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tconst sw = (getDisplayValues(this, shape).strokeWidth + 1) * shape.props.scale\n\n\t\t// A dot\n\t\tif (shape.props.segments.length === 1) {\n\t\t\tconst box = Box.FromPoints(points)\n\t\t\tif (box.width < sw * 2 && box.height < sw * 2) {\n\t\t\t\treturn new Circle2d({\n\t\t\t\t\tx: -sw,\n\t\t\t\t\ty: -sw,\n\t\t\t\t\tradius: sw,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst strokePoints = getStrokePoints(\n\t\t\tpoints,\n\t\t\tgetFreehandOptions(shape.props, sw, shape.props.isPen, true)\n\t\t).map((p) => p.point)\n\n\t\t// A closed draw stroke\n\t\tif (shape.props.isClosed && strokePoints.length > 2) {\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: strokePoints,\n\t\t\t\tisFilled: shape.props.fill !== 'none',\n\t\t\t})\n\t\t}\n\n\t\tif (strokePoints.length === 1) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -sw,\n\t\t\t\ty: -sw,\n\t\t\t\tradius: sw,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\t// An open draw stroke\n\t\treturn new Polyline2d({\n\t\t\tpoints: strokePoints,\n\t\t})\n\t}\n\n\tcomponent(shape: TLDrawShape) {\n\t\tconst dv = getDisplayValues(this, shape)\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DrawShapeSvg\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tstrokeColor={dv.strokeColor}\n\t\t\t\t\tstrokeWidth={dv.strokeWidth}\n\t\t\t\t\tfillColor={dv.fillColor}\n\t\t\t\t\tpatternFillFallbackColor={dv.patternFillFallbackColor}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\toverride getIndicatorPath(shape: TLDrawShape): Path2D {\n\t\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tlet sw = (getDisplayValues(this, shape).strokeWidth + 1) * shape.props.scale\n\n\t\tconst zoomLevel = this.editor.getEfficientZoomLevel()\n\t\tconst forceSolid = zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\n\t\tif (\n\t\t\t!forceSolid &&\n\t\t\t!shape.props.isPen &&\n\t\t\tshape.props.dash === 'draw' &&\n\t\t\tallPointsFromSegments.length === 1\n\t\t) {\n\t\t\tsw += rng(shape.id)() * (sw / 6)\n\t\t}\n\n\t\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\t\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, true)\n\t\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\t\tconst solidStrokePath =\n\t\t\tstrokePoints.length > 1\n\t\t\t\t? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\t\t\t\t: getDot(allPointsFromSegments[0], sw)\n\n\t\treturn new Path2D(solidStrokePath)\n\t}\n\n\toverride toSvg(shape: TLDrawShape, ctx: SvgExportContext) {\n\t\tctx.addExportDef(getFillDefForExport(shape.props.fill))\n\t\tconst dv = getDisplayValues(this, shape, ctx.colorMode)\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<DrawShapeSvg\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tzoomOverride={1}\n\t\t\t\t\tstrokeColor={dv.strokeColor}\n\t\t\t\t\tstrokeWidth={dv.strokeWidth}\n\t\t\t\t\tfillColor={dv.fillColor}\n\t\t\t\t\tpatternFillFallbackColor={dv.patternFillFallbackColor}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(shape: TLDrawShape, info: TLResizeInfo<TLDrawShape>) {\n\t\tconst newScaleX = info.scaleX * shape.props.scaleX\n\t\tconst newScaleY = info.scaleY * shape.props.scaleY\n\t\tif (newScaleX === 0 || newScaleY === 0) return\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tscaleX: newScaleX,\n\t\t\t\tscaleY: newScaleY,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride expandSelectionOutlinePx(shape: TLDrawShape): number {\n\t\tconst multiplier = shape.props.dash === 'draw' ? 1.6 : 1\n\t\treturn ((getDisplayValues(this, shape).strokeWidth * multiplier) / 2) * shape.props.scale\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLDrawShape,\n\t\tendShape: TLDrawShape,\n\t\tt: number\n\t): TLDrawShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getDot(point: VecLike, sw: number) {\n\tconst r = (sw + 1) * 0.5\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIsDot(shape: TLDrawShape) {\n\t// A dot is a single-point segment. isSinglePoint knows the per-encoding length\n\t// (and takes the segment's dim), so this stays correct for both 2D and 3D paths.\n\t// A bare length threshold can't: a 2-point 2D path is the same length as a 1-point\n\t// 3D path, so only the dim disambiguates them.\n\tconst segment = shape.props.segments[0]\n\treturn shape.props.segments.length === 1 && b64Vecs.isSinglePoint(segment.path, segment.dim)\n}\n\nfunction DrawShapeSvg({\n\tshape,\n\tzoomOverride,\n\tstrokeColor,\n\tstrokeWidth: baseStrokeWidth,\n\tfillColor,\n\tpatternFillFallbackColor,\n}: {\n\tshape: TLDrawShape\n\tzoomOverride?: number\n\tstrokeColor: string\n\tstrokeWidth: number\n\tfillColor: string\n\tpatternFillFallbackColor: string\n}) {\n\tconst editor = useEditor()\n\n\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\tshape.props.segments,\n\t\tshape.props.scaleX,\n\t\tshape.props.scaleY\n\t)\n\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = (baseStrokeWidth + 1) * shape.props.scale\n\tconst forceSolid = useValue(\n\t\t'force solid',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel()\n\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t},\n\t\t[editor, sw, zoomOverride]\n\t)\n\n\tconst dotAdjustment = useValue(\n\t\t'dot adjustment',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel()\n\t\t\t// If we're zoomed way out (10%), then we need to make the dotted line go to 9 instead 0.1\n\t\t\t// Chrome doesn't render anything otherwise.\n\t\t\treturn zoomLevel < 0.2 ? 9 : 0.1\n\t\t},\n\t\t[editor, zoomOverride]\n\t)\n\n\tif (\n\t\t!forceSolid &&\n\t\t!shape.props.isPen &&\n\t\tshape.props.dash === 'draw' &&\n\t\tallPointsFromSegments.length === 1\n\t) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, forceSolid)\n\n\tif (!forceSolid && shape.props.dash === 'draw') {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{shape.props.isClosed &&\n\t\t\t\t\tshape.props.fill !== 'none' &&\n\t\t\t\t\tallPointsFromSegments.length > 1 &&\n\t\t\t\t\t(shape.props.fill === 'pattern' ? (\n\t\t\t\t\t\t<PatternFill\n\t\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tfillColor={fillColor}\n\t\t\t\t\t\t\tpatternFillFallbackColor={patternFillFallbackColor}\n\t\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\tfill={fillColor}\n\t\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t<path d={svgInk(allPointsFromSegments, options)} strokeLinecap=\"round\" fill={strokeColor} />\n\t\t\t</>\n\t\t)\n\t}\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\tconst isDot = strokePoints.length < 2\n\tconst solidStrokePath = isDot\n\t\t? getDot(allPointsFromSegments[0], 0)\n\t\t: getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\n\tconst fill = isDot || shape.props.isClosed ? shape.props.fill : 'none'\n\n\treturn (\n\t\t<>\n\t\t\t{isDot || !shape.props.isClosed || fill === 'none' ? null : fill === 'pattern' ? (\n\t\t\t\t<PatternFill\n\t\t\t\t\td={solidStrokePath}\n\t\t\t\t\tfillColor={fillColor}\n\t\t\t\t\tpatternFillFallbackColor={patternFillFallbackColor}\n\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<path fill={fillColor} d={solidStrokePath} />\n\t\t\t)}\n\t\t\t{shape.props.dash !== 'none' && (\n\t\t\t\t<path\n\t\t\t\t\td={solidStrokePath}\n\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\tfill={isDot ? strokeColor : 'none'}\n\t\t\t\t\tstroke={strokeColor}\n\t\t\t\t\tstrokeWidth={sw}\n\t\t\t\t\tstrokeDasharray={isDot ? 'none' : getDrawShapeStrokeDashArray(shape, sw, dotAdjustment)}\n\t\t\t\t\tstrokeDashoffset=\"0\"\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tBox,\n\tCircle2d,\n\tPolygon2d,\n\tPolyline2d,\n\tSVGContainer,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLDrawShape,\n\tTLDrawShapeProps,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVecLike,\n\tb64Vecs,\n\tdrawShapeMigrations,\n\tdrawShapeProps,\n\tgetColorValue,\n\tlast,\n\tlerp,\n\trng,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { STROKE_SIZES } from '../shared/default-shape-constants'\nimport { DEFAULT_FILL_COLOR_NAMES } from '../shared/defaultFills'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { svgInk } from '../shared/freehand/svgInk'\nimport { ShapeOptionsWithDisplayValues, getDisplayValues } from '../shared/getDisplayValues'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { PatternFill } from '../shared/PatternFill'\nimport {\n\tgetDrawShapeStrokeDashArray,\n\tgetFreehandOptions,\n\tgetPointsFromDrawSegments,\n} from './getPath'\n\n/** @public */\nexport interface DrawShapeUtilDisplayValues {\n\tstrokeColor: string\n\tstrokeWidth: number\n\tfillColor: string\n\tpatternFillFallbackColor: string\n}\n\n/** @public */\nexport interface DrawShapeOptions extends ShapeOptionsWithDisplayValues<\n\tTLDrawShape,\n\tDrawShapeUtilDisplayValues\n> {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n}\n\n/** @public */\nexport class DrawShapeUtil extends ShapeUtil<TLDrawShape> {\n\tstatic override type = 'draw' as const\n\tstatic override props = drawShapeProps\n\tstatic override migrations = drawShapeMigrations\n\n\toverride options: DrawShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t\tgetDefaultDisplayValues(_editor, shape, theme, colorMode): DrawShapeUtilDisplayValues {\n\t\t\tconst { color, fill, size } = shape.props\n\t\t\tconst colors = theme.colors[colorMode]\n\t\t\treturn {\n\t\t\t\tstrokeColor: getColorValue(colors, color, 'solid'),\n\t\t\t\tstrokeWidth: theme.strokeWidth * STROKE_SIZES[size],\n\t\t\t\tfillColor:\n\t\t\t\t\tfill === 'none'\n\t\t\t\t\t\t? 'transparent'\n\t\t\t\t\t\t: fill === 'semi'\n\t\t\t\t\t\t\t? colors.solid\n\t\t\t\t\t\t\t: getColorValue(colors, color, DEFAULT_FILL_COLOR_NAMES[fill]),\n\t\t\t\tpatternFillFallbackColor: getColorValue(colors, color, 'semi'),\n\t\t\t}\n\t\t},\n\t\tgetCustomDisplayValues(): Partial<DrawShapeUtilDisplayValues> {\n\t\t\treturn {}\n\t\t},\n\t}\n\n\toverride hideResizeHandles(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLDrawShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tfill: 'none',\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisClosed: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t\tscaleX: 1,\n\t\t\tscaleY: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLDrawShape) {\n\t\tconst points = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tconst sw = (getDisplayValues(this, shape).strokeWidth + 1) * shape.props.scale\n\n\t\t// A dot\n\t\tif (shape.props.segments.length === 1) {\n\t\t\tconst box = Box.FromPoints(points)\n\t\t\tif (box.width < sw * 2 && box.height < sw * 2) {\n\t\t\t\treturn new Circle2d({\n\t\t\t\t\tx: -sw,\n\t\t\t\t\ty: -sw,\n\t\t\t\t\tradius: sw,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst strokePoints = getStrokePoints(\n\t\t\tpoints,\n\t\t\tgetFreehandOptions(shape.props, sw, shape.props.isPen, true)\n\t\t).map((p) => p.point)\n\n\t\t// A closed draw stroke\n\t\tif (shape.props.isClosed && strokePoints.length > 2) {\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: strokePoints,\n\t\t\t\tisFilled: shape.props.fill !== 'none',\n\t\t\t})\n\t\t}\n\n\t\tif (strokePoints.length === 1) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -sw,\n\t\t\t\ty: -sw,\n\t\t\t\tradius: sw,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\t// An open draw stroke\n\t\treturn new Polyline2d({\n\t\t\tpoints: strokePoints,\n\t\t})\n\t}\n\n\tcomponent(shape: TLDrawShape) {\n\t\tconst dv = getDisplayValues(this, shape)\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DrawShapeSvg\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tstrokeColor={dv.strokeColor}\n\t\t\t\t\tstrokeWidth={dv.strokeWidth}\n\t\t\t\t\tfillColor={dv.fillColor}\n\t\t\t\t\tpatternFillFallbackColor={dv.patternFillFallbackColor}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\toverride getIndicatorPath(shape: TLDrawShape): Path2D {\n\t\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tlet sw = (getDisplayValues(this, shape).strokeWidth + 1) * shape.props.scale\n\n\t\tconst zoomLevel = this.editor.getEfficientZoomLevel()\n\t\tconst forceSolid = zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\n\t\tif (\n\t\t\t!forceSolid &&\n\t\t\t!shape.props.isPen &&\n\t\t\tshape.props.dash === 'draw' &&\n\t\t\tallPointsFromSegments.length === 1\n\t\t) {\n\t\t\tsw += rng(shape.id)() * (sw / 6)\n\t\t}\n\n\t\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\t\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, true)\n\t\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\t\tconst solidStrokePath =\n\t\t\tstrokePoints.length > 1\n\t\t\t\t? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\t\t\t\t: getDot(allPointsFromSegments[0], sw)\n\n\t\treturn new Path2D(solidStrokePath)\n\t}\n\n\toverride toSvg(shape: TLDrawShape, ctx: SvgExportContext) {\n\t\tctx.addExportDef(getFillDefForExport(shape.props.fill))\n\t\tconst dv = getDisplayValues(this, shape, ctx.colorMode)\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<DrawShapeSvg\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tzoomOverride={1}\n\t\t\t\t\tstrokeColor={dv.strokeColor}\n\t\t\t\t\tstrokeWidth={dv.strokeWidth}\n\t\t\t\t\tfillColor={dv.fillColor}\n\t\t\t\t\tpatternFillFallbackColor={dv.patternFillFallbackColor}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(shape: TLDrawShape, info: TLResizeInfo<TLDrawShape>) {\n\t\tconst newScaleX = info.scaleX * shape.props.scaleX\n\t\tconst newScaleY = info.scaleY * shape.props.scaleY\n\t\tif (newScaleX === 0 || newScaleY === 0) return\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tscaleX: newScaleX,\n\t\t\t\tscaleY: newScaleY,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride expandSelectionOutlinePx(shape: TLDrawShape): number {\n\t\tconst multiplier = shape.props.dash === 'draw' ? 1.6 : 1\n\t\treturn ((getDisplayValues(this, shape).strokeWidth * multiplier) / 2) * shape.props.scale\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLDrawShape,\n\t\tendShape: TLDrawShape,\n\t\tt: number\n\t): TLDrawShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getDot(point: VecLike, sw: number) {\n\tconst r = (sw + 1) * 0.5\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIsDot(shape: TLDrawShape) {\n\t// A dot is a single-point segment. isSinglePoint knows the per-encoding length\n\t// (and takes the segment's dim), so this stays correct for both 2D and 3D paths.\n\t// A bare length threshold can't: a 2-point 2D path is the same length as a 1-point\n\t// 3D path, so only the dim disambiguates them.\n\tconst segment = shape.props.segments[0]\n\treturn shape.props.segments.length === 1 && b64Vecs.isSinglePoint(segment.path, segment.dim)\n}\n\nfunction DrawShapeSvg({\n\tshape,\n\tzoomOverride,\n\tstrokeColor,\n\tstrokeWidth: baseStrokeWidth,\n\tfillColor,\n\tpatternFillFallbackColor,\n}: {\n\tshape: TLDrawShape\n\tzoomOverride?: number\n\tstrokeColor: string\n\tstrokeWidth: number\n\tfillColor: string\n\tpatternFillFallbackColor: string\n}) {\n\tconst editor = useEditor()\n\n\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\tshape.props.segments,\n\t\tshape.props.scaleX,\n\t\tshape.props.scaleY\n\t)\n\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = (baseStrokeWidth + 1) * shape.props.scale\n\tconst forceSolid = useValue(\n\t\t'force solid',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel()\n\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t},\n\t\t[editor, sw, zoomOverride]\n\t)\n\n\tconst dotAdjustment = useValue(\n\t\t'dot adjustment',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel()\n\t\t\t// If we're zoomed way out (10%), then we need to make the dotted line go to 9 instead 0.1\n\t\t\t// Chrome doesn't render anything otherwise.\n\t\t\treturn zoomLevel < 0.2 ? 9 : 0.1\n\t\t},\n\t\t[editor, zoomOverride]\n\t)\n\n\tif (\n\t\t!forceSolid &&\n\t\t!shape.props.isPen &&\n\t\tshape.props.dash === 'draw' &&\n\t\tallPointsFromSegments.length === 1\n\t) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, forceSolid)\n\n\tif (!forceSolid && shape.props.dash === 'draw') {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{shape.props.isClosed &&\n\t\t\t\t\tshape.props.fill !== 'none' &&\n\t\t\t\t\tallPointsFromSegments.length > 1 &&\n\t\t\t\t\t(shape.props.fill === 'pattern' ? (\n\t\t\t\t\t\t<PatternFill\n\t\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tfillColor={fillColor}\n\t\t\t\t\t\t\tpatternFillFallbackColor={patternFillFallbackColor}\n\t\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\tfill={fillColor}\n\t\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t<path d={svgInk(allPointsFromSegments, options)} strokeLinecap=\"round\" fill={strokeColor} />\n\t\t\t</>\n\t\t)\n\t}\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\tconst isDot = strokePoints.length < 2\n\tconst fill = isDot || shape.props.isClosed ? shape.props.fill : 'none'\n\n\tconst solidStrokePath = isDot\n\t\t? getDot(allPointsFromSegments[0], 0)\n\t\t: getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed && fill !== 'none')\n\n\treturn (\n\t\t<>\n\t\t\t{isDot || !shape.props.isClosed || fill === 'none' ? null : fill === 'pattern' ? (\n\t\t\t\t<PatternFill\n\t\t\t\t\td={solidStrokePath}\n\t\t\t\t\tfillColor={fillColor}\n\t\t\t\t\tpatternFillFallbackColor={patternFillFallbackColor}\n\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<path fill={fillColor} d={solidStrokePath} />\n\t\t\t)}\n\t\t\t{shape.props.dash !== 'none' && (\n\t\t\t\t<path\n\t\t\t\t\td={solidStrokePath}\n\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\tfill={isDot ? strokeColor : 'none'}\n\t\t\t\t\tstroke={strokeColor}\n\t\t\t\t\tstrokeWidth={sw}\n\t\t\t\t\tstrokeDasharray={isDot ? 'none' : getDrawShapeStrokeDashArray(shape, sw, dotAdjustment)}\n\t\t\t\t\tstrokeDashoffset=\"0\"\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,8 +1,8 @@
1
- const version = "5.2.3";
1
+ const version = "5.2.5";
2
2
  const publishDates = {
3
3
  major: "2026-05-06T16:28:18.473Z",
4
4
  minor: "2026-07-01T09:20:01.735Z",
5
- patch: "2026-07-06T16:50:48.696Z"
5
+ patch: "2026-07-15T23:10:03.621Z"
6
6
  };
7
7
  export {
8
8
  publishDates,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/ui/version.ts"],
4
- "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '5.2.3'\nexport const publishDates = {\n\tmajor: '2026-05-06T16:28:18.473Z',\n\tminor: '2026-07-01T09:20:01.735Z',\n\tpatch: '2026-07-06T16:50:48.696Z',\n}\n"],
4
+ "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '5.2.5'\nexport const publishDates = {\n\tmajor: '2026-05-06T16:28:18.473Z',\n\tminor: '2026-07-01T09:20:01.735Z',\n\tpatch: '2026-07-15T23:10:03.621Z',\n}\n"],
5
5
  "mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tldraw",
3
3
  "description": "A tiny little drawing editor.",
4
- "version": "5.2.3",
4
+ "version": "5.2.5",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
@@ -63,9 +63,9 @@
63
63
  "@tiptap/pm": "^3.12.1",
64
64
  "@tiptap/react": "^3.12.1",
65
65
  "@tiptap/starter-kit": "^3.12.1",
66
- "@tldraw/driver": "5.2.3",
67
- "@tldraw/editor": "5.2.3",
68
- "@tldraw/store": "5.2.3",
66
+ "@tldraw/driver": "5.2.5",
67
+ "@tldraw/editor": "5.2.5",
68
+ "@tldraw/store": "5.2.5",
69
69
  "classnames": "^2.5.1",
70
70
  "idb": "^7.1.1",
71
71
  "lz-string": "^1.5.0",
@@ -364,11 +364,11 @@ function DrawShapeSvg({
364
364
 
365
365
  const strokePoints = getStrokePoints(allPointsFromSegments, options)
366
366
  const isDot = strokePoints.length < 2
367
+ const fill = isDot || shape.props.isClosed ? shape.props.fill : 'none'
368
+
367
369
  const solidStrokePath = isDot
368
370
  ? getDot(allPointsFromSegments[0], 0)
369
- : getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)
370
-
371
- const fill = isDot || shape.props.isClosed ? shape.props.fill : 'none'
371
+ : getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed && fill !== 'none')
372
372
 
373
373
  return (
374
374
  <>
@@ -1,9 +1,9 @@
1
1
  // This file is automatically generated by internal/scripts/refresh-assets.ts.
2
2
  // Do not edit manually. Or do, I'm a comment, not a cop.
3
3
 
4
- export const version = '5.2.3'
4
+ export const version = '5.2.5'
5
5
  export const publishDates = {
6
6
  major: '2026-05-06T16:28:18.473Z',
7
7
  minor: '2026-07-01T09:20:01.735Z',
8
- patch: '2026-07-06T16:50:48.696Z',
8
+ patch: '2026-07-15T23:10:03.621Z',
9
9
  }