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 +2 -1
- package/dist/index.cjs +79 -17
- package/dist/index.js +78 -18
- package/dist/styles.css +35 -0
- package/package.json +5 -9
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
|
-
|
|
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
|
-
//
|
|
2
|
-
|
|
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.
|
|
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
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"gradient",
|
|
63
|
-
"easing",
|
|
64
|
-
"css"
|
|
59
|
+
"measurement",
|
|
60
|
+
"alignment"
|
|
65
61
|
]
|
|
66
62
|
}
|