mesurer 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,6 +33,8 @@ function App() {
33
33
  }
34
34
  ```
35
35
 
36
+ No additional CSS import is required.
37
+
36
38
  ## Features
37
39
 
38
40
  - **Toggle on/off** – Enable the overlay with a single shortcut
@@ -45,7 +47,6 @@ function App() {
45
47
  ## Requirements
46
48
 
47
49
  - React 18+
48
- - Tailwind CSS v4 with package content included
49
50
 
50
51
  ## License
51
52
 
package/dist/index.cjs CHANGED
@@ -23,12 +23,39 @@ __export(index_exports, {
23
23
  Measurer: () => Measurer
24
24
  });
25
25
  module.exports = __toCommonJS(index_exports);
26
- var import_styles = require("./styles.css");
26
+
27
+ // style-inject.ts
28
+ var MESURER_STYLE_ID = "mesurer-styles";
29
+ function ensureMeasurerStyles(cssText) {
30
+ if (typeof document === "undefined") return;
31
+ if (!cssText) return;
32
+ if (document.getElementById(MESURER_STYLE_ID)) return;
33
+ const style = document.createElement("style");
34
+ style.id = MESURER_STYLE_ID;
35
+ style.textContent = cssText;
36
+ document.head.appendChild(style);
37
+ }
38
+
39
+ // styles.generated.ts
40
+ var MESURER_STYLES = '/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n@layer properties;\n@layer theme, base, components, utilities;\n@layer theme {\n :root, :host {\n --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",\n "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";\n --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",\n "Courier New", monospace;\n --color-black: #000;\n --color-white: #fff;\n --spacing: 0.25rem;\n --radius-md: 0.375rem;\n --radius-lg: 0.5rem;\n --default-transition-duration: 150ms;\n --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n --color-ink-50: var(--color-ink-50);\n --color-ink-200: var(--color-ink-200);\n --color-ink-500: var(--color-ink-500);\n --color-ink-700: var(--color-ink-700);\n --color-ink-900: var(--color-ink-900);\n }\n}\n@layer base {\n *, ::after, ::before, ::backdrop, ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n }\n html, :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n h1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n b, strong {\n font-weight: bolder;\n }\n code, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n small {\n font-size: 80%;\n }\n sub, sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n sub {\n bottom: -0.25em;\n }\n sup {\n top: -0.5em;\n }\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n :-moz-focusring {\n outline: auto;\n }\n progress {\n vertical-align: baseline;\n }\n summary {\n display: list-item;\n }\n ol, ul, menu {\n list-style: none;\n }\n img, svg, video, canvas, audio, iframe, embed, object {\n display: block;\n vertical-align: middle;\n }\n img, video {\n max-width: 100%;\n height: auto;\n }\n button, input, select, optgroup, textarea, ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n }\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n ::placeholder {\n opacity: 1;\n }\n @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n textarea {\n resize: vertical;\n }\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n ::-webkit-calendar-picker-indicator {\n line-height: 1;\n }\n :-moz-ui-invalid {\n box-shadow: none;\n }\n button, input:where([type="button"], [type="reset"], [type="submit"]), ::file-selector-button {\n appearance: button;\n }\n ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {\n height: auto;\n }\n [hidden]:where(:not([hidden="until-found"])) {\n display: none !important;\n }\n}\n@layer utilities {\n .pointer-events-auto {\n pointer-events: auto;\n }\n .pointer-events-none {\n pointer-events: none;\n }\n .absolute {\n position: absolute;\n }\n .fixed {\n position: fixed;\n }\n .relative {\n position: relative;\n }\n .inset-0 {\n inset: calc(var(--spacing) * 0);\n }\n .start {\n inset-inline-start: var(--spacing);\n }\n .end {\n inset-inline-end: var(--spacing);\n }\n .top-0 {\n top: calc(var(--spacing) * 0);\n }\n .top-full {\n top: 100%;\n }\n .right-0 {\n right: calc(var(--spacing) * 0);\n }\n .bottom-0 {\n bottom: calc(var(--spacing) * 0);\n }\n .bottom-full {\n bottom: 100%;\n }\n .left-0 {\n left: calc(var(--spacing) * 0);\n }\n .left-1 {\n left: calc(var(--spacing) * 1);\n }\n .left-1\\/2 {\n left: calc(1 / 2 * 100%);\n }\n .z-50 {\n z-index: 50;\n }\n .z-\\[70\\] {\n z-index: 70;\n }\n .z-\\[90\\] {\n z-index: 90;\n }\n .mt-2 {\n margin-top: calc(var(--spacing) * 2);\n }\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n .-ml-1 {\n margin-left: calc(var(--spacing) * -1);\n }\n .flex {\n display: flex;\n }\n .table {\n display: table;\n }\n .size-8 {\n width: calc(var(--spacing) * 8);\n height: calc(var(--spacing) * 8);\n }\n .h-8 {\n height: calc(var(--spacing) * 8);\n }\n .h-full {\n height: 100%;\n }\n .h-px {\n height: 1px;\n }\n .w-4 {\n width: calc(var(--spacing) * 4);\n }\n .w-44 {\n width: calc(var(--spacing) * 44);\n }\n .w-full {\n width: 100%;\n }\n .w-px {\n width: 1px;\n }\n .flex-1 {\n flex: 1;\n }\n .border-collapse {\n border-collapse: collapse;\n }\n .-translate-x-1 {\n --tw-translate-x: calc(var(--spacing) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .-translate-x-1\\/2 {\n --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .-translate-y-1 {\n --tw-translate-y: calc(var(--spacing) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .-translate-y-1\\/2 {\n --tw-translate-y: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .rotate-90 {\n rotate: 90deg;\n }\n .rotate-\\[45deg\\] {\n rotate: 45deg;\n }\n .rotate-\\[135deg\\] {\n rotate: 135deg;\n }\n .cursor-crosshair {\n cursor: crosshair;\n }\n .cursor-default {\n cursor: default;\n }\n .cursor-grab {\n cursor: grab;\n }\n .cursor-grabbing {\n cursor: grabbing;\n }\n .cursor-pointer {\n cursor: pointer;\n }\n .resize {\n resize: both;\n }\n .flex-col {\n flex-direction: column;\n }\n .items-center {\n align-items: center;\n }\n .items-stretch {\n align-items: stretch;\n }\n .justify-center {\n justify-content: center;\n }\n .gap-1 {\n gap: calc(var(--spacing) * 1);\n }\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n .gap-px {\n gap: 1px;\n }\n .rounded {\n border-radius: 0.25rem;\n }\n .rounded-\\[6px\\] {\n border-radius: 6px;\n }\n .rounded-\\[8px\\] {\n border-radius: 8px;\n }\n .rounded-\\[12px\\] {\n border-radius: 12px;\n }\n .rounded-lg {\n border-radius: var(--radius-lg);\n }\n .rounded-md {\n border-radius: var(--radius-md);\n }\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n }\n .border-l {\n border-left-style: var(--tw-border-style);\n border-left-width: 1px;\n }\n .border-dashed {\n --tw-border-style: dashed;\n border-style: dashed;\n }\n .border-\\[\\#2563eb\\]\\/70 {\n border-color: color-mix(in oklab, #2563eb 70%, transparent);\n }\n .border-ink-200 {\n border-color: var(--color-ink-200);\n }\n .bg-\\[\\#0d99ff\\] {\n background-color: #0d99ff;\n }\n .bg-\\[\\#2563eb\\] {\n background-color: #2563eb;\n }\n .bg-\\[\\#fff\\] {\n background-color: #fff;\n }\n .bg-black {\n background-color: var(--color-black);\n }\n .bg-black\\/10 {\n background-color: color-mix(in srgb, #000 10%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 10%, transparent);\n }\n }\n .bg-ink-900 {\n background-color: var(--color-ink-900);\n }\n .bg-ink-900\\/90 {\n background-color: var(--color-ink-900);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-ink-900) 90%, transparent);\n }\n }\n .bg-transparent {\n background-color: transparent;\n }\n .bg-white {\n background-color: var(--color-white);\n }\n .p-1 {\n padding: calc(var(--spacing) * 1);\n }\n .px-1 {\n padding-inline: calc(var(--spacing) * 1);\n }\n .px-2 {\n padding-inline: calc(var(--spacing) * 2);\n }\n .py-0 {\n padding-block: calc(var(--spacing) * 0);\n }\n .py-0\\.5 {\n padding-block: calc(var(--spacing) * 0.5);\n }\n .py-1 {\n padding-block: calc(var(--spacing) * 1);\n }\n .py-1\\.5 {\n padding-block: calc(var(--spacing) * 1.5);\n }\n .text-left {\n text-align: left;\n }\n .text-\\[10px\\] {\n font-size: 10px;\n }\n .text-\\[11px\\] {\n font-size: 11px;\n }\n .text-\\[12px\\] {\n font-size: 12px;\n }\n .whitespace-nowrap {\n white-space: nowrap;\n }\n .text-black {\n color: var(--color-black);\n }\n .text-ink-50 {\n color: var(--color-ink-50);\n }\n .text-ink-500 {\n color: var(--color-ink-500);\n }\n .text-ink-700 {\n color: var(--color-ink-700);\n }\n .text-white {\n color: var(--color-white);\n }\n .text-white\\/60 {\n color: color-mix(in srgb, #fff 60%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, var(--color-white) 60%, transparent);\n }\n }\n .tabular-nums {\n --tw-numeric-spacing: tabular-nums;\n font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);\n }\n .underline {\n text-decoration-line: underline;\n }\n .opacity-0 {\n opacity: 0%;\n }\n .opacity-100 {\n opacity: 100%;\n }\n .shadow-\\[0px_0px_\\.5px_rgba\\(0\\,0\\,0\\,\\.18\\)\\,0px_3px_8px_rgba\\(0\\,0\\,0\\,\\.1\\)\\,0px_1px_3px_rgba\\(0\\,0\\,0\\,\\.1\\)\\] {\n --tw-shadow: 0px 0px .5px var(--tw-shadow-color, rgba(0,0,0,.18)), 0px 3px 8px var(--tw-shadow-color, rgba(0,0,0,.1)), 0px 1px 3px var(--tw-shadow-color, rgba(0,0,0,.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-\\[0px_10px_30px_rgba\\(0\\,0\\,0\\,0\\.08\\)\\] {\n --tw-shadow: 0px 10px 30px var(--tw-shadow-color, rgba(0,0,0,0.08));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .outline {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n .outline-transparent {\n outline-color: transparent;\n }\n .transition {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-opacity {\n transition-property: opacity;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .duration-150 {\n --tw-duration: 150ms;\n transition-duration: 150ms;\n }\n .outline-none {\n --tw-outline-style: none;\n outline-style: none;\n }\n .select-none {\n -webkit-user-select: none;\n user-select: none;\n }\n .hover\\:bg-\\[\\#0d99ff\\] {\n &:hover {\n @media (hover: hover) {\n background-color: #0d99ff;\n }\n }\n }\n .hover\\:bg-black\\/4 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #000 4%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 4%, transparent);\n }\n }\n }\n }\n .hover\\:bg-black\\/10 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #000 10%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 10%, transparent);\n }\n }\n }\n }\n .hover\\:text-white {\n &:hover {\n @media (hover: hover) {\n color: var(--color-white);\n }\n }\n }\n .focus\\:outline-none {\n &:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n }\n}\n:root {\n --color-ink-50: #f8fafc;\n --color-ink-200: #e2e8f0;\n --color-ink-500: #64748b;\n --color-ink-700: #334155;\n --color-ink-900: #0f172a;\n}\n@property --tw-translate-x {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-y {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-z {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-border-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-ordinal {\n syntax: "*";\n inherits: false;\n}\n@property --tw-slashed-zero {\n syntax: "*";\n inherits: false;\n}\n@property --tw-numeric-figure {\n syntax: "*";\n inherits: false;\n}\n@property --tw-numeric-spacing {\n syntax: "*";\n inherits: false;\n}\n@property --tw-numeric-fraction {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: "<percentage>";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: "<percentage>";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: "<length>";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: "*";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-outline-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-duration {\n syntax: "*";\n inherits: false;\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-border-style: solid;\n --tw-ordinal: initial;\n --tw-slashed-zero: initial;\n --tw-numeric-figure: initial;\n --tw-numeric-spacing: initial;\n --tw-numeric-fraction: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-outline-style: solid;\n --tw-duration: initial;\n }\n }\n}\n';
27
41
 
28
42
  // measurer.tsx
29
43
  var import_react19 = require("react");
30
44
  var import_react_dom = require("react-dom");
31
45
 
46
+ // constants.ts
47
+ var MEASURE_LABEL_OFFSET = 2;
48
+ var GUIDE_SNAP_DISTANCE = 10;
49
+ var GUIDE_HITBOX_SIZE = 14;
50
+ var GUIDE_DRAG_HOLD_MS = 220;
51
+ var MEASURE_TRANSITION_MS = 140;
52
+ var MIN_MULTI_TARGET_SIZE = 8;
53
+ var MIN_MULTI_ELEMENT_COVERAGE = 0.45;
54
+ var ANCESTOR_PRUNE_SCALE = 1.6;
55
+ var ANCESTOR_KEEP_COVERAGE = 0.92;
56
+ var MIN_SINGLE_TARGET_SIZE = 8;
57
+ var MIN_SINGLE_ELEMENT_COVERAGE = 0.15;
58
+
32
59
  // components/toolbar.tsx
33
60
  var import_react = require("react");
34
61
 
@@ -530,21 +557,6 @@ var useDragState = () => {
530
557
 
531
558
  // hooks/use-guide-drag-hold.ts
532
559
  var import_react3 = require("react");
533
-
534
- // constants.ts
535
- var MEASURE_LABEL_OFFSET = 2;
536
- var GUIDE_SNAP_DISTANCE = 10;
537
- var GUIDE_HITBOX_SIZE = 14;
538
- var GUIDE_DRAG_HOLD_MS = 220;
539
- var MEASURE_TRANSITION_MS = 140;
540
- var MIN_MULTI_TARGET_SIZE = 8;
541
- var MIN_MULTI_ELEMENT_COVERAGE = 0.45;
542
- var ANCESTOR_PRUNE_SCALE = 1.6;
543
- var ANCESTOR_KEEP_COVERAGE = 0.92;
544
- var MIN_SINGLE_TARGET_SIZE = 8;
545
- var MIN_SINGLE_ELEMENT_COVERAGE = 0.15;
546
-
547
- // hooks/use-guide-drag-hold.ts
548
560
  var useGuideDragHold = () => {
549
561
  const guideDragHoldTimerRef = (0, import_react3.useRef)(null);
550
562
  const guideDragHoldGuideIdRef = (0, import_react3.useRef)(null);
@@ -2846,6 +2858,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
2846
2858
  optionContainerLines,
2847
2859
  guides,
2848
2860
  hoverGuide,
2861
+ draggingGuideId,
2849
2862
  selectedGuideIds,
2850
2863
  guideColorActive,
2851
2864
  guideColorHover,
@@ -2862,7 +2875,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
2862
2875
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2863
2876
  "div",
2864
2877
  {
2865
- className: `absolute inset-0 ${enabled && toolMode !== "none" ? `pointer-events-auto ${guidesEnabled ? "cursor-crosshair" : "cursor-default"} opacity-100` : "pointer-events-none opacity-0"}`,
2878
+ className: `absolute inset-0 ${enabled && toolMode !== "none" ? `pointer-events-auto ${guidesEnabled ? hoverGuide || draggingGuideId ? "cursor-default" : "cursor-crosshair" : "cursor-default"} opacity-100` : "pointer-events-none opacity-0"}`,
2866
2879
  onPointerDown,
2867
2880
  onPointerMove,
2868
2881
  onPointerUp,
@@ -3227,6 +3240,7 @@ function MeasurerClient({
3227
3240
  }) {
3228
3241
  const selectionRectRef = (0, import_react19.useRef)(null);
3229
3242
  const toolbarRef = (0, import_react19.useRef)(null);
3243
+ const selectionAnimationCleanupTimeoutRef = (0, import_react19.useRef)(null);
3230
3244
  const persistedState = (0, import_react19.useMemo)(() => {
3231
3245
  if (!persistOnReload) return null;
3232
3246
  const stored = window.localStorage.getItem("mesurer-state");
@@ -3483,6 +3497,50 @@ function MeasurerClient({
3483
3497
  if (hoverHighlightEnabled) return;
3484
3498
  setHoverRect(null);
3485
3499
  }, [hoverHighlightEnabled, setHoverRect]);
3500
+ (0, import_react19.useEffect)(() => {
3501
+ const hasSelectionAnimationState = !!selectionOriginRect || !!selectedMeasurement?.originRect || selectedMeasurements.some((measurement) => !!measurement.originRect);
3502
+ if (!hasSelectionAnimationState) {
3503
+ if (selectionAnimationCleanupTimeoutRef.current !== null) {
3504
+ window.clearTimeout(selectionAnimationCleanupTimeoutRef.current);
3505
+ selectionAnimationCleanupTimeoutRef.current = null;
3506
+ }
3507
+ return;
3508
+ }
3509
+ if (selectionAnimationCleanupTimeoutRef.current !== null) return;
3510
+ selectionAnimationCleanupTimeoutRef.current = window.setTimeout(() => {
3511
+ selectionAnimationCleanupTimeoutRef.current = null;
3512
+ setSelectionOriginRect((prev) => prev ? null : prev);
3513
+ setSelectedMeasurement((prev) => {
3514
+ if (!prev?.originRect) return prev;
3515
+ const { originRect: _originRect, ...next } = prev;
3516
+ return next;
3517
+ });
3518
+ setSelectedMeasurements((prev) => {
3519
+ let changed = false;
3520
+ const next = prev.map((measurement) => {
3521
+ if (!measurement.originRect) return measurement;
3522
+ changed = true;
3523
+ const { originRect: _originRect, ...rest } = measurement;
3524
+ return rest;
3525
+ });
3526
+ return changed ? next : prev;
3527
+ });
3528
+ }, MEASURE_TRANSITION_MS);
3529
+ }, [
3530
+ selectionOriginRect,
3531
+ selectedMeasurement,
3532
+ selectedMeasurements,
3533
+ setSelectedMeasurement,
3534
+ setSelectedMeasurements,
3535
+ setSelectionOriginRect
3536
+ ]);
3537
+ (0, import_react19.useEffect)(() => {
3538
+ return () => {
3539
+ if (selectionAnimationCleanupTimeoutRef.current !== null) {
3540
+ window.clearTimeout(selectionAnimationCleanupTimeoutRef.current);
3541
+ }
3542
+ };
3543
+ }, []);
3486
3544
  const displayedMeasurements = holdEnabled ? measurements : multiMeasureEnabled && measurements.length > 0 ? measurements : activeMeasurement ? [activeMeasurement] : [];
3487
3545
  const {
3488
3546
  activeRect,
@@ -3644,6 +3702,7 @@ function MeasurerClient({
3644
3702
  optionContainerLines,
3645
3703
  guides,
3646
3704
  hoverGuide,
3705
+ draggingGuideId,
3647
3706
  selectedGuideIds,
3648
3707
  guideColorActive,
3649
3708
  guideColorHover,
@@ -3692,6 +3751,9 @@ function Measurer({
3692
3751
  }
3693
3752
  );
3694
3753
  }
3754
+
3755
+ // index.ts
3756
+ ensureMeasurerStyles(MESURER_STYLES);
3695
3757
  // Annotate the CommonJS export names for ESM import in node:
3696
3758
  0 && (module.exports = {
3697
3759
  Measurer
package/dist/index.js CHANGED
@@ -1,5 +1,17 @@
1
- // index.ts
2
- import "./styles.css";
1
+ // style-inject.ts
2
+ var MESURER_STYLE_ID = "mesurer-styles";
3
+ function ensureMeasurerStyles(cssText) {
4
+ if (typeof document === "undefined") return;
5
+ if (!cssText) return;
6
+ if (document.getElementById(MESURER_STYLE_ID)) return;
7
+ const style = document.createElement("style");
8
+ style.id = MESURER_STYLE_ID;
9
+ style.textContent = cssText;
10
+ document.head.appendChild(style);
11
+ }
12
+
13
+ // styles.generated.ts
14
+ var MESURER_STYLES = '/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n@layer properties;\n@layer theme, base, components, utilities;\n@layer theme {\n :root, :host {\n --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",\n "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";\n --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",\n "Courier New", monospace;\n --color-black: #000;\n --color-white: #fff;\n --spacing: 0.25rem;\n --radius-md: 0.375rem;\n --radius-lg: 0.5rem;\n --default-transition-duration: 150ms;\n --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n --color-ink-50: var(--color-ink-50);\n --color-ink-200: var(--color-ink-200);\n --color-ink-500: var(--color-ink-500);\n --color-ink-700: var(--color-ink-700);\n --color-ink-900: var(--color-ink-900);\n }\n}\n@layer base {\n *, ::after, ::before, ::backdrop, ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n }\n html, :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n h1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n b, strong {\n font-weight: bolder;\n }\n code, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n small {\n font-size: 80%;\n }\n sub, sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n sub {\n bottom: -0.25em;\n }\n sup {\n top: -0.5em;\n }\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n :-moz-focusring {\n outline: auto;\n }\n progress {\n vertical-align: baseline;\n }\n summary {\n display: list-item;\n }\n ol, ul, menu {\n list-style: none;\n }\n img, svg, video, canvas, audio, iframe, embed, object {\n display: block;\n vertical-align: middle;\n }\n img, video {\n max-width: 100%;\n height: auto;\n }\n button, input, select, optgroup, textarea, ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n }\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n ::placeholder {\n opacity: 1;\n }\n @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n textarea {\n resize: vertical;\n }\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n ::-webkit-calendar-picker-indicator {\n line-height: 1;\n }\n :-moz-ui-invalid {\n box-shadow: none;\n }\n button, input:where([type="button"], [type="reset"], [type="submit"]), ::file-selector-button {\n appearance: button;\n }\n ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {\n height: auto;\n }\n [hidden]:where(:not([hidden="until-found"])) {\n display: none !important;\n }\n}\n@layer utilities {\n .pointer-events-auto {\n pointer-events: auto;\n }\n .pointer-events-none {\n pointer-events: none;\n }\n .absolute {\n position: absolute;\n }\n .fixed {\n position: fixed;\n }\n .relative {\n position: relative;\n }\n .inset-0 {\n inset: calc(var(--spacing) * 0);\n }\n .start {\n inset-inline-start: var(--spacing);\n }\n .end {\n inset-inline-end: var(--spacing);\n }\n .top-0 {\n top: calc(var(--spacing) * 0);\n }\n .top-full {\n top: 100%;\n }\n .right-0 {\n right: calc(var(--spacing) * 0);\n }\n .bottom-0 {\n bottom: calc(var(--spacing) * 0);\n }\n .bottom-full {\n bottom: 100%;\n }\n .left-0 {\n left: calc(var(--spacing) * 0);\n }\n .left-1 {\n left: calc(var(--spacing) * 1);\n }\n .left-1\\/2 {\n left: calc(1 / 2 * 100%);\n }\n .z-50 {\n z-index: 50;\n }\n .z-\\[70\\] {\n z-index: 70;\n }\n .z-\\[90\\] {\n z-index: 90;\n }\n .mt-2 {\n margin-top: calc(var(--spacing) * 2);\n }\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n .-ml-1 {\n margin-left: calc(var(--spacing) * -1);\n }\n .flex {\n display: flex;\n }\n .table {\n display: table;\n }\n .size-8 {\n width: calc(var(--spacing) * 8);\n height: calc(var(--spacing) * 8);\n }\n .h-8 {\n height: calc(var(--spacing) * 8);\n }\n .h-full {\n height: 100%;\n }\n .h-px {\n height: 1px;\n }\n .w-4 {\n width: calc(var(--spacing) * 4);\n }\n .w-44 {\n width: calc(var(--spacing) * 44);\n }\n .w-full {\n width: 100%;\n }\n .w-px {\n width: 1px;\n }\n .flex-1 {\n flex: 1;\n }\n .border-collapse {\n border-collapse: collapse;\n }\n .-translate-x-1 {\n --tw-translate-x: calc(var(--spacing) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .-translate-x-1\\/2 {\n --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .-translate-y-1 {\n --tw-translate-y: calc(var(--spacing) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .-translate-y-1\\/2 {\n --tw-translate-y: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .rotate-90 {\n rotate: 90deg;\n }\n .rotate-\\[45deg\\] {\n rotate: 45deg;\n }\n .rotate-\\[135deg\\] {\n rotate: 135deg;\n }\n .cursor-crosshair {\n cursor: crosshair;\n }\n .cursor-default {\n cursor: default;\n }\n .cursor-grab {\n cursor: grab;\n }\n .cursor-grabbing {\n cursor: grabbing;\n }\n .cursor-pointer {\n cursor: pointer;\n }\n .resize {\n resize: both;\n }\n .flex-col {\n flex-direction: column;\n }\n .items-center {\n align-items: center;\n }\n .items-stretch {\n align-items: stretch;\n }\n .justify-center {\n justify-content: center;\n }\n .gap-1 {\n gap: calc(var(--spacing) * 1);\n }\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n .gap-px {\n gap: 1px;\n }\n .rounded {\n border-radius: 0.25rem;\n }\n .rounded-\\[6px\\] {\n border-radius: 6px;\n }\n .rounded-\\[8px\\] {\n border-radius: 8px;\n }\n .rounded-\\[12px\\] {\n border-radius: 12px;\n }\n .rounded-lg {\n border-radius: var(--radius-lg);\n }\n .rounded-md {\n border-radius: var(--radius-md);\n }\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n }\n .border-l {\n border-left-style: var(--tw-border-style);\n border-left-width: 1px;\n }\n .border-dashed {\n --tw-border-style: dashed;\n border-style: dashed;\n }\n .border-\\[\\#2563eb\\]\\/70 {\n border-color: color-mix(in oklab, #2563eb 70%, transparent);\n }\n .border-ink-200 {\n border-color: var(--color-ink-200);\n }\n .bg-\\[\\#0d99ff\\] {\n background-color: #0d99ff;\n }\n .bg-\\[\\#2563eb\\] {\n background-color: #2563eb;\n }\n .bg-\\[\\#fff\\] {\n background-color: #fff;\n }\n .bg-black {\n background-color: var(--color-black);\n }\n .bg-black\\/10 {\n background-color: color-mix(in srgb, #000 10%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 10%, transparent);\n }\n }\n .bg-ink-900 {\n background-color: var(--color-ink-900);\n }\n .bg-ink-900\\/90 {\n background-color: var(--color-ink-900);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-ink-900) 90%, transparent);\n }\n }\n .bg-transparent {\n background-color: transparent;\n }\n .bg-white {\n background-color: var(--color-white);\n }\n .p-1 {\n padding: calc(var(--spacing) * 1);\n }\n .px-1 {\n padding-inline: calc(var(--spacing) * 1);\n }\n .px-2 {\n padding-inline: calc(var(--spacing) * 2);\n }\n .py-0 {\n padding-block: calc(var(--spacing) * 0);\n }\n .py-0\\.5 {\n padding-block: calc(var(--spacing) * 0.5);\n }\n .py-1 {\n padding-block: calc(var(--spacing) * 1);\n }\n .py-1\\.5 {\n padding-block: calc(var(--spacing) * 1.5);\n }\n .text-left {\n text-align: left;\n }\n .text-\\[10px\\] {\n font-size: 10px;\n }\n .text-\\[11px\\] {\n font-size: 11px;\n }\n .text-\\[12px\\] {\n font-size: 12px;\n }\n .whitespace-nowrap {\n white-space: nowrap;\n }\n .text-black {\n color: var(--color-black);\n }\n .text-ink-50 {\n color: var(--color-ink-50);\n }\n .text-ink-500 {\n color: var(--color-ink-500);\n }\n .text-ink-700 {\n color: var(--color-ink-700);\n }\n .text-white {\n color: var(--color-white);\n }\n .text-white\\/60 {\n color: color-mix(in srgb, #fff 60%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, var(--color-white) 60%, transparent);\n }\n }\n .tabular-nums {\n --tw-numeric-spacing: tabular-nums;\n font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);\n }\n .underline {\n text-decoration-line: underline;\n }\n .opacity-0 {\n opacity: 0%;\n }\n .opacity-100 {\n opacity: 100%;\n }\n .shadow-\\[0px_0px_\\.5px_rgba\\(0\\,0\\,0\\,\\.18\\)\\,0px_3px_8px_rgba\\(0\\,0\\,0\\,\\.1\\)\\,0px_1px_3px_rgba\\(0\\,0\\,0\\,\\.1\\)\\] {\n --tw-shadow: 0px 0px .5px var(--tw-shadow-color, rgba(0,0,0,.18)), 0px 3px 8px var(--tw-shadow-color, rgba(0,0,0,.1)), 0px 1px 3px var(--tw-shadow-color, rgba(0,0,0,.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-\\[0px_10px_30px_rgba\\(0\\,0\\,0\\,0\\.08\\)\\] {\n --tw-shadow: 0px 10px 30px var(--tw-shadow-color, rgba(0,0,0,0.08));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .outline {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n .outline-transparent {\n outline-color: transparent;\n }\n .transition {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-opacity {\n transition-property: opacity;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .duration-150 {\n --tw-duration: 150ms;\n transition-duration: 150ms;\n }\n .outline-none {\n --tw-outline-style: none;\n outline-style: none;\n }\n .select-none {\n -webkit-user-select: none;\n user-select: none;\n }\n .hover\\:bg-\\[\\#0d99ff\\] {\n &:hover {\n @media (hover: hover) {\n background-color: #0d99ff;\n }\n }\n }\n .hover\\:bg-black\\/4 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #000 4%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 4%, transparent);\n }\n }\n }\n }\n .hover\\:bg-black\\/10 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #000 10%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 10%, transparent);\n }\n }\n }\n }\n .hover\\:text-white {\n &:hover {\n @media (hover: hover) {\n color: var(--color-white);\n }\n }\n }\n .focus\\:outline-none {\n &:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n }\n}\n:root {\n --color-ink-50: #f8fafc;\n --color-ink-200: #e2e8f0;\n --color-ink-500: #64748b;\n --color-ink-700: #334155;\n --color-ink-900: #0f172a;\n}\n@property --tw-translate-x {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-y {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-z {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-border-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-ordinal {\n syntax: "*";\n inherits: false;\n}\n@property --tw-slashed-zero {\n syntax: "*";\n inherits: false;\n}\n@property --tw-numeric-figure {\n syntax: "*";\n inherits: false;\n}\n@property --tw-numeric-spacing {\n syntax: "*";\n inherits: false;\n}\n@property --tw-numeric-fraction {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: "<percentage>";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: "<percentage>";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: "<length>";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: "*";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-outline-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-duration {\n syntax: "*";\n inherits: false;\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-border-style: solid;\n --tw-ordinal: initial;\n --tw-slashed-zero: initial;\n --tw-numeric-figure: initial;\n --tw-numeric-spacing: initial;\n --tw-numeric-fraction: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-outline-style: solid;\n --tw-duration: initial;\n }\n }\n}\n';
3
15
 
4
16
  // measurer.tsx
5
17
  import {
@@ -12,6 +24,19 @@ import {
12
24
  } from "react";
13
25
  import { createPortal } from "react-dom";
14
26
 
27
+ // constants.ts
28
+ var MEASURE_LABEL_OFFSET = 2;
29
+ var GUIDE_SNAP_DISTANCE = 10;
30
+ var GUIDE_HITBOX_SIZE = 14;
31
+ var GUIDE_DRAG_HOLD_MS = 220;
32
+ var MEASURE_TRANSITION_MS = 140;
33
+ var MIN_MULTI_TARGET_SIZE = 8;
34
+ var MIN_MULTI_ELEMENT_COVERAGE = 0.45;
35
+ var ANCESTOR_PRUNE_SCALE = 1.6;
36
+ var ANCESTOR_KEEP_COVERAGE = 0.92;
37
+ var MIN_SINGLE_TARGET_SIZE = 8;
38
+ var MIN_SINGLE_ELEMENT_COVERAGE = 0.15;
39
+
15
40
  // components/toolbar.tsx
16
41
  import {
17
42
  forwardRef,
@@ -521,21 +546,6 @@ var useDragState = () => {
521
546
 
522
547
  // hooks/use-guide-drag-hold.ts
523
548
  import { useCallback as useCallback2, useRef as useRef2 } from "react";
524
-
525
- // constants.ts
526
- var MEASURE_LABEL_OFFSET = 2;
527
- var GUIDE_SNAP_DISTANCE = 10;
528
- var GUIDE_HITBOX_SIZE = 14;
529
- var GUIDE_DRAG_HOLD_MS = 220;
530
- var MEASURE_TRANSITION_MS = 140;
531
- var MIN_MULTI_TARGET_SIZE = 8;
532
- var MIN_MULTI_ELEMENT_COVERAGE = 0.45;
533
- var ANCESTOR_PRUNE_SCALE = 1.6;
534
- var ANCESTOR_KEEP_COVERAGE = 0.92;
535
- var MIN_SINGLE_TARGET_SIZE = 8;
536
- var MIN_SINGLE_ELEMENT_COVERAGE = 0.15;
537
-
538
- // hooks/use-guide-drag-hold.ts
539
549
  var useGuideDragHold = () => {
540
550
  const guideDragHoldTimerRef = useRef2(null);
541
551
  const guideDragHoldGuideIdRef = useRef2(null);
@@ -2837,6 +2847,7 @@ var MeasurerOverlay = memo5(function MeasurerOverlay2({
2837
2847
  optionContainerLines,
2838
2848
  guides,
2839
2849
  hoverGuide,
2850
+ draggingGuideId,
2840
2851
  selectedGuideIds,
2841
2852
  guideColorActive,
2842
2853
  guideColorHover,
@@ -2853,7 +2864,7 @@ var MeasurerOverlay = memo5(function MeasurerOverlay2({
2853
2864
  return /* @__PURE__ */ jsxs5(
2854
2865
  "div",
2855
2866
  {
2856
- className: `absolute inset-0 ${enabled && toolMode !== "none" ? `pointer-events-auto ${guidesEnabled ? "cursor-crosshair" : "cursor-default"} opacity-100` : "pointer-events-none opacity-0"}`,
2867
+ className: `absolute inset-0 ${enabled && toolMode !== "none" ? `pointer-events-auto ${guidesEnabled ? hoverGuide || draggingGuideId ? "cursor-default" : "cursor-crosshair" : "cursor-default"} opacity-100` : "pointer-events-none opacity-0"}`,
2857
2868
  onPointerDown,
2858
2869
  onPointerMove,
2859
2870
  onPointerUp,
@@ -3218,6 +3229,7 @@ function MeasurerClient({
3218
3229
  }) {
3219
3230
  const selectionRectRef = useRef8(null);
3220
3231
  const toolbarRef = useRef8(null);
3232
+ const selectionAnimationCleanupTimeoutRef = useRef8(null);
3221
3233
  const persistedState = useMemo2(() => {
3222
3234
  if (!persistOnReload) return null;
3223
3235
  const stored = window.localStorage.getItem("mesurer-state");
@@ -3474,6 +3486,50 @@ function MeasurerClient({
3474
3486
  if (hoverHighlightEnabled) return;
3475
3487
  setHoverRect(null);
3476
3488
  }, [hoverHighlightEnabled, setHoverRect]);
3489
+ useEffect9(() => {
3490
+ const hasSelectionAnimationState = !!selectionOriginRect || !!selectedMeasurement?.originRect || selectedMeasurements.some((measurement) => !!measurement.originRect);
3491
+ if (!hasSelectionAnimationState) {
3492
+ if (selectionAnimationCleanupTimeoutRef.current !== null) {
3493
+ window.clearTimeout(selectionAnimationCleanupTimeoutRef.current);
3494
+ selectionAnimationCleanupTimeoutRef.current = null;
3495
+ }
3496
+ return;
3497
+ }
3498
+ if (selectionAnimationCleanupTimeoutRef.current !== null) return;
3499
+ selectionAnimationCleanupTimeoutRef.current = window.setTimeout(() => {
3500
+ selectionAnimationCleanupTimeoutRef.current = null;
3501
+ setSelectionOriginRect((prev) => prev ? null : prev);
3502
+ setSelectedMeasurement((prev) => {
3503
+ if (!prev?.originRect) return prev;
3504
+ const { originRect: _originRect, ...next } = prev;
3505
+ return next;
3506
+ });
3507
+ setSelectedMeasurements((prev) => {
3508
+ let changed = false;
3509
+ const next = prev.map((measurement) => {
3510
+ if (!measurement.originRect) return measurement;
3511
+ changed = true;
3512
+ const { originRect: _originRect, ...rest } = measurement;
3513
+ return rest;
3514
+ });
3515
+ return changed ? next : prev;
3516
+ });
3517
+ }, MEASURE_TRANSITION_MS);
3518
+ }, [
3519
+ selectionOriginRect,
3520
+ selectedMeasurement,
3521
+ selectedMeasurements,
3522
+ setSelectedMeasurement,
3523
+ setSelectedMeasurements,
3524
+ setSelectionOriginRect
3525
+ ]);
3526
+ useEffect9(() => {
3527
+ return () => {
3528
+ if (selectionAnimationCleanupTimeoutRef.current !== null) {
3529
+ window.clearTimeout(selectionAnimationCleanupTimeoutRef.current);
3530
+ }
3531
+ };
3532
+ }, []);
3477
3533
  const displayedMeasurements = holdEnabled ? measurements : multiMeasureEnabled && measurements.length > 0 ? measurements : activeMeasurement ? [activeMeasurement] : [];
3478
3534
  const {
3479
3535
  activeRect,
@@ -3635,6 +3691,7 @@ function MeasurerClient({
3635
3691
  optionContainerLines,
3636
3692
  guides,
3637
3693
  hoverGuide,
3694
+ draggingGuideId,
3638
3695
  selectedGuideIds,
3639
3696
  guideColorActive,
3640
3697
  guideColorHover,
@@ -3683,6 +3740,9 @@ function Measurer({
3683
3740
  }
3684
3741
  );
3685
3742
  }
3743
+
3744
+ // index.ts
3745
+ ensureMeasurerStyles(MESURER_STYLES);
3686
3746
  export {
3687
3747
  Measurer
3688
3748
  };
package/dist/styles.css CHANGED
@@ -214,6 +214,9 @@
214
214
  .left-0 {
215
215
  left: calc(var(--spacing) * 0);
216
216
  }
217
+ .left-1 {
218
+ left: calc(var(--spacing) * 1);
219
+ }
217
220
  .left-1\/2 {
218
221
  left: calc(1 / 2 * 100%);
219
222
  }
@@ -238,6 +241,9 @@
238
241
  .flex {
239
242
  display: flex;
240
243
  }
244
+ .table {
245
+ display: table;
246
+ }
241
247
  .size-8 {
242
248
  width: calc(var(--spacing) * 8);
243
249
  height: calc(var(--spacing) * 8);
@@ -266,10 +272,21 @@
266
272
  .flex-1 {
267
273
  flex: 1;
268
274
  }
275
+ .border-collapse {
276
+ border-collapse: collapse;
277
+ }
278
+ .-translate-x-1 {
279
+ --tw-translate-x: calc(var(--spacing) * -1);
280
+ translate: var(--tw-translate-x) var(--tw-translate-y);
281
+ }
269
282
  .-translate-x-1\/2 {
270
283
  --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);
271
284
  translate: var(--tw-translate-x) var(--tw-translate-y);
272
285
  }
286
+ .-translate-y-1 {
287
+ --tw-translate-y: calc(var(--spacing) * -1);
288
+ translate: var(--tw-translate-x) var(--tw-translate-y);
289
+ }
273
290
  .-translate-y-1\/2 {
274
291
  --tw-translate-y: calc(calc(1 / 2 * 100%) * -1);
275
292
  translate: var(--tw-translate-x) var(--tw-translate-y);
@@ -289,6 +306,15 @@
289
306
  .cursor-default {
290
307
  cursor: default;
291
308
  }
309
+ .cursor-grab {
310
+ cursor: grab;
311
+ }
312
+ .cursor-grabbing {
313
+ cursor: grabbing;
314
+ }
315
+ .cursor-pointer {
316
+ cursor: pointer;
317
+ }
292
318
  .resize {
293
319
  resize: both;
294
320
  }
@@ -371,6 +397,9 @@
371
397
  background-color: color-mix(in oklab, var(--color-black) 10%, transparent);
372
398
  }
373
399
  }
400
+ .bg-ink-900 {
401
+ background-color: var(--color-ink-900);
402
+ }
374
403
  .bg-ink-900\/90 {
375
404
  background-color: var(--color-ink-900);
376
405
  @supports (color: color-mix(in lab, red, red)) {
@@ -392,6 +421,9 @@
392
421
  .px-2 {
393
422
  padding-inline: calc(var(--spacing) * 2);
394
423
  }
424
+ .py-0 {
425
+ padding-block: calc(var(--spacing) * 0);
426
+ }
395
427
  .py-0\.5 {
396
428
  padding-block: calc(var(--spacing) * 0.5);
397
429
  }
@@ -441,6 +473,9 @@
441
473
  --tw-numeric-spacing: tabular-nums;
442
474
  font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);
443
475
  }
476
+ .underline {
477
+ text-decoration-line: underline;
478
+ }
444
479
  .opacity-0 {
445
480
  opacity: 0%;
446
481
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mesurer",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Measure and align everything on localhost.",
5
5
  "license": "MIT",
6
6
  "author": "Julien Thibeaut",
@@ -36,15 +36,14 @@
36
36
  "url": "https://github.com/ibelick/mesurer/issues"
37
37
  },
38
38
  "scripts": {
39
- "build": "tsup && pnpm exec tailwindcss -i styles.css -o dist/styles.css",
39
+ "build": "pnpm exec tailwindcss -i styles.css -o styles.generated.css && node scripts/generate-styles.mjs && tsup && pnpm exec tailwindcss -i styles.css -o dist/styles.css",
40
40
  "dev": "tsup --watch",
41
41
  "typecheck": "tsc --noEmit",
42
42
  "prepublishOnly": "npm run typecheck && npm run build"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "react": ">=18.0.0",
46
- "react-dom": ">=18.0.0",
47
- "tailwindcss": ">=4.0.0"
46
+ "react-dom": ">=18.0.0"
48
47
  },
49
48
  "devDependencies": {
50
49
  "@tailwindcss/cli": "^4.2.2",
@@ -57,10 +56,7 @@
57
56
  "typescript": "^5.9.2"
58
57
  },
59
58
  "keywords": [
60
- "tailwindcss",
61
- "plugin",
62
- "gradient",
63
- "easing",
64
- "css"
59
+ "measurement",
60
+ "alignment"
65
61
  ]
66
62
  }