mesurer 0.0.8 → 0.0.9
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/CHANGELOG.md +13 -0
- package/README.md +4 -0
- package/dist/index.cjs +2291 -543
- package/dist/index.d.cts +39 -2
- package/dist/index.d.ts +39 -2
- package/dist/index.js +2274 -529
- package/dist/styles.css +34 -0
- package/package.json +11 -10
package/dist/index.cjs
CHANGED
|
@@ -20,15 +20,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
Measurer: () => Measurer
|
|
23
|
+
Measurer: () => Measurer,
|
|
24
|
+
TextInspector: () => TextInspector,
|
|
25
|
+
createTextInspector: () => createTextInspector
|
|
24
26
|
});
|
|
25
27
|
module.exports = __toCommonJS(index_exports);
|
|
26
28
|
|
|
27
29
|
// measurer.tsx
|
|
28
|
-
var
|
|
30
|
+
var import_react20 = require("react");
|
|
29
31
|
var import_react_dom = require("react-dom");
|
|
30
32
|
|
|
31
|
-
// constants.ts
|
|
33
|
+
// core/constants.ts
|
|
32
34
|
var MEASURE_LABEL_OFFSET = 2;
|
|
33
35
|
var GUIDE_SNAP_DISTANCE = 10;
|
|
34
36
|
var GUIDE_HITBOX_SIZE = 14;
|
|
@@ -41,15 +43,17 @@ var ANCESTOR_KEEP_COVERAGE = 0.92;
|
|
|
41
43
|
var MIN_SINGLE_TARGET_SIZE = 8;
|
|
42
44
|
var MIN_SINGLE_ELEMENT_COVERAGE = 0.15;
|
|
43
45
|
|
|
44
|
-
// style-inject.ts
|
|
46
|
+
// runtime/style-inject.ts
|
|
45
47
|
var MESURER_STYLE_ID = "mesurer-styles";
|
|
48
|
+
var isDocument = (target) => target.nodeType === 9;
|
|
49
|
+
var isShadowRoot = (target) => target.nodeType === 11;
|
|
46
50
|
var getStyleTarget = (target) => {
|
|
47
51
|
if (typeof document === "undefined") return null;
|
|
48
52
|
if (!target) return document;
|
|
49
|
-
if (target
|
|
53
|
+
if (isShadowRoot(target)) return target;
|
|
50
54
|
const rootNode = target.getRootNode();
|
|
51
|
-
if (rootNode
|
|
52
|
-
return document;
|
|
55
|
+
if (rootNode.nodeType === 11) return rootNode;
|
|
56
|
+
return target.ownerDocument ?? document;
|
|
53
57
|
};
|
|
54
58
|
function ensureMeasurerStyles(cssText, target) {
|
|
55
59
|
if (typeof document === "undefined") return;
|
|
@@ -57,23 +61,25 @@ function ensureMeasurerStyles(cssText, target) {
|
|
|
57
61
|
const styleTarget = getStyleTarget(target);
|
|
58
62
|
if (!styleTarget) return;
|
|
59
63
|
if (styleTarget.querySelector(`#${MESURER_STYLE_ID}`)) return;
|
|
60
|
-
const
|
|
64
|
+
const ownerDocument = isDocument(styleTarget) ? styleTarget : styleTarget.ownerDocument;
|
|
65
|
+
if (!ownerDocument) return;
|
|
66
|
+
const style = ownerDocument.createElement("style");
|
|
61
67
|
style.id = MESURER_STYLE_ID;
|
|
62
68
|
style.textContent = cssText;
|
|
63
|
-
if (styleTarget
|
|
69
|
+
if (isShadowRoot(styleTarget)) {
|
|
64
70
|
styleTarget.appendChild(style);
|
|
65
71
|
return;
|
|
66
72
|
}
|
|
67
|
-
|
|
73
|
+
ownerDocument.head.appendChild(style);
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
// styles.generated.ts
|
|
71
|
-
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 --msr-font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",\n "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";\n --msr-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",\n "Courier New", monospace;\n --msr-color-black: #000;\n --msr-color-white: #fff;\n --msr-spacing: 0.25rem;\n --msr-radius-md: 0.375rem;\n --msr-radius-lg: 0.5rem;\n --msr-default-transition-duration: 150ms;\n --msr-default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n --msr-default-font-family: var(--msr-font-sans);\n --msr-default-mono-font-family: var(--msr-font-mono);\n --msr-color-ink-50: var(--color-ink-50);\n --msr-color-ink-200: var(--color-ink-200);\n --msr-color-ink-700: var(--color-ink-700);\n --msr-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(--msr-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(--msr-default-font-feature-settings, normal);\n font-variation-settings: var(--msr-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(--msr-default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);\n font-feature-settings: var(--msr-default-mono-font-feature-settings, normal);\n font-variation-settings: var(--msr-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 .msr\\:pointer-events-auto {\n pointer-events: auto;\n }\n .msr\\:pointer-events-none {\n pointer-events: none;\n }\n .msr\\:absolute {\n position: absolute;\n }\n .msr\\:fixed {\n position: fixed;\n }\n .msr\\:relative {\n position: relative;\n }\n .msr\\:inset-0 {\n inset: calc(var(--msr-spacing) * 0);\n }\n .msr\\:top-0 {\n top: calc(var(--msr-spacing) * 0);\n }\n .msr\\:top-full {\n top: 100%;\n }\n .msr\\:right-0 {\n right: calc(var(--msr-spacing) * 0);\n }\n .msr\\:bottom-0 {\n bottom: calc(var(--msr-spacing) * 0);\n }\n .msr\\:bottom-full {\n bottom: 100%;\n }\n .msr\\:left-0 {\n left: calc(var(--msr-spacing) * 0);\n }\n .msr\\:left-1\\/2 {\n left: calc(1 / 2 * 100%);\n }\n .msr\\:z-50 {\n z-index: 50;\n }\n .msr\\:z-\\[70\\] {\n z-index: 70;\n }\n .msr\\:z-\\[90\\] {\n z-index: 90;\n }\n .msr\\:mt-2 {\n margin-top: calc(var(--msr-spacing) * 2);\n }\n .msr\\:mb-2 {\n margin-bottom: calc(var(--msr-spacing) * 2);\n }\n .msr\\:-ml-1 {\n margin-left: calc(var(--msr-spacing) * -1);\n }\n .msr\\:flex {\n display: flex;\n }\n .msr\\:size-8 {\n width: calc(var(--msr-spacing) * 8);\n height: calc(var(--msr-spacing) * 8);\n }\n .msr\\:h-8 {\n height: calc(var(--msr-spacing) * 8);\n }\n .msr\\:h-full {\n height: 100%;\n }\n .msr\\:h-px {\n height: 1px;\n }\n .msr\\:w-4 {\n width: calc(var(--msr-spacing) * 4);\n }\n .msr\\:w-44 {\n width: calc(var(--msr-spacing) * 44);\n }\n .msr\\:w-full {\n width: 100%;\n }\n .msr\\:w-px {\n width: 1px;\n }\n .msr\\:flex-1 {\n flex: 1;\n }\n .msr\\:-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 .msr\\:-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 .msr\\:rotate-90 {\n rotate: 90deg;\n }\n .msr\\:rotate-\\[45deg\\] {\n rotate: 45deg;\n }\n .msr\\:rotate-\\[135deg\\] {\n rotate: 135deg;\n }\n .msr\\:cursor-crosshair {\n cursor: crosshair;\n }\n .msr\\:cursor-default {\n cursor: default;\n }\n .msr\\:flex-col {\n flex-direction: column;\n }\n .msr\\:items-center {\n align-items: center;\n }\n .msr\\:items-stretch {\n align-items: stretch;\n }\n .msr\\:justify-center {\n justify-content: center;\n }\n .msr\\:gap-1 {\n gap: calc(var(--msr-spacing) * 1);\n }\n .msr\\:gap-2 {\n gap: calc(var(--msr-spacing) * 2);\n }\n .msr\\:gap-px {\n gap: 1px;\n }\n .msr\\:rounded {\n border-radius: 0.25rem;\n }\n .msr\\:rounded-\\[6px\\] {\n border-radius: 6px;\n }\n .msr\\:rounded-\\[8px\\] {\n border-radius: 8px;\n }\n .msr\\:rounded-\\[12px\\] {\n border-radius: 12px;\n }\n .msr\\:rounded-lg {\n border-radius: var(--msr-radius-lg);\n }\n .msr\\:rounded-md {\n border-radius: var(--msr-radius-md);\n }\n .msr\\:border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .msr\\:border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n }\n .msr\\:border-l {\n border-left-style: var(--tw-border-style);\n border-left-width: 1px;\n }\n .msr\\:border-dashed {\n --tw-border-style: dashed;\n border-style: dashed;\n }\n .msr\\:border-\\[\\#2563eb\\]\\/70 {\n border-color: color-mix(in oklab, #2563eb 70%, transparent);\n }\n .msr\\:border-ink-200 {\n border-color: var(--msr-color-ink-200);\n }\n .msr\\:bg-\\[\\#0d99ff\\] {\n background-color: #0d99ff;\n }\n .msr\\:bg-\\[\\#2563eb\\] {\n background-color: #2563eb;\n }\n .msr\\:bg-\\[\\#fff\\] {\n background-color: #fff;\n }\n .msr\\:bg-black {\n background-color: var(--msr-color-black);\n }\n .msr\\:bg-black\\/10 {\n background-color: var(--msr-color-black);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--msr-color-black) 10%, transparent);\n }\n }\n .msr\\:bg-ink-900\\/90 {\n background-color: var(--msr-color-ink-900);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--msr-color-ink-900) 90%, transparent);\n }\n }\n .msr\\:bg-transparent {\n background-color: transparent;\n }\n .msr\\:bg-white {\n background-color: var(--msr-color-white);\n }\n .msr\\:p-1 {\n padding: calc(var(--msr-spacing) * 1);\n }\n .msr\\:px-1 {\n padding-inline: calc(var(--msr-spacing) * 1);\n }\n .msr\\:px-2 {\n padding-inline: calc(var(--msr-spacing) * 2);\n }\n .msr\\:py-0\\.5 {\n padding-block: calc(var(--msr-spacing) * 0.5);\n }\n .msr\\:py-1 {\n padding-block: calc(var(--msr-spacing) * 1);\n }\n .msr\\:py-1\\.5 {\n padding-block: calc(var(--msr-spacing) * 1.5);\n }\n .msr\\:text-left {\n text-align: left;\n }\n .msr\\:text-\\[10px\\] {\n font-size: 10px;\n }\n .msr\\:text-\\[11px\\] {\n font-size: 11px;\n }\n .msr\\:text-\\[12px\\] {\n font-size: 12px;\n }\n .msr\\:whitespace-nowrap {\n white-space: nowrap;\n }\n .msr\\:text-black {\n color: var(--msr-color-black);\n }\n .msr\\:text-ink-50 {\n color: var(--msr-color-ink-50);\n }\n .msr\\:text-ink-700 {\n color: var(--msr-color-ink-700);\n }\n .msr\\:text-white {\n color: var(--msr-color-white);\n }\n .msr\\:text-white\\/60 {\n color: var(--msr-color-white);\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, var(--msr-color-white) 60%, transparent);\n }\n }\n .msr\\: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 .msr\\:opacity-0 {\n opacity: 0%;\n }\n .msr\\:opacity-100 {\n opacity: 100%;\n }\n .msr\\:outline {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n .msr\\:outline-transparent {\n outline-color: transparent;\n }\n .msr\\:transition-opacity {\n transition-property: opacity;\n transition-timing-function: var(--tw-ease, var(--msr-default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--msr-default-transition-duration));\n }\n .msr\\:duration-150 {\n --tw-duration: 150ms;\n transition-duration: 150ms;\n }\n .msr\\:outline-none {\n --tw-outline-style: none;\n outline-style: none;\n }\n .msr\\:select-none {\n -webkit-user-select: none;\n user-select: none;\n }\n .msr\\:hover\\:bg-\\[\\#0d99ff\\] {\n &:hover {\n @media (hover: hover) {\n background-color: #0d99ff;\n }\n }\n }\n .msr\\:hover\\:bg-black\\/4 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--msr-color-black);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--msr-color-black) 4%, transparent);\n }\n }\n }\n }\n .msr\\:hover\\:bg-black\\/10 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--msr-color-black);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--msr-color-black) 10%, transparent);\n }\n }\n }\n }\n .msr\\:hover\\:text-white {\n &:hover {\n @media (hover: hover) {\n color: var(--msr-color-white);\n }\n }\n }\n .msr\\:focus\\:outline-none {\n &:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n }\n}\n:root, :host {\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.mesurer-toolbar-surface {\n box-shadow: 0 0 0.5px rgba(0, 0, 0, 0.18), 0 3px 8px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.mesurer-menu-surface {\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);\n}\n.mesurer-root {\n --msr-spacing: 4px;\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-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-outline-style: solid;\n --tw-duration: initial;\n }\n }\n}\n';
|
|
77
|
+
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 --msr-font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",\n "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";\n --msr-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",\n "Courier New", monospace;\n --msr-color-black: #000;\n --msr-color-white: #fff;\n --msr-spacing: 0.25rem;\n --msr-radius-md: 0.375rem;\n --msr-radius-lg: 0.5rem;\n --msr-default-transition-duration: 150ms;\n --msr-default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n --msr-default-font-family: var(--msr-font-sans);\n --msr-default-mono-font-family: var(--msr-font-mono);\n --msr-color-ink-50: var(--color-ink-50);\n --msr-color-ink-200: var(--color-ink-200);\n --msr-color-ink-700: var(--color-ink-700);\n --msr-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(--msr-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(--msr-default-font-feature-settings, normal);\n font-variation-settings: var(--msr-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(--msr-default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);\n font-feature-settings: var(--msr-default-mono-font-feature-settings, normal);\n font-variation-settings: var(--msr-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 .msr\\:pointer-events-auto {\n pointer-events: auto;\n }\n .msr\\:pointer-events-none {\n pointer-events: none;\n }\n .msr\\:absolute {\n position: absolute;\n }\n .msr\\:fixed {\n position: fixed;\n }\n .msr\\:relative {\n position: relative;\n }\n .msr\\:inset-0 {\n inset: calc(var(--msr-spacing) * 0);\n }\n .msr\\:top-0 {\n top: calc(var(--msr-spacing) * 0);\n }\n .msr\\:top-\\[18px\\] {\n top: 18px;\n }\n .msr\\:top-full {\n top: 100%;\n }\n .msr\\:right-0 {\n right: calc(var(--msr-spacing) * 0);\n }\n .msr\\:bottom-0 {\n bottom: calc(var(--msr-spacing) * 0);\n }\n .msr\\:bottom-full {\n bottom: 100%;\n }\n .msr\\:left-0 {\n left: calc(var(--msr-spacing) * 0);\n }\n .msr\\:left-1\\/2 {\n left: calc(1 / 2 * 100%);\n }\n .msr\\:left-\\[18px\\] {\n left: 18px;\n }\n .msr\\:z-50 {\n z-index: 50;\n }\n .msr\\:z-\\[70\\] {\n z-index: 70;\n }\n .msr\\:z-\\[90\\] {\n z-index: 90;\n }\n .msr\\:mt-2 {\n margin-top: calc(var(--msr-spacing) * 2);\n }\n .msr\\:mb-2 {\n margin-bottom: calc(var(--msr-spacing) * 2);\n }\n .msr\\:-ml-1 {\n margin-left: calc(var(--msr-spacing) * -1);\n }\n .msr\\:block {\n display: block;\n }\n .msr\\:flex {\n display: flex;\n }\n .msr\\:size-8 {\n width: calc(var(--msr-spacing) * 8);\n height: calc(var(--msr-spacing) * 8);\n }\n .msr\\:size-\\[18px\\] {\n width: 18px;\n height: 18px;\n }\n .msr\\:h-6 {\n height: calc(var(--msr-spacing) * 6);\n }\n .msr\\:h-8 {\n height: calc(var(--msr-spacing) * 8);\n }\n .msr\\:h-full {\n height: 100%;\n }\n .msr\\:h-px {\n height: 1px;\n }\n .msr\\:w-4 {\n width: calc(var(--msr-spacing) * 4);\n }\n .msr\\:w-6 {\n width: calc(var(--msr-spacing) * 6);\n }\n .msr\\:w-44 {\n width: calc(var(--msr-spacing) * 44);\n }\n .msr\\:w-\\[18px\\] {\n width: 18px;\n }\n .msr\\:w-full {\n width: 100%;\n }\n .msr\\:w-px {\n width: 1px;\n }\n .msr\\:flex-1 {\n flex: 1;\n }\n .msr\\:-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 .msr\\:-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 .msr\\:rotate-90 {\n rotate: 90deg;\n }\n .msr\\:rotate-\\[45deg\\] {\n rotate: 45deg;\n }\n .msr\\:rotate-\\[135deg\\] {\n rotate: 135deg;\n }\n .msr\\:cursor-crosshair {\n cursor: crosshair;\n }\n .msr\\:cursor-default {\n cursor: default;\n }\n .msr\\:flex-col {\n flex-direction: column;\n }\n .msr\\:items-center {\n align-items: center;\n }\n .msr\\:items-stretch {\n align-items: stretch;\n }\n .msr\\:justify-center {\n justify-content: center;\n }\n .msr\\:gap-1 {\n gap: calc(var(--msr-spacing) * 1);\n }\n .msr\\:gap-2 {\n gap: calc(var(--msr-spacing) * 2);\n }\n .msr\\:gap-px {\n gap: 1px;\n }\n .msr\\:overflow-hidden {\n overflow: hidden;\n }\n .msr\\:rounded {\n border-radius: 0.25rem;\n }\n .msr\\:rounded-\\[6px\\] {\n border-radius: 6px;\n }\n .msr\\:rounded-\\[8px\\] {\n border-radius: 8px;\n }\n .msr\\:rounded-\\[12px\\] {\n border-radius: 12px;\n }\n .msr\\:rounded-lg {\n border-radius: var(--msr-radius-lg);\n }\n .msr\\:rounded-md {\n border-radius: var(--msr-radius-md);\n }\n .msr\\:border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .msr\\:border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n }\n .msr\\:border-l {\n border-left-style: var(--tw-border-style);\n border-left-width: 1px;\n }\n .msr\\:border-dashed {\n --tw-border-style: dashed;\n border-style: dashed;\n }\n .msr\\:border-\\[\\#2563eb\\]\\/70 {\n border-color: color-mix(in oklab, #2563eb 70%, transparent);\n }\n .msr\\:border-ink-200 {\n border-color: var(--msr-color-ink-200);\n }\n .msr\\:bg-\\[\\#0d99ff\\] {\n background-color: #0d99ff;\n }\n .msr\\:bg-\\[\\#2563eb\\] {\n background-color: #2563eb;\n }\n .msr\\:bg-\\[\\#fff\\] {\n background-color: #fff;\n }\n .msr\\:bg-black {\n background-color: var(--msr-color-black);\n }\n .msr\\:bg-black\\/10 {\n background-color: var(--msr-color-black);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--msr-color-black) 10%, transparent);\n }\n }\n .msr\\:bg-ink-900\\/90 {\n background-color: var(--msr-color-ink-900);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--msr-color-ink-900) 90%, transparent);\n }\n }\n .msr\\:bg-transparent {\n background-color: transparent;\n }\n .msr\\:bg-white {\n background-color: var(--msr-color-white);\n }\n .msr\\:p-1 {\n padding: calc(var(--msr-spacing) * 1);\n }\n .msr\\:px-1 {\n padding-inline: calc(var(--msr-spacing) * 1);\n }\n .msr\\:px-2 {\n padding-inline: calc(var(--msr-spacing) * 2);\n }\n .msr\\:py-0\\.5 {\n padding-block: calc(var(--msr-spacing) * 0.5);\n }\n .msr\\:py-1 {\n padding-block: calc(var(--msr-spacing) * 1);\n }\n .msr\\:py-1\\.5 {\n padding-block: calc(var(--msr-spacing) * 1.5);\n }\n .msr\\:text-left {\n text-align: left;\n }\n .msr\\:text-\\[9px\\] {\n font-size: 9px;\n }\n .msr\\:text-\\[10px\\] {\n font-size: 10px;\n }\n .msr\\:text-\\[11px\\] {\n font-size: 11px;\n }\n .msr\\:text-\\[12px\\] {\n font-size: 12px;\n }\n .msr\\:whitespace-nowrap {\n white-space: nowrap;\n }\n .msr\\:text-\\[\\#64748b\\] {\n color: #64748b;\n }\n .msr\\:text-black {\n color: var(--msr-color-black);\n }\n .msr\\:text-ink-50 {\n color: var(--msr-color-ink-50);\n }\n .msr\\:text-ink-700 {\n color: var(--msr-color-ink-700);\n }\n .msr\\:text-white {\n color: var(--msr-color-white);\n }\n .msr\\:text-white\\/60 {\n color: var(--msr-color-white);\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, var(--msr-color-white) 60%, transparent);\n }\n }\n .msr\\: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 .msr\\:opacity-0 {\n opacity: 0%;\n }\n .msr\\:opacity-100 {\n opacity: 100%;\n }\n .msr\\:outline {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n .msr\\:outline-transparent {\n outline-color: transparent;\n }\n .msr\\:transition-opacity {\n transition-property: opacity;\n transition-timing-function: var(--tw-ease, var(--msr-default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--msr-default-transition-duration));\n }\n .msr\\:transition-none {\n transition-property: none;\n }\n .msr\\:duration-150 {\n --tw-duration: 150ms;\n transition-duration: 150ms;\n }\n .msr\\:outline-none {\n --tw-outline-style: none;\n outline-style: none;\n }\n .msr\\:select-none {\n -webkit-user-select: none;\n user-select: none;\n }\n .msr\\:hover\\:bg-\\[\\#0d99ff\\] {\n &:hover {\n @media (hover: hover) {\n background-color: #0d99ff;\n }\n }\n }\n .msr\\:hover\\:bg-black\\/4 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--msr-color-black);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--msr-color-black) 4%, transparent);\n }\n }\n }\n }\n .msr\\:hover\\:bg-black\\/10 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--msr-color-black);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--msr-color-black) 10%, transparent);\n }\n }\n }\n }\n .msr\\:hover\\:text-white {\n &:hover {\n @media (hover: hover) {\n color: var(--msr-color-white);\n }\n }\n }\n .msr\\:focus\\:outline-none {\n &:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n }\n}\n:root, :host {\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.mesurer-toolbar-surface {\n box-shadow: 0 0 0.5px rgba(0, 0, 0, 0.18), 0 3px 8px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.mesurer-menu-surface {\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);\n}\n.mesurer-root {\n --msr-spacing: 4px;\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-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-outline-style: solid;\n --tw-duration: initial;\n }\n }\n}\n';
|
|
72
78
|
|
|
73
79
|
// components/toolbar.tsx
|
|
74
80
|
var import_react = require("react");
|
|
75
81
|
|
|
76
|
-
// utils.ts
|
|
82
|
+
// core/utils.ts
|
|
77
83
|
var formatValue = (value) => Math.round(value);
|
|
78
84
|
var cn = (...inputs) => inputs.filter(Boolean).join(" ");
|
|
79
85
|
var createId = () => typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`;
|
|
@@ -93,9 +99,57 @@ var IconBase = ({ size = 24, ...props }) => /* @__PURE__ */ (0, import_jsx_runti
|
|
|
93
99
|
);
|
|
94
100
|
var CursorIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M166.59,134.1a1.91,1.91,0,0,1-.55-1.79,2,2,0,0,1,1.08-1.42l46.25-17.76.24-.1A14,14,0,0,0,212.38,87L52.29,34.7A13.95,13.95,0,0,0,34.7,52.29L87,212.38a13.82,13.82,0,0,0,12.6,9.6c.23,0,.46,0,.69,0A13.84,13.84,0,0,0,113,213.61a2.44,2.44,0,0,0,.1-.24l17.76-46.25a2,2,0,0,1,3.21-.53l51.31,51.31a14,14,0,0,0,19.8,0l12.69-12.69a14,14,0,0,0,0-19.8Zm42.82,62.63-12.68,12.68a2,2,0,0,1-2.83,0L142.59,158.1a14,14,0,0,0-22.74,4.32,2.44,2.44,0,0,0-.1.24L102,208.91a2,2,0,0,1-3.61-.26L46.11,48.57a1.87,1.87,0,0,1,.47-2A1.92,1.92,0,0,1,47.93,46a2.22,2.22,0,0,1,.64.1L208.65,98.38a2,2,0,0,1,.26,3.61l-46.25,17.76-.24.1a14,14,0,0,0-4.32,22.74h0l51.31,51.31A2,2,0,0,1,209.41,196.73Z" }) });
|
|
95
101
|
var RulerIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M233.91,74.79,181.22,22.1a14,14,0,0,0-19.8,0L22.09,161.41a14,14,0,0,0,0,19.8L74.78,233.9a14,14,0,0,0,19.8,0L233.91,94.59A14,14,0,0,0,233.91,74.79ZM225.42,86.1,86.1,225.41h0a2,2,0,0,1-2.83,0L30.58,172.73a2,2,0,0,1,0-2.83L64,136.48l27.76,27.76a6,6,0,1,0,8.48-8.48L72.48,128,96,104.48l27.76,27.76a6,6,0,0,0,8.48-8.48L104.48,96,128,72.49l27.76,27.75a6,6,0,0,0,8.48-8.48L136.49,64,169.9,30.59a2,2,0,0,1,2.83,0l52.69,52.68A2,2,0,0,1,225.42,86.1Z" }) });
|
|
102
|
+
var XrayIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
103
|
+
"path",
|
|
104
|
+
{
|
|
105
|
+
fill: "none",
|
|
106
|
+
stroke: "currentColor",
|
|
107
|
+
strokeLinecap: "round",
|
|
108
|
+
strokeLinejoin: "round",
|
|
109
|
+
strokeWidth: "12",
|
|
110
|
+
strokeOpacity: "0.78",
|
|
111
|
+
d: "M76 48h96a16 16 0 0 1 16 16v96a16 16 0 0 1-16 16H76a16 16 0 0 1-16-16V64a16 16 0 0 1 16-16Zm32 32h96a16 16 0 0 1 16 16v96a16 16 0 0 1-16 16h-96a16 16 0 0 1-16-16V96a16 16 0 0 1 16-16Z"
|
|
112
|
+
}
|
|
113
|
+
) });
|
|
114
|
+
var RulersIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
115
|
+
"path",
|
|
116
|
+
{
|
|
117
|
+
fill: "none",
|
|
118
|
+
stroke: "currentColor",
|
|
119
|
+
strokeLinecap: "round",
|
|
120
|
+
strokeLinejoin: "round",
|
|
121
|
+
strokeWidth: "12",
|
|
122
|
+
d: "M48 208V48h160M80 48v24m32-24v24m32-24v24m32-24v24M48 80h24M48 112h24m-24 32h24m-24 32h24"
|
|
123
|
+
}
|
|
124
|
+
) });
|
|
96
125
|
var CaretDownIcon = ({ size = 8, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z" }) });
|
|
97
126
|
var CheckIcon = ({ size = 12, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z" }) });
|
|
98
127
|
var MinusIcon = ({ size = 12, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M228,128a12,12,0,0,1-12,12H40a12,12,0,0,1,0-24H216A12,12,0,0,1,228,128Z" }) });
|
|
128
|
+
var TextInspectorIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
129
|
+
"svg",
|
|
130
|
+
{
|
|
131
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
132
|
+
width: size,
|
|
133
|
+
height: size,
|
|
134
|
+
viewBox: "0 0 256 256",
|
|
135
|
+
fill: "currentColor",
|
|
136
|
+
...props,
|
|
137
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
138
|
+
"text",
|
|
139
|
+
{
|
|
140
|
+
x: "50%",
|
|
141
|
+
y: "60%",
|
|
142
|
+
textAnchor: "middle",
|
|
143
|
+
dominantBaseline: "middle",
|
|
144
|
+
fill: "currentColor",
|
|
145
|
+
fontFamily: "ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif",
|
|
146
|
+
fontWeight: 300,
|
|
147
|
+
fontSize: 220,
|
|
148
|
+
children: "Aa"
|
|
149
|
+
}
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
);
|
|
99
153
|
|
|
100
154
|
// components/toolbar.tsx
|
|
101
155
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
@@ -110,6 +164,7 @@ function ToolbarButton({
|
|
|
110
164
|
shortcut,
|
|
111
165
|
onClick,
|
|
112
166
|
tooltipVisible,
|
|
167
|
+
tooltipInstant,
|
|
113
168
|
tooltipSide,
|
|
114
169
|
onTooltipEnter,
|
|
115
170
|
onTooltipLeave,
|
|
@@ -127,6 +182,7 @@ function ToolbarButton({
|
|
|
127
182
|
{
|
|
128
183
|
type: "button",
|
|
129
184
|
"aria-label": `${label} (${shortcut})`,
|
|
185
|
+
"aria-pressed": active,
|
|
130
186
|
title: `${label} (${shortcut})`,
|
|
131
187
|
className: cn(
|
|
132
188
|
"msr:flex msr:size-8 msr:items-center msr:justify-center msr:rounded-[8px] msr:outline-none",
|
|
@@ -140,7 +196,10 @@ function ToolbarButton({
|
|
|
140
196
|
"span",
|
|
141
197
|
{
|
|
142
198
|
className: cn(
|
|
143
|
-
|
|
199
|
+
cn(
|
|
200
|
+
"msr:pointer-events-none msr:absolute msr:left-1/2 msr:-translate-x-1/2 msr:whitespace-nowrap msr:rounded msr:bg-black msr:px-2 msr:py-1 msr:text-[11px] msr:text-white msr:transition-opacity msr:duration-150 msr:select-none",
|
|
201
|
+
tooltipInstant && "msr:transition-none"
|
|
202
|
+
),
|
|
144
203
|
tooltipSide === "top" ? "msr:bottom-full msr:mb-2" : "msr:top-full msr:mt-2",
|
|
145
204
|
tooltipVisible ? "msr:opacity-100" : "msr:opacity-0"
|
|
146
205
|
),
|
|
@@ -159,6 +218,7 @@ function useToolbarTooltip() {
|
|
|
159
218
|
const [visibleTooltipId, setVisibleTooltipId] = (0, import_react.useState)(null);
|
|
160
219
|
const timerRef = (0, import_react.useRef)(null);
|
|
161
220
|
const instantRef = (0, import_react.useRef)(false);
|
|
221
|
+
const [tooltipInstant, setTooltipInstant] = (0, import_react.useState)(false);
|
|
162
222
|
const clearTimer = (0, import_react.useCallback)(() => {
|
|
163
223
|
if (timerRef.current === null) return;
|
|
164
224
|
window.clearTimeout(timerRef.current);
|
|
@@ -168,9 +228,11 @@ function useToolbarTooltip() {
|
|
|
168
228
|
(id) => {
|
|
169
229
|
clearTimer();
|
|
170
230
|
if (instantRef.current) {
|
|
231
|
+
setTooltipInstant(true);
|
|
171
232
|
setVisibleTooltipId(id);
|
|
172
233
|
return;
|
|
173
234
|
}
|
|
235
|
+
setTooltipInstant(false);
|
|
174
236
|
timerRef.current = window.setTimeout(() => {
|
|
175
237
|
setVisibleTooltipId(id);
|
|
176
238
|
instantRef.current = true;
|
|
@@ -190,15 +252,17 @@ function useToolbarTooltip() {
|
|
|
190
252
|
clearTimer();
|
|
191
253
|
setVisibleTooltipId(null);
|
|
192
254
|
instantRef.current = false;
|
|
255
|
+
setTooltipInstant(false);
|
|
193
256
|
}, [clearTimer]);
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
257
|
+
return {
|
|
258
|
+
visibleTooltipId,
|
|
259
|
+
tooltipInstant,
|
|
260
|
+
onTooltipEnter,
|
|
261
|
+
onTooltipLeave,
|
|
262
|
+
onToolbarLeave
|
|
263
|
+
};
|
|
200
264
|
}
|
|
201
|
-
function useToolbarDrag(initialPosition) {
|
|
265
|
+
function useToolbarDrag(initialPosition, eventTarget) {
|
|
202
266
|
const [position, setPosition] = (0, import_react.useState)(initialPosition);
|
|
203
267
|
const suppressClickRef = (0, import_react.useRef)(false);
|
|
204
268
|
const detachListenersRef = (0, import_react.useRef)(null);
|
|
@@ -241,8 +305,8 @@ function useToolbarDrag(initialPosition) {
|
|
|
241
305
|
}
|
|
242
306
|
if (!current.active) return;
|
|
243
307
|
current.didDrag = true;
|
|
244
|
-
const maxX = Math.max(8,
|
|
245
|
-
const maxY = Math.max(8,
|
|
308
|
+
const maxX = Math.max(8, eventTarget.innerWidth - current.width - 8);
|
|
309
|
+
const maxY = Math.max(8, eventTarget.innerHeight - current.height - 8);
|
|
246
310
|
setPosition({
|
|
247
311
|
x: Math.min(maxX, Math.max(8, current.originX + dx)),
|
|
248
312
|
y: Math.min(maxY, Math.max(8, current.originY + dy))
|
|
@@ -256,21 +320,21 @@ function useToolbarDrag(initialPosition) {
|
|
|
256
320
|
current.active = false;
|
|
257
321
|
current.didDrag = false;
|
|
258
322
|
current.pointerId = -1;
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
323
|
+
eventTarget.removeEventListener("pointermove", handlePointerMove);
|
|
324
|
+
eventTarget.removeEventListener("pointerup", handlePointerEnd);
|
|
325
|
+
eventTarget.removeEventListener("pointercancel", handlePointerEnd);
|
|
262
326
|
detachListenersRef.current = null;
|
|
263
327
|
};
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
328
|
+
eventTarget.addEventListener("pointermove", handlePointerMove);
|
|
329
|
+
eventTarget.addEventListener("pointerup", handlePointerEnd);
|
|
330
|
+
eventTarget.addEventListener("pointercancel", handlePointerEnd);
|
|
267
331
|
detachListenersRef.current = () => {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
332
|
+
eventTarget.removeEventListener("pointermove", handlePointerMove);
|
|
333
|
+
eventTarget.removeEventListener("pointerup", handlePointerEnd);
|
|
334
|
+
eventTarget.removeEventListener("pointercancel", handlePointerEnd);
|
|
271
335
|
};
|
|
272
336
|
},
|
|
273
|
-
[position.x, position.y]
|
|
337
|
+
[eventTarget, position.x, position.y]
|
|
274
338
|
);
|
|
275
339
|
const onClickCapture = (0, import_react.useCallback)(
|
|
276
340
|
(event) => {
|
|
@@ -287,15 +351,24 @@ function ToolbarComponent({
|
|
|
287
351
|
toolMode,
|
|
288
352
|
setEnabled,
|
|
289
353
|
setToolMode,
|
|
354
|
+
rulersVisible,
|
|
355
|
+
setRulersVisible,
|
|
290
356
|
guideOrientation,
|
|
291
357
|
setGuideOrientation,
|
|
292
|
-
onInteract
|
|
358
|
+
onInteract,
|
|
359
|
+
eventTarget
|
|
293
360
|
}, ref) {
|
|
294
361
|
const { position, onPointerDown, onClickCapture } = useToolbarDrag({
|
|
295
362
|
x: 16,
|
|
296
363
|
y: 16
|
|
297
|
-
});
|
|
298
|
-
const {
|
|
364
|
+
}, eventTarget);
|
|
365
|
+
const {
|
|
366
|
+
visibleTooltipId,
|
|
367
|
+
tooltipInstant,
|
|
368
|
+
onTooltipEnter,
|
|
369
|
+
onTooltipLeave,
|
|
370
|
+
onToolbarLeave
|
|
371
|
+
} = useToolbarTooltip();
|
|
299
372
|
const [guideMenuOpen, setGuideMenuOpen] = (0, import_react.useState)(false);
|
|
300
373
|
const guideMenuRef = (0, import_react.useRef)(null);
|
|
301
374
|
const [activeMenuIndex, setActiveMenuIndex] = (0, import_react.useState)(0);
|
|
@@ -309,13 +382,13 @@ function ToolbarComponent({
|
|
|
309
382
|
setMenuAlign("left");
|
|
310
383
|
return;
|
|
311
384
|
}
|
|
312
|
-
if (leftAlignedRight >
|
|
385
|
+
if (leftAlignedRight > eventTarget.innerWidth - VIEWPORT_PADDING) {
|
|
313
386
|
setMenuAlign("right");
|
|
314
387
|
return;
|
|
315
388
|
}
|
|
316
389
|
setMenuAlign("right");
|
|
317
|
-
}, []);
|
|
318
|
-
const viewportHeight =
|
|
390
|
+
}, [eventTarget]);
|
|
391
|
+
const viewportHeight = eventTarget.innerHeight || 0;
|
|
319
392
|
const nearTop = position.y < 56;
|
|
320
393
|
const nearBottom = viewportHeight > 0 && position.y > viewportHeight - 56;
|
|
321
394
|
const tooltipSide = nearTop && !nearBottom ? "bottom" : "top";
|
|
@@ -330,6 +403,23 @@ function ToolbarComponent({
|
|
|
330
403
|
setToolMode((prev) => prev === "guides" ? "none" : "guides");
|
|
331
404
|
onInteract();
|
|
332
405
|
}, [onInteract, setEnabled, setToolMode]);
|
|
406
|
+
const textInspectorMode = (0, import_react.useCallback)(() => {
|
|
407
|
+
setEnabled(true);
|
|
408
|
+
setToolMode(
|
|
409
|
+
(prev) => prev === "text-inspector" ? "none" : "text-inspector"
|
|
410
|
+
);
|
|
411
|
+
onInteract();
|
|
412
|
+
}, [onInteract, setEnabled, setToolMode]);
|
|
413
|
+
const xrayMode = (0, import_react.useCallback)(() => {
|
|
414
|
+
setEnabled(true);
|
|
415
|
+
setToolMode((prev) => prev === "xray" ? "none" : "xray");
|
|
416
|
+
onInteract();
|
|
417
|
+
}, [onInteract, setEnabled, setToolMode]);
|
|
418
|
+
const rulersMode = (0, import_react.useCallback)(() => {
|
|
419
|
+
setEnabled(true);
|
|
420
|
+
setRulersVisible((prev) => !prev);
|
|
421
|
+
onInteract();
|
|
422
|
+
}, [onInteract, setEnabled, setRulersVisible]);
|
|
333
423
|
const selectGuideOrientation = (0, import_react.useCallback)(
|
|
334
424
|
(orientation) => {
|
|
335
425
|
setEnabled(true);
|
|
@@ -342,7 +432,7 @@ function ToolbarComponent({
|
|
|
342
432
|
);
|
|
343
433
|
(0, import_react.useLayoutEffect)(() => {
|
|
344
434
|
if (!guideMenuOpen) return;
|
|
345
|
-
const frame = requestAnimationFrame(() => {
|
|
435
|
+
const frame = eventTarget.requestAnimationFrame(() => {
|
|
346
436
|
guideMenuRef.current?.querySelector("[role='menu']")?.focus();
|
|
347
437
|
});
|
|
348
438
|
const handlePointerDown = (event) => {
|
|
@@ -355,14 +445,14 @@ function ToolbarComponent({
|
|
|
355
445
|
const handleResize = () => {
|
|
356
446
|
updateMenuAlign();
|
|
357
447
|
};
|
|
358
|
-
|
|
359
|
-
|
|
448
|
+
eventTarget.addEventListener("pointerdown", handlePointerDown);
|
|
449
|
+
eventTarget.addEventListener("resize", handleResize);
|
|
360
450
|
return () => {
|
|
361
|
-
cancelAnimationFrame(frame);
|
|
362
|
-
|
|
363
|
-
|
|
451
|
+
eventTarget.cancelAnimationFrame(frame);
|
|
452
|
+
eventTarget.removeEventListener("pointerdown", handlePointerDown);
|
|
453
|
+
eventTarget.removeEventListener("resize", handleResize);
|
|
364
454
|
};
|
|
365
|
-
}, [guideMenuOpen, guideOrientation, updateMenuAlign]);
|
|
455
|
+
}, [eventTarget, guideMenuOpen, guideOrientation, updateMenuAlign]);
|
|
366
456
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
367
457
|
"div",
|
|
368
458
|
{
|
|
@@ -385,12 +475,61 @@ function ToolbarComponent({
|
|
|
385
475
|
shortcut: "S",
|
|
386
476
|
onClick: selectMode,
|
|
387
477
|
tooltipVisible: visibleTooltipId === "select",
|
|
478
|
+
tooltipInstant,
|
|
388
479
|
tooltipSide,
|
|
389
480
|
onTooltipEnter,
|
|
390
481
|
onTooltipLeave,
|
|
391
482
|
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CursorIcon, { size: 20 })
|
|
392
483
|
}
|
|
393
484
|
),
|
|
485
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
486
|
+
ToolbarButton,
|
|
487
|
+
{
|
|
488
|
+
id: "xray",
|
|
489
|
+
active: toolMode === "xray",
|
|
490
|
+
label: "X-ray",
|
|
491
|
+
shortcut: "X",
|
|
492
|
+
onClick: xrayMode,
|
|
493
|
+
tooltipVisible: visibleTooltipId === "xray",
|
|
494
|
+
tooltipInstant,
|
|
495
|
+
tooltipSide,
|
|
496
|
+
onTooltipEnter,
|
|
497
|
+
onTooltipLeave,
|
|
498
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(XrayIcon, { size: 20 })
|
|
499
|
+
}
|
|
500
|
+
),
|
|
501
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
502
|
+
ToolbarButton,
|
|
503
|
+
{
|
|
504
|
+
id: "rulers",
|
|
505
|
+
active: rulersVisible,
|
|
506
|
+
label: "Rulers",
|
|
507
|
+
shortcut: "R",
|
|
508
|
+
onClick: rulersMode,
|
|
509
|
+
tooltipVisible: visibleTooltipId === "rulers",
|
|
510
|
+
tooltipInstant,
|
|
511
|
+
tooltipSide,
|
|
512
|
+
onTooltipEnter,
|
|
513
|
+
onTooltipLeave,
|
|
514
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RulersIcon, { size: 20 })
|
|
515
|
+
}
|
|
516
|
+
),
|
|
517
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
518
|
+
ToolbarButton,
|
|
519
|
+
{
|
|
520
|
+
id: "text-inspector",
|
|
521
|
+
active: toolMode === "text-inspector",
|
|
522
|
+
label: "Text inspector",
|
|
523
|
+
shortcut: "A",
|
|
524
|
+
onClick: textInspectorMode,
|
|
525
|
+
tooltipVisible: visibleTooltipId === "text-inspector",
|
|
526
|
+
tooltipInstant,
|
|
527
|
+
tooltipSide,
|
|
528
|
+
onTooltipEnter,
|
|
529
|
+
onTooltipLeave,
|
|
530
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TextInspectorIcon, { size: 20, "aria-hidden": "true" })
|
|
531
|
+
}
|
|
532
|
+
),
|
|
394
533
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
395
534
|
ToolbarButton,
|
|
396
535
|
{
|
|
@@ -400,6 +539,7 @@ function ToolbarComponent({
|
|
|
400
539
|
shortcut: "G",
|
|
401
540
|
onClick: guidesMode,
|
|
402
541
|
tooltipVisible: visibleTooltipId === "guides",
|
|
542
|
+
tooltipInstant,
|
|
403
543
|
tooltipSide,
|
|
404
544
|
onTooltipEnter,
|
|
405
545
|
onTooltipLeave,
|
|
@@ -559,32 +699,337 @@ function ToolbarComponent({
|
|
|
559
699
|
}
|
|
560
700
|
var Toolbar = (0, import_react.memo)((0, import_react.forwardRef)(ToolbarComponent));
|
|
561
701
|
|
|
562
|
-
//
|
|
702
|
+
// components/rulers-overlay.tsx
|
|
563
703
|
var import_react2 = require("react");
|
|
704
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
705
|
+
var RULER_SIZE = 18;
|
|
706
|
+
var RULER_LENGTH = 4e3;
|
|
707
|
+
var TICK_STEP = 5;
|
|
708
|
+
var ticks = Array.from(
|
|
709
|
+
{ length: RULER_LENGTH / TICK_STEP + 1 },
|
|
710
|
+
(_, index) => index * TICK_STEP
|
|
711
|
+
);
|
|
712
|
+
var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
713
|
+
onStartGuide,
|
|
714
|
+
onMoveGuide,
|
|
715
|
+
onFinishGuide,
|
|
716
|
+
onCancelGuide,
|
|
717
|
+
guides,
|
|
718
|
+
selectedGuideIds
|
|
719
|
+
}) {
|
|
720
|
+
const [dragPosition, setDragPosition] = (0, import_react2.useState)(null);
|
|
721
|
+
const [dragOrientation, setDragOrientation] = (0, import_react2.useState)(null);
|
|
722
|
+
const dragRef = (0, import_react2.useRef)(null);
|
|
723
|
+
const beginGuideDrag = (orientation, event) => {
|
|
724
|
+
if (event.button !== 0) return;
|
|
725
|
+
event.stopPropagation();
|
|
726
|
+
const position = orientation === "horizontal" ? event.clientY : event.clientX;
|
|
727
|
+
setDragPosition(position);
|
|
728
|
+
setDragOrientation(orientation);
|
|
729
|
+
dragRef.current = {
|
|
730
|
+
orientation,
|
|
731
|
+
pointerId: event.pointerId,
|
|
732
|
+
id: onStartGuide(orientation, position)
|
|
733
|
+
};
|
|
734
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
735
|
+
};
|
|
736
|
+
const moveGuide = (event) => {
|
|
737
|
+
const drag = dragRef.current;
|
|
738
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
739
|
+
event.stopPropagation();
|
|
740
|
+
const position = drag.orientation === "horizontal" ? event.clientY : event.clientX;
|
|
741
|
+
setDragPosition(position);
|
|
742
|
+
onMoveGuide(drag.id, position);
|
|
743
|
+
};
|
|
744
|
+
const finishGuideDrag = (event) => {
|
|
745
|
+
const drag = dragRef.current;
|
|
746
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
747
|
+
event.stopPropagation();
|
|
748
|
+
const position = drag.orientation === "horizontal" ? event.clientY : event.clientX;
|
|
749
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
|
|
750
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
751
|
+
}
|
|
752
|
+
dragRef.current = null;
|
|
753
|
+
setDragPosition(null);
|
|
754
|
+
setDragOrientation(null);
|
|
755
|
+
onMoveGuide(drag.id, position);
|
|
756
|
+
onFinishGuide(drag.id);
|
|
757
|
+
};
|
|
758
|
+
const cancelGuideDrag = (event) => {
|
|
759
|
+
const drag = dragRef.current;
|
|
760
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
761
|
+
dragRef.current = null;
|
|
762
|
+
setDragPosition(null);
|
|
763
|
+
setDragOrientation(null);
|
|
764
|
+
onCancelGuide(drag.id);
|
|
765
|
+
};
|
|
766
|
+
const selectedVerticalGuides = guides.filter(
|
|
767
|
+
(guide) => guide.orientation === "vertical" && selectedGuideIds.includes(guide.id)
|
|
768
|
+
);
|
|
769
|
+
const selectedHorizontalGuides = guides.filter(
|
|
770
|
+
(guide) => guide.orientation === "horizontal" && selectedGuideIds.includes(guide.id)
|
|
771
|
+
);
|
|
772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
773
|
+
"div",
|
|
774
|
+
{
|
|
775
|
+
"aria-hidden": "true",
|
|
776
|
+
className: "msr:pointer-events-none msr:absolute msr:inset-0 msr:select-none msr:text-[9px] msr:text-[#64748b]",
|
|
777
|
+
children: [
|
|
778
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
779
|
+
"div",
|
|
780
|
+
{
|
|
781
|
+
className: "msr:absolute msr:left-[18px] msr:right-0 msr:top-0 msr:overflow-hidden msr:bg-white",
|
|
782
|
+
style: {
|
|
783
|
+
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.12)",
|
|
784
|
+
height: RULER_SIZE,
|
|
785
|
+
cursor: "ns-resize",
|
|
786
|
+
pointerEvents: "auto"
|
|
787
|
+
},
|
|
788
|
+
onPointerDown: (event) => beginGuideDrag("horizontal", event),
|
|
789
|
+
onPointerMove: moveGuide,
|
|
790
|
+
onPointerUp: finishGuideDrag,
|
|
791
|
+
onPointerCancel: cancelGuideDrag,
|
|
792
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
793
|
+
"svg",
|
|
794
|
+
{
|
|
795
|
+
className: "msr:block msr:h-6",
|
|
796
|
+
width: RULER_LENGTH,
|
|
797
|
+
height: RULER_SIZE,
|
|
798
|
+
viewBox: `0 0 ${RULER_LENGTH} ${RULER_SIZE}`,
|
|
799
|
+
children: [
|
|
800
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
801
|
+
"linearGradient",
|
|
802
|
+
{
|
|
803
|
+
id: "ruler-label-fade-x",
|
|
804
|
+
x1: "0%",
|
|
805
|
+
x2: "100%",
|
|
806
|
+
gradientUnits: "objectBoundingBox",
|
|
807
|
+
children: [
|
|
808
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("stop", { offset: "0", stopColor: "white", stopOpacity: "0" }),
|
|
809
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("stop", { offset: "0.2", stopColor: "white" }),
|
|
810
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("stop", { offset: "0.8", stopColor: "white" }),
|
|
811
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
|
|
812
|
+
]
|
|
813
|
+
}
|
|
814
|
+
) }),
|
|
815
|
+
ticks.map((x) => {
|
|
816
|
+
const major = x % 100 === 0;
|
|
817
|
+
const medium = x % 50 === 0;
|
|
818
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
819
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
820
|
+
"line",
|
|
821
|
+
{
|
|
822
|
+
x1: x,
|
|
823
|
+
y1: RULER_SIZE,
|
|
824
|
+
x2: x,
|
|
825
|
+
y2: major ? 8 : medium ? 13 : 17,
|
|
826
|
+
stroke: "currentColor",
|
|
827
|
+
strokeWidth: "1"
|
|
828
|
+
}
|
|
829
|
+
),
|
|
830
|
+
major ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("text", { x, y: "8", textAnchor: "middle", fill: "currentColor", children: x }) : null
|
|
831
|
+
] }, x);
|
|
832
|
+
}),
|
|
833
|
+
selectedVerticalGuides.map((guide) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
834
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
835
|
+
"rect",
|
|
836
|
+
{
|
|
837
|
+
x: guide.position - RULER_SIZE - 8,
|
|
838
|
+
y: "-1",
|
|
839
|
+
width: "48",
|
|
840
|
+
height: "12",
|
|
841
|
+
fill: "url(#ruler-label-fade-x)"
|
|
842
|
+
}
|
|
843
|
+
),
|
|
844
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
845
|
+
"text",
|
|
846
|
+
{
|
|
847
|
+
x: guide.position - RULER_SIZE + 16,
|
|
848
|
+
y: "8",
|
|
849
|
+
textAnchor: "middle",
|
|
850
|
+
fill: "#ef4444",
|
|
851
|
+
fontWeight: "600",
|
|
852
|
+
children: Math.round(guide.position - RULER_SIZE)
|
|
853
|
+
}
|
|
854
|
+
)
|
|
855
|
+
] }, guide.id)),
|
|
856
|
+
dragOrientation === "vertical" && dragPosition !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
857
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
858
|
+
"rect",
|
|
859
|
+
{
|
|
860
|
+
x: dragPosition - RULER_SIZE - 8,
|
|
861
|
+
y: "-1",
|
|
862
|
+
width: "48",
|
|
863
|
+
height: "12",
|
|
864
|
+
fill: "url(#ruler-label-fade-x)"
|
|
865
|
+
}
|
|
866
|
+
),
|
|
867
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
868
|
+
"text",
|
|
869
|
+
{
|
|
870
|
+
x: dragPosition - RULER_SIZE + 16,
|
|
871
|
+
y: "8",
|
|
872
|
+
textAnchor: "middle",
|
|
873
|
+
fill: "#ef4444",
|
|
874
|
+
fontWeight: "600",
|
|
875
|
+
children: Math.round(dragPosition - RULER_SIZE)
|
|
876
|
+
}
|
|
877
|
+
)
|
|
878
|
+
] }) : null
|
|
879
|
+
]
|
|
880
|
+
}
|
|
881
|
+
)
|
|
882
|
+
}
|
|
883
|
+
),
|
|
884
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
885
|
+
"div",
|
|
886
|
+
{
|
|
887
|
+
className: "msr:absolute msr:bottom-0 msr:left-0 msr:top-[18px] msr:w-[18px] msr:overflow-hidden msr:bg-white",
|
|
888
|
+
style: {
|
|
889
|
+
boxShadow: "1px 0 3px rgba(0, 0, 0, 0.12)",
|
|
890
|
+
width: RULER_SIZE,
|
|
891
|
+
cursor: "ew-resize",
|
|
892
|
+
pointerEvents: "auto"
|
|
893
|
+
},
|
|
894
|
+
onPointerDown: (event) => beginGuideDrag("vertical", event),
|
|
895
|
+
onPointerMove: moveGuide,
|
|
896
|
+
onPointerUp: finishGuideDrag,
|
|
897
|
+
onPointerCancel: cancelGuideDrag,
|
|
898
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
899
|
+
"svg",
|
|
900
|
+
{
|
|
901
|
+
className: "msr:block msr:w-6",
|
|
902
|
+
width: RULER_SIZE,
|
|
903
|
+
height: RULER_LENGTH,
|
|
904
|
+
viewBox: `0 0 ${RULER_SIZE} ${RULER_LENGTH}`,
|
|
905
|
+
children: [
|
|
906
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
907
|
+
"linearGradient",
|
|
908
|
+
{
|
|
909
|
+
id: "ruler-label-fade-y",
|
|
910
|
+
y1: "0%",
|
|
911
|
+
y2: "100%",
|
|
912
|
+
gradientUnits: "objectBoundingBox",
|
|
913
|
+
children: [
|
|
914
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("stop", { offset: "0", stopColor: "white", stopOpacity: "0" }),
|
|
915
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("stop", { offset: "0.2", stopColor: "white" }),
|
|
916
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("stop", { offset: "0.8", stopColor: "white" }),
|
|
917
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
|
|
918
|
+
]
|
|
919
|
+
}
|
|
920
|
+
) }),
|
|
921
|
+
ticks.map((y) => {
|
|
922
|
+
const major = y % 100 === 0;
|
|
923
|
+
const medium = y % 50 === 0;
|
|
924
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
925
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
926
|
+
"line",
|
|
927
|
+
{
|
|
928
|
+
x1: RULER_SIZE,
|
|
929
|
+
y1: y,
|
|
930
|
+
x2: major ? 8 : medium ? 13 : 17,
|
|
931
|
+
y2: y,
|
|
932
|
+
stroke: "currentColor",
|
|
933
|
+
strokeWidth: "1"
|
|
934
|
+
}
|
|
935
|
+
),
|
|
936
|
+
major ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
937
|
+
"text",
|
|
938
|
+
{
|
|
939
|
+
x: "8",
|
|
940
|
+
y: y + 10,
|
|
941
|
+
fill: "currentColor",
|
|
942
|
+
transform: `rotate(-90 8 ${y + 10})`,
|
|
943
|
+
children: y
|
|
944
|
+
}
|
|
945
|
+
) : null
|
|
946
|
+
] }, y);
|
|
947
|
+
}),
|
|
948
|
+
selectedHorizontalGuides.map((guide) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
949
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
950
|
+
"rect",
|
|
951
|
+
{
|
|
952
|
+
x: "-3",
|
|
953
|
+
y: guide.position - RULER_SIZE - 38,
|
|
954
|
+
width: "24",
|
|
955
|
+
height: "48",
|
|
956
|
+
fill: "url(#ruler-label-fade-y)"
|
|
957
|
+
}
|
|
958
|
+
),
|
|
959
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
960
|
+
"text",
|
|
961
|
+
{
|
|
962
|
+
x: "9",
|
|
963
|
+
y: guide.position - RULER_SIZE - 16,
|
|
964
|
+
textAnchor: "middle",
|
|
965
|
+
fill: "#ef4444",
|
|
966
|
+
fontWeight: "600",
|
|
967
|
+
transform: `rotate(-90 9 ${guide.position - RULER_SIZE - 16})`,
|
|
968
|
+
children: Math.round(guide.position - RULER_SIZE)
|
|
969
|
+
}
|
|
970
|
+
)
|
|
971
|
+
] }, guide.id)),
|
|
972
|
+
dragOrientation === "horizontal" && dragPosition !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("g", { children: [
|
|
973
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
974
|
+
"rect",
|
|
975
|
+
{
|
|
976
|
+
x: "-3",
|
|
977
|
+
y: dragPosition - RULER_SIZE - 38,
|
|
978
|
+
width: "24",
|
|
979
|
+
height: "48",
|
|
980
|
+
fill: "url(#ruler-label-fade-y)"
|
|
981
|
+
}
|
|
982
|
+
),
|
|
983
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
984
|
+
"text",
|
|
985
|
+
{
|
|
986
|
+
x: "9",
|
|
987
|
+
y: dragPosition - RULER_SIZE - 16,
|
|
988
|
+
textAnchor: "middle",
|
|
989
|
+
fill: "#ef4444",
|
|
990
|
+
fontWeight: "600",
|
|
991
|
+
transform: `rotate(-90 9 ${dragPosition - RULER_SIZE - 16})`,
|
|
992
|
+
children: Math.round(dragPosition - RULER_SIZE)
|
|
993
|
+
}
|
|
994
|
+
)
|
|
995
|
+
] }) : null
|
|
996
|
+
]
|
|
997
|
+
}
|
|
998
|
+
)
|
|
999
|
+
}
|
|
1000
|
+
),
|
|
1001
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "msr:absolute msr:left-0 msr:top-0 msr:size-[18px] msr:bg-white" })
|
|
1002
|
+
]
|
|
1003
|
+
}
|
|
1004
|
+
);
|
|
1005
|
+
});
|
|
1006
|
+
|
|
1007
|
+
// hooks/use-drag-state.ts
|
|
1008
|
+
var import_react3 = require("react");
|
|
564
1009
|
var useDragState = () => {
|
|
565
|
-
const [start, setStart] = (0,
|
|
566
|
-
const [end, setEnd] = (0,
|
|
567
|
-
const [isDragging, setIsDragging] = (0,
|
|
1010
|
+
const [start, setStart] = (0, import_react3.useState)(null);
|
|
1011
|
+
const [end, setEnd] = (0, import_react3.useState)(null);
|
|
1012
|
+
const [isDragging, setIsDragging] = (0, import_react3.useState)(false);
|
|
568
1013
|
return { start, setStart, end, setEnd, isDragging, setIsDragging };
|
|
569
1014
|
};
|
|
570
1015
|
|
|
571
1016
|
// hooks/use-guide-drag-hold.ts
|
|
572
|
-
var
|
|
573
|
-
var useGuideDragHold = () => {
|
|
574
|
-
const guideDragHoldTimerRef = (0,
|
|
575
|
-
const guideDragHoldGuideIdRef = (0,
|
|
576
|
-
const clearGuideDragHold = (0,
|
|
1017
|
+
var import_react4 = require("react");
|
|
1018
|
+
var useGuideDragHold = (eventTarget) => {
|
|
1019
|
+
const guideDragHoldTimerRef = (0, import_react4.useRef)(null);
|
|
1020
|
+
const guideDragHoldGuideIdRef = (0, import_react4.useRef)(null);
|
|
1021
|
+
const clearGuideDragHold = (0, import_react4.useCallback)(() => {
|
|
577
1022
|
if (guideDragHoldTimerRef.current !== null) {
|
|
578
|
-
|
|
1023
|
+
eventTarget.clearTimeout(guideDragHoldTimerRef.current);
|
|
579
1024
|
guideDragHoldTimerRef.current = null;
|
|
580
1025
|
}
|
|
581
1026
|
guideDragHoldGuideIdRef.current = null;
|
|
582
1027
|
}, []);
|
|
583
|
-
const scheduleGuideDragHold = (0,
|
|
1028
|
+
const scheduleGuideDragHold = (0, import_react4.useCallback)(
|
|
584
1029
|
(id, onHold) => {
|
|
585
1030
|
clearGuideDragHold();
|
|
586
1031
|
guideDragHoldGuideIdRef.current = id;
|
|
587
|
-
guideDragHoldTimerRef.current =
|
|
1032
|
+
guideDragHoldTimerRef.current = eventTarget.setTimeout(() => {
|
|
588
1033
|
if (guideDragHoldGuideIdRef.current === id) {
|
|
589
1034
|
onHold(id);
|
|
590
1035
|
}
|
|
@@ -599,11 +1044,11 @@ var useGuideDragHold = () => {
|
|
|
599
1044
|
};
|
|
600
1045
|
|
|
601
1046
|
// hooks/use-guide-state.ts
|
|
602
|
-
var
|
|
1047
|
+
var import_react5 = require("react");
|
|
603
1048
|
var useGuideState = (options = {}) => {
|
|
604
|
-
const [guides, setGuides] = (0,
|
|
605
|
-
const [draggingGuideId, setDraggingGuideId] = (0,
|
|
606
|
-
const [selectedGuideIds, setSelectedGuideIds] = (0,
|
|
1049
|
+
const [guides, setGuides] = (0, import_react5.useState)(options.initialGuides ?? []);
|
|
1050
|
+
const [draggingGuideId, setDraggingGuideId] = (0, import_react5.useState)(null);
|
|
1051
|
+
const [selectedGuideIds, setSelectedGuideIds] = (0, import_react5.useState)(
|
|
607
1052
|
options.initialSelectedGuideIds ?? []
|
|
608
1053
|
);
|
|
609
1054
|
return {
|
|
@@ -617,19 +1062,37 @@ var useGuideState = (options = {}) => {
|
|
|
617
1062
|
};
|
|
618
1063
|
|
|
619
1064
|
// hooks/use-hotkeys.ts
|
|
620
|
-
var
|
|
1065
|
+
var import_react6 = require("react");
|
|
621
1066
|
var useHotkeys = (options) => {
|
|
622
|
-
(0,
|
|
1067
|
+
(0, import_react6.useEffect)(() => {
|
|
1068
|
+
const target = options.eventTarget;
|
|
623
1069
|
const handleKeyDown = (event) => {
|
|
624
1070
|
if (event.key === "Escape") {
|
|
625
1071
|
options.clearAll();
|
|
626
1072
|
return;
|
|
627
1073
|
}
|
|
1074
|
+
if (event.metaKey || event.ctrlKey) {
|
|
1075
|
+
if (event.key.toLowerCase() !== "z") return;
|
|
1076
|
+
if (event.shiftKey) {
|
|
1077
|
+
event.preventDefault();
|
|
1078
|
+
options.redo();
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
event.preventDefault();
|
|
1082
|
+
options.undo();
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
628
1085
|
if (event.key.toLowerCase() === "m") {
|
|
629
1086
|
options.setEnabled((prev) => !prev);
|
|
630
1087
|
}
|
|
631
1088
|
const key = event.key.toLowerCase();
|
|
632
1089
|
if (options.isOverlayActive()) {
|
|
1090
|
+
if (key === "a") {
|
|
1091
|
+
options.setToolMode(
|
|
1092
|
+
(prev) => prev === "text-inspector" ? "none" : "text-inspector"
|
|
1093
|
+
);
|
|
1094
|
+
options.onInteract();
|
|
1095
|
+
}
|
|
633
1096
|
if (key === "s") {
|
|
634
1097
|
options.setToolMode((prev) => prev === "select" ? "none" : "select");
|
|
635
1098
|
options.onInteract();
|
|
@@ -638,6 +1101,14 @@ var useHotkeys = (options) => {
|
|
|
638
1101
|
options.setToolMode((prev) => prev === "guides" ? "none" : "guides");
|
|
639
1102
|
options.onInteract();
|
|
640
1103
|
}
|
|
1104
|
+
if (key === "x") {
|
|
1105
|
+
options.setToolMode((prev) => prev === "xray" ? "none" : "xray");
|
|
1106
|
+
options.onInteract();
|
|
1107
|
+
}
|
|
1108
|
+
if (key === "r") {
|
|
1109
|
+
options.setRulersVisible((prev) => !prev);
|
|
1110
|
+
options.onInteract();
|
|
1111
|
+
}
|
|
641
1112
|
if (key === "h") {
|
|
642
1113
|
options.setGuideOrientation("horizontal");
|
|
643
1114
|
options.onInteract();
|
|
@@ -662,22 +1133,22 @@ var useHotkeys = (options) => {
|
|
|
662
1133
|
options.setAltPressed(false);
|
|
663
1134
|
}
|
|
664
1135
|
};
|
|
665
|
-
|
|
666
|
-
|
|
1136
|
+
target.addEventListener("keydown", handleKeyDown);
|
|
1137
|
+
target.addEventListener("keyup", handleKeyUp);
|
|
667
1138
|
return () => {
|
|
668
|
-
|
|
669
|
-
|
|
1139
|
+
target.removeEventListener("keydown", handleKeyDown);
|
|
1140
|
+
target.removeEventListener("keyup", handleKeyUp);
|
|
670
1141
|
};
|
|
671
1142
|
}, [options]);
|
|
672
1143
|
};
|
|
673
1144
|
|
|
674
1145
|
// hooks/use-live-element-tracking.ts
|
|
675
|
-
var
|
|
1146
|
+
var import_react7 = require("react");
|
|
676
1147
|
|
|
677
|
-
// geometry.ts
|
|
678
|
-
var getViewportSize = () => ({
|
|
679
|
-
width: typeof window === "undefined" ? 1 : window.innerWidth || 1,
|
|
680
|
-
height: typeof window === "undefined" ? 1 : window.innerHeight || 1
|
|
1148
|
+
// core/geometry.ts
|
|
1149
|
+
var getViewportSize = (ownerWindow) => ({
|
|
1150
|
+
width: ownerWindow?.innerWidth || (typeof window === "undefined" ? 1 : window.innerWidth) || 1,
|
|
1151
|
+
height: ownerWindow?.innerHeight || (typeof window === "undefined" ? 1 : window.innerHeight) || 1
|
|
681
1152
|
});
|
|
682
1153
|
var normalizeRect = (rect, viewport = getViewportSize()) => ({
|
|
683
1154
|
left: rect.left / viewport.width,
|
|
@@ -719,9 +1190,9 @@ var getDistanceToRect = (point, rect) => {
|
|
|
719
1190
|
return Math.hypot(dx, dy);
|
|
720
1191
|
};
|
|
721
1192
|
|
|
722
|
-
// distances.ts
|
|
723
|
-
var getDistanceOverlay = (rectA, rectB, elementRefA, elementRefB) => {
|
|
724
|
-
const viewport = getViewportSize();
|
|
1193
|
+
// core/distances.ts
|
|
1194
|
+
var getDistanceOverlay = (rectA, rectB, elementRefA, elementRefB, ownerWindow = window) => {
|
|
1195
|
+
const viewport = getViewportSize(ownerWindow);
|
|
725
1196
|
const normalizedRectA = normalizeRect(rectA, viewport);
|
|
726
1197
|
const normalizedRectB = normalizeRect(rectB, viewport);
|
|
727
1198
|
const rightA = rectA.left + rectA.width;
|
|
@@ -762,10 +1233,10 @@ var getDistanceOverlay = (rectA, rectB, elementRefA, elementRefB) => {
|
|
|
762
1233
|
}
|
|
763
1234
|
}
|
|
764
1235
|
const normalizedConnectors = connectors.map((segment) => ({
|
|
765
|
-
x1: clamp(segment.x1, 0,
|
|
766
|
-
y1: clamp(segment.y1, 0,
|
|
767
|
-
x2: clamp(segment.x2, 0,
|
|
768
|
-
y2: clamp(segment.y2, 0,
|
|
1236
|
+
x1: clamp(segment.x1, 0, ownerWindow.innerWidth),
|
|
1237
|
+
y1: clamp(segment.y1, 0, ownerWindow.innerHeight),
|
|
1238
|
+
x2: clamp(segment.x2, 0, ownerWindow.innerWidth),
|
|
1239
|
+
y2: clamp(segment.y2, 0, ownerWindow.innerHeight)
|
|
769
1240
|
})).filter(
|
|
770
1241
|
(segment) => Math.abs(segment.x1 - segment.x2) > 0.5 || Math.abs(segment.y1 - segment.y2) > 0.5
|
|
771
1242
|
);
|
|
@@ -782,17 +1253,17 @@ var getDistanceOverlay = (rectA, rectB, elementRefA, elementRefB) => {
|
|
|
782
1253
|
connectors: normalizedConnectors
|
|
783
1254
|
};
|
|
784
1255
|
};
|
|
785
|
-
var updateDistanceForResize = (distance, viewport = getViewportSize()) => {
|
|
786
|
-
const normalizedRectA = distance.normalizedRectA ?? normalizeRect(distance.rectA);
|
|
787
|
-
const normalizedRectB = distance.normalizedRectB ?? normalizeRect(distance.rectB);
|
|
1256
|
+
var updateDistanceForResize = (distance, viewport = getViewportSize(), ownerDocument = document, ownerWindow = window) => {
|
|
1257
|
+
const normalizedRectA = distance.normalizedRectA ?? normalizeRect(distance.rectA, viewport);
|
|
1258
|
+
const normalizedRectB = distance.normalizedRectB ?? normalizeRect(distance.rectB, viewport);
|
|
788
1259
|
let rectA = distance.rectA;
|
|
789
1260
|
let rectB = distance.rectB;
|
|
790
|
-
if (distance.elementRefA &&
|
|
1261
|
+
if (distance.elementRefA && ownerDocument.contains(distance.elementRefA)) {
|
|
791
1262
|
rectA = distance.elementRefA.getBoundingClientRect();
|
|
792
1263
|
} else {
|
|
793
1264
|
rectA = denormalizeRect(normalizedRectA, viewport);
|
|
794
1265
|
}
|
|
795
|
-
if (distance.elementRefB &&
|
|
1266
|
+
if (distance.elementRefB && ownerDocument.contains(distance.elementRefB)) {
|
|
796
1267
|
rectB = distance.elementRefB.getBoundingClientRect();
|
|
797
1268
|
} else {
|
|
798
1269
|
rectB = denormalizeRect(normalizedRectB, viewport);
|
|
@@ -801,7 +1272,8 @@ var updateDistanceForResize = (distance, viewport = getViewportSize()) => {
|
|
|
801
1272
|
rectA,
|
|
802
1273
|
rectB,
|
|
803
1274
|
distance.elementRefA,
|
|
804
|
-
distance.elementRefB
|
|
1275
|
+
distance.elementRefB,
|
|
1276
|
+
ownerWindow
|
|
805
1277
|
);
|
|
806
1278
|
return {
|
|
807
1279
|
...updated,
|
|
@@ -809,7 +1281,7 @@ var updateDistanceForResize = (distance, viewport = getViewportSize()) => {
|
|
|
809
1281
|
};
|
|
810
1282
|
};
|
|
811
1283
|
|
|
812
|
-
// dom.ts
|
|
1284
|
+
// core/dom.ts
|
|
813
1285
|
var getElementLabel = (element) => {
|
|
814
1286
|
const tag = element.tagName.toLowerCase();
|
|
815
1287
|
const id = element.id ? `#${element.id}` : "";
|
|
@@ -842,24 +1314,38 @@ var getRectFromDomCached = (element) => {
|
|
|
842
1314
|
};
|
|
843
1315
|
var cachedElements = [];
|
|
844
1316
|
var cachedFrame = -1;
|
|
1317
|
+
var cachedDocument = null;
|
|
845
1318
|
var getFrameToken = () => {
|
|
846
1319
|
if (typeof performance === "undefined") return 0;
|
|
847
1320
|
return Math.floor(performance.now() / 16);
|
|
848
1321
|
};
|
|
849
|
-
var getBodyElementsCached = () => {
|
|
1322
|
+
var getBodyElementsCached = (ownerDocument = document) => {
|
|
850
1323
|
const frame = getFrameToken();
|
|
851
|
-
if (frame === cachedFrame && cachedElements.length > 0) {
|
|
1324
|
+
if (frame === cachedFrame && cachedDocument === ownerDocument && cachedElements.length > 0) {
|
|
852
1325
|
return cachedElements;
|
|
853
1326
|
}
|
|
854
1327
|
cachedFrame = frame;
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
1328
|
+
cachedDocument = ownerDocument;
|
|
1329
|
+
const elements = [];
|
|
1330
|
+
const HTMLElementConstructor = ownerDocument.defaultView?.HTMLElement ?? HTMLElement;
|
|
1331
|
+
const visit = (root) => {
|
|
1332
|
+
const walker = ownerDocument.createTreeWalker(root, 1);
|
|
1333
|
+
let node = walker.nextNode();
|
|
1334
|
+
while (node) {
|
|
1335
|
+
if (node instanceof HTMLElementConstructor) {
|
|
1336
|
+
elements.push(node);
|
|
1337
|
+
if (node.shadowRoot) visit(node.shadowRoot);
|
|
1338
|
+
}
|
|
1339
|
+
node = walker.nextNode();
|
|
1340
|
+
}
|
|
1341
|
+
};
|
|
1342
|
+
if (ownerDocument.body) visit(ownerDocument.body);
|
|
1343
|
+
cachedElements = elements;
|
|
858
1344
|
return cachedElements;
|
|
859
1345
|
};
|
|
860
|
-
var getInspectMeasurement = (element) => {
|
|
1346
|
+
var getInspectMeasurement = (element, ownerWindow = window) => {
|
|
861
1347
|
const rect = element.getBoundingClientRect();
|
|
862
|
-
const style =
|
|
1348
|
+
const style = ownerWindow.getComputedStyle(element);
|
|
863
1349
|
const padding = {
|
|
864
1350
|
top: parseEdge(style.paddingTop),
|
|
865
1351
|
right: parseEdge(style.paddingRight),
|
|
@@ -900,9 +1386,9 @@ var getInspectMeasurement = (element) => {
|
|
|
900
1386
|
elementRef: element
|
|
901
1387
|
};
|
|
902
1388
|
};
|
|
903
|
-
var updateMeasurementForResize = (measurement, viewport = getViewportSize()) => {
|
|
1389
|
+
var updateMeasurementForResize = (measurement, viewport = getViewportSize(), ownerDocument = document) => {
|
|
904
1390
|
let rect = measurement.rect;
|
|
905
|
-
if (measurement.elementRef &&
|
|
1391
|
+
if (measurement.elementRef && ownerDocument.contains(measurement.elementRef)) {
|
|
906
1392
|
rect = getRectFromDom(measurement.elementRef);
|
|
907
1393
|
} else if (measurement.normalizedRect) {
|
|
908
1394
|
rect = denormalizeRect(measurement.normalizedRect, viewport);
|
|
@@ -917,11 +1403,11 @@ var updateMeasurementForResize = (measurement, viewport = getViewportSize()) =>
|
|
|
917
1403
|
|
|
918
1404
|
// hooks/use-live-element-tracking.ts
|
|
919
1405
|
var useLiveElementTracking = (params) => {
|
|
920
|
-
const frameRef = (0,
|
|
921
|
-
(0,
|
|
1406
|
+
const frameRef = (0, import_react7.useRef)(null);
|
|
1407
|
+
(0, import_react7.useEffect)(() => {
|
|
922
1408
|
if (!params.enabled) {
|
|
923
1409
|
if (frameRef.current) {
|
|
924
|
-
cancelAnimationFrame(frameRef.current);
|
|
1410
|
+
params.window.cancelAnimationFrame(frameRef.current);
|
|
925
1411
|
}
|
|
926
1412
|
frameRef.current = null;
|
|
927
1413
|
return;
|
|
@@ -929,7 +1415,7 @@ var useLiveElementTracking = (params) => {
|
|
|
929
1415
|
const tick = () => {
|
|
930
1416
|
params.setMeasurements(
|
|
931
1417
|
(prev) => prev.map((measurement) => {
|
|
932
|
-
if (!measurement.elementRef || !document.contains(measurement.elementRef)) {
|
|
1418
|
+
if (!measurement.elementRef || !params.document.contains(measurement.elementRef)) {
|
|
933
1419
|
return measurement;
|
|
934
1420
|
}
|
|
935
1421
|
const rect = getRectFromDom(measurement.elementRef);
|
|
@@ -943,7 +1429,7 @@ var useLiveElementTracking = (params) => {
|
|
|
943
1429
|
})
|
|
944
1430
|
);
|
|
945
1431
|
params.setActiveMeasurement((prev) => {
|
|
946
|
-
if (!prev?.elementRef || !document.contains(prev.elementRef))
|
|
1432
|
+
if (!prev?.elementRef || !params.document.contains(prev.elementRef))
|
|
947
1433
|
return prev;
|
|
948
1434
|
const rect = getRectFromDom(prev.elementRef);
|
|
949
1435
|
if (rectAlmostEqual(rect, prev.rect)) return prev;
|
|
@@ -956,8 +1442,8 @@ var useLiveElementTracking = (params) => {
|
|
|
956
1442
|
});
|
|
957
1443
|
params.setHeldDistances(
|
|
958
1444
|
(prev) => prev.map((distance) => {
|
|
959
|
-
const canTrackA = distance.elementRefA && document.contains(distance.elementRefA);
|
|
960
|
-
const canTrackB = distance.elementRefB && document.contains(distance.elementRefB);
|
|
1445
|
+
const canTrackA = distance.elementRefA && params.document.contains(distance.elementRefA);
|
|
1446
|
+
const canTrackB = distance.elementRefB && params.document.contains(distance.elementRefB);
|
|
961
1447
|
if (!canTrackA && !canTrackB) return distance;
|
|
962
1448
|
const rectA = canTrackA ? getRectFromDom(distance.elementRefA) : distance.rectA;
|
|
963
1449
|
const rectB = canTrackB ? getRectFromDom(distance.elementRefB) : distance.rectB;
|
|
@@ -968,7 +1454,8 @@ var useLiveElementTracking = (params) => {
|
|
|
968
1454
|
rectA,
|
|
969
1455
|
rectB,
|
|
970
1456
|
distance.elementRefA,
|
|
971
|
-
distance.elementRefB
|
|
1457
|
+
distance.elementRefB,
|
|
1458
|
+
params.window
|
|
972
1459
|
);
|
|
973
1460
|
return {
|
|
974
1461
|
...updated,
|
|
@@ -977,19 +1464,19 @@ var useLiveElementTracking = (params) => {
|
|
|
977
1464
|
})
|
|
978
1465
|
);
|
|
979
1466
|
const selected = params.selectedElementRef.current;
|
|
980
|
-
if (selected && document.contains(selected)) {
|
|
1467
|
+
if (selected && params.document.contains(selected)) {
|
|
981
1468
|
params.setSelectedMeasurement((prev) => {
|
|
982
|
-
const next = getInspectMeasurement(selected);
|
|
1469
|
+
const next = getInspectMeasurement(selected, params.window);
|
|
983
1470
|
if (prev && rectAlmostEqual(prev.rect, next.rect)) return prev;
|
|
984
1471
|
return next;
|
|
985
1472
|
});
|
|
986
1473
|
}
|
|
987
1474
|
params.setSelectedMeasurements(
|
|
988
1475
|
(prev) => prev.map((measurement) => {
|
|
989
|
-
if (!measurement.elementRef || !document.contains(measurement.elementRef)) {
|
|
1476
|
+
if (!measurement.elementRef || !params.document.contains(measurement.elementRef)) {
|
|
990
1477
|
return measurement;
|
|
991
1478
|
}
|
|
992
|
-
const next = getInspectMeasurement(measurement.elementRef);
|
|
1479
|
+
const next = getInspectMeasurement(measurement.elementRef, params.window);
|
|
993
1480
|
if (rectAlmostEqual(next.rect, measurement.rect)) return measurement;
|
|
994
1481
|
return {
|
|
995
1482
|
...next,
|
|
@@ -998,18 +1485,18 @@ var useLiveElementTracking = (params) => {
|
|
|
998
1485
|
})
|
|
999
1486
|
);
|
|
1000
1487
|
const hover = params.hoverElementRef.current;
|
|
1001
|
-
if (hover && document.contains(hover)) {
|
|
1488
|
+
if (hover && params.document.contains(hover)) {
|
|
1002
1489
|
const rect = getRectFromDom(hover);
|
|
1003
1490
|
params.setHoverRect(
|
|
1004
1491
|
(prev) => prev && rectAlmostEqual(prev, rect) ? prev : rect
|
|
1005
1492
|
);
|
|
1006
1493
|
}
|
|
1007
|
-
frameRef.current = requestAnimationFrame(tick);
|
|
1494
|
+
frameRef.current = params.window.requestAnimationFrame(tick);
|
|
1008
1495
|
};
|
|
1009
|
-
frameRef.current = requestAnimationFrame(tick);
|
|
1496
|
+
frameRef.current = params.window.requestAnimationFrame(tick);
|
|
1010
1497
|
return () => {
|
|
1011
1498
|
if (frameRef.current) {
|
|
1012
|
-
cancelAnimationFrame(frameRef.current);
|
|
1499
|
+
params.window.cancelAnimationFrame(frameRef.current);
|
|
1013
1500
|
}
|
|
1014
1501
|
frameRef.current = null;
|
|
1015
1502
|
};
|
|
@@ -1017,13 +1504,16 @@ var useLiveElementTracking = (params) => {
|
|
|
1017
1504
|
};
|
|
1018
1505
|
|
|
1019
1506
|
// hooks/use-measure-toggles.ts
|
|
1020
|
-
var
|
|
1507
|
+
var import_react8 = require("react");
|
|
1021
1508
|
var useMeasureToggles = (options = {}) => {
|
|
1022
|
-
const [enabled, setEnabled] = (0,
|
|
1023
|
-
const [altPressed, setAltPressed] = (0,
|
|
1024
|
-
const [toolMode, setToolMode] = (0,
|
|
1509
|
+
const [enabled, setEnabled] = (0, import_react8.useState)(options.initialEnabled ?? true);
|
|
1510
|
+
const [altPressed, setAltPressed] = (0, import_react8.useState)(false);
|
|
1511
|
+
const [toolMode, setToolMode] = (0, import_react8.useState)(
|
|
1025
1512
|
options.initialToolMode ?? "none"
|
|
1026
1513
|
);
|
|
1514
|
+
const [rulersVisible, setRulersVisible] = (0, import_react8.useState)(
|
|
1515
|
+
options.initialRulersVisible ?? false
|
|
1516
|
+
);
|
|
1027
1517
|
const holdEnabled = false;
|
|
1028
1518
|
const multiMeasureEnabled = false;
|
|
1029
1519
|
const snapGuidesEnabled = true;
|
|
@@ -1037,6 +1527,8 @@ var useMeasureToggles = (options = {}) => {
|
|
|
1037
1527
|
setAltPressed,
|
|
1038
1528
|
toolMode,
|
|
1039
1529
|
setToolMode,
|
|
1530
|
+
rulersVisible,
|
|
1531
|
+
setRulersVisible,
|
|
1040
1532
|
guidesEnabled,
|
|
1041
1533
|
multiMeasureEnabled,
|
|
1042
1534
|
snapGuidesEnabled,
|
|
@@ -1045,16 +1537,16 @@ var useMeasureToggles = (options = {}) => {
|
|
|
1045
1537
|
};
|
|
1046
1538
|
|
|
1047
1539
|
// hooks/use-measurement-state.ts
|
|
1048
|
-
var
|
|
1540
|
+
var import_react9 = require("react");
|
|
1049
1541
|
var useMeasurementState = (options = {}) => {
|
|
1050
|
-
const [activeMeasurement, setActiveMeasurement] = (0,
|
|
1051
|
-
const [measurements, setMeasurements] = (0,
|
|
1542
|
+
const [activeMeasurement, setActiveMeasurement] = (0, import_react9.useState)(options.initialActiveMeasurement ?? null);
|
|
1543
|
+
const [measurements, setMeasurements] = (0, import_react9.useState)(
|
|
1052
1544
|
options.initialMeasurements ?? []
|
|
1053
1545
|
);
|
|
1054
|
-
const [selectedMeasurement, setSelectedMeasurement] = (0,
|
|
1055
|
-
const [selectedMeasurements, setSelectedMeasurements] = (0,
|
|
1056
|
-
const [hoverRect, setHoverRect] = (0,
|
|
1057
|
-
const [heldDistances, setHeldDistances] = (0,
|
|
1546
|
+
const [selectedMeasurement, setSelectedMeasurement] = (0, import_react9.useState)(null);
|
|
1547
|
+
const [selectedMeasurements, setSelectedMeasurements] = (0, import_react9.useState)([]);
|
|
1548
|
+
const [hoverRect, setHoverRect] = (0, import_react9.useState)(null);
|
|
1549
|
+
const [heldDistances, setHeldDistances] = (0, import_react9.useState)(
|
|
1058
1550
|
options.initialHeldDistances ?? []
|
|
1059
1551
|
);
|
|
1060
1552
|
return {
|
|
@@ -1074,9 +1566,9 @@ var useMeasurementState = (options = {}) => {
|
|
|
1074
1566
|
};
|
|
1075
1567
|
|
|
1076
1568
|
// hooks/use-measurer-derived.ts
|
|
1077
|
-
var
|
|
1569
|
+
var import_react10 = require("react");
|
|
1078
1570
|
|
|
1079
|
-
// edge-visibility.ts
|
|
1571
|
+
// core/edge-visibility.ts
|
|
1080
1572
|
var rangesOverlap = (a1, a2, b1, b2) => Math.min(a2, b2) - Math.max(a1, b1) > 0;
|
|
1081
1573
|
var getEdgeVisibilityForRects = (rects, epsilon = 1) => {
|
|
1082
1574
|
const visibility = rects.map(() => ({
|
|
@@ -1116,24 +1608,25 @@ var getEdgeVisibilityForRects = (rects, epsilon = 1) => {
|
|
|
1116
1608
|
return visibility;
|
|
1117
1609
|
};
|
|
1118
1610
|
|
|
1119
|
-
// guides.ts
|
|
1120
|
-
var getGuideRect = (guide) => {
|
|
1121
|
-
const viewport = getViewportSize();
|
|
1611
|
+
// core/guides.ts
|
|
1612
|
+
var getGuideRect = (guide, ownerWindow = window) => {
|
|
1613
|
+
const viewport = getViewportSize(ownerWindow);
|
|
1122
1614
|
return guide.orientation === "vertical" ? { left: guide.position, top: 0, width: 1, height: viewport.height } : { left: 0, top: guide.position, width: viewport.width, height: 1 };
|
|
1123
1615
|
};
|
|
1124
1616
|
var getGuideDistance = (guide, point) => guide.orientation === "vertical" ? Math.abs(guide.position - point.x) : Math.abs(guide.position - point.y);
|
|
1125
1617
|
var getSnapGuidePosition = (params) => {
|
|
1618
|
+
const ownerDocument = params.document ?? document;
|
|
1126
1619
|
const { orientation, point, snapGuidesEnabled, overlayNode, guides } = params;
|
|
1127
1620
|
if (!snapGuidesEnabled) {
|
|
1128
1621
|
return orientation === "vertical" ? point.x : point.y;
|
|
1129
1622
|
}
|
|
1130
|
-
const elements = getBodyElementsCached();
|
|
1623
|
+
const elements = getBodyElementsCached(ownerDocument);
|
|
1131
1624
|
let bestValue = orientation === "vertical" ? point.x : point.y;
|
|
1132
1625
|
let bestDistance = GUIDE_SNAP_DISTANCE + 1;
|
|
1133
1626
|
for (const element of elements) {
|
|
1134
|
-
if (!(element instanceof HTMLElement)) continue;
|
|
1627
|
+
if (!(element instanceof (ownerDocument.defaultView?.HTMLElement ?? HTMLElement))) continue;
|
|
1135
1628
|
if (overlayNode && overlayNode.contains(element)) continue;
|
|
1136
|
-
if (element ===
|
|
1629
|
+
if (element === ownerDocument.body || element === ownerDocument.documentElement)
|
|
1137
1630
|
continue;
|
|
1138
1631
|
const rect = getRectFromDomCached(element);
|
|
1139
1632
|
if (rect.width <= 2 || rect.height <= 2) continue;
|
|
@@ -1169,7 +1662,7 @@ var getSnapGuidePosition = (params) => {
|
|
|
1169
1662
|
return bestDistance <= GUIDE_SNAP_DISTANCE ? bestValue : orientation === "vertical" ? point.x : point.y;
|
|
1170
1663
|
};
|
|
1171
1664
|
|
|
1172
|
-
// option-measurements.ts
|
|
1665
|
+
// core/option-measurements.ts
|
|
1173
1666
|
var getHoveredGuide = (point, guides) => {
|
|
1174
1667
|
if (!point || guides.length === 0) return null;
|
|
1175
1668
|
let closest = null;
|
|
@@ -1190,6 +1683,8 @@ var getSelectedGuide = (guides, selectedGuideIds) => {
|
|
|
1190
1683
|
return guides.find((guide) => guide.id === lastId) ?? null;
|
|
1191
1684
|
};
|
|
1192
1685
|
var getOptionPairOverlay = (params) => {
|
|
1686
|
+
const ownerDocument = params.document ?? document;
|
|
1687
|
+
const ownerWindow = params.window ?? window;
|
|
1193
1688
|
if (!params.altPressed) return null;
|
|
1194
1689
|
if (!params.selectedGuide && !params.primarySelectedMeasurement) return null;
|
|
1195
1690
|
const primary = params.primarySelectedMeasurement;
|
|
@@ -1218,10 +1713,13 @@ var getOptionPairOverlay = (params) => {
|
|
|
1218
1713
|
selectedTarget.rect,
|
|
1219
1714
|
hoverTarget.rect,
|
|
1220
1715
|
selectedTarget.element ?? null,
|
|
1221
|
-
hoverTarget.element ?? null
|
|
1716
|
+
hoverTarget.element ?? null,
|
|
1717
|
+
ownerWindow
|
|
1222
1718
|
);
|
|
1223
1719
|
};
|
|
1224
1720
|
var getOptionContainerLines = (params) => {
|
|
1721
|
+
const ownerDocument = params.document ?? document;
|
|
1722
|
+
const ownerWindow = params.window ?? window;
|
|
1225
1723
|
if (!params.altPressed || !params.primarySelectedMeasurement || params.optionPairOverlay)
|
|
1226
1724
|
return null;
|
|
1227
1725
|
if (params.selectedGuideIds.length > 0) return null;
|
|
@@ -1229,11 +1727,11 @@ var getOptionContainerLines = (params) => {
|
|
|
1229
1727
|
if (params.selectedElement && params.hoverElement && params.hoverElement !== params.selectedElement && params.hoverElement.contains(params.selectedElement)) {
|
|
1230
1728
|
containerElement = params.hoverElement;
|
|
1231
1729
|
}
|
|
1232
|
-
const containerRect = containerElement && containerElement !==
|
|
1730
|
+
const containerRect = containerElement && containerElement !== ownerDocument.body && containerElement !== ownerDocument.documentElement ? getRectFromDom(containerElement) : {
|
|
1233
1731
|
left: 0,
|
|
1234
1732
|
top: 0,
|
|
1235
|
-
width:
|
|
1236
|
-
height:
|
|
1733
|
+
width: ownerWindow.innerWidth,
|
|
1734
|
+
height: ownerWindow.innerHeight
|
|
1237
1735
|
};
|
|
1238
1736
|
const rect = params.primarySelectedMeasurement.rect;
|
|
1239
1737
|
const right = rect.left + rect.width;
|
|
@@ -1272,18 +1770,20 @@ var getOptionContainerLines = (params) => {
|
|
|
1272
1770
|
};
|
|
1273
1771
|
};
|
|
1274
1772
|
|
|
1275
|
-
// selection-helpers.ts
|
|
1773
|
+
// core/selection-helpers.ts
|
|
1276
1774
|
var getOverlayHost = (overlayNode) => {
|
|
1277
1775
|
if (!overlayNode) return null;
|
|
1278
1776
|
const rootNode = overlayNode.getRootNode();
|
|
1279
|
-
return rootNode
|
|
1777
|
+
return rootNode.nodeType === 11 ? rootNode.host : null;
|
|
1280
1778
|
};
|
|
1281
1779
|
var getPrimarySelectedMeasurement = (selectedMeasurements, selectedMeasurement) => selectedMeasurements.length > 0 ? selectedMeasurements[selectedMeasurements.length - 1] : selectedMeasurement;
|
|
1282
1780
|
var getSelectedMeasurementHit = (params) => {
|
|
1781
|
+
const ownerDocument = params.document ?? document;
|
|
1782
|
+
const HTMLElementConstructor = ownerDocument.defaultView?.HTMLElement ?? HTMLElement;
|
|
1283
1783
|
const overlayHost = getOverlayHost(params.overlayNode);
|
|
1284
1784
|
const candidates = params.selectedMeasurements.map((measurement) => {
|
|
1285
1785
|
const element = measurement.elementRef;
|
|
1286
|
-
if (!element || !
|
|
1786
|
+
if (!element || !ownerDocument.contains(element)) return null;
|
|
1287
1787
|
const rect = getRectFromDom(element);
|
|
1288
1788
|
return {
|
|
1289
1789
|
measurement,
|
|
@@ -1293,9 +1793,9 @@ var getSelectedMeasurementHit = (params) => {
|
|
|
1293
1793
|
};
|
|
1294
1794
|
}).filter((item) => item !== null).sort((a, b) => a.area - b.area);
|
|
1295
1795
|
if (candidates.length === 0) return null;
|
|
1296
|
-
const stack =
|
|
1796
|
+
const stack = ownerDocument.elementsFromPoint(params.point.x, params.point.y);
|
|
1297
1797
|
for (const element of stack) {
|
|
1298
|
-
if (!(element instanceof
|
|
1798
|
+
if (!(element instanceof HTMLElementConstructor)) continue;
|
|
1299
1799
|
if (params.overlayNode && params.overlayNode.contains(element)) continue;
|
|
1300
1800
|
if (overlayHost && element === overlayHost) continue;
|
|
1301
1801
|
for (const candidate of candidates) {
|
|
@@ -1314,6 +1814,8 @@ var getSelectedMeasurementHit = (params) => {
|
|
|
1314
1814
|
|
|
1315
1815
|
// hooks/use-measurer-derived.ts
|
|
1316
1816
|
var useMeasurerDerived = ({
|
|
1817
|
+
document: document2,
|
|
1818
|
+
window: window2,
|
|
1317
1819
|
start,
|
|
1318
1820
|
end,
|
|
1319
1821
|
selectedMeasurements,
|
|
@@ -1333,7 +1835,7 @@ var useMeasurerDerived = ({
|
|
|
1333
1835
|
highlightColor,
|
|
1334
1836
|
guideColor
|
|
1335
1837
|
}) => {
|
|
1336
|
-
const activeRect = (0,
|
|
1838
|
+
const activeRect = (0, import_react10.useMemo)(() => {
|
|
1337
1839
|
if (!start || !end) return null;
|
|
1338
1840
|
return {
|
|
1339
1841
|
left: Math.min(start.x, end.x),
|
|
@@ -1344,7 +1846,7 @@ var useMeasurerDerived = ({
|
|
|
1344
1846
|
}, [end, start]);
|
|
1345
1847
|
const activeWidth = activeRect ? formatValue(activeRect.width) : 0;
|
|
1346
1848
|
const activeHeight = activeRect ? formatValue(activeRect.height) : 0;
|
|
1347
|
-
const groupedSelection = (0,
|
|
1849
|
+
const groupedSelection = (0, import_react10.useMemo)(() => {
|
|
1348
1850
|
if (selectedMeasurements.length <= 1) return null;
|
|
1349
1851
|
const selectionKey = selectedMeasurements.map((measurement) => measurement.id).join("|");
|
|
1350
1852
|
const rects = selectedMeasurements.map((measurement) => measurement.rect);
|
|
@@ -1374,31 +1876,33 @@ var useMeasurerDerived = ({
|
|
|
1374
1876
|
originRect: selectionOriginRect ?? void 0
|
|
1375
1877
|
};
|
|
1376
1878
|
}, [selectedMeasurements, selectionOriginRect]);
|
|
1377
|
-
const displayedSelectedMeasurements = (0,
|
|
1879
|
+
const displayedSelectedMeasurements = (0, import_react10.useMemo)(
|
|
1378
1880
|
() => groupedSelection ? [groupedSelection] : selectedMeasurements.length > 0 ? selectedMeasurements : selectedMeasurement ? [selectedMeasurement] : [],
|
|
1379
1881
|
[groupedSelection, selectedMeasurement, selectedMeasurements]
|
|
1380
1882
|
);
|
|
1381
|
-
const selectedGuide = (0,
|
|
1883
|
+
const selectedGuide = (0, import_react10.useMemo)(
|
|
1382
1884
|
() => getSelectedGuide(guides, selectedGuideIds),
|
|
1383
1885
|
[guides, selectedGuideIds]
|
|
1384
1886
|
);
|
|
1385
|
-
const hoverGuide = (0,
|
|
1887
|
+
const hoverGuide = (0, import_react10.useMemo)(
|
|
1386
1888
|
() => getHoveredGuide(hoverPointer, guides),
|
|
1387
1889
|
[guides, hoverPointer]
|
|
1388
1890
|
);
|
|
1389
|
-
const primarySelectedMeasurement = (0,
|
|
1891
|
+
const primarySelectedMeasurement = (0, import_react10.useMemo)(
|
|
1390
1892
|
() => getPrimarySelectedMeasurement(selectedMeasurements, selectedMeasurement),
|
|
1391
1893
|
[selectedMeasurement, selectedMeasurements]
|
|
1392
1894
|
);
|
|
1393
1895
|
const effectivePrimarySelected = groupedSelection ?? primarySelectedMeasurement;
|
|
1394
|
-
const optionPairOverlay = (0,
|
|
1896
|
+
const optionPairOverlay = (0, import_react10.useMemo)(() => {
|
|
1395
1897
|
return getOptionPairOverlay({
|
|
1396
1898
|
altPressed,
|
|
1397
1899
|
primarySelectedMeasurement: effectivePrimarySelected,
|
|
1398
1900
|
selectedGuide,
|
|
1399
1901
|
hoverGuide,
|
|
1400
1902
|
hoverElement,
|
|
1401
|
-
selectedElementRef: selectedElement
|
|
1903
|
+
selectedElementRef: selectedElement,
|
|
1904
|
+
document: document2,
|
|
1905
|
+
window: window2
|
|
1402
1906
|
});
|
|
1403
1907
|
}, [
|
|
1404
1908
|
altPressed,
|
|
@@ -1408,14 +1912,16 @@ var useMeasurerDerived = ({
|
|
|
1408
1912
|
selectedElement,
|
|
1409
1913
|
selectedGuide
|
|
1410
1914
|
]);
|
|
1411
|
-
const optionContainerLines = (0,
|
|
1915
|
+
const optionContainerLines = (0, import_react10.useMemo)(() => {
|
|
1412
1916
|
return getOptionContainerLines({
|
|
1413
1917
|
altPressed,
|
|
1414
1918
|
primarySelectedMeasurement: effectivePrimarySelected,
|
|
1415
1919
|
optionPairOverlay,
|
|
1416
1920
|
selectedGuideIds,
|
|
1417
1921
|
selectedElement,
|
|
1418
|
-
hoverElement
|
|
1922
|
+
hoverElement,
|
|
1923
|
+
document: document2,
|
|
1924
|
+
window: window2
|
|
1419
1925
|
});
|
|
1420
1926
|
}, [
|
|
1421
1927
|
altPressed,
|
|
@@ -1425,12 +1931,15 @@ var useMeasurerDerived = ({
|
|
|
1425
1931
|
selectedElement,
|
|
1426
1932
|
selectedGuideIds
|
|
1427
1933
|
]);
|
|
1428
|
-
const guideDistanceOverlay = (0,
|
|
1934
|
+
const guideDistanceOverlay = (0, import_react10.useMemo)(() => {
|
|
1429
1935
|
if (!altPressed || !guidesEnabled) return null;
|
|
1430
1936
|
if (selectedGuide && hoverGuide && selectedGuide.id !== hoverGuide.id) {
|
|
1431
1937
|
return getDistanceOverlay(
|
|
1432
|
-
getGuideRect(selectedGuide),
|
|
1433
|
-
getGuideRect(hoverGuide)
|
|
1938
|
+
getGuideRect(selectedGuide, window2),
|
|
1939
|
+
getGuideRect(hoverGuide, window2),
|
|
1940
|
+
null,
|
|
1941
|
+
null,
|
|
1942
|
+
window2
|
|
1434
1943
|
);
|
|
1435
1944
|
}
|
|
1436
1945
|
if (!guidePreview) return null;
|
|
@@ -1453,8 +1962,11 @@ var useMeasurerDerived = ({
|
|
|
1453
1962
|
);
|
|
1454
1963
|
if (!nearest) return null;
|
|
1455
1964
|
return getDistanceOverlay(
|
|
1456
|
-
getGuideRect(previewGuide),
|
|
1457
|
-
getGuideRect(nearest.guide)
|
|
1965
|
+
getGuideRect(previewGuide, window2),
|
|
1966
|
+
getGuideRect(nearest.guide, window2),
|
|
1967
|
+
null,
|
|
1968
|
+
null,
|
|
1969
|
+
window2
|
|
1458
1970
|
);
|
|
1459
1971
|
}, [
|
|
1460
1972
|
altPressed,
|
|
@@ -1471,7 +1983,7 @@ var useMeasurerDerived = ({
|
|
|
1471
1983
|
guideColorHover,
|
|
1472
1984
|
guideColorDefault,
|
|
1473
1985
|
guideColorPreview
|
|
1474
|
-
} = (0,
|
|
1986
|
+
} = (0, import_react10.useMemo)(
|
|
1475
1987
|
() => ({
|
|
1476
1988
|
outlineColor: `color-mix(in oklch, ${highlightColor} 80%, transparent)`,
|
|
1477
1989
|
fillColor: `color-mix(in oklch, ${highlightColor} 8%, transparent)`,
|
|
@@ -1482,12 +1994,12 @@ var useMeasurerDerived = ({
|
|
|
1482
1994
|
}),
|
|
1483
1995
|
[guideColor, highlightColor]
|
|
1484
1996
|
);
|
|
1485
|
-
const selectedRects = (0,
|
|
1997
|
+
const selectedRects = (0, import_react10.useMemo)(
|
|
1486
1998
|
() => displayedSelectedMeasurements.map((measurement) => measurement.rect),
|
|
1487
1999
|
[displayedSelectedMeasurements]
|
|
1488
2000
|
);
|
|
1489
2001
|
const hoverRectToShow = hoverHighlightEnabled && hoverRect && selectedMeasurements.length <= 1 ? hoverRect : null;
|
|
1490
|
-
const selectionEdgeVisibility = (0,
|
|
2002
|
+
const selectionEdgeVisibility = (0, import_react10.useMemo)(
|
|
1491
2003
|
() => getEdgeVisibilityForRects(selectedRects),
|
|
1492
2004
|
[selectedRects]
|
|
1493
2005
|
);
|
|
@@ -1496,7 +2008,7 @@ var useMeasurerDerived = ({
|
|
|
1496
2008
|
selectedRects.length
|
|
1497
2009
|
);
|
|
1498
2010
|
const hoverEdgeVisibility = hoverRectToShow ? { top: true, right: true, bottom: true, left: true } : null;
|
|
1499
|
-
const measurementEdgeVisibility = (0,
|
|
2011
|
+
const measurementEdgeVisibility = (0, import_react10.useMemo)(
|
|
1500
2012
|
() => getEdgeVisibilityForRects(displayedMeasurements.map((m) => m.rect)),
|
|
1501
2013
|
[displayedMeasurements]
|
|
1502
2014
|
);
|
|
@@ -1524,7 +2036,7 @@ var useMeasurerDerived = ({
|
|
|
1524
2036
|
};
|
|
1525
2037
|
|
|
1526
2038
|
// hooks/use-measurer-history.ts
|
|
1527
|
-
var
|
|
2039
|
+
var import_react11 = require("react");
|
|
1528
2040
|
var HISTORY_LIMIT = 50;
|
|
1529
2041
|
var useMeasurerHistory = ({
|
|
1530
2042
|
toggles,
|
|
@@ -1570,10 +2082,10 @@ var useMeasurerHistory = ({
|
|
|
1570
2082
|
setSelectedElement,
|
|
1571
2083
|
clearSelectionRect
|
|
1572
2084
|
} = transient;
|
|
1573
|
-
const historyRef = (0,
|
|
1574
|
-
const futureRef = (0,
|
|
1575
|
-
const historySignatureRef = (0,
|
|
1576
|
-
const captureSnapshot = (0,
|
|
2085
|
+
const historyRef = (0, import_react11.useRef)([]);
|
|
2086
|
+
const futureRef = (0, import_react11.useRef)([]);
|
|
2087
|
+
const historySignatureRef = (0, import_react11.useRef)(null);
|
|
2088
|
+
const captureSnapshot = (0, import_react11.useCallback)(() => {
|
|
1577
2089
|
return {
|
|
1578
2090
|
enabled,
|
|
1579
2091
|
toolMode,
|
|
@@ -1600,7 +2112,7 @@ var useMeasurerHistory = ({
|
|
|
1600
2112
|
selectedMeasurements,
|
|
1601
2113
|
toolMode
|
|
1602
2114
|
]);
|
|
1603
|
-
const getSnapshotSignature = (0,
|
|
2115
|
+
const getSnapshotSignature = (0, import_react11.useCallback)((snapshot) => {
|
|
1604
2116
|
const serializeRect = (rect) => `${Math.round(rect.left)}:${Math.round(rect.top)}:${Math.round(rect.width)}:${Math.round(rect.height)}`;
|
|
1605
2117
|
return [
|
|
1606
2118
|
snapshot.enabled ? "1" : "0",
|
|
@@ -1616,7 +2128,7 @@ var useMeasurerHistory = ({
|
|
|
1616
2128
|
snapshot.draggingGuideId ?? ""
|
|
1617
2129
|
].join("|");
|
|
1618
2130
|
}, []);
|
|
1619
|
-
const recordSnapshot = (0,
|
|
2131
|
+
const recordSnapshot = (0, import_react11.useCallback)(() => {
|
|
1620
2132
|
const snapshot = captureSnapshot();
|
|
1621
2133
|
const signature = getSnapshotSignature(snapshot);
|
|
1622
2134
|
if (historySignatureRef.current === signature) return;
|
|
@@ -1627,7 +2139,7 @@ var useMeasurerHistory = ({
|
|
|
1627
2139
|
historyRef.current.shift();
|
|
1628
2140
|
}
|
|
1629
2141
|
}, [captureSnapshot, getSnapshotSignature]);
|
|
1630
|
-
const restoreSnapshot = (0,
|
|
2142
|
+
const restoreSnapshot = (0, import_react11.useCallback)(
|
|
1631
2143
|
(snapshot) => {
|
|
1632
2144
|
setEnabled(snapshot.enabled);
|
|
1633
2145
|
setToolMode(snapshot.toolMode);
|
|
@@ -1672,7 +2184,7 @@ var useMeasurerHistory = ({
|
|
|
1672
2184
|
setHoverElement
|
|
1673
2185
|
]
|
|
1674
2186
|
);
|
|
1675
|
-
const undo = (0,
|
|
2187
|
+
const undo = (0, import_react11.useCallback)(() => {
|
|
1676
2188
|
const previousSnapshot = historyRef.current.pop();
|
|
1677
2189
|
if (!previousSnapshot) return;
|
|
1678
2190
|
const currentSnapshot = captureSnapshot();
|
|
@@ -1683,7 +2195,7 @@ var useMeasurerHistory = ({
|
|
|
1683
2195
|
historySignatureRef.current = null;
|
|
1684
2196
|
restoreSnapshot(previousSnapshot);
|
|
1685
2197
|
}, [captureSnapshot, restoreSnapshot]);
|
|
1686
|
-
const redo = (0,
|
|
2198
|
+
const redo = (0, import_react11.useCallback)(() => {
|
|
1687
2199
|
const nextSnapshot = futureRef.current.pop();
|
|
1688
2200
|
if (!nextSnapshot) return;
|
|
1689
2201
|
historyRef.current.push(captureSnapshot());
|
|
@@ -1693,7 +2205,7 @@ var useMeasurerHistory = ({
|
|
|
1693
2205
|
historySignatureRef.current = null;
|
|
1694
2206
|
restoreSnapshot(nextSnapshot);
|
|
1695
2207
|
}, [captureSnapshot, restoreSnapshot]);
|
|
1696
|
-
const setToolModeWithHistory = (0,
|
|
2208
|
+
const setToolModeWithHistory = (0, import_react11.useCallback)(
|
|
1697
2209
|
(value) => {
|
|
1698
2210
|
setToolMode((prev) => {
|
|
1699
2211
|
const next = typeof value === "function" ? value(prev) : value;
|
|
@@ -1704,7 +2216,7 @@ var useMeasurerHistory = ({
|
|
|
1704
2216
|
},
|
|
1705
2217
|
[recordSnapshot, setToolMode]
|
|
1706
2218
|
);
|
|
1707
|
-
const setGuideOrientationWithHistory = (0,
|
|
2219
|
+
const setGuideOrientationWithHistory = (0, import_react11.useCallback)(
|
|
1708
2220
|
(value) => {
|
|
1709
2221
|
setGuideOrientation((prev) => {
|
|
1710
2222
|
const next = typeof value === "function" ? value(prev) : value;
|
|
@@ -1715,7 +2227,7 @@ var useMeasurerHistory = ({
|
|
|
1715
2227
|
},
|
|
1716
2228
|
[recordSnapshot, setGuideOrientation]
|
|
1717
2229
|
);
|
|
1718
|
-
const setEnabledWithHistory = (0,
|
|
2230
|
+
const setEnabledWithHistory = (0, import_react11.useCallback)(
|
|
1719
2231
|
(value) => {
|
|
1720
2232
|
setEnabled((prev) => {
|
|
1721
2233
|
const next = typeof value === "function" ? value(prev) : value;
|
|
@@ -1726,7 +2238,7 @@ var useMeasurerHistory = ({
|
|
|
1726
2238
|
},
|
|
1727
2239
|
[recordSnapshot, setEnabled]
|
|
1728
2240
|
);
|
|
1729
|
-
const createActionCommit = (0,
|
|
2241
|
+
const createActionCommit = (0, import_react11.useCallback)(() => {
|
|
1730
2242
|
let committed = false;
|
|
1731
2243
|
return () => {
|
|
1732
2244
|
if (committed) return;
|
|
@@ -1734,64 +2246,47 @@ var useMeasurerHistory = ({
|
|
|
1734
2246
|
committed = true;
|
|
1735
2247
|
};
|
|
1736
2248
|
}, [recordSnapshot]);
|
|
1737
|
-
(0, import_react10.useEffect)(() => {
|
|
1738
|
-
const handleKeyDown = (event) => {
|
|
1739
|
-
if (!(event.metaKey || event.ctrlKey)) return;
|
|
1740
|
-
if (event.key.toLowerCase() !== "z") return;
|
|
1741
|
-
if (event.shiftKey) {
|
|
1742
|
-
if (futureRef.current.length === 0) return;
|
|
1743
|
-
event.preventDefault();
|
|
1744
|
-
redo();
|
|
1745
|
-
return;
|
|
1746
|
-
}
|
|
1747
|
-
if (historyRef.current.length === 0) return;
|
|
1748
|
-
event.preventDefault();
|
|
1749
|
-
undo();
|
|
1750
|
-
};
|
|
1751
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
1752
|
-
return () => {
|
|
1753
|
-
window.removeEventListener("keydown", handleKeyDown);
|
|
1754
|
-
};
|
|
1755
|
-
}, [redo, undo]);
|
|
1756
2249
|
return {
|
|
1757
2250
|
recordSnapshot,
|
|
1758
2251
|
createActionCommit,
|
|
1759
2252
|
setToolModeWithHistory,
|
|
1760
2253
|
setGuideOrientationWithHistory,
|
|
1761
|
-
setEnabledWithHistory
|
|
2254
|
+
setEnabledWithHistory,
|
|
2255
|
+
undo,
|
|
2256
|
+
redo
|
|
1762
2257
|
};
|
|
1763
2258
|
};
|
|
1764
2259
|
|
|
1765
2260
|
// hooks/use-measurer-local-state.ts
|
|
1766
|
-
var
|
|
2261
|
+
var import_react12 = require("react");
|
|
1767
2262
|
var useMeasurerLocalState = ({
|
|
1768
2263
|
selectedElementRef,
|
|
1769
2264
|
hoverElementRef,
|
|
1770
2265
|
selectionRectRef
|
|
1771
2266
|
}) => {
|
|
1772
|
-
const [selectionOriginRect, setSelectionOriginRect] = (0,
|
|
2267
|
+
const [selectionOriginRect, setSelectionOriginRect] = (0, import_react12.useState)(
|
|
1773
2268
|
null
|
|
1774
2269
|
);
|
|
1775
|
-
const [hoverPointer, setHoverPointer] = (0,
|
|
1776
|
-
const [hoverElement, setHoverElementState] = (0,
|
|
2270
|
+
const [hoverPointer, setHoverPointer] = (0, import_react12.useState)(null);
|
|
2271
|
+
const [hoverElement, setHoverElementState] = (0, import_react12.useState)(
|
|
1777
2272
|
null
|
|
1778
2273
|
);
|
|
1779
|
-
const [selectedElement, setSelectedElementState] = (0,
|
|
1780
|
-
const setSelectedElement = (0,
|
|
2274
|
+
const [selectedElement, setSelectedElementState] = (0, import_react12.useState)(null);
|
|
2275
|
+
const setSelectedElement = (0, import_react12.useCallback)(
|
|
1781
2276
|
(element) => {
|
|
1782
2277
|
selectedElementRef.current = element;
|
|
1783
2278
|
setSelectedElementState(element);
|
|
1784
2279
|
},
|
|
1785
2280
|
[selectedElementRef]
|
|
1786
2281
|
);
|
|
1787
|
-
const setHoverElement = (0,
|
|
2282
|
+
const setHoverElement = (0, import_react12.useCallback)(
|
|
1788
2283
|
(element) => {
|
|
1789
2284
|
hoverElementRef.current = element;
|
|
1790
2285
|
setHoverElementState(element);
|
|
1791
2286
|
},
|
|
1792
2287
|
[hoverElementRef]
|
|
1793
2288
|
);
|
|
1794
|
-
const clearSelectionRect = (0,
|
|
2289
|
+
const clearSelectionRect = (0, import_react12.useCallback)(() => {
|
|
1795
2290
|
selectionRectRef.current = null;
|
|
1796
2291
|
setSelectionOriginRect(null);
|
|
1797
2292
|
}, [selectionRectRef]);
|
|
@@ -1809,9 +2304,9 @@ var useMeasurerLocalState = ({
|
|
|
1809
2304
|
};
|
|
1810
2305
|
|
|
1811
2306
|
// hooks/use-measurer-pointer.ts
|
|
1812
|
-
var
|
|
2307
|
+
var import_react13 = require("react");
|
|
1813
2308
|
|
|
1814
|
-
// targets.ts
|
|
2309
|
+
// core/targets.ts
|
|
1815
2310
|
var pickMultiTargets = (selectionRect, items) => {
|
|
1816
2311
|
const candidates = items.map(({ element, rect }) => {
|
|
1817
2312
|
const overlapArea = intersectionArea(selectionRect, rect);
|
|
@@ -1876,28 +2371,39 @@ var pickPointTarget = (point, items) => {
|
|
|
1876
2371
|
return scored[0].element;
|
|
1877
2372
|
};
|
|
1878
2373
|
|
|
1879
|
-
// selection.ts
|
|
2374
|
+
// core/selection.ts
|
|
1880
2375
|
var getOverlayHost2 = (overlayNode) => {
|
|
1881
2376
|
if (!overlayNode) return null;
|
|
1882
2377
|
const rootNode = overlayNode.getRootNode();
|
|
1883
|
-
return rootNode
|
|
2378
|
+
return rootNode.nodeType === 11 ? rootNode.host : null;
|
|
1884
2379
|
};
|
|
1885
2380
|
var isOverlayElement = (element, overlayNode, overlayHost) => {
|
|
1886
2381
|
if (overlayNode && overlayNode.contains(element)) return true;
|
|
1887
2382
|
if (overlayHost && element === overlayHost) return true;
|
|
1888
2383
|
return false;
|
|
1889
2384
|
};
|
|
1890
|
-
var
|
|
2385
|
+
var getDeepestElementAt = (element, point) => {
|
|
2386
|
+
let current = element;
|
|
2387
|
+
const HTMLElementConstructor = element.ownerDocument.defaultView?.HTMLElement ?? HTMLElement;
|
|
2388
|
+
while (current instanceof HTMLElementConstructor && current.shadowRoot) {
|
|
2389
|
+
const nested = current.shadowRoot.elementFromPoint(point.x, point.y);
|
|
2390
|
+
if (!nested || nested === current) break;
|
|
2391
|
+
current = nested;
|
|
2392
|
+
}
|
|
2393
|
+
return current;
|
|
2394
|
+
};
|
|
2395
|
+
var getTargetElement = (point, overlayNode, ownerDocument = document) => {
|
|
1891
2396
|
const overlayHost = getOverlayHost2(overlayNode);
|
|
1892
2397
|
if (overlayNode) {
|
|
1893
2398
|
const previous = overlayNode.style.pointerEvents;
|
|
1894
2399
|
overlayNode.style.pointerEvents = "none";
|
|
1895
|
-
const elements2 =
|
|
2400
|
+
const elements2 = ownerDocument.elementsFromPoint(point.x, point.y);
|
|
1896
2401
|
overlayNode.style.pointerEvents = previous;
|
|
1897
|
-
for (const
|
|
1898
|
-
|
|
2402
|
+
for (const rawElement of elements2) {
|
|
2403
|
+
const element = getDeepestElementAt(rawElement, point);
|
|
2404
|
+
if (!(element instanceof (ownerDocument.defaultView?.HTMLElement ?? HTMLElement))) continue;
|
|
1899
2405
|
if (isOverlayElement(element, overlayNode, overlayHost)) continue;
|
|
1900
|
-
if (element ===
|
|
2406
|
+
if (element === ownerDocument.body || element === ownerDocument.documentElement)
|
|
1901
2407
|
continue;
|
|
1902
2408
|
const rect = element.getBoundingClientRect();
|
|
1903
2409
|
if (rect.width <= 2 || rect.height <= 2) continue;
|
|
@@ -1905,11 +2411,12 @@ var getTargetElement = (point, overlayNode) => {
|
|
|
1905
2411
|
}
|
|
1906
2412
|
return null;
|
|
1907
2413
|
}
|
|
1908
|
-
const elements =
|
|
1909
|
-
for (const
|
|
1910
|
-
|
|
2414
|
+
const elements = ownerDocument.elementsFromPoint(point.x, point.y);
|
|
2415
|
+
for (const rawElement of elements) {
|
|
2416
|
+
const element = getDeepestElementAt(rawElement, point);
|
|
2417
|
+
if (!(element instanceof (ownerDocument.defaultView?.HTMLElement ?? HTMLElement))) continue;
|
|
1911
2418
|
if (isOverlayElement(element, overlayNode, overlayHost)) continue;
|
|
1912
|
-
if (element ===
|
|
2419
|
+
if (element === ownerDocument.body || element === ownerDocument.documentElement)
|
|
1913
2420
|
continue;
|
|
1914
2421
|
const rect = element.getBoundingClientRect();
|
|
1915
2422
|
if (rect.width <= 2 || rect.height <= 2) continue;
|
|
@@ -1917,34 +2424,34 @@ var getTargetElement = (point, overlayNode) => {
|
|
|
1917
2424
|
}
|
|
1918
2425
|
return null;
|
|
1919
2426
|
};
|
|
1920
|
-
var getSnappedClickTarget = (point, overlayNode, snapEnabled) => {
|
|
1921
|
-
if (!snapEnabled) return getTargetElement(point, overlayNode);
|
|
2427
|
+
var getSnappedClickTarget = (point, overlayNode, snapEnabled, ownerDocument = document) => {
|
|
2428
|
+
if (!snapEnabled) return getTargetElement(point, overlayNode, ownerDocument);
|
|
1922
2429
|
const probeRect = {
|
|
1923
2430
|
left: point.x - 20,
|
|
1924
2431
|
top: point.y - 20,
|
|
1925
2432
|
width: 40,
|
|
1926
2433
|
height: 40
|
|
1927
2434
|
};
|
|
1928
|
-
const entries = getSelectionEntries(probeRect, overlayNode);
|
|
1929
|
-
return pickPointTarget(point, entries) ?? pickSingleTarget(probeRect, point, entries) ?? getTargetElement(point, overlayNode);
|
|
2435
|
+
const entries = getSelectionEntries(probeRect, overlayNode, ownerDocument);
|
|
2436
|
+
return pickPointTarget(point, entries) ?? pickSingleTarget(probeRect, point, entries) ?? getTargetElement(point, overlayNode, ownerDocument);
|
|
1930
2437
|
};
|
|
1931
|
-
var getSelectionEntries = (rect, overlayNode) => {
|
|
2438
|
+
var getSelectionEntries = (rect, overlayNode, ownerDocument = document) => {
|
|
1932
2439
|
const overlayHost = getOverlayHost2(overlayNode);
|
|
1933
2440
|
const frame = getFrameToken();
|
|
1934
2441
|
const key = `${Math.round(rect.left)}:${Math.round(rect.top)}:${Math.round(
|
|
1935
2442
|
rect.width
|
|
1936
2443
|
)}:${Math.round(rect.height)}`;
|
|
1937
|
-
if (frame === cachedSelectionFrame && cachedSelectionKey === key && cachedOverlayNode === overlayNode) {
|
|
2444
|
+
if (frame === cachedSelectionFrame && cachedSelectionKey === key && cachedOverlayNode === overlayNode && cachedSelectionDocument === ownerDocument) {
|
|
1938
2445
|
return cachedSelectionEntries;
|
|
1939
2446
|
}
|
|
1940
2447
|
const minLeft = rect.left - 1;
|
|
1941
2448
|
const minTop = rect.top - 1;
|
|
1942
2449
|
const maxRight = rect.left + rect.width + 1;
|
|
1943
2450
|
const maxBottom = rect.top + rect.height + 1;
|
|
1944
|
-
const elements = getBodyElementsCached();
|
|
2451
|
+
const elements = getBodyElementsCached(ownerDocument);
|
|
1945
2452
|
const entries = elements.map((element) => ({ element, rect: getRectFromDomCached(element) })).filter(({ element, rect: elementRect }) => {
|
|
1946
2453
|
if (isOverlayElement(element, overlayNode, overlayHost)) return false;
|
|
1947
|
-
if (element ===
|
|
2454
|
+
if (element === ownerDocument.body || element === ownerDocument.documentElement)
|
|
1948
2455
|
return false;
|
|
1949
2456
|
if (elementRect.width < MIN_MULTI_TARGET_SIZE || elementRect.height < MIN_MULTI_TARGET_SIZE) {
|
|
1950
2457
|
return false;
|
|
@@ -1958,6 +2465,7 @@ var getSelectionEntries = (rect, overlayNode) => {
|
|
|
1958
2465
|
cachedSelectionFrame = frame;
|
|
1959
2466
|
cachedSelectionKey = key;
|
|
1960
2467
|
cachedOverlayNode = overlayNode;
|
|
2468
|
+
cachedSelectionDocument = ownerDocument;
|
|
1961
2469
|
cachedSelectionEntries = entries;
|
|
1962
2470
|
return entries;
|
|
1963
2471
|
};
|
|
@@ -1965,30 +2473,33 @@ var cachedSelectionFrame = -1;
|
|
|
1965
2473
|
var cachedSelectionKey = "";
|
|
1966
2474
|
var cachedSelectionEntries = [];
|
|
1967
2475
|
var cachedOverlayNode = null;
|
|
2476
|
+
var cachedSelectionDocument = null;
|
|
1968
2477
|
var getSelectionCacheKey = (rect) => `${Math.round(rect.left)}:${Math.round(rect.top)}:${Math.round(
|
|
1969
2478
|
rect.width
|
|
1970
2479
|
)}:${Math.round(rect.height)}`;
|
|
1971
|
-
var getSelectionEntriesCached = (rect, overlayNode, cache) => {
|
|
2480
|
+
var getSelectionEntriesCached = (rect, overlayNode, cache, ownerDocument = document) => {
|
|
1972
2481
|
const frame = getFrameToken();
|
|
1973
2482
|
const key = getSelectionCacheKey(rect);
|
|
1974
2483
|
if (cache.key === key && cache.overlayNode === overlayNode && cache.frame === frame) {
|
|
1975
2484
|
return cache.entries;
|
|
1976
2485
|
}
|
|
1977
|
-
const entries = getSelectionEntries(rect, overlayNode);
|
|
2486
|
+
const entries = getSelectionEntries(rect, overlayNode, ownerDocument);
|
|
1978
2487
|
cache.key = key;
|
|
1979
2488
|
cache.overlayNode = overlayNode;
|
|
1980
2489
|
cache.frame = frame;
|
|
1981
2490
|
cache.entries = entries;
|
|
1982
2491
|
return entries;
|
|
1983
2492
|
};
|
|
1984
|
-
var getElementsInRectCached = (rect, overlayNode, cache) => {
|
|
1985
|
-
const entries = getSelectionEntriesCached(rect, overlayNode, cache);
|
|
2493
|
+
var getElementsInRectCached = (rect, overlayNode, cache, ownerDocument = document) => {
|
|
2494
|
+
const entries = getSelectionEntriesCached(rect, overlayNode, cache, ownerDocument);
|
|
1986
2495
|
if (entries.length === 0) return [];
|
|
1987
2496
|
return pickMultiTargets(rect, entries);
|
|
1988
2497
|
};
|
|
1989
2498
|
|
|
1990
2499
|
// hooks/use-measurer-pointer.ts
|
|
1991
2500
|
var useMeasurerPointer = ({
|
|
2501
|
+
document: document2,
|
|
2502
|
+
window: window2,
|
|
1992
2503
|
toolbarRef,
|
|
1993
2504
|
overlayRef,
|
|
1994
2505
|
selectionRectRef,
|
|
@@ -2032,46 +2543,26 @@ var useMeasurerPointer = ({
|
|
|
2032
2543
|
setHoverPointer,
|
|
2033
2544
|
clearSelectionRect
|
|
2034
2545
|
}) => {
|
|
2035
|
-
const hoverFrameRef = (0,
|
|
2036
|
-
const hoverPointRef = (0,
|
|
2037
|
-
const selectionCacheRef = (0,
|
|
2546
|
+
const hoverFrameRef = (0, import_react13.useRef)(null);
|
|
2547
|
+
const hoverPointRef = (0, import_react13.useRef)(null);
|
|
2548
|
+
const selectionCacheRef = (0, import_react13.useRef)({
|
|
2038
2549
|
key: "",
|
|
2039
2550
|
entries: [],
|
|
2040
2551
|
overlayNode: null,
|
|
2041
2552
|
frame: -1
|
|
2042
2553
|
});
|
|
2043
|
-
const shiftDragRef = (0,
|
|
2044
|
-
const shiftToggleElementRef = (0,
|
|
2045
|
-
|
|
2046
|
-
const guidesRef = (0, import_react12.useRef)(guides);
|
|
2047
|
-
const snapGuidesEnabledRef = (0, import_react12.useRef)(snapGuidesEnabled);
|
|
2048
|
-
const draggingGuideIdRef = (0, import_react12.useRef)(draggingGuideId);
|
|
2049
|
-
const guideOrientationRef = (0, import_react12.useRef)(guideOrientation);
|
|
2050
|
-
(0, import_react12.useEffect)(() => {
|
|
2554
|
+
const shiftDragRef = (0, import_react13.useRef)(false);
|
|
2555
|
+
const shiftToggleElementRef = (0, import_react13.useRef)(null);
|
|
2556
|
+
(0, import_react13.useEffect)(() => {
|
|
2051
2557
|
return () => {
|
|
2052
2558
|
if (hoverFrameRef.current) {
|
|
2053
|
-
cancelAnimationFrame(hoverFrameRef.current);
|
|
2559
|
+
window2.cancelAnimationFrame(hoverFrameRef.current);
|
|
2054
2560
|
}
|
|
2055
2561
|
};
|
|
2056
2562
|
}, []);
|
|
2057
|
-
(0,
|
|
2058
|
-
guidesEnabledRef.current = guidesEnabled;
|
|
2059
|
-
}, [guidesEnabled]);
|
|
2060
|
-
(0, import_react12.useEffect)(() => {
|
|
2061
|
-
guidesRef.current = guides;
|
|
2062
|
-
}, [guides]);
|
|
2063
|
-
(0, import_react12.useEffect)(() => {
|
|
2064
|
-
snapGuidesEnabledRef.current = snapGuidesEnabled;
|
|
2065
|
-
}, [snapGuidesEnabled]);
|
|
2066
|
-
(0, import_react12.useEffect)(() => {
|
|
2067
|
-
guideOrientationRef.current = guideOrientation;
|
|
2068
|
-
}, [guideOrientation]);
|
|
2069
|
-
(0, import_react12.useEffect)(() => {
|
|
2070
|
-
draggingGuideIdRef.current = draggingGuideId;
|
|
2071
|
-
}, [draggingGuideId]);
|
|
2072
|
-
const updateHoverTarget = (0, import_react12.useCallback)(
|
|
2563
|
+
const updateHoverTarget = (0, import_react13.useCallback)(
|
|
2073
2564
|
(point) => {
|
|
2074
|
-
const target = getTargetElement(point, overlayRef.current);
|
|
2565
|
+
const target = getTargetElement(point, overlayRef.current, document2);
|
|
2075
2566
|
if (target) {
|
|
2076
2567
|
const rect = target.getBoundingClientRect();
|
|
2077
2568
|
setHoverRect({
|
|
@@ -2086,16 +2577,16 @@ var useMeasurerPointer = ({
|
|
|
2086
2577
|
setHoverElement(null);
|
|
2087
2578
|
}
|
|
2088
2579
|
},
|
|
2089
|
-
[overlayRef, setHoverElement, setHoverRect]
|
|
2580
|
+
[document2, overlayRef, setHoverElement, setHoverRect]
|
|
2090
2581
|
);
|
|
2091
|
-
const updateHoverElement = (0,
|
|
2582
|
+
const updateHoverElement = (0, import_react13.useCallback)(
|
|
2092
2583
|
(point) => {
|
|
2093
|
-
const target = getTargetElement(point, overlayRef.current);
|
|
2584
|
+
const target = getTargetElement(point, overlayRef.current, document2);
|
|
2094
2585
|
setHoverElement(target);
|
|
2095
2586
|
},
|
|
2096
|
-
[overlayRef, setHoverElement]
|
|
2587
|
+
[document2, overlayRef, setHoverElement]
|
|
2097
2588
|
);
|
|
2098
|
-
const handlePointerDown = (0,
|
|
2589
|
+
const handlePointerDown = (0, import_react13.useCallback)(
|
|
2099
2590
|
(event) => {
|
|
2100
2591
|
const commit = createActionCommit();
|
|
2101
2592
|
const toolbarNode = toolbarRef.current;
|
|
@@ -2108,7 +2599,8 @@ var useMeasurerPointer = ({
|
|
|
2108
2599
|
shiftToggleElementRef.current = event.shiftKey ? getSelectedMeasurementHit({
|
|
2109
2600
|
point,
|
|
2110
2601
|
selectedMeasurements,
|
|
2111
|
-
overlayNode: overlayRef.current
|
|
2602
|
+
overlayNode: overlayRef.current,
|
|
2603
|
+
document: document2
|
|
2112
2604
|
})?.elementRef ?? null : null;
|
|
2113
2605
|
selectionCacheRef.current.key = "";
|
|
2114
2606
|
if (altPressed && optionPairOverlay) {
|
|
@@ -2130,10 +2622,11 @@ var useMeasurerPointer = ({
|
|
|
2130
2622
|
snapGuidesEnabled,
|
|
2131
2623
|
overlayNode: overlayRef.current,
|
|
2132
2624
|
guides,
|
|
2133
|
-
draggingGuideId
|
|
2625
|
+
draggingGuideId,
|
|
2626
|
+
document: document2
|
|
2134
2627
|
});
|
|
2135
2628
|
const id = createId();
|
|
2136
|
-
setSelectedGuideIds([]);
|
|
2629
|
+
setSelectedGuideIds([id]);
|
|
2137
2630
|
setGuides((prev) => [
|
|
2138
2631
|
...prev,
|
|
2139
2632
|
{ id, orientation: guideOrientation, position }
|
|
@@ -2156,6 +2649,7 @@ var useMeasurerPointer = ({
|
|
|
2156
2649
|
clearSelectionRect,
|
|
2157
2650
|
createActionCommit,
|
|
2158
2651
|
draggingGuideId,
|
|
2652
|
+
document2,
|
|
2159
2653
|
enabled,
|
|
2160
2654
|
guideOrientation,
|
|
2161
2655
|
guides,
|
|
@@ -2177,7 +2671,7 @@ var useMeasurerPointer = ({
|
|
|
2177
2671
|
toolbarRef
|
|
2178
2672
|
]
|
|
2179
2673
|
);
|
|
2180
|
-
const handlePointerMove = (0,
|
|
2674
|
+
const handlePointerMove = (0, import_react13.useCallback)(
|
|
2181
2675
|
(event) => {
|
|
2182
2676
|
const toolbarNode = toolbarRef.current;
|
|
2183
2677
|
if (toolbarNode && toolbarNode.contains(event.target)) return;
|
|
@@ -2197,31 +2691,32 @@ var useMeasurerPointer = ({
|
|
|
2197
2691
|
}
|
|
2198
2692
|
hoverPointRef.current = point;
|
|
2199
2693
|
if (!hoverFrameRef.current) {
|
|
2200
|
-
hoverFrameRef.current = requestAnimationFrame(() => {
|
|
2694
|
+
hoverFrameRef.current = window2.requestAnimationFrame(() => {
|
|
2201
2695
|
const latest = hoverPointRef.current;
|
|
2202
|
-
if (latest && !
|
|
2696
|
+
if (latest && !draggingGuideId) {
|
|
2203
2697
|
if (hoverHighlightEnabled) {
|
|
2204
2698
|
updateHoverTarget(latest);
|
|
2205
2699
|
} else {
|
|
2206
2700
|
updateHoverElement(latest);
|
|
2207
2701
|
}
|
|
2208
2702
|
}
|
|
2209
|
-
if (latest &&
|
|
2703
|
+
if (latest && guides.length > 0) {
|
|
2210
2704
|
setHoverPointer(latest);
|
|
2211
2705
|
} else {
|
|
2212
2706
|
setHoverPointer(null);
|
|
2213
2707
|
}
|
|
2214
|
-
if (
|
|
2708
|
+
if (guidesEnabled && latest && !draggingGuideId) {
|
|
2215
2709
|
const position = getSnapGuidePosition({
|
|
2216
|
-
orientation:
|
|
2710
|
+
orientation: guideOrientation,
|
|
2217
2711
|
point: latest,
|
|
2218
|
-
snapGuidesEnabled
|
|
2712
|
+
snapGuidesEnabled,
|
|
2219
2713
|
overlayNode: overlayRef.current,
|
|
2220
|
-
guides
|
|
2221
|
-
draggingGuideId
|
|
2714
|
+
guides,
|
|
2715
|
+
draggingGuideId,
|
|
2716
|
+
document: document2
|
|
2222
2717
|
});
|
|
2223
2718
|
setGuidePreview({
|
|
2224
|
-
orientation:
|
|
2719
|
+
orientation: guideOrientation,
|
|
2225
2720
|
position
|
|
2226
2721
|
});
|
|
2227
2722
|
} else {
|
|
@@ -2238,10 +2733,11 @@ var useMeasurerPointer = ({
|
|
|
2238
2733
|
position: getSnapGuidePosition({
|
|
2239
2734
|
orientation: guide.orientation,
|
|
2240
2735
|
point,
|
|
2241
|
-
snapGuidesEnabled
|
|
2736
|
+
snapGuidesEnabled,
|
|
2242
2737
|
overlayNode: overlayRef.current,
|
|
2243
|
-
guides
|
|
2244
|
-
draggingGuideId
|
|
2738
|
+
guides,
|
|
2739
|
+
draggingGuideId,
|
|
2740
|
+
document: document2
|
|
2245
2741
|
})
|
|
2246
2742
|
} : guide
|
|
2247
2743
|
)
|
|
@@ -2263,8 +2759,11 @@ var useMeasurerPointer = ({
|
|
|
2263
2759
|
draggingGuideId,
|
|
2264
2760
|
enabled,
|
|
2265
2761
|
hoverHighlightEnabled,
|
|
2762
|
+
guides,
|
|
2763
|
+
guidesEnabled,
|
|
2266
2764
|
isDragging,
|
|
2267
2765
|
overlayRef,
|
|
2766
|
+
guideOrientation,
|
|
2268
2767
|
setAltPressed,
|
|
2269
2768
|
setEnd,
|
|
2270
2769
|
setGuidePreview,
|
|
@@ -2273,6 +2772,7 @@ var useMeasurerPointer = ({
|
|
|
2273
2772
|
setHoverPointer,
|
|
2274
2773
|
setHoverRect,
|
|
2275
2774
|
setIsDragging,
|
|
2775
|
+
snapGuidesEnabled,
|
|
2276
2776
|
start,
|
|
2277
2777
|
toolMode,
|
|
2278
2778
|
toolbarRef,
|
|
@@ -2280,7 +2780,7 @@ var useMeasurerPointer = ({
|
|
|
2280
2780
|
updateHoverTarget
|
|
2281
2781
|
]
|
|
2282
2782
|
);
|
|
2283
|
-
const handlePointerUp = (0,
|
|
2783
|
+
const handlePointerUp = (0, import_react13.useCallback)(
|
|
2284
2784
|
(event) => {
|
|
2285
2785
|
const commit = createActionCommit();
|
|
2286
2786
|
const toolbarNode = toolbarRef.current;
|
|
@@ -2326,7 +2826,8 @@ var useMeasurerPointer = ({
|
|
|
2326
2826
|
const elements = getElementsInRectCached(
|
|
2327
2827
|
selectionRect,
|
|
2328
2828
|
overlayRef.current,
|
|
2329
|
-
selectionCacheRef.current
|
|
2829
|
+
selectionCacheRef.current,
|
|
2830
|
+
document2
|
|
2330
2831
|
);
|
|
2331
2832
|
const hasSameSelection = elements.length === selectedMeasurements.length && elements.every(
|
|
2332
2833
|
(element, index) => selectedMeasurements[index]?.elementRef === element
|
|
@@ -2337,7 +2838,7 @@ var useMeasurerPointer = ({
|
|
|
2337
2838
|
if (!hasSameSelection) {
|
|
2338
2839
|
commit();
|
|
2339
2840
|
const nextMeasurements = elements.map((element) => ({
|
|
2340
|
-
...getInspectMeasurement(element),
|
|
2841
|
+
...getInspectMeasurement(element, window2),
|
|
2341
2842
|
originRect: selectionRect
|
|
2342
2843
|
}));
|
|
2343
2844
|
setSelectedMeasurements(nextMeasurements);
|
|
@@ -2371,7 +2872,8 @@ var useMeasurerPointer = ({
|
|
|
2371
2872
|
) ?? null : getSelectedMeasurementHit({
|
|
2372
2873
|
point,
|
|
2373
2874
|
selectedMeasurements,
|
|
2374
|
-
overlayNode: overlayRef.current
|
|
2875
|
+
overlayNode: overlayRef.current,
|
|
2876
|
+
document: document2
|
|
2375
2877
|
});
|
|
2376
2878
|
if (event.shiftKey && selectedHit) {
|
|
2377
2879
|
commit();
|
|
@@ -2401,9 +2903,9 @@ var useMeasurerPointer = ({
|
|
|
2401
2903
|
resetDragState();
|
|
2402
2904
|
return;
|
|
2403
2905
|
}
|
|
2404
|
-
const target = event.shiftKey ? getTargetElement(point, overlayRef.current) ?? getSnappedClickTarget(point, overlayRef.current, snapEnabled) : getSnappedClickTarget(point, overlayRef.current, snapEnabled);
|
|
2906
|
+
const target = event.shiftKey ? getTargetElement(point, overlayRef.current, document2) ?? getSnappedClickTarget(point, overlayRef.current, snapEnabled, document2) : getSnappedClickTarget(point, overlayRef.current, snapEnabled, document2);
|
|
2405
2907
|
if (target) {
|
|
2406
|
-
const inspectMeasurement = getInspectMeasurement(target);
|
|
2908
|
+
const inspectMeasurement = getInspectMeasurement(target, window2);
|
|
2407
2909
|
clearTransientMeasurements();
|
|
2408
2910
|
if (event.shiftKey) {
|
|
2409
2911
|
const alreadySelected = selectedMeasurements.some(
|
|
@@ -2478,7 +2980,7 @@ var useMeasurerPointer = ({
|
|
|
2478
2980
|
toolbarRef
|
|
2479
2981
|
]
|
|
2480
2982
|
);
|
|
2481
|
-
const handlePointerLeave = (0,
|
|
2983
|
+
const handlePointerLeave = (0, import_react13.useCallback)(() => {
|
|
2482
2984
|
clearGuideDragHold();
|
|
2483
2985
|
setStart(null);
|
|
2484
2986
|
setEnd(null);
|
|
@@ -2502,41 +3004,48 @@ var useMeasurerPointer = ({
|
|
|
2502
3004
|
};
|
|
2503
3005
|
|
|
2504
3006
|
// hooks/use-overlay-refs.ts
|
|
2505
|
-
var
|
|
3007
|
+
var import_react14 = require("react");
|
|
2506
3008
|
var useOverlayRefs = () => {
|
|
2507
|
-
const overlayRef = (0,
|
|
2508
|
-
const selectedElementRef = (0,
|
|
2509
|
-
const hoverElementRef = (0,
|
|
3009
|
+
const overlayRef = (0, import_react14.useRef)(null);
|
|
3010
|
+
const selectedElementRef = (0, import_react14.useRef)(null);
|
|
3011
|
+
const hoverElementRef = (0, import_react14.useRef)(null);
|
|
2510
3012
|
return { overlayRef, selectedElementRef, hoverElementRef };
|
|
2511
3013
|
};
|
|
2512
3014
|
|
|
2513
3015
|
// hooks/use-resize-sync.ts
|
|
2514
|
-
var
|
|
3016
|
+
var import_react15 = require("react");
|
|
2515
3017
|
var useResizeSync = (params) => {
|
|
2516
|
-
const resizeFrameRef = (0,
|
|
2517
|
-
const viewportRef = (0,
|
|
2518
|
-
(0,
|
|
3018
|
+
const resizeFrameRef = (0, import_react15.useRef)(null);
|
|
3019
|
+
const viewportRef = (0, import_react15.useRef)(getViewportSize(params.window));
|
|
3020
|
+
(0, import_react15.useEffect)(() => {
|
|
2519
3021
|
const handleResize = () => {
|
|
2520
3022
|
if (resizeFrameRef.current) {
|
|
2521
|
-
cancelAnimationFrame(resizeFrameRef.current);
|
|
3023
|
+
params.window.cancelAnimationFrame(resizeFrameRef.current);
|
|
2522
3024
|
}
|
|
2523
|
-
resizeFrameRef.current = requestAnimationFrame(() => {
|
|
2524
|
-
const viewport = getViewportSize();
|
|
3025
|
+
resizeFrameRef.current = params.window.requestAnimationFrame(() => {
|
|
3026
|
+
const viewport = getViewportSize(params.window);
|
|
2525
3027
|
const previousViewport = viewportRef.current;
|
|
2526
3028
|
params.setMeasurements(
|
|
2527
3029
|
(prev) => prev.map(
|
|
2528
|
-
(measurement) => updateMeasurementForResize(measurement, viewport)
|
|
3030
|
+
(measurement) => updateMeasurementForResize(measurement, viewport, params.document)
|
|
2529
3031
|
)
|
|
2530
3032
|
);
|
|
2531
3033
|
params.setActiveMeasurement(
|
|
2532
|
-
(prev) => prev ? updateMeasurementForResize(prev, viewport) : prev
|
|
3034
|
+
(prev) => prev ? updateMeasurementForResize(prev, viewport, params.document) : prev
|
|
2533
3035
|
);
|
|
2534
3036
|
params.setHeldDistances(
|
|
2535
|
-
(prev) => prev.map(
|
|
3037
|
+
(prev) => prev.map(
|
|
3038
|
+
(distance) => updateDistanceForResize(
|
|
3039
|
+
distance,
|
|
3040
|
+
viewport,
|
|
3041
|
+
params.document,
|
|
3042
|
+
params.window
|
|
3043
|
+
)
|
|
3044
|
+
)
|
|
2536
3045
|
);
|
|
2537
|
-
if (params.selectedElementRef.current) {
|
|
3046
|
+
if (params.selectedElementRef.current && params.document.contains(params.selectedElementRef.current)) {
|
|
2538
3047
|
params.setSelectedMeasurement(
|
|
2539
|
-
getInspectMeasurement(params.selectedElementRef.current)
|
|
3048
|
+
getInspectMeasurement(params.selectedElementRef.current, params.window)
|
|
2540
3049
|
);
|
|
2541
3050
|
}
|
|
2542
3051
|
if (previousViewport.width > 0 && previousViewport.height > 0) {
|
|
@@ -2551,27 +3060,27 @@ var useResizeSync = (params) => {
|
|
|
2551
3060
|
viewportRef.current = viewport;
|
|
2552
3061
|
});
|
|
2553
3062
|
};
|
|
2554
|
-
window.addEventListener("resize", handleResize);
|
|
3063
|
+
params.window.addEventListener("resize", handleResize);
|
|
2555
3064
|
return () => {
|
|
2556
3065
|
if (resizeFrameRef.current) {
|
|
2557
|
-
cancelAnimationFrame(resizeFrameRef.current);
|
|
3066
|
+
params.window.cancelAnimationFrame(resizeFrameRef.current);
|
|
2558
3067
|
}
|
|
2559
|
-
window.removeEventListener("resize", handleResize);
|
|
3068
|
+
params.window.removeEventListener("resize", handleResize);
|
|
2560
3069
|
};
|
|
2561
3070
|
}, [params]);
|
|
2562
3071
|
};
|
|
2563
3072
|
|
|
2564
3073
|
// render/measurer-overlay.tsx
|
|
2565
|
-
var
|
|
3074
|
+
var import_react19 = require("react");
|
|
2566
3075
|
|
|
2567
3076
|
// components/measure-tag.tsx
|
|
2568
|
-
var
|
|
3077
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
2569
3078
|
function MeasureTag({
|
|
2570
3079
|
children,
|
|
2571
3080
|
className = "",
|
|
2572
3081
|
style
|
|
2573
3082
|
}) {
|
|
2574
|
-
return /* @__PURE__ */ (0,
|
|
3083
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2575
3084
|
"div",
|
|
2576
3085
|
{
|
|
2577
3086
|
className: cn(
|
|
@@ -2585,31 +3094,21 @@ function MeasureTag({
|
|
|
2585
3094
|
}
|
|
2586
3095
|
|
|
2587
3096
|
// components/measurement-box.tsx
|
|
2588
|
-
var
|
|
2589
|
-
var
|
|
3097
|
+
var import_react16 = require("react");
|
|
3098
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
2590
3099
|
var formatValue2 = (value) => Math.round(value);
|
|
2591
|
-
var MeasurementBox = (0,
|
|
3100
|
+
var MeasurementBox = (0, import_react16.memo)(function MeasurementBox2({
|
|
2592
3101
|
measurement,
|
|
2593
3102
|
transitionMs,
|
|
2594
3103
|
labelOffset,
|
|
2595
3104
|
edgeVisibility
|
|
2596
3105
|
}) {
|
|
2597
|
-
const [rect, setRect] = (0, import_react15.useState)(
|
|
2598
|
-
measurement.originRect ?? measurement.rect
|
|
2599
|
-
);
|
|
2600
|
-
(0, import_react15.useEffect)(() => {
|
|
2601
|
-
if (!measurement.originRect) return;
|
|
2602
|
-
const frame = requestAnimationFrame(() => {
|
|
2603
|
-
setRect(measurement.rect);
|
|
2604
|
-
});
|
|
2605
|
-
return () => cancelAnimationFrame(frame);
|
|
2606
|
-
}, [measurement]);
|
|
2607
3106
|
const edges = edgeVisibility ?? { top: true, right: true, bottom: true, left: true };
|
|
2608
|
-
const displayRect = measurement.
|
|
3107
|
+
const displayRect = measurement.rect;
|
|
2609
3108
|
const outlineColor = "color-mix(in oklch, oklch(0.62 0.18 255) 80%, transparent)";
|
|
2610
3109
|
const fillColor = "color-mix(in oklch, oklch(0.62 0.18 255) 8%, transparent)";
|
|
2611
|
-
return /* @__PURE__ */ (0,
|
|
2612
|
-
/* @__PURE__ */ (0,
|
|
3110
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "msr:pointer-events-none", children: [
|
|
3111
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2613
3112
|
"div",
|
|
2614
3113
|
{
|
|
2615
3114
|
className: "msr:absolute",
|
|
@@ -2619,31 +3118,31 @@ var MeasurementBox = (0, import_react15.memo)(function MeasurementBox2({
|
|
|
2619
3118
|
width: displayRect.width,
|
|
2620
3119
|
height: displayRect.height,
|
|
2621
3120
|
backgroundColor: fillColor,
|
|
2622
|
-
transition:
|
|
3121
|
+
transition: `left ${transitionMs}ms ease, top ${transitionMs}ms ease, width ${transitionMs}ms ease, height ${transitionMs}ms ease`
|
|
2623
3122
|
},
|
|
2624
3123
|
children: [
|
|
2625
|
-
edges.top ? /* @__PURE__ */ (0,
|
|
3124
|
+
edges.top ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2626
3125
|
"div",
|
|
2627
3126
|
{
|
|
2628
3127
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-px msr:w-full",
|
|
2629
3128
|
style: { backgroundColor: outlineColor }
|
|
2630
3129
|
}
|
|
2631
3130
|
) : null,
|
|
2632
|
-
edges.right ? /* @__PURE__ */ (0,
|
|
3131
|
+
edges.right ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2633
3132
|
"div",
|
|
2634
3133
|
{
|
|
2635
3134
|
className: "msr:absolute msr:right-0 msr:top-0 msr:h-full msr:w-px",
|
|
2636
3135
|
style: { backgroundColor: outlineColor }
|
|
2637
3136
|
}
|
|
2638
3137
|
) : null,
|
|
2639
|
-
edges.bottom ? /* @__PURE__ */ (0,
|
|
3138
|
+
edges.bottom ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2640
3139
|
"div",
|
|
2641
3140
|
{
|
|
2642
3141
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:h-px msr:w-full",
|
|
2643
3142
|
style: { backgroundColor: outlineColor }
|
|
2644
3143
|
}
|
|
2645
3144
|
) : null,
|
|
2646
|
-
edges.left ? /* @__PURE__ */ (0,
|
|
3145
|
+
edges.left ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2647
3146
|
"div",
|
|
2648
3147
|
{
|
|
2649
3148
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-full msr:w-px",
|
|
@@ -2653,14 +3152,14 @@ var MeasurementBox = (0, import_react15.memo)(function MeasurementBox2({
|
|
|
2653
3152
|
]
|
|
2654
3153
|
}
|
|
2655
3154
|
),
|
|
2656
|
-
/* @__PURE__ */ (0,
|
|
3155
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2657
3156
|
MeasureTag,
|
|
2658
3157
|
{
|
|
2659
3158
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
2660
3159
|
style: {
|
|
2661
3160
|
left: displayRect.left + displayRect.width / 2,
|
|
2662
3161
|
top: displayRect.top + displayRect.height + labelOffset,
|
|
2663
|
-
transition:
|
|
3162
|
+
transition: `left ${transitionMs}ms ease, top ${transitionMs}ms ease`
|
|
2664
3163
|
},
|
|
2665
3164
|
children: [
|
|
2666
3165
|
formatValue2(displayRect.width),
|
|
@@ -2673,31 +3172,21 @@ var MeasurementBox = (0, import_react15.memo)(function MeasurementBox2({
|
|
|
2673
3172
|
});
|
|
2674
3173
|
|
|
2675
3174
|
// components/selected-measurement-box.tsx
|
|
2676
|
-
var
|
|
2677
|
-
var
|
|
3175
|
+
var import_react17 = require("react");
|
|
3176
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2678
3177
|
var formatValue3 = (value) => Math.round(value);
|
|
2679
|
-
var SelectedMeasurementBox = (0,
|
|
3178
|
+
var SelectedMeasurementBox = (0, import_react17.memo)(function SelectedMeasurementBox2({
|
|
2680
3179
|
measurement,
|
|
2681
3180
|
transitionMs,
|
|
2682
3181
|
labelOffset,
|
|
2683
3182
|
edgeVisibility
|
|
2684
3183
|
}) {
|
|
2685
|
-
const [rect, setRect] = (0, import_react16.useState)(
|
|
2686
|
-
measurement.originRect ?? measurement.rect
|
|
2687
|
-
);
|
|
2688
|
-
(0, import_react16.useEffect)(() => {
|
|
2689
|
-
if (!measurement.originRect) return;
|
|
2690
|
-
const frame = requestAnimationFrame(() => {
|
|
2691
|
-
setRect(measurement.rect);
|
|
2692
|
-
});
|
|
2693
|
-
return () => cancelAnimationFrame(frame);
|
|
2694
|
-
}, [measurement]);
|
|
2695
3184
|
const edges = edgeVisibility ?? { top: true, right: true, bottom: true, left: true };
|
|
2696
|
-
const displayRect = measurement.
|
|
3185
|
+
const displayRect = measurement.rect;
|
|
2697
3186
|
const outlineColor = "color-mix(in oklch, oklch(0.62 0.18 255) 80%, transparent)";
|
|
2698
3187
|
const fillColor = "color-mix(in oklch, oklch(0.62 0.18 255) 8%, transparent)";
|
|
2699
|
-
return /* @__PURE__ */ (0,
|
|
2700
|
-
/* @__PURE__ */ (0,
|
|
3188
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "msr:pointer-events-none", children: [
|
|
3189
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2701
3190
|
"div",
|
|
2702
3191
|
{
|
|
2703
3192
|
className: "msr:absolute",
|
|
@@ -2707,31 +3196,31 @@ var SelectedMeasurementBox = (0, import_react16.memo)(function SelectedMeasureme
|
|
|
2707
3196
|
width: displayRect.width,
|
|
2708
3197
|
height: displayRect.height,
|
|
2709
3198
|
backgroundColor: fillColor,
|
|
2710
|
-
transition:
|
|
3199
|
+
transition: `left ${transitionMs}ms ease, top ${transitionMs}ms ease, width ${transitionMs}ms ease, height ${transitionMs}ms ease`
|
|
2711
3200
|
},
|
|
2712
3201
|
children: [
|
|
2713
|
-
edges.top ? /* @__PURE__ */ (0,
|
|
3202
|
+
edges.top ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2714
3203
|
"div",
|
|
2715
3204
|
{
|
|
2716
3205
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-px msr:w-full",
|
|
2717
3206
|
style: { backgroundColor: outlineColor }
|
|
2718
3207
|
}
|
|
2719
3208
|
) : null,
|
|
2720
|
-
edges.right ? /* @__PURE__ */ (0,
|
|
3209
|
+
edges.right ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2721
3210
|
"div",
|
|
2722
3211
|
{
|
|
2723
3212
|
className: "msr:absolute msr:right-0 msr:top-0 msr:h-full msr:w-px",
|
|
2724
3213
|
style: { backgroundColor: outlineColor }
|
|
2725
3214
|
}
|
|
2726
3215
|
) : null,
|
|
2727
|
-
edges.bottom ? /* @__PURE__ */ (0,
|
|
3216
|
+
edges.bottom ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2728
3217
|
"div",
|
|
2729
3218
|
{
|
|
2730
3219
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:h-px msr:w-full",
|
|
2731
3220
|
style: { backgroundColor: outlineColor }
|
|
2732
3221
|
}
|
|
2733
3222
|
) : null,
|
|
2734
|
-
edges.left ? /* @__PURE__ */ (0,
|
|
3223
|
+
edges.left ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2735
3224
|
"div",
|
|
2736
3225
|
{
|
|
2737
3226
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-full msr:w-px",
|
|
@@ -2741,14 +3230,14 @@ var SelectedMeasurementBox = (0, import_react16.memo)(function SelectedMeasureme
|
|
|
2741
3230
|
]
|
|
2742
3231
|
}
|
|
2743
3232
|
),
|
|
2744
|
-
/* @__PURE__ */ (0,
|
|
3233
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2745
3234
|
MeasureTag,
|
|
2746
3235
|
{
|
|
2747
3236
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
2748
3237
|
style: {
|
|
2749
3238
|
left: displayRect.left + displayRect.width / 2,
|
|
2750
3239
|
top: displayRect.top + displayRect.height + labelOffset,
|
|
2751
|
-
transition:
|
|
3240
|
+
transition: `left ${transitionMs}ms ease, top ${transitionMs}ms ease`
|
|
2752
3241
|
},
|
|
2753
3242
|
children: [
|
|
2754
3243
|
formatValue3(displayRect.width),
|
|
@@ -2761,14 +3250,14 @@ var SelectedMeasurementBox = (0, import_react16.memo)(function SelectedMeasureme
|
|
|
2761
3250
|
});
|
|
2762
3251
|
|
|
2763
3252
|
// render/distance-overlay-item.tsx
|
|
2764
|
-
var
|
|
2765
|
-
var
|
|
2766
|
-
var DistanceOverlayItem = (0,
|
|
3253
|
+
var import_react18 = require("react");
|
|
3254
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
3255
|
+
var DistanceOverlayItem = (0, import_react18.memo)(function DistanceOverlayItem2({
|
|
2767
3256
|
distance,
|
|
2768
3257
|
labelOffset,
|
|
2769
3258
|
onRemove
|
|
2770
3259
|
}) {
|
|
2771
|
-
return /* @__PURE__ */ (0,
|
|
3260
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2772
3261
|
"div",
|
|
2773
3262
|
{
|
|
2774
3263
|
className: onRemove ? "msr:pointer-events-auto" : "msr:pointer-events-none",
|
|
@@ -2777,7 +3266,7 @@ var DistanceOverlayItem = (0, import_react17.memo)(function DistanceOverlayItem2
|
|
|
2777
3266
|
onRemove(distance.id);
|
|
2778
3267
|
} : void 0,
|
|
2779
3268
|
children: [
|
|
2780
|
-
/* @__PURE__ */ (0,
|
|
3269
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2781
3270
|
"div",
|
|
2782
3271
|
{
|
|
2783
3272
|
className: "msr:absolute msr:rounded msr:border msr:border-[#2563eb]/70",
|
|
@@ -2789,7 +3278,7 @@ var DistanceOverlayItem = (0, import_react17.memo)(function DistanceOverlayItem2
|
|
|
2789
3278
|
}
|
|
2790
3279
|
}
|
|
2791
3280
|
),
|
|
2792
|
-
/* @__PURE__ */ (0,
|
|
3281
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2793
3282
|
"div",
|
|
2794
3283
|
{
|
|
2795
3284
|
className: "msr:absolute msr:rounded msr:border msr:border-[#2563eb]/70",
|
|
@@ -2802,7 +3291,7 @@ var DistanceOverlayItem = (0, import_react17.memo)(function DistanceOverlayItem2
|
|
|
2802
3291
|
}
|
|
2803
3292
|
),
|
|
2804
3293
|
distance.connectors.map(
|
|
2805
|
-
(connector, index) => Math.abs(connector.x1 - connector.x2) < 1 ? /* @__PURE__ */ (0,
|
|
3294
|
+
(connector, index) => Math.abs(connector.x1 - connector.x2) < 1 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2806
3295
|
"div",
|
|
2807
3296
|
{
|
|
2808
3297
|
className: "msr:absolute msr:border-l msr:border-dashed msr:border-[#2563eb]/70",
|
|
@@ -2813,7 +3302,7 @@ var DistanceOverlayItem = (0, import_react17.memo)(function DistanceOverlayItem2
|
|
|
2813
3302
|
}
|
|
2814
3303
|
},
|
|
2815
3304
|
`${distance.id}-connector-${index}`
|
|
2816
|
-
) : /* @__PURE__ */ (0,
|
|
3305
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2817
3306
|
"div",
|
|
2818
3307
|
{
|
|
2819
3308
|
className: "msr:absolute msr:border-t msr:border-dashed msr:border-[#2563eb]/70",
|
|
@@ -2826,8 +3315,8 @@ var DistanceOverlayItem = (0, import_react17.memo)(function DistanceOverlayItem2
|
|
|
2826
3315
|
`${distance.id}-connector-${index}`
|
|
2827
3316
|
)
|
|
2828
3317
|
),
|
|
2829
|
-
distance.horizontal && distance.horizontal.value > 0 ? /* @__PURE__ */ (0,
|
|
2830
|
-
/* @__PURE__ */ (0,
|
|
3318
|
+
distance.horizontal && distance.horizontal.value > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
3319
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2831
3320
|
"div",
|
|
2832
3321
|
{
|
|
2833
3322
|
className: "msr:absolute msr:h-px msr:bg-[#2563eb]",
|
|
@@ -2838,7 +3327,7 @@ var DistanceOverlayItem = (0, import_react17.memo)(function DistanceOverlayItem2
|
|
|
2838
3327
|
}
|
|
2839
3328
|
}
|
|
2840
3329
|
),
|
|
2841
|
-
/* @__PURE__ */ (0,
|
|
3330
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2842
3331
|
MeasureTag,
|
|
2843
3332
|
{
|
|
2844
3333
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -2850,8 +3339,8 @@ var DistanceOverlayItem = (0, import_react17.memo)(function DistanceOverlayItem2
|
|
|
2850
3339
|
}
|
|
2851
3340
|
)
|
|
2852
3341
|
] }) : null,
|
|
2853
|
-
distance.vertical && distance.vertical.value > 0 ? /* @__PURE__ */ (0,
|
|
2854
|
-
/* @__PURE__ */ (0,
|
|
3342
|
+
distance.vertical && distance.vertical.value > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
3343
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2855
3344
|
"div",
|
|
2856
3345
|
{
|
|
2857
3346
|
className: "msr:absolute msr:w-px msr:bg-[#2563eb]",
|
|
@@ -2862,7 +3351,7 @@ var DistanceOverlayItem = (0, import_react17.memo)(function DistanceOverlayItem2
|
|
|
2862
3351
|
}
|
|
2863
3352
|
}
|
|
2864
3353
|
),
|
|
2865
|
-
/* @__PURE__ */ (0,
|
|
3354
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2866
3355
|
MeasureTag,
|
|
2867
3356
|
{
|
|
2868
3357
|
className: "msr:-translate-y-1/2 msr:bg-ink-900/90",
|
|
@@ -2880,10 +3369,11 @@ var DistanceOverlayItem = (0, import_react17.memo)(function DistanceOverlayItem2
|
|
|
2880
3369
|
});
|
|
2881
3370
|
|
|
2882
3371
|
// render/measurer-overlay.tsx
|
|
2883
|
-
var
|
|
2884
|
-
var MeasurerOverlay = (0,
|
|
3372
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
3373
|
+
var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
2885
3374
|
enabled,
|
|
2886
3375
|
toolMode,
|
|
3376
|
+
guidePointerEvents,
|
|
2887
3377
|
guidesEnabled,
|
|
2888
3378
|
altPressed,
|
|
2889
3379
|
isDragging,
|
|
@@ -2920,16 +3410,20 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
2920
3410
|
onGuidePointerUp,
|
|
2921
3411
|
onGuidePointerCancel
|
|
2922
3412
|
}) {
|
|
2923
|
-
|
|
3413
|
+
const overlayVisible = enabled;
|
|
3414
|
+
const overlayInteractive = overlayVisible && toolMode !== "none" && toolMode !== "text-inspector" && toolMode !== "xray" && toolMode !== "rulers";
|
|
3415
|
+
const selectionVisible = toolMode === "select";
|
|
3416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2924
3417
|
"div",
|
|
2925
3418
|
{
|
|
2926
|
-
className: `msr:absolute msr:inset-0 ${
|
|
3419
|
+
className: `msr:absolute msr:inset-0 ${overlayVisible ? `msr:pointer-events-auto ${guidesEnabled ? hoverGuide || draggingGuideId ? "msr:cursor-default" : "msr:cursor-crosshair" : "msr:cursor-default"} msr:opacity-100` : "msr:pointer-events-none msr:opacity-0"}`,
|
|
3420
|
+
style: { pointerEvents: overlayInteractive ? "auto" : "none" },
|
|
2927
3421
|
onPointerDown,
|
|
2928
3422
|
onPointerMove,
|
|
2929
3423
|
onPointerUp,
|
|
2930
3424
|
onPointerLeave,
|
|
2931
3425
|
children: [
|
|
2932
|
-
|
|
3426
|
+
selectionVisible ? displayedMeasurements.map((measurement, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2933
3427
|
MeasurementBox,
|
|
2934
3428
|
{
|
|
2935
3429
|
measurement,
|
|
@@ -2939,8 +3433,8 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
2939
3433
|
},
|
|
2940
3434
|
measurement.id
|
|
2941
3435
|
)) : null,
|
|
2942
|
-
|
|
2943
|
-
/* @__PURE__ */ (0,
|
|
3436
|
+
selectionVisible && activeRect && isDragging ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
3437
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2944
3438
|
"div",
|
|
2945
3439
|
{
|
|
2946
3440
|
className: "msr:pointer-events-none msr:absolute",
|
|
@@ -2952,28 +3446,28 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
2952
3446
|
backgroundColor: fillColor
|
|
2953
3447
|
},
|
|
2954
3448
|
children: [
|
|
2955
|
-
/* @__PURE__ */ (0,
|
|
3449
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2956
3450
|
"div",
|
|
2957
3451
|
{
|
|
2958
3452
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-px msr:w-full",
|
|
2959
3453
|
style: { backgroundColor: outlineColor }
|
|
2960
3454
|
}
|
|
2961
3455
|
),
|
|
2962
|
-
/* @__PURE__ */ (0,
|
|
3456
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2963
3457
|
"div",
|
|
2964
3458
|
{
|
|
2965
3459
|
className: "msr:absolute msr:right-0 msr:top-0 msr:h-full msr:w-px",
|
|
2966
3460
|
style: { backgroundColor: outlineColor }
|
|
2967
3461
|
}
|
|
2968
3462
|
),
|
|
2969
|
-
/* @__PURE__ */ (0,
|
|
3463
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2970
3464
|
"div",
|
|
2971
3465
|
{
|
|
2972
3466
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:h-px msr:w-full",
|
|
2973
3467
|
style: { backgroundColor: outlineColor }
|
|
2974
3468
|
}
|
|
2975
3469
|
),
|
|
2976
|
-
/* @__PURE__ */ (0,
|
|
3470
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2977
3471
|
"div",
|
|
2978
3472
|
{
|
|
2979
3473
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-full msr:w-px",
|
|
@@ -2983,7 +3477,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
2983
3477
|
]
|
|
2984
3478
|
}
|
|
2985
3479
|
),
|
|
2986
|
-
/* @__PURE__ */ (0,
|
|
3480
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2987
3481
|
MeasureTag,
|
|
2988
3482
|
{
|
|
2989
3483
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -2999,7 +3493,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
2999
3493
|
}
|
|
3000
3494
|
)
|
|
3001
3495
|
] }) : null,
|
|
3002
|
-
|
|
3496
|
+
selectionVisible && hoverRectToShow ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3003
3497
|
"div",
|
|
3004
3498
|
{
|
|
3005
3499
|
className: "msr:pointer-events-none msr:absolute",
|
|
@@ -3011,28 +3505,28 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3011
3505
|
backgroundColor: fillColor
|
|
3012
3506
|
},
|
|
3013
3507
|
children: [
|
|
3014
|
-
hoverEdgeVisibility?.top ? /* @__PURE__ */ (0,
|
|
3508
|
+
hoverEdgeVisibility?.top ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3015
3509
|
"div",
|
|
3016
3510
|
{
|
|
3017
3511
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-px msr:w-full",
|
|
3018
3512
|
style: { backgroundColor: outlineColor }
|
|
3019
3513
|
}
|
|
3020
3514
|
) : null,
|
|
3021
|
-
hoverEdgeVisibility?.right ? /* @__PURE__ */ (0,
|
|
3515
|
+
hoverEdgeVisibility?.right ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3022
3516
|
"div",
|
|
3023
3517
|
{
|
|
3024
3518
|
className: "msr:absolute msr:right-0 msr:top-0 msr:h-full msr:w-px",
|
|
3025
3519
|
style: { backgroundColor: outlineColor }
|
|
3026
3520
|
}
|
|
3027
3521
|
) : null,
|
|
3028
|
-
hoverEdgeVisibility?.bottom ? /* @__PURE__ */ (0,
|
|
3522
|
+
hoverEdgeVisibility?.bottom ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3029
3523
|
"div",
|
|
3030
3524
|
{
|
|
3031
3525
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:h-px msr:w-full",
|
|
3032
3526
|
style: { backgroundColor: outlineColor }
|
|
3033
3527
|
}
|
|
3034
3528
|
) : null,
|
|
3035
|
-
hoverEdgeVisibility?.left ? /* @__PURE__ */ (0,
|
|
3529
|
+
hoverEdgeVisibility?.left ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3036
3530
|
"div",
|
|
3037
3531
|
{
|
|
3038
3532
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-full msr:w-px",
|
|
@@ -3042,7 +3536,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3042
3536
|
]
|
|
3043
3537
|
}
|
|
3044
3538
|
) : null,
|
|
3045
|
-
guidesEnabled && guidePreview ? /* @__PURE__ */ (0,
|
|
3539
|
+
guidesEnabled && guidePreview ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3046
3540
|
"div",
|
|
3047
3541
|
{
|
|
3048
3542
|
className: "msr:pointer-events-none msr:absolute",
|
|
@@ -3057,7 +3551,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3057
3551
|
height: GUIDE_HITBOX_SIZE,
|
|
3058
3552
|
width: "100%"
|
|
3059
3553
|
},
|
|
3060
|
-
children: /* @__PURE__ */ (0,
|
|
3554
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3061
3555
|
"div",
|
|
3062
3556
|
{
|
|
3063
3557
|
className: "msr:absolute",
|
|
@@ -3078,7 +3572,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3078
3572
|
)
|
|
3079
3573
|
}
|
|
3080
3574
|
) : null,
|
|
3081
|
-
|
|
3575
|
+
selectionVisible ? displayedSelectedMeasurements.map((measurement, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3082
3576
|
SelectedMeasurementBox,
|
|
3083
3577
|
{
|
|
3084
3578
|
measurement,
|
|
@@ -3088,7 +3582,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3088
3582
|
},
|
|
3089
3583
|
measurement.id
|
|
3090
3584
|
)) : null,
|
|
3091
|
-
heldDistances.map((distance) => /* @__PURE__ */ (0,
|
|
3585
|
+
heldDistances.map((distance) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3092
3586
|
DistanceOverlayItem,
|
|
3093
3587
|
{
|
|
3094
3588
|
distance,
|
|
@@ -3097,7 +3591,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3097
3591
|
},
|
|
3098
3592
|
`held-${distance.id}`
|
|
3099
3593
|
)),
|
|
3100
|
-
|
|
3594
|
+
selectionVisible && altPressed && optionPairOverlay ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3101
3595
|
DistanceOverlayItem,
|
|
3102
3596
|
{
|
|
3103
3597
|
distance: optionPairOverlay,
|
|
@@ -3105,7 +3599,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3105
3599
|
},
|
|
3106
3600
|
`option-${optionPairOverlay.id}`
|
|
3107
3601
|
) : null,
|
|
3108
|
-
guidesEnabled && altPressed && guideDistanceOverlay ? /* @__PURE__ */ (0,
|
|
3602
|
+
guidesEnabled && altPressed && guideDistanceOverlay ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3109
3603
|
DistanceOverlayItem,
|
|
3110
3604
|
{
|
|
3111
3605
|
distance: guideDistanceOverlay,
|
|
@@ -3113,9 +3607,9 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3113
3607
|
},
|
|
3114
3608
|
`guide-preview-${guideDistanceOverlay.id}`
|
|
3115
3609
|
) : null,
|
|
3116
|
-
|
|
3117
|
-
optionContainerLines.top.value > 0 ? /* @__PURE__ */ (0,
|
|
3118
|
-
/* @__PURE__ */ (0,
|
|
3610
|
+
selectionVisible && altPressed && optionContainerLines ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
3611
|
+
optionContainerLines.top.value > 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
3612
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3119
3613
|
"div",
|
|
3120
3614
|
{
|
|
3121
3615
|
className: "msr:absolute msr:w-px msr:bg-[#2563eb]",
|
|
@@ -3126,7 +3620,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3126
3620
|
}
|
|
3127
3621
|
}
|
|
3128
3622
|
),
|
|
3129
|
-
/* @__PURE__ */ (0,
|
|
3623
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3130
3624
|
MeasureTag,
|
|
3131
3625
|
{
|
|
3132
3626
|
className: "msr:-translate-y-1/2 msr:bg-ink-900/90",
|
|
@@ -3138,8 +3632,8 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3138
3632
|
}
|
|
3139
3633
|
)
|
|
3140
3634
|
] }) : null,
|
|
3141
|
-
optionContainerLines.bottom.value > 0 ? /* @__PURE__ */ (0,
|
|
3142
|
-
/* @__PURE__ */ (0,
|
|
3635
|
+
optionContainerLines.bottom.value > 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
3636
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3143
3637
|
"div",
|
|
3144
3638
|
{
|
|
3145
3639
|
className: "msr:absolute msr:w-px msr:bg-[#2563eb]",
|
|
@@ -3150,7 +3644,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3150
3644
|
}
|
|
3151
3645
|
}
|
|
3152
3646
|
),
|
|
3153
|
-
/* @__PURE__ */ (0,
|
|
3647
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3154
3648
|
MeasureTag,
|
|
3155
3649
|
{
|
|
3156
3650
|
className: "msr:-translate-y-1/2 msr:bg-ink-900/90",
|
|
@@ -3162,8 +3656,8 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3162
3656
|
}
|
|
3163
3657
|
)
|
|
3164
3658
|
] }) : null,
|
|
3165
|
-
optionContainerLines.left.value > 0 ? /* @__PURE__ */ (0,
|
|
3166
|
-
/* @__PURE__ */ (0,
|
|
3659
|
+
optionContainerLines.left.value > 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
3660
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3167
3661
|
"div",
|
|
3168
3662
|
{
|
|
3169
3663
|
className: "msr:absolute msr:h-px msr:bg-[#2563eb]",
|
|
@@ -3174,7 +3668,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3174
3668
|
}
|
|
3175
3669
|
}
|
|
3176
3670
|
),
|
|
3177
|
-
/* @__PURE__ */ (0,
|
|
3671
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3178
3672
|
MeasureTag,
|
|
3179
3673
|
{
|
|
3180
3674
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3186,8 +3680,8 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3186
3680
|
}
|
|
3187
3681
|
)
|
|
3188
3682
|
] }) : null,
|
|
3189
|
-
optionContainerLines.right.value > 0 ? /* @__PURE__ */ (0,
|
|
3190
|
-
/* @__PURE__ */ (0,
|
|
3683
|
+
optionContainerLines.right.value > 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
3684
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3191
3685
|
"div",
|
|
3192
3686
|
{
|
|
3193
3687
|
className: "msr:absolute msr:h-px msr:bg-[#2563eb]",
|
|
@@ -3198,7 +3692,7 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3198
3692
|
}
|
|
3199
3693
|
}
|
|
3200
3694
|
),
|
|
3201
|
-
/* @__PURE__ */ (0,
|
|
3695
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3202
3696
|
MeasureTag,
|
|
3203
3697
|
{
|
|
3204
3698
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3216,25 +3710,28 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3216
3710
|
const isHovered = hoverGuide?.id === guide.id;
|
|
3217
3711
|
const strokeWidth = isSelected || isHovered ? 2 : 1;
|
|
3218
3712
|
const strokeColor = isSelected ? guideColorActive : isHovered ? guideColorHover : guideColorDefault;
|
|
3219
|
-
return /* @__PURE__ */ (0,
|
|
3713
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3220
3714
|
"div",
|
|
3221
3715
|
{
|
|
3222
3716
|
className: "msr:absolute",
|
|
3717
|
+
"data-mesurer-guide": "true",
|
|
3223
3718
|
style: guide.orientation === "vertical" ? {
|
|
3224
3719
|
left: guide.position - GUIDE_HITBOX_SIZE / 2,
|
|
3225
3720
|
top: 0,
|
|
3226
3721
|
width: GUIDE_HITBOX_SIZE,
|
|
3227
|
-
height: "100%"
|
|
3722
|
+
height: "100%",
|
|
3723
|
+
pointerEvents: guidePointerEvents ? "auto" : "none"
|
|
3228
3724
|
} : {
|
|
3229
3725
|
top: guide.position - GUIDE_HITBOX_SIZE / 2,
|
|
3230
3726
|
left: 0,
|
|
3231
3727
|
height: GUIDE_HITBOX_SIZE,
|
|
3232
|
-
width: "100%"
|
|
3728
|
+
width: "100%",
|
|
3729
|
+
pointerEvents: guidePointerEvents ? "auto" : "none"
|
|
3233
3730
|
},
|
|
3234
3731
|
onPointerDown: (event) => onGuidePointerDown(guide, event),
|
|
3235
3732
|
onPointerUp: (event) => onGuidePointerUp(guide, event),
|
|
3236
3733
|
onPointerCancel: (event) => onGuidePointerCancel(guide, event),
|
|
3237
|
-
children: /* @__PURE__ */ (0,
|
|
3734
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3238
3735
|
"div",
|
|
3239
3736
|
{
|
|
3240
3737
|
className: "msr:absolute",
|
|
@@ -3262,46 +3759,991 @@ var MeasurerOverlay = (0, import_react18.memo)(function MeasurerOverlay2({
|
|
|
3262
3759
|
);
|
|
3263
3760
|
});
|
|
3264
3761
|
|
|
3265
|
-
//
|
|
3266
|
-
var
|
|
3267
|
-
var
|
|
3762
|
+
// runtime/text-inspector-dom.ts
|
|
3763
|
+
var INK_50 = "#f8fafc";
|
|
3764
|
+
var INK_200 = "#e2e8f0";
|
|
3765
|
+
var INK_500 = "#64748b";
|
|
3766
|
+
var INK_900 = "#0f172a";
|
|
3767
|
+
var makeEdge = (document2, side, color) => {
|
|
3768
|
+
const edge = document2.createElement("div");
|
|
3769
|
+
Object.assign(edge.style, {
|
|
3770
|
+
position: "absolute",
|
|
3771
|
+
backgroundColor: color,
|
|
3772
|
+
...side === "top" || side === "bottom" ? { left: "0", [side]: "0", width: "100%", height: "1px" } : { top: "0", [side]: "0", width: "1px", height: "100%" }
|
|
3773
|
+
});
|
|
3774
|
+
return edge;
|
|
3268
3775
|
};
|
|
3269
|
-
var
|
|
3270
|
-
|
|
3271
|
-
(
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
});
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
}
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3776
|
+
var makeBox = (document2, fill, outline) => {
|
|
3777
|
+
const box = document2.createElement("div");
|
|
3778
|
+
Object.assign(box.style, {
|
|
3779
|
+
position: "fixed",
|
|
3780
|
+
zIndex: "0",
|
|
3781
|
+
pointerEvents: "none",
|
|
3782
|
+
backgroundColor: fill,
|
|
3783
|
+
boxSizing: "border-box"
|
|
3784
|
+
});
|
|
3785
|
+
box.className = "mesurer-ti-box";
|
|
3786
|
+
box.dataset.state = "hidden";
|
|
3787
|
+
for (const side of ["top", "right", "bottom", "left"]) {
|
|
3788
|
+
box.appendChild(makeEdge(document2, side, outline));
|
|
3789
|
+
}
|
|
3790
|
+
return box;
|
|
3791
|
+
};
|
|
3792
|
+
var positionBox = (box, rect) => {
|
|
3793
|
+
Object.assign(box.style, {
|
|
3794
|
+
left: `${rect.left}px`,
|
|
3795
|
+
top: `${rect.top}px`,
|
|
3796
|
+
width: `${rect.width}px`,
|
|
3797
|
+
height: `${rect.height}px`
|
|
3798
|
+
});
|
|
3799
|
+
};
|
|
3800
|
+
var makeCard = (document2, pinned) => {
|
|
3801
|
+
const card = document2.createElement("div");
|
|
3802
|
+
Object.assign(card.style, {
|
|
3803
|
+
position: "fixed",
|
|
3804
|
+
zIndex: "1",
|
|
3805
|
+
pointerEvents: pinned ? "auto" : "none",
|
|
3806
|
+
background: "#ffffff",
|
|
3807
|
+
color: INK_900,
|
|
3808
|
+
borderRadius: "13px",
|
|
3809
|
+
padding: "10px 12px",
|
|
3810
|
+
fontSize: "11px",
|
|
3811
|
+
lineHeight: "1.5",
|
|
3812
|
+
fontFamily: "ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif",
|
|
3813
|
+
fontVariantNumeric: "tabular-nums",
|
|
3814
|
+
userSelect: "none",
|
|
3815
|
+
whiteSpace: "nowrap",
|
|
3816
|
+
width: "320px",
|
|
3817
|
+
minWidth: "320px",
|
|
3818
|
+
maxWidth: "320px",
|
|
3819
|
+
boxSizing: "border-box",
|
|
3820
|
+
boxShadow: "0px 0px 0.5px rgba(0, 0, 0, 0.18), 0px 3px 8px rgba(0, 0, 0, 0.1), 0px 1px 3px rgba(0, 0, 0, 0.1)"
|
|
3821
|
+
});
|
|
3822
|
+
card.className = pinned ? "mesurer-ti-card mesurer-ti-card--pinned" : "mesurer-ti-card";
|
|
3823
|
+
card.dataset.state = "hidden";
|
|
3824
|
+
return card;
|
|
3825
|
+
};
|
|
3826
|
+
var populateCard = (document2, card, info, pinned) => {
|
|
3827
|
+
card.replaceChildren();
|
|
3828
|
+
const header = document2.createElement("div");
|
|
3829
|
+
Object.assign(header.style, {
|
|
3830
|
+
display: "flex",
|
|
3831
|
+
alignItems: "center",
|
|
3832
|
+
gap: "8px",
|
|
3833
|
+
marginBottom: "8px",
|
|
3834
|
+
paddingBottom: "6px"
|
|
3835
|
+
});
|
|
3836
|
+
const tag = document2.createElement("span");
|
|
3837
|
+
Object.assign(tag.style, {
|
|
3838
|
+
color: INK_50,
|
|
3839
|
+
background: INK_900,
|
|
3840
|
+
borderRadius: "4px",
|
|
3841
|
+
padding: "1px 5px",
|
|
3842
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
3843
|
+
fontSize: "10px",
|
|
3844
|
+
fontWeight: "500"
|
|
3845
|
+
});
|
|
3846
|
+
tag.textContent = info.tagName;
|
|
3847
|
+
header.appendChild(tag);
|
|
3848
|
+
if (info.textSnippet) {
|
|
3849
|
+
const snippet = document2.createElement("span");
|
|
3850
|
+
Object.assign(snippet.style, {
|
|
3851
|
+
color: INK_500,
|
|
3852
|
+
overflow: "hidden",
|
|
3853
|
+
textOverflow: "ellipsis",
|
|
3854
|
+
whiteSpace: "nowrap",
|
|
3855
|
+
flex: "1",
|
|
3856
|
+
minWidth: "0",
|
|
3857
|
+
fontSize: "10px"
|
|
3858
|
+
});
|
|
3859
|
+
snippet.textContent = info.textSnippet;
|
|
3860
|
+
header.appendChild(snippet);
|
|
3861
|
+
}
|
|
3862
|
+
if (pinned) {
|
|
3863
|
+
const close = document2.createElement("button");
|
|
3864
|
+
close.type = "button";
|
|
3865
|
+
close.className = "mesurer-ti-close";
|
|
3866
|
+
close.setAttribute("aria-label", "Close");
|
|
3867
|
+
close.textContent = "\xD7";
|
|
3868
|
+
Object.assign(close.style, {
|
|
3869
|
+
all: "unset",
|
|
3870
|
+
marginLeft: info.textSnippet ? "0" : "auto",
|
|
3871
|
+
flex: "0 0 auto",
|
|
3872
|
+
width: "16px",
|
|
3873
|
+
height: "16px",
|
|
3874
|
+
lineHeight: "14px",
|
|
3875
|
+
textAlign: "center",
|
|
3876
|
+
borderRadius: "4px",
|
|
3877
|
+
color: INK_500,
|
|
3878
|
+
fontSize: "14px"
|
|
3879
|
+
});
|
|
3880
|
+
header.appendChild(close);
|
|
3881
|
+
}
|
|
3882
|
+
card.appendChild(header);
|
|
3883
|
+
const grid = document2.createElement("div");
|
|
3884
|
+
Object.assign(grid.style, {
|
|
3885
|
+
display: "grid",
|
|
3886
|
+
gridTemplateColumns: "auto 1fr",
|
|
3887
|
+
columnGap: "12px",
|
|
3888
|
+
rowGap: "3px",
|
|
3889
|
+
alignItems: "baseline"
|
|
3890
|
+
});
|
|
3891
|
+
for (const row of info.rows) {
|
|
3892
|
+
const label = document2.createElement("span");
|
|
3893
|
+
label.style.color = INK_500;
|
|
3894
|
+
label.style.fontSize = "11px";
|
|
3895
|
+
label.textContent = row.label;
|
|
3896
|
+
const value = document2.createElement("span");
|
|
3897
|
+
Object.assign(value.style, {
|
|
3898
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
3899
|
+
fontSize: "11px",
|
|
3900
|
+
color: INK_900,
|
|
3901
|
+
overflow: "hidden",
|
|
3902
|
+
textOverflow: "ellipsis",
|
|
3903
|
+
whiteSpace: "nowrap"
|
|
3904
|
+
});
|
|
3905
|
+
if (!row.varName) {
|
|
3906
|
+
value.textContent = row.value;
|
|
3907
|
+
} else {
|
|
3908
|
+
const variable = document2.createElement("span");
|
|
3909
|
+
variable.textContent = row.value;
|
|
3910
|
+
const separator = document2.createElement("span");
|
|
3911
|
+
separator.style.color = INK_200;
|
|
3912
|
+
separator.style.margin = "0 6px";
|
|
3913
|
+
separator.textContent = "\xB7";
|
|
3914
|
+
const name = document2.createElement("span");
|
|
3915
|
+
name.style.color = "#0369a1";
|
|
3916
|
+
name.textContent = row.varName;
|
|
3917
|
+
value.append(variable, separator, name);
|
|
3918
|
+
}
|
|
3919
|
+
grid.append(label, value);
|
|
3920
|
+
}
|
|
3921
|
+
card.appendChild(grid);
|
|
3922
|
+
};
|
|
3923
|
+
var positionCard = (window2, card, rect, offsetX = 0, offsetY = 0) => {
|
|
3924
|
+
const center = rect.left + rect.width / 2 + offsetX;
|
|
3925
|
+
card.style.left = `${center}px`;
|
|
3926
|
+
const size = card.getBoundingClientRect();
|
|
3927
|
+
let top = rect.bottom + 4 + offsetY;
|
|
3928
|
+
if (top + size.height > window2.innerHeight - 8) {
|
|
3929
|
+
top = rect.top - size.height - 4 + offsetY;
|
|
3930
|
+
}
|
|
3931
|
+
card.style.top = `${Math.max(8, top)}px`;
|
|
3932
|
+
const half = size.width / 2;
|
|
3933
|
+
card.style.left = `${Math.min(
|
|
3934
|
+
Math.max(center, 8 + half),
|
|
3935
|
+
window2.innerWidth - 8 - half
|
|
3936
|
+
)}px`;
|
|
3937
|
+
};
|
|
3938
|
+
|
|
3939
|
+
// runtime/text-inspector-typography.ts
|
|
3940
|
+
var FONT_WEIGHT_KEYWORD = {
|
|
3941
|
+
"100": "thin",
|
|
3942
|
+
"200": "extralight",
|
|
3943
|
+
"300": "light",
|
|
3944
|
+
"400": "normal",
|
|
3945
|
+
"500": "medium",
|
|
3946
|
+
"600": "semibold",
|
|
3947
|
+
"700": "bold",
|
|
3948
|
+
"800": "extrabold",
|
|
3949
|
+
"900": "black"
|
|
3950
|
+
};
|
|
3951
|
+
var TYPO_PROPS = [
|
|
3952
|
+
"font-family",
|
|
3953
|
+
"font-size",
|
|
3954
|
+
"font-weight",
|
|
3955
|
+
"line-height",
|
|
3956
|
+
"letter-spacing"
|
|
3957
|
+
];
|
|
3958
|
+
var TYPO_LABELS = {
|
|
3959
|
+
Family: "font-family",
|
|
3960
|
+
Size: "font-size",
|
|
3961
|
+
Weight: "font-weight",
|
|
3962
|
+
Line: "line-height",
|
|
3963
|
+
Tracking: "letter-spacing"
|
|
3964
|
+
};
|
|
3965
|
+
var formatPx = (raw) => {
|
|
3966
|
+
if (!raw || raw === "normal") return raw || "normal";
|
|
3967
|
+
const match = /^(-?[\d.]+)px$/.exec(raw);
|
|
3968
|
+
if (!match) return raw;
|
|
3969
|
+
return `${Math.round(Number(match[1]) * 10) / 10}px`;
|
|
3970
|
+
};
|
|
3971
|
+
var firstFontFamily = (families) => (families.split(",")[0] ?? "").trim().replace(/^['"]|['"]$/g, "");
|
|
3972
|
+
var weightWithKeyword = (weight) => {
|
|
3973
|
+
const keyword = FONT_WEIGHT_KEYWORD[weight];
|
|
3974
|
+
return keyword ? `${weight} / ${keyword}` : weight;
|
|
3975
|
+
};
|
|
3976
|
+
var extractVarName = (value) => {
|
|
3977
|
+
if (!value) return null;
|
|
3978
|
+
return /var\(\s*(--[a-zA-Z0-9_-]+)/.exec(value)?.[1] ?? null;
|
|
3979
|
+
};
|
|
3980
|
+
var selectorSpecificity = (selector) => {
|
|
3981
|
+
const ids = (selector.match(/#[\w-]+/g) ?? []).length;
|
|
3982
|
+
const classes = (selector.match(/\.[\w-]+|\[[^\]]+\]|:[\w-]+/g) ?? []).length;
|
|
3983
|
+
const elements = (selector.match(/(?:^|[ >+~])([a-zA-Z][\w-]*)/g) ?? []).length;
|
|
3984
|
+
return ids * 1e4 + classes * 100 + elements;
|
|
3985
|
+
};
|
|
3986
|
+
var wins = (next, previous) => {
|
|
3987
|
+
if (!previous) return true;
|
|
3988
|
+
if (next.important !== previous.important) return next.important;
|
|
3989
|
+
if (next.specificity !== previous.specificity) {
|
|
3990
|
+
return next.specificity > previous.specificity;
|
|
3991
|
+
}
|
|
3992
|
+
return next.order > previous.order;
|
|
3993
|
+
};
|
|
3994
|
+
var TypographyInspector = class {
|
|
3995
|
+
constructor(document2, window2) {
|
|
3996
|
+
this.document = document2;
|
|
3997
|
+
this.window = window2;
|
|
3998
|
+
}
|
|
3999
|
+
collectRules(rules, output, mediaOk, order) {
|
|
4000
|
+
for (let i = 0; i < rules.length; i++) {
|
|
4001
|
+
const rule = rules[i];
|
|
4002
|
+
const currentOrder = order.value++;
|
|
4003
|
+
if (rule.type === 4) {
|
|
4004
|
+
const mediaRule = rule;
|
|
4005
|
+
let matches = mediaOk;
|
|
4006
|
+
try {
|
|
4007
|
+
matches = mediaOk && this.window.matchMedia(mediaRule.media.mediaText).matches;
|
|
4008
|
+
} catch {
|
|
4009
|
+
matches = false;
|
|
4010
|
+
}
|
|
4011
|
+
this.collectRules(mediaRule.cssRules, output, matches, order);
|
|
4012
|
+
} else if (rule.type === 12) {
|
|
4013
|
+
this.collectRules(rule.cssRules, output, mediaOk, order);
|
|
4014
|
+
} else if (rule.type === 1) {
|
|
4015
|
+
output.push({
|
|
4016
|
+
rule,
|
|
4017
|
+
mediaOk,
|
|
4018
|
+
order: currentOrder
|
|
4019
|
+
});
|
|
4020
|
+
}
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
getRules() {
|
|
4024
|
+
const rules = [];
|
|
4025
|
+
const order = { value: 0 };
|
|
4026
|
+
for (const sheet of Array.from(this.document.styleSheets)) {
|
|
4027
|
+
try {
|
|
4028
|
+
this.collectRules(sheet.cssRules, rules, true, order);
|
|
4029
|
+
} catch {
|
|
4030
|
+
continue;
|
|
4031
|
+
}
|
|
4032
|
+
}
|
|
4033
|
+
return rules;
|
|
4034
|
+
}
|
|
4035
|
+
findVarReferences(el) {
|
|
4036
|
+
const result = Object.fromEntries(
|
|
4037
|
+
TYPO_PROPS.map((prop) => [prop, null])
|
|
4038
|
+
);
|
|
4039
|
+
const rules = this.getRules();
|
|
4040
|
+
for (const prop of TYPO_PROPS) {
|
|
4041
|
+
let node = el;
|
|
4042
|
+
while (node && result[prop] === null) {
|
|
4043
|
+
let winner;
|
|
4044
|
+
const inlineValue = node.style.getPropertyValue(prop);
|
|
4045
|
+
const inlineName = extractVarName(inlineValue);
|
|
4046
|
+
if (inlineName) {
|
|
4047
|
+
winner = {
|
|
4048
|
+
name: inlineName,
|
|
4049
|
+
specificity: Number.MAX_SAFE_INTEGER,
|
|
4050
|
+
order: Number.MAX_SAFE_INTEGER,
|
|
4051
|
+
important: node.style.getPropertyPriority(prop) === "important"
|
|
4052
|
+
};
|
|
4053
|
+
}
|
|
4054
|
+
for (const { rule, mediaOk, order } of rules) {
|
|
4055
|
+
if (!mediaOk) continue;
|
|
4056
|
+
let matches = false;
|
|
4057
|
+
try {
|
|
4058
|
+
matches = node.matches(rule.selectorText);
|
|
4059
|
+
} catch {
|
|
4060
|
+
continue;
|
|
4061
|
+
}
|
|
4062
|
+
if (!matches) continue;
|
|
4063
|
+
const name = extractVarName(rule.style.getPropertyValue(prop));
|
|
4064
|
+
if (!name) continue;
|
|
4065
|
+
const candidate = {
|
|
4066
|
+
name,
|
|
4067
|
+
specificity: selectorSpecificity(rule.selectorText),
|
|
4068
|
+
order,
|
|
4069
|
+
important: rule.style.getPropertyPriority(prop) === "important"
|
|
4070
|
+
};
|
|
4071
|
+
if (wins(candidate, winner)) winner = candidate;
|
|
4072
|
+
}
|
|
4073
|
+
if (winner) result[prop] = winner.name;
|
|
4074
|
+
node = node.parentElement;
|
|
4075
|
+
}
|
|
4076
|
+
}
|
|
4077
|
+
return result;
|
|
4078
|
+
}
|
|
4079
|
+
getFast(el) {
|
|
4080
|
+
const styles = this.window.getComputedStyle(el);
|
|
4081
|
+
const rows = [
|
|
4082
|
+
{ label: "Family", value: firstFontFamily(styles.fontFamily), varName: null },
|
|
4083
|
+
{ label: "Size", value: formatPx(styles.fontSize), varName: null },
|
|
4084
|
+
{
|
|
4085
|
+
label: "Weight",
|
|
4086
|
+
value: weightWithKeyword(styles.fontWeight),
|
|
4087
|
+
varName: null
|
|
4088
|
+
},
|
|
4089
|
+
{
|
|
4090
|
+
label: "Line",
|
|
4091
|
+
value: styles.lineHeight === "normal" ? "normal" : formatPx(styles.lineHeight),
|
|
4092
|
+
varName: null
|
|
4093
|
+
},
|
|
4094
|
+
{
|
|
4095
|
+
label: "Tracking",
|
|
4096
|
+
value: styles.letterSpacing === "normal" ? "normal" : formatPx(styles.letterSpacing),
|
|
4097
|
+
varName: null
|
|
4098
|
+
}
|
|
4099
|
+
];
|
|
4100
|
+
const directText = Array.from(el.childNodes).filter((node) => node.nodeType === Node.TEXT_NODE).map((node) => node.nodeValue?.trim() ?? "").filter(Boolean).join(" ").replace(/\s+/g, " ");
|
|
4101
|
+
return {
|
|
4102
|
+
rows,
|
|
4103
|
+
tagName: el.tagName.toLowerCase(),
|
|
4104
|
+
textSnippet: directText.length > 40 ? `${directText.slice(0, 40)}\u2026` : directText
|
|
4105
|
+
};
|
|
4106
|
+
}
|
|
4107
|
+
getFull(el, base = this.getFast(el)) {
|
|
4108
|
+
const vars = this.findVarReferences(el);
|
|
4109
|
+
return {
|
|
4110
|
+
...base,
|
|
4111
|
+
rows: base.rows.map((row) => ({
|
|
4112
|
+
...row,
|
|
4113
|
+
varName: vars[TYPO_LABELS[row.label]]
|
|
4114
|
+
}))
|
|
4115
|
+
};
|
|
4116
|
+
}
|
|
4117
|
+
};
|
|
4118
|
+
|
|
4119
|
+
// runtime/text-inspector.ts
|
|
4120
|
+
var DEFAULT_EXTENSION_HOST_ID = "mesurer-extension-host";
|
|
4121
|
+
var DEFAULT_OVERLAY_ID = "mesurer-text-inspector-overlay";
|
|
4122
|
+
var DEFAULT_STYLE_ID = "mesurer-text-inspector-styles";
|
|
4123
|
+
var DEFAULT_BODY_MODE_CLASS = "mesurer-text-inspect-mode";
|
|
4124
|
+
var inspectorInstanceCount = 0;
|
|
4125
|
+
var FILL_HOVER = "color-mix(in oklch, oklch(0.62 0.18 255) 8%, transparent)";
|
|
4126
|
+
var OUTLINE_HOVER = "color-mix(in oklch, oklch(0.62 0.18 255) 80%, transparent)";
|
|
4127
|
+
var FILL_PINNED = "color-mix(in oklch, oklch(0.62 0.18 255) 4%, transparent)";
|
|
4128
|
+
var OUTLINE_PINNED = "color-mix(in oklch, oklch(0.62 0.18 255) 35%, transparent)";
|
|
4129
|
+
var DEFAULT_SKIP_TAGS = [
|
|
4130
|
+
"HTML",
|
|
4131
|
+
"BODY",
|
|
4132
|
+
"SCRIPT",
|
|
4133
|
+
"STYLE",
|
|
4134
|
+
"META",
|
|
4135
|
+
"LINK",
|
|
4136
|
+
"NOSCRIPT",
|
|
4137
|
+
"IMG",
|
|
4138
|
+
"VIDEO",
|
|
4139
|
+
"AUDIO",
|
|
4140
|
+
"IFRAME"
|
|
4141
|
+
];
|
|
4142
|
+
var createInspectorStyles = (extensionHostId, overlayId, bodyModeClass) => `
|
|
4143
|
+
.${bodyModeClass},
|
|
4144
|
+
.${bodyModeClass} * {
|
|
4145
|
+
cursor: help !important;
|
|
4146
|
+
}
|
|
4147
|
+
.${bodyModeClass} #${extensionHostId},
|
|
4148
|
+
.${bodyModeClass} #${extensionHostId} * {
|
|
4149
|
+
cursor: auto !important;
|
|
4150
|
+
}
|
|
4151
|
+
#${overlayId} .mesurer-ti-card--pinned {
|
|
4152
|
+
cursor: grab;
|
|
4153
|
+
}
|
|
4154
|
+
#${overlayId} .mesurer-ti-card--pinned:active {
|
|
4155
|
+
cursor: grabbing;
|
|
4156
|
+
}
|
|
4157
|
+
#${overlayId} .mesurer-ti-close {
|
|
4158
|
+
cursor: pointer;
|
|
4159
|
+
}
|
|
4160
|
+
#${overlayId} .mesurer-ti-close:hover {
|
|
4161
|
+
background: rgba(15, 23, 42, 0.06);
|
|
4162
|
+
color: #0f172a;
|
|
4163
|
+
}
|
|
4164
|
+
#${overlayId} .mesurer-ti-box,
|
|
4165
|
+
#${overlayId} .mesurer-ti-card {
|
|
4166
|
+
opacity: 1;
|
|
4167
|
+
}
|
|
4168
|
+
#${overlayId} .mesurer-ti-box[data-state="hidden"],
|
|
4169
|
+
#${overlayId} .mesurer-ti-card[data-state="hidden"] {
|
|
4170
|
+
opacity: 0;
|
|
4171
|
+
}
|
|
4172
|
+
#${overlayId} .mesurer-ti-card {
|
|
4173
|
+
transform: translateX(-50%);
|
|
4174
|
+
}
|
|
4175
|
+
`;
|
|
4176
|
+
var createIdleScheduler = (window2) => {
|
|
4177
|
+
const browser = window2;
|
|
4178
|
+
if (browser.requestIdleCallback) {
|
|
4179
|
+
return {
|
|
4180
|
+
request: (callback) => browser.requestIdleCallback(
|
|
4181
|
+
() => callback(),
|
|
4182
|
+
{ timeout: 250 }
|
|
4183
|
+
),
|
|
4184
|
+
cancel: (id) => browser.cancelIdleCallback?.(id)
|
|
4185
|
+
};
|
|
4186
|
+
}
|
|
4187
|
+
return {
|
|
4188
|
+
request: (callback) => window2.setTimeout(callback, 32),
|
|
4189
|
+
cancel: (id) => window2.clearTimeout(id)
|
|
4190
|
+
};
|
|
4191
|
+
};
|
|
4192
|
+
var createTextInspector = (options = {}, legacy = false) => {
|
|
4193
|
+
const portalDocument = options.portalTarget?.ownerDocument;
|
|
4194
|
+
const availableDocument = portalDocument ?? (typeof globalThis.document === "undefined" ? null : globalThis.document);
|
|
4195
|
+
const availableWindow = availableDocument?.defaultView ?? (typeof globalThis.window === "undefined" ? null : globalThis.window);
|
|
4196
|
+
const document2 = availableDocument;
|
|
4197
|
+
const window2 = availableWindow;
|
|
4198
|
+
const realm = availableWindow;
|
|
4199
|
+
const HTMLElementConstructor = realm?.HTMLElement ?? globalThis.HTMLElement;
|
|
4200
|
+
const SVGElementConstructor = realm?.SVGElement ?? globalThis.SVGElement;
|
|
4201
|
+
const extensionHostId = DEFAULT_EXTENSION_HOST_ID;
|
|
4202
|
+
const instanceId = (options.id ?? (legacy ? DEFAULT_OVERLAY_ID : `mesurer-text-inspector-${++inspectorInstanceCount}`)).replace(
|
|
4203
|
+
/[^a-zA-Z0-9_-]/g,
|
|
4204
|
+
"-"
|
|
4205
|
+
);
|
|
4206
|
+
const overlayId = legacy ? DEFAULT_OVERLAY_ID : `${instanceId}-overlay`;
|
|
4207
|
+
const styleId = legacy ? DEFAULT_STYLE_ID : `${instanceId}-styles`;
|
|
4208
|
+
const bodyModeClass = legacy ? DEFAULT_BODY_MODE_CLASS : `${instanceId}-mode`;
|
|
4209
|
+
const skipTags = new Set(
|
|
4210
|
+
(options.ignoredTags ?? DEFAULT_SKIP_TAGS).map((tag) => tag.toUpperCase())
|
|
4211
|
+
);
|
|
4212
|
+
const maxPinned = Number.isFinite(options.maxPinned) ? Math.max(1, Math.floor(options.maxPinned)) : Infinity;
|
|
4213
|
+
const inspectorStyles = createInspectorStyles(
|
|
4214
|
+
extensionHostId,
|
|
4215
|
+
overlayId,
|
|
4216
|
+
bodyModeClass
|
|
4217
|
+
);
|
|
4218
|
+
const EXTENSION_HOST_ID = extensionHostId;
|
|
4219
|
+
const OVERLAY_ID = overlayId;
|
|
4220
|
+
const STYLE_ID = styleId;
|
|
4221
|
+
const BODY_MODE_CLASS = bodyModeClass;
|
|
4222
|
+
const SKIP_TAGS = skipTags;
|
|
4223
|
+
const INSPECTOR_STYLES = inspectorStyles;
|
|
4224
|
+
const portalIsShadowRoot = options.portalTarget?.nodeType === 11;
|
|
4225
|
+
const typography = new TypographyInspector(document2, window2);
|
|
4226
|
+
const pinned = [];
|
|
4227
|
+
const history = [];
|
|
4228
|
+
const future = [];
|
|
4229
|
+
let enabled = false;
|
|
4230
|
+
let overlay = null;
|
|
4231
|
+
let hoverBox = null;
|
|
4232
|
+
let hoverCard = null;
|
|
4233
|
+
let hoveredEl = null;
|
|
4234
|
+
let pointerX = 0;
|
|
4235
|
+
let pointerY = 0;
|
|
4236
|
+
let frameScheduled = false;
|
|
4237
|
+
let pendingElement = null;
|
|
4238
|
+
let pendingIdleId = -1;
|
|
4239
|
+
let idleScheduler = null;
|
|
4240
|
+
const getIdleScheduler = () => {
|
|
4241
|
+
idleScheduler ?? (idleScheduler = createIdleScheduler(window2));
|
|
4242
|
+
return idleScheduler;
|
|
4243
|
+
};
|
|
4244
|
+
const hasDirectText = (el) => Array.from(el.childNodes).some(
|
|
4245
|
+
(node) => node.nodeType === Node.TEXT_NODE && !!node.nodeValue?.trim()
|
|
4246
|
+
);
|
|
4247
|
+
const isInspectable = (el) => !!el && el instanceof HTMLElementConstructor && !SKIP_TAGS.has(el.tagName) && !(el instanceof SVGElementConstructor) && hasDirectText(el);
|
|
4248
|
+
const isOverlayNode = (node) => {
|
|
4249
|
+
for (let current = node; current; current = current.parentNode) {
|
|
4250
|
+
if (current instanceof HTMLElementConstructor) {
|
|
4251
|
+
const element = current;
|
|
4252
|
+
if (element.id === OVERLAY_ID || element.id === EXTENSION_HOST_ID) {
|
|
4253
|
+
return true;
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
4256
|
+
}
|
|
4257
|
+
return false;
|
|
4258
|
+
};
|
|
4259
|
+
const pickElementAt = (x, y) => {
|
|
4260
|
+
return document2.elementsFromPoint(x, y).find(
|
|
4261
|
+
(el) => !isOverlayNode(el) && isInspectable(el)
|
|
4262
|
+
) ?? null;
|
|
4263
|
+
};
|
|
4264
|
+
const pointerOverToolbar = (x, y) => {
|
|
4265
|
+
const shadow = document2.getElementById(EXTENSION_HOST_ID)?.shadowRoot;
|
|
4266
|
+
const element = shadow?.elementFromPoint(x, y);
|
|
4267
|
+
if (!element) return false;
|
|
4268
|
+
for (let node = element; node; node = node.parentElement) {
|
|
4269
|
+
if (node.classList.contains("mesurer-toolbar-surface")) return true;
|
|
4270
|
+
}
|
|
4271
|
+
return false;
|
|
4272
|
+
};
|
|
4273
|
+
const ensureStyles = () => {
|
|
4274
|
+
const append = (root) => {
|
|
4275
|
+
if (root.querySelector(`#${STYLE_ID}`)) return;
|
|
4276
|
+
const style = document2.createElement("style");
|
|
4277
|
+
style.id = STYLE_ID;
|
|
4278
|
+
style.textContent = INSPECTOR_STYLES;
|
|
4279
|
+
root.nodeType === 9 ? root.head.appendChild(style) : root.appendChild(style);
|
|
4280
|
+
};
|
|
4281
|
+
append(document2);
|
|
4282
|
+
if (portalIsShadowRoot) append(options.portalTarget);
|
|
4283
|
+
};
|
|
4284
|
+
const ensureOverlay = () => {
|
|
4285
|
+
if (overlay?.isConnected) return overlay;
|
|
4286
|
+
overlay = document2.createElement("div");
|
|
4287
|
+
overlay.id = OVERLAY_ID;
|
|
4288
|
+
Object.assign(overlay.style, {
|
|
4289
|
+
position: "fixed",
|
|
4290
|
+
inset: "0",
|
|
4291
|
+
pointerEvents: "none",
|
|
4292
|
+
zIndex: "2147483646"
|
|
4293
|
+
});
|
|
4294
|
+
(options.portalTarget ?? document2.body).appendChild(overlay);
|
|
4295
|
+
return overlay;
|
|
4296
|
+
};
|
|
4297
|
+
const setState = (element, visible) => {
|
|
4298
|
+
element.dataset.state = visible ? "visible" : "hidden";
|
|
4299
|
+
};
|
|
4300
|
+
const ensureHover = () => {
|
|
4301
|
+
const root = ensureOverlay();
|
|
4302
|
+
hoverBox ?? (hoverBox = makeBox(document2, FILL_HOVER, OUTLINE_HOVER));
|
|
4303
|
+
hoverCard ?? (hoverCard = makeCard(document2, false));
|
|
4304
|
+
if (!hoverBox.parentNode) root.appendChild(hoverBox);
|
|
4305
|
+
if (!hoverCard.parentNode) root.appendChild(hoverCard);
|
|
4306
|
+
};
|
|
4307
|
+
const scheduleEnrichment = (element, fast) => {
|
|
4308
|
+
if (pendingElement === element) return;
|
|
4309
|
+
if (pendingIdleId !== -1) getIdleScheduler().cancel(pendingIdleId);
|
|
4310
|
+
pendingElement = element;
|
|
4311
|
+
pendingIdleId = getIdleScheduler().request(() => {
|
|
4312
|
+
pendingIdleId = -1;
|
|
4313
|
+
pendingElement = null;
|
|
4314
|
+
if (!enabled) return;
|
|
4315
|
+
const full = typography.getFull(element, fast);
|
|
4316
|
+
if (hoveredEl !== element || !hoverCard) return;
|
|
4317
|
+
populateCard(document2, hoverCard, full, false);
|
|
4318
|
+
positionCard(window2, hoverCard, element.getBoundingClientRect());
|
|
4319
|
+
options.onInspect?.(element, full);
|
|
4320
|
+
});
|
|
4321
|
+
};
|
|
4322
|
+
const inspect = (element) => {
|
|
4323
|
+
if (!enabled || !isInspectable(element)) return false;
|
|
4324
|
+
ensureHover();
|
|
4325
|
+
const rect = element.getBoundingClientRect();
|
|
4326
|
+
hoveredEl = element;
|
|
4327
|
+
const fast = typography.getFast(element);
|
|
4328
|
+
populateCard(document2, hoverCard, fast, false);
|
|
4329
|
+
scheduleEnrichment(element, fast);
|
|
4330
|
+
positionBox(hoverBox, rect);
|
|
4331
|
+
positionCard(window2, hoverCard, rect);
|
|
4332
|
+
setState(hoverBox, true);
|
|
4333
|
+
setState(hoverCard, true);
|
|
4334
|
+
return true;
|
|
4335
|
+
};
|
|
4336
|
+
const updateHover = () => {
|
|
4337
|
+
if (!enabled || pointerOverToolbar(pointerX, pointerY)) {
|
|
4338
|
+
hideHover();
|
|
4339
|
+
return;
|
|
4340
|
+
}
|
|
4341
|
+
const element = pickElementAt(pointerX, pointerY);
|
|
4342
|
+
if (!element) {
|
|
4343
|
+
hideHover();
|
|
4344
|
+
return;
|
|
4345
|
+
}
|
|
4346
|
+
if (element !== hoveredEl) inspect(element);
|
|
4347
|
+
else {
|
|
4348
|
+
positionBox(hoverBox, element.getBoundingClientRect());
|
|
4349
|
+
positionCard(window2, hoverCard, element.getBoundingClientRect());
|
|
4350
|
+
}
|
|
4351
|
+
};
|
|
4352
|
+
const hideHover = () => {
|
|
4353
|
+
hoveredEl = null;
|
|
4354
|
+
if (hoverBox) setState(hoverBox, false);
|
|
4355
|
+
if (hoverCard) setState(hoverCard, false);
|
|
4356
|
+
};
|
|
4357
|
+
const snapshotPins = () => pinned.map((pin) => {
|
|
4358
|
+
const rect = pin.card.getBoundingClientRect();
|
|
4359
|
+
return {
|
|
4360
|
+
sourceEl: pin.sourceEl,
|
|
4361
|
+
left: pin.userPlaced ? rect.left + rect.width / 2 : 0,
|
|
4362
|
+
top: pin.userPlaced ? rect.top : 0,
|
|
4363
|
+
userPlaced: pin.userPlaced
|
|
4364
|
+
};
|
|
4365
|
+
});
|
|
4366
|
+
const recordPinState = () => {
|
|
4367
|
+
history.push(snapshotPins());
|
|
4368
|
+
future.length = 0;
|
|
4369
|
+
};
|
|
4370
|
+
const removePin = (pin, record = true, notify = record) => {
|
|
4371
|
+
const index = pinned.indexOf(pin);
|
|
4372
|
+
if (index === -1) return;
|
|
4373
|
+
if (record) recordPinState();
|
|
4374
|
+
pinned.splice(index, 1);
|
|
4375
|
+
pin.detach();
|
|
4376
|
+
pin.box.remove();
|
|
4377
|
+
pin.card.remove();
|
|
4378
|
+
if (notify) options.onUnpin?.(pin.sourceEl);
|
|
4379
|
+
};
|
|
4380
|
+
const clearPins = (notify = false) => {
|
|
4381
|
+
while (pinned.length) {
|
|
4382
|
+
removePin(pinned[pinned.length - 1], false, notify);
|
|
4383
|
+
}
|
|
4384
|
+
};
|
|
4385
|
+
const attachDrag = (pin) => {
|
|
4386
|
+
let pointerId = -1;
|
|
4387
|
+
let startX = 0;
|
|
4388
|
+
let startY = 0;
|
|
4389
|
+
let originLeft = 0;
|
|
4390
|
+
let originTop = 0;
|
|
4391
|
+
let active = false;
|
|
4392
|
+
let dragged = false;
|
|
4393
|
+
let historyRecorded = false;
|
|
4394
|
+
const slop = 6;
|
|
4395
|
+
const onMove = (event) => {
|
|
4396
|
+
if (event.pointerId !== pointerId) return;
|
|
4397
|
+
const dx = event.clientX - startX;
|
|
4398
|
+
const dy = event.clientY - startY;
|
|
4399
|
+
if (!active) active = Math.abs(dx) > slop || Math.abs(dy) > slop;
|
|
4400
|
+
if (!active) return;
|
|
4401
|
+
if (!historyRecorded) {
|
|
4402
|
+
recordPinState();
|
|
4403
|
+
historyRecorded = true;
|
|
4404
|
+
}
|
|
4405
|
+
dragged = true;
|
|
4406
|
+
pin.card.style.left = `${Math.min(
|
|
4407
|
+
window2.innerWidth - 8,
|
|
4408
|
+
Math.max(8, originLeft + dx)
|
|
4409
|
+
)}px`;
|
|
4410
|
+
pin.card.style.top = `${Math.min(
|
|
4411
|
+
window2.innerHeight - 8,
|
|
4412
|
+
Math.max(8, originTop + dy)
|
|
4413
|
+
)}px`;
|
|
4414
|
+
pin.userPlaced = true;
|
|
4415
|
+
};
|
|
4416
|
+
const onEnd = (event) => {
|
|
4417
|
+
if (event.pointerId !== pointerId && pointerId !== -1) return;
|
|
4418
|
+
window2.removeEventListener("pointermove", onMove);
|
|
4419
|
+
window2.removeEventListener("pointerup", onEnd);
|
|
4420
|
+
window2.removeEventListener("pointercancel", onEnd);
|
|
4421
|
+
pointerId = -1;
|
|
4422
|
+
active = false;
|
|
4423
|
+
historyRecorded = false;
|
|
4424
|
+
if (dragged) {
|
|
4425
|
+
const swallow = (click) => {
|
|
4426
|
+
click.preventDefault();
|
|
4427
|
+
click.stopPropagation();
|
|
4428
|
+
window2.removeEventListener("click", swallow, true);
|
|
4429
|
+
};
|
|
4430
|
+
window2.addEventListener("click", swallow, true);
|
|
4431
|
+
}
|
|
4432
|
+
dragged = false;
|
|
4433
|
+
};
|
|
4434
|
+
const onDown = (event) => {
|
|
4435
|
+
if (event.button !== 0) return;
|
|
4436
|
+
if (event.target?.classList.contains("mesurer-ti-close")) {
|
|
4437
|
+
return;
|
|
4438
|
+
}
|
|
4439
|
+
const rect = pin.card.getBoundingClientRect();
|
|
4440
|
+
originLeft = rect.left + rect.width / 2;
|
|
4441
|
+
originTop = rect.top;
|
|
4442
|
+
startX = event.clientX;
|
|
4443
|
+
startY = event.clientY;
|
|
4444
|
+
pointerId = event.pointerId;
|
|
4445
|
+
active = false;
|
|
4446
|
+
dragged = false;
|
|
4447
|
+
window2.addEventListener("pointermove", onMove);
|
|
4448
|
+
window2.addEventListener("pointerup", onEnd);
|
|
4449
|
+
window2.addEventListener("pointercancel", onEnd);
|
|
4450
|
+
};
|
|
4451
|
+
pin.card.addEventListener("pointerdown", onDown);
|
|
4452
|
+
return () => {
|
|
4453
|
+
pin.card.removeEventListener("pointerdown", onDown);
|
|
4454
|
+
window2.removeEventListener("pointermove", onMove);
|
|
4455
|
+
window2.removeEventListener("pointerup", onEnd);
|
|
4456
|
+
window2.removeEventListener("pointercancel", onEnd);
|
|
4457
|
+
};
|
|
4458
|
+
};
|
|
4459
|
+
const createPin = (sourceEl, state, record = true, notify = record) => {
|
|
4460
|
+
const existing = pinned.find((pin2) => pin2.sourceEl === sourceEl);
|
|
4461
|
+
if (existing) {
|
|
4462
|
+
const root2 = ensureOverlay();
|
|
4463
|
+
root2.append(existing.box, existing.card);
|
|
4464
|
+
return;
|
|
4465
|
+
}
|
|
4466
|
+
if (record) {
|
|
4467
|
+
recordPinState();
|
|
4468
|
+
if (pinned.length >= maxPinned) removePin(pinned[0], false, true);
|
|
4469
|
+
}
|
|
4470
|
+
const root = ensureOverlay();
|
|
4471
|
+
const box = makeBox(document2, FILL_PINNED, OUTLINE_PINNED);
|
|
4472
|
+
const card = makeCard(document2, true);
|
|
4473
|
+
const info = typography.getFull(sourceEl);
|
|
4474
|
+
populateCard(document2, card, info, true);
|
|
4475
|
+
root.append(box, card);
|
|
4476
|
+
const pin = {
|
|
4477
|
+
sourceEl,
|
|
4478
|
+
box,
|
|
4479
|
+
card,
|
|
4480
|
+
userPlaced: state?.userPlaced ?? false,
|
|
4481
|
+
detach: () => {
|
|
4482
|
+
}
|
|
4483
|
+
};
|
|
4484
|
+
const rect = sourceEl.getBoundingClientRect();
|
|
4485
|
+
positionBox(box, rect);
|
|
4486
|
+
positionCard(window2, card, rect);
|
|
4487
|
+
if (state?.userPlaced) {
|
|
4488
|
+
card.style.left = `${state.left}px`;
|
|
4489
|
+
card.style.top = `${state.top}px`;
|
|
4490
|
+
}
|
|
4491
|
+
setState(box, true);
|
|
4492
|
+
setState(card, true);
|
|
4493
|
+
pinned.push(pin);
|
|
4494
|
+
card.querySelector(".mesurer-ti-close")?.addEventListener(
|
|
4495
|
+
"click",
|
|
4496
|
+
(event) => {
|
|
4497
|
+
event.preventDefault();
|
|
4498
|
+
event.stopPropagation();
|
|
4499
|
+
removePin(pin);
|
|
4500
|
+
}
|
|
4501
|
+
);
|
|
4502
|
+
pin.detach = attachDrag(pin);
|
|
4503
|
+
if (notify) options.onPin?.(sourceEl, info);
|
|
4504
|
+
};
|
|
4505
|
+
const restorePins = (states) => {
|
|
4506
|
+
clearPins(false);
|
|
4507
|
+
for (const state of states) {
|
|
4508
|
+
if (state.sourceEl.isConnected) createPin(state.sourceEl, state, false, false);
|
|
4509
|
+
}
|
|
4510
|
+
};
|
|
4511
|
+
const undo = () => {
|
|
4512
|
+
const previous = history.pop();
|
|
4513
|
+
if (!previous) return false;
|
|
4514
|
+
future.push(snapshotPins());
|
|
4515
|
+
restorePins(previous);
|
|
4516
|
+
return true;
|
|
4517
|
+
};
|
|
4518
|
+
const redo = () => {
|
|
4519
|
+
const next = future.pop();
|
|
4520
|
+
if (!next) return false;
|
|
4521
|
+
history.push(snapshotPins());
|
|
4522
|
+
restorePins(next);
|
|
4523
|
+
return true;
|
|
4524
|
+
};
|
|
4525
|
+
const clear = () => {
|
|
4526
|
+
if (!pinned.length) return;
|
|
4527
|
+
recordPinState();
|
|
4528
|
+
clearPins(true);
|
|
4529
|
+
};
|
|
4530
|
+
const syncPins = () => {
|
|
4531
|
+
for (const pin of [...pinned]) {
|
|
4532
|
+
if (!pin.sourceEl.isConnected) {
|
|
4533
|
+
removePin(pin, false);
|
|
4534
|
+
continue;
|
|
4535
|
+
}
|
|
4536
|
+
const rect = pin.sourceEl.getBoundingClientRect();
|
|
4537
|
+
positionBox(pin.box, rect);
|
|
4538
|
+
if (!pin.userPlaced) positionCard(window2, pin.card, rect);
|
|
4539
|
+
const visible = rect.bottom >= 0 && rect.right >= 0 && rect.left <= window2.innerWidth && rect.top <= window2.innerHeight;
|
|
4540
|
+
setState(pin.box, visible);
|
|
4541
|
+
setState(pin.card, visible);
|
|
4542
|
+
pin.card.style.pointerEvents = visible ? "auto" : "none";
|
|
4543
|
+
}
|
|
4544
|
+
};
|
|
4545
|
+
const scheduleFrame = () => {
|
|
4546
|
+
if (frameScheduled) return;
|
|
4547
|
+
frameScheduled = true;
|
|
4548
|
+
requestAnimationFrame(() => {
|
|
4549
|
+
frameScheduled = false;
|
|
4550
|
+
if (!enabled) return;
|
|
4551
|
+
updateHover();
|
|
4552
|
+
syncPins();
|
|
4553
|
+
});
|
|
4554
|
+
};
|
|
4555
|
+
const onMouseMove = (event) => {
|
|
4556
|
+
pointerX = event.clientX;
|
|
4557
|
+
pointerY = event.clientY;
|
|
4558
|
+
scheduleFrame();
|
|
4559
|
+
};
|
|
4560
|
+
const onMouseOut = (event) => {
|
|
4561
|
+
if (!event.relatedTarget) hideHover();
|
|
4562
|
+
};
|
|
4563
|
+
const onScrollOrResize = () => scheduleFrame();
|
|
4564
|
+
const isInspectorUIEvent = (event) => event.composedPath().some(
|
|
4565
|
+
(node) => node instanceof HTMLElementConstructor && (() => {
|
|
4566
|
+
const element = node;
|
|
4567
|
+
return element.id === OVERLAY_ID || element.classList.contains("mesurer-ti-card") || element.classList.contains("mesurer-ti-box") || element.classList.contains("mesurer-ti-close") || element.classList.contains("mesurer-toolbar-surface");
|
|
4568
|
+
})()
|
|
4569
|
+
);
|
|
4570
|
+
const onClick = (event) => {
|
|
4571
|
+
if (isInspectorUIEvent(event) || pointerOverToolbar(event.clientX, event.clientY)) {
|
|
4572
|
+
return;
|
|
4573
|
+
}
|
|
4574
|
+
event.preventDefault();
|
|
4575
|
+
event.stopImmediatePropagation();
|
|
4576
|
+
if (event.button === 0) {
|
|
4577
|
+
const source = pickElementAt(event.clientX, event.clientY);
|
|
4578
|
+
if (source) createPin(source);
|
|
4579
|
+
}
|
|
4580
|
+
};
|
|
4581
|
+
const onAuxClick = (event) => {
|
|
4582
|
+
if (isInspectorUIEvent(event) || pointerOverToolbar(event.clientX, event.clientY)) {
|
|
4583
|
+
return;
|
|
4584
|
+
}
|
|
4585
|
+
event.preventDefault();
|
|
4586
|
+
event.stopImmediatePropagation();
|
|
4587
|
+
};
|
|
4588
|
+
const enable = () => {
|
|
4589
|
+
if (enabled || !availableDocument || !availableWindow) return;
|
|
4590
|
+
enabled = true;
|
|
4591
|
+
ensureStyles();
|
|
4592
|
+
ensureOverlay();
|
|
4593
|
+
document2.body.classList.add(BODY_MODE_CLASS);
|
|
4594
|
+
window2.addEventListener("mousemove", onMouseMove, true);
|
|
4595
|
+
window2.addEventListener("mouseout", onMouseOut, true);
|
|
4596
|
+
window2.addEventListener("click", onClick, true);
|
|
4597
|
+
window2.addEventListener("auxclick", onAuxClick, true);
|
|
4598
|
+
window2.addEventListener("scroll", onScrollOrResize, true);
|
|
4599
|
+
window2.addEventListener("resize", onScrollOrResize, true);
|
|
4600
|
+
};
|
|
4601
|
+
const disable = () => {
|
|
4602
|
+
if (!enabled) return;
|
|
4603
|
+
enabled = false;
|
|
4604
|
+
if (pendingIdleId !== -1) getIdleScheduler().cancel(pendingIdleId);
|
|
4605
|
+
pendingIdleId = -1;
|
|
4606
|
+
pendingElement = null;
|
|
4607
|
+
history.length = 0;
|
|
4608
|
+
future.length = 0;
|
|
4609
|
+
window2.removeEventListener("mousemove", onMouseMove, true);
|
|
4610
|
+
window2.removeEventListener("mouseout", onMouseOut, true);
|
|
4611
|
+
window2.removeEventListener("click", onClick, true);
|
|
4612
|
+
window2.removeEventListener("auxclick", onAuxClick, true);
|
|
4613
|
+
window2.removeEventListener("scroll", onScrollOrResize, true);
|
|
4614
|
+
window2.removeEventListener("resize", onScrollOrResize, true);
|
|
4615
|
+
hideHover();
|
|
4616
|
+
hoverBox?.remove();
|
|
4617
|
+
hoverCard?.remove();
|
|
4618
|
+
hoverBox = null;
|
|
4619
|
+
hoverCard = null;
|
|
4620
|
+
clearPins();
|
|
4621
|
+
document2.body.classList.remove(BODY_MODE_CLASS);
|
|
4622
|
+
};
|
|
4623
|
+
const cleanup = () => {
|
|
4624
|
+
disable();
|
|
4625
|
+
overlay?.remove();
|
|
4626
|
+
overlay = null;
|
|
4627
|
+
if (typeof document2 !== "undefined") {
|
|
4628
|
+
document2.getElementById(STYLE_ID)?.remove();
|
|
4629
|
+
if (portalIsShadowRoot) {
|
|
4630
|
+
options.portalTarget.querySelector(`#${STYLE_ID}`)?.remove();
|
|
4631
|
+
}
|
|
4632
|
+
}
|
|
4633
|
+
};
|
|
4634
|
+
return {
|
|
4635
|
+
enable,
|
|
4636
|
+
disable,
|
|
4637
|
+
undo,
|
|
4638
|
+
redo,
|
|
4639
|
+
canUndo: () => history.length > 0,
|
|
4640
|
+
canRedo: () => future.length > 0,
|
|
4641
|
+
clear,
|
|
4642
|
+
inspect,
|
|
4643
|
+
isEnabled: () => enabled,
|
|
4644
|
+
cleanup,
|
|
4645
|
+
destroy: cleanup
|
|
4646
|
+
};
|
|
4647
|
+
};
|
|
4648
|
+
var TextInspector = createTextInspector({}, true);
|
|
4649
|
+
|
|
4650
|
+
// measurer.tsx
|
|
4651
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
4652
|
+
var measurerInstanceCount = 0;
|
|
4653
|
+
var XRAY_STYLE_ID = "mesurer-xray-styles";
|
|
4654
|
+
var XRAY_STYLES = `
|
|
4655
|
+
.xray-mode * {
|
|
4656
|
+
outline: solid 1px blue !important;
|
|
4657
|
+
}
|
|
4658
|
+
.xray-mode #mesurer-extension-host,
|
|
4659
|
+
.xray-mode #mesurer-extension-host *,
|
|
4660
|
+
.xray-mode .mesurer-root,
|
|
4661
|
+
.xray-mode .mesurer-root *,
|
|
4662
|
+
.xray-mode .mesurer-toolbar-surface,
|
|
4663
|
+
.xray-mode .mesurer-toolbar-surface * {
|
|
4664
|
+
outline: none !important;
|
|
4665
|
+
}
|
|
4666
|
+
`;
|
|
4667
|
+
var subscribeHydration = () => () => {
|
|
4668
|
+
};
|
|
4669
|
+
var useHydrated = () => (0, import_react20.useSyncExternalStore)(
|
|
4670
|
+
subscribeHydration,
|
|
4671
|
+
() => true,
|
|
4672
|
+
() => false
|
|
4673
|
+
);
|
|
4674
|
+
var stripMeasurement = (measurement) => ({
|
|
4675
|
+
...measurement,
|
|
4676
|
+
elementRef: void 0
|
|
4677
|
+
});
|
|
4678
|
+
var stripDistance = (distance) => ({
|
|
4679
|
+
...distance,
|
|
4680
|
+
elementRefA: void 0,
|
|
4681
|
+
elementRefB: void 0
|
|
4682
|
+
});
|
|
4683
|
+
function MeasurerClient({
|
|
4684
|
+
highlightColor,
|
|
4685
|
+
guideColor,
|
|
4686
|
+
hoverHighlightEnabled,
|
|
3287
4687
|
persistOnReload,
|
|
3288
|
-
portalTarget
|
|
4688
|
+
portalTarget,
|
|
4689
|
+
persistKey
|
|
3289
4690
|
}) {
|
|
3290
|
-
const
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
4691
|
+
const instanceIdRef = (0, import_react20.useRef)(null);
|
|
4692
|
+
if (instanceIdRef.current === null) {
|
|
4693
|
+
instanceIdRef.current = ++measurerInstanceCount;
|
|
4694
|
+
}
|
|
4695
|
+
const storageKey = persistKey ?? (instanceIdRef.current === 1 ? "mesurer-state" : `mesurer-state-${instanceIdRef.current}`);
|
|
4696
|
+
const ownerDocument = portalTarget.ownerDocument ?? document;
|
|
4697
|
+
const ownerWindow = ownerDocument.defaultView ?? window;
|
|
4698
|
+
const guideScrollRef = (0, import_react20.useRef)({
|
|
4699
|
+
x: ownerWindow.scrollX,
|
|
4700
|
+
y: ownerWindow.scrollY
|
|
4701
|
+
});
|
|
4702
|
+
const textInspectorRef = (0, import_react20.useRef)(null);
|
|
4703
|
+
if (!textInspectorRef.current) {
|
|
4704
|
+
textInspectorRef.current = createTextInspector({ portalTarget });
|
|
4705
|
+
}
|
|
4706
|
+
const textInspector = textInspectorRef.current;
|
|
4707
|
+
const selectionRectRef = (0, import_react20.useRef)(null);
|
|
4708
|
+
const toolbarRef = (0, import_react20.useRef)(null);
|
|
4709
|
+
const selectionAnimationCleanupTimeoutRef = (0, import_react20.useRef)(null);
|
|
4710
|
+
const guideDragRef = (0, import_react20.useRef)(null);
|
|
4711
|
+
const guideUserSelectRef = (0, import_react20.useRef)(null);
|
|
4712
|
+
const persistedState = (0, import_react20.useMemo)(() => {
|
|
3294
4713
|
if (!persistOnReload) return null;
|
|
3295
|
-
const stored = window.localStorage.getItem("mesurer-state");
|
|
3296
|
-
if (!stored) return null;
|
|
3297
4714
|
try {
|
|
4715
|
+
const stored = window.localStorage.getItem(storageKey);
|
|
4716
|
+
if (!stored) return null;
|
|
3298
4717
|
const parsed = JSON.parse(stored);
|
|
3299
4718
|
if (!parsed || parsed.version !== 1) return null;
|
|
3300
4719
|
return parsed;
|
|
3301
4720
|
} catch {
|
|
3302
4721
|
return null;
|
|
3303
4722
|
}
|
|
3304
|
-
}, [persistOnReload]);
|
|
4723
|
+
}, [persistOnReload, storageKey]);
|
|
4724
|
+
const enabledRef = (0, import_react20.useRef)(false);
|
|
4725
|
+
const toolModeRef = (0, import_react20.useRef)(
|
|
4726
|
+
persistedState?.toolMode === "rulers" ? "none" : persistedState?.toolMode ?? "none"
|
|
4727
|
+
);
|
|
4728
|
+
const rulersVisibleRef = (0, import_react20.useRef)(
|
|
4729
|
+
persistedState?.rulersVisible ?? persistedState?.toolMode === "rulers"
|
|
4730
|
+
);
|
|
4731
|
+
const guideOrientationRef = (0, import_react20.useRef)(
|
|
4732
|
+
persistedState?.guideOrientation ?? "vertical"
|
|
4733
|
+
);
|
|
4734
|
+
const measurementsRef = (0, import_react20.useRef)(
|
|
4735
|
+
persistedState?.measurements ?? []
|
|
4736
|
+
);
|
|
4737
|
+
const activeMeasurementRef = (0, import_react20.useRef)(
|
|
4738
|
+
persistedState?.activeMeasurement ?? null
|
|
4739
|
+
);
|
|
4740
|
+
const heldDistancesRef = (0, import_react20.useRef)(
|
|
4741
|
+
persistedState?.heldDistances ?? []
|
|
4742
|
+
);
|
|
4743
|
+
const guidesRef = (0, import_react20.useRef)(persistedState?.guides ?? []);
|
|
4744
|
+
const selectedGuideIdsRef = (0, import_react20.useRef)(
|
|
4745
|
+
persistedState?.selectedGuideIds ?? []
|
|
4746
|
+
);
|
|
3305
4747
|
const { overlayRef, selectedElementRef, hoverElementRef } = useOverlayRefs();
|
|
3306
4748
|
const {
|
|
3307
4749
|
selectionOriginRect,
|
|
@@ -3327,12 +4769,15 @@ function MeasurerClient({
|
|
|
3327
4769
|
setAltPressed,
|
|
3328
4770
|
toolMode,
|
|
3329
4771
|
setToolMode,
|
|
4772
|
+
rulersVisible,
|
|
4773
|
+
setRulersVisible,
|
|
3330
4774
|
guidesEnabled,
|
|
3331
4775
|
multiMeasureEnabled,
|
|
3332
4776
|
snapGuidesEnabled
|
|
3333
4777
|
} = useMeasureToggles({
|
|
3334
4778
|
initialEnabled: persistedState?.enabled,
|
|
3335
|
-
initialToolMode: persistedState?.toolMode
|
|
4779
|
+
initialToolMode: persistedState?.toolMode === "rulers" ? "none" : persistedState?.toolMode,
|
|
4780
|
+
initialRulersVisible: persistedState?.rulersVisible ?? persistedState?.toolMode === "rulers"
|
|
3336
4781
|
});
|
|
3337
4782
|
const { start, setStart, end, setEnd, isDragging, setIsDragging } = useDragState();
|
|
3338
4783
|
const {
|
|
@@ -3364,85 +4809,170 @@ function MeasurerClient({
|
|
|
3364
4809
|
initialGuides: persistedState?.guides ?? [],
|
|
3365
4810
|
initialSelectedGuideIds: persistedState?.selectedGuideIds ?? []
|
|
3366
4811
|
});
|
|
3367
|
-
const [toolbarActive, setToolbarActive] = (0,
|
|
3368
|
-
const { clearGuideDragHold, scheduleGuideDragHold } = useGuideDragHold();
|
|
3369
|
-
const [guidePreview, setGuidePreview] = (0,
|
|
3370
|
-
const [guideOrientation, setGuideOrientation] = (0,
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
activeMeasurement: activeMeasurement ? stripMeasurement(activeMeasurement) : null,
|
|
3382
|
-
heldDistances: heldDistances.map(stripDistance)
|
|
3383
|
-
});
|
|
3384
|
-
}, [
|
|
3385
|
-
activeMeasurement,
|
|
3386
|
-
enabled,
|
|
3387
|
-
guideOrientation,
|
|
3388
|
-
guides,
|
|
3389
|
-
heldDistances,
|
|
3390
|
-
measurements,
|
|
3391
|
-
persistOnReload,
|
|
3392
|
-
selectedGuideIds,
|
|
3393
|
-
toolMode
|
|
3394
|
-
]);
|
|
3395
|
-
(0, import_react19.useEffect)(() => {
|
|
4812
|
+
const [toolbarActive, setToolbarActive] = (0, import_react20.useState)(true);
|
|
4813
|
+
const { clearGuideDragHold, scheduleGuideDragHold } = useGuideDragHold(ownerWindow);
|
|
4814
|
+
const [guidePreview, setGuidePreview] = (0, import_react20.useState)(null);
|
|
4815
|
+
const [guideOrientation, setGuideOrientation] = (0, import_react20.useState)(persistedState?.guideOrientation ?? "vertical");
|
|
4816
|
+
enabledRef.current = enabled;
|
|
4817
|
+
toolModeRef.current = toolMode;
|
|
4818
|
+
rulersVisibleRef.current = rulersVisible;
|
|
4819
|
+
guideOrientationRef.current = guideOrientation;
|
|
4820
|
+
measurementsRef.current = measurements;
|
|
4821
|
+
activeMeasurementRef.current = activeMeasurement;
|
|
4822
|
+
heldDistancesRef.current = heldDistances;
|
|
4823
|
+
guidesRef.current = guides;
|
|
4824
|
+
selectedGuideIdsRef.current = selectedGuideIds;
|
|
4825
|
+
const persistState = (0, import_react20.useCallback)(() => {
|
|
3396
4826
|
if (!persistOnReload) return;
|
|
3397
4827
|
if (typeof window === "undefined") return;
|
|
3398
|
-
if (!persistPayload) return;
|
|
3399
4828
|
try {
|
|
3400
|
-
window.localStorage.setItem(
|
|
4829
|
+
window.localStorage.setItem(
|
|
4830
|
+
storageKey,
|
|
4831
|
+
JSON.stringify({
|
|
4832
|
+
version: 1,
|
|
4833
|
+
enabled: enabledRef.current,
|
|
4834
|
+
toolMode: toolModeRef.current,
|
|
4835
|
+
rulersVisible: rulersVisibleRef.current,
|
|
4836
|
+
guideOrientation: guideOrientationRef.current,
|
|
4837
|
+
guides: guidesRef.current,
|
|
4838
|
+
selectedGuideIds: selectedGuideIdsRef.current,
|
|
4839
|
+
measurements: measurementsRef.current.map(stripMeasurement),
|
|
4840
|
+
activeMeasurement: activeMeasurementRef.current ? stripMeasurement(activeMeasurementRef.current) : null,
|
|
4841
|
+
heldDistances: heldDistancesRef.current.map(stripDistance)
|
|
4842
|
+
})
|
|
4843
|
+
);
|
|
3401
4844
|
} catch {
|
|
3402
4845
|
}
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
4846
|
+
}, [persistOnReload, storageKey]);
|
|
4847
|
+
const setEnabledPersisted = (0, import_react20.useCallback)(
|
|
4848
|
+
(value) => {
|
|
4849
|
+
const next = typeof value === "function" ? value(enabledRef.current) : value;
|
|
4850
|
+
if (Object.is(next, enabledRef.current)) return;
|
|
4851
|
+
enabledRef.current = next;
|
|
4852
|
+
setEnabled(next);
|
|
4853
|
+
persistState();
|
|
4854
|
+
},
|
|
4855
|
+
[persistState, setEnabled]
|
|
4856
|
+
);
|
|
4857
|
+
const setRulersVisiblePersisted = (0, import_react20.useCallback)(
|
|
4858
|
+
(value) => {
|
|
4859
|
+
const next = typeof value === "function" ? value(rulersVisibleRef.current) : value;
|
|
4860
|
+
if (Object.is(next, rulersVisibleRef.current)) return;
|
|
4861
|
+
rulersVisibleRef.current = next;
|
|
4862
|
+
setRulersVisible(next);
|
|
4863
|
+
persistState();
|
|
4864
|
+
},
|
|
4865
|
+
[persistState, setRulersVisible]
|
|
4866
|
+
);
|
|
4867
|
+
const setToolModePersisted = (0, import_react20.useCallback)(
|
|
4868
|
+
(value) => {
|
|
4869
|
+
const next = typeof value === "function" ? value(toolModeRef.current) : value;
|
|
4870
|
+
if (Object.is(next, toolModeRef.current)) return;
|
|
4871
|
+
toolModeRef.current = next;
|
|
4872
|
+
setToolMode(next);
|
|
4873
|
+
if (next === "text-inspector") {
|
|
4874
|
+
textInspector.enable();
|
|
4875
|
+
} else {
|
|
4876
|
+
textInspector.disable();
|
|
3407
4877
|
}
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
4878
|
+
persistState();
|
|
4879
|
+
},
|
|
4880
|
+
[persistState, setToolMode, textInspector]
|
|
4881
|
+
);
|
|
4882
|
+
const setGuideOrientationPersisted = (0, import_react20.useCallback)(
|
|
4883
|
+
(value) => {
|
|
4884
|
+
const next = typeof value === "function" ? value(guideOrientationRef.current) : value;
|
|
4885
|
+
if (Object.is(next, guideOrientationRef.current)) return;
|
|
4886
|
+
guideOrientationRef.current = next;
|
|
4887
|
+
setGuideOrientation(next);
|
|
4888
|
+
persistState();
|
|
4889
|
+
},
|
|
4890
|
+
[persistState, setGuideOrientation]
|
|
4891
|
+
);
|
|
4892
|
+
const setMeasurementsPersisted = (0, import_react20.useCallback)(
|
|
4893
|
+
(value) => {
|
|
4894
|
+
const next = typeof value === "function" ? value(measurementsRef.current) : value;
|
|
4895
|
+
if (Object.is(next, measurementsRef.current)) return;
|
|
4896
|
+
measurementsRef.current = next;
|
|
4897
|
+
setMeasurements(next);
|
|
4898
|
+
persistState();
|
|
4899
|
+
},
|
|
4900
|
+
[persistState, setMeasurements]
|
|
4901
|
+
);
|
|
4902
|
+
const setActiveMeasurementPersisted = (0, import_react20.useCallback)(
|
|
4903
|
+
(value) => {
|
|
4904
|
+
const next = typeof value === "function" ? value(activeMeasurementRef.current) : value;
|
|
4905
|
+
if (Object.is(next, activeMeasurementRef.current)) return;
|
|
4906
|
+
activeMeasurementRef.current = next;
|
|
4907
|
+
setActiveMeasurement(next);
|
|
4908
|
+
persistState();
|
|
4909
|
+
},
|
|
4910
|
+
[persistState, setActiveMeasurement]
|
|
4911
|
+
);
|
|
4912
|
+
const setHeldDistancesPersisted = (0, import_react20.useCallback)(
|
|
4913
|
+
(value) => {
|
|
4914
|
+
const next = typeof value === "function" ? value(heldDistancesRef.current) : value;
|
|
4915
|
+
if (Object.is(next, heldDistancesRef.current)) return;
|
|
4916
|
+
heldDistancesRef.current = next;
|
|
4917
|
+
setHeldDistances(next);
|
|
4918
|
+
persistState();
|
|
4919
|
+
},
|
|
4920
|
+
[persistState, setHeldDistances]
|
|
4921
|
+
);
|
|
4922
|
+
const setGuidesPersisted = (0, import_react20.useCallback)(
|
|
4923
|
+
(value) => {
|
|
4924
|
+
const next = typeof value === "function" ? value(guidesRef.current) : value;
|
|
4925
|
+
if (Object.is(next, guidesRef.current)) return;
|
|
4926
|
+
guidesRef.current = next;
|
|
4927
|
+
setGuides(next);
|
|
4928
|
+
persistState();
|
|
4929
|
+
},
|
|
4930
|
+
[persistState, setGuides]
|
|
4931
|
+
);
|
|
4932
|
+
const setSelectedGuideIdsPersisted = (0, import_react20.useCallback)(
|
|
4933
|
+
(value) => {
|
|
4934
|
+
const next = typeof value === "function" ? value(selectedGuideIdsRef.current) : value;
|
|
4935
|
+
if (Object.is(next, selectedGuideIdsRef.current)) return;
|
|
4936
|
+
selectedGuideIdsRef.current = next;
|
|
4937
|
+
setSelectedGuideIds(next);
|
|
4938
|
+
persistState();
|
|
4939
|
+
},
|
|
4940
|
+
[persistState, setSelectedGuideIds]
|
|
4941
|
+
);
|
|
3414
4942
|
const {
|
|
3415
4943
|
recordSnapshot,
|
|
3416
4944
|
createActionCommit,
|
|
3417
4945
|
setToolModeWithHistory,
|
|
3418
4946
|
setGuideOrientationWithHistory,
|
|
3419
|
-
setEnabledWithHistory
|
|
4947
|
+
setEnabledWithHistory,
|
|
4948
|
+
undo: undoHistory,
|
|
4949
|
+
redo: redoHistory
|
|
3420
4950
|
} = useMeasurerHistory({
|
|
3421
4951
|
toggles: {
|
|
3422
4952
|
enabled,
|
|
3423
|
-
setEnabled,
|
|
4953
|
+
setEnabled: setEnabledPersisted,
|
|
3424
4954
|
toolMode,
|
|
3425
|
-
setToolMode,
|
|
4955
|
+
setToolMode: setToolModePersisted,
|
|
3426
4956
|
guideOrientation,
|
|
3427
|
-
setGuideOrientation
|
|
4957
|
+
setGuideOrientation: setGuideOrientationPersisted
|
|
3428
4958
|
},
|
|
3429
4959
|
measurements: {
|
|
3430
4960
|
measurements,
|
|
3431
|
-
setMeasurements,
|
|
4961
|
+
setMeasurements: setMeasurementsPersisted,
|
|
3432
4962
|
activeMeasurement,
|
|
3433
|
-
setActiveMeasurement,
|
|
4963
|
+
setActiveMeasurement: setActiveMeasurementPersisted,
|
|
3434
4964
|
selectedMeasurements,
|
|
3435
4965
|
setSelectedMeasurements,
|
|
3436
4966
|
selectedMeasurement,
|
|
3437
4967
|
setSelectedMeasurement,
|
|
3438
4968
|
heldDistances,
|
|
3439
|
-
setHeldDistances
|
|
4969
|
+
setHeldDistances: setHeldDistancesPersisted
|
|
3440
4970
|
},
|
|
3441
4971
|
guides: {
|
|
3442
4972
|
guides,
|
|
3443
|
-
setGuides,
|
|
4973
|
+
setGuides: setGuidesPersisted,
|
|
3444
4974
|
selectedGuideIds,
|
|
3445
|
-
setSelectedGuideIds,
|
|
4975
|
+
setSelectedGuideIds: setSelectedGuideIdsPersisted,
|
|
3446
4976
|
draggingGuideId,
|
|
3447
4977
|
setDraggingGuideId
|
|
3448
4978
|
},
|
|
@@ -3457,96 +4987,254 @@ function MeasurerClient({
|
|
|
3457
4987
|
clearSelectionRect
|
|
3458
4988
|
}
|
|
3459
4989
|
});
|
|
3460
|
-
const
|
|
4990
|
+
const undo = (0, import_react20.useCallback)(() => {
|
|
4991
|
+
if (toolMode === "text-inspector" && textInspector.undo()) return;
|
|
4992
|
+
undoHistory();
|
|
4993
|
+
}, [textInspector, toolMode, undoHistory]);
|
|
4994
|
+
const redo = (0, import_react20.useCallback)(() => {
|
|
4995
|
+
if (toolMode === "text-inspector" && textInspector.redo()) return;
|
|
4996
|
+
redoHistory();
|
|
4997
|
+
}, [redoHistory, textInspector, toolMode]);
|
|
4998
|
+
const clearAll = (0, import_react20.useCallback)(() => {
|
|
4999
|
+
if (toolMode === "text-inspector") {
|
|
5000
|
+
textInspector.clear();
|
|
5001
|
+
}
|
|
3461
5002
|
recordSnapshot();
|
|
3462
5003
|
clearGuideDragHold();
|
|
3463
5004
|
setStart(null);
|
|
3464
5005
|
setEnd(null);
|
|
3465
5006
|
setIsDragging(false);
|
|
3466
|
-
|
|
3467
|
-
|
|
5007
|
+
setActiveMeasurementPersisted(null);
|
|
5008
|
+
setMeasurementsPersisted([]);
|
|
3468
5009
|
setSelectedMeasurement(null);
|
|
3469
5010
|
setSelectedMeasurements([]);
|
|
3470
5011
|
clearSelectionRect();
|
|
3471
5012
|
setSelectedElement(null);
|
|
3472
5013
|
setHoverRect(null);
|
|
3473
5014
|
setHoverElement(null);
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
5015
|
+
setGuidesPersisted([]);
|
|
5016
|
+
setSelectedGuideIdsPersisted([]);
|
|
5017
|
+
setHeldDistancesPersisted([]);
|
|
3477
5018
|
}, [
|
|
3478
5019
|
clearGuideDragHold,
|
|
3479
5020
|
clearSelectionRect,
|
|
3480
5021
|
recordSnapshot,
|
|
3481
|
-
|
|
5022
|
+
setActiveMeasurementPersisted,
|
|
3482
5023
|
setEnd,
|
|
3483
|
-
|
|
3484
|
-
|
|
5024
|
+
setGuidesPersisted,
|
|
5025
|
+
setHeldDistancesPersisted,
|
|
3485
5026
|
setHoverElement,
|
|
3486
5027
|
setHoverRect,
|
|
3487
5028
|
setIsDragging,
|
|
3488
|
-
|
|
5029
|
+
setMeasurementsPersisted,
|
|
3489
5030
|
setSelectedElement,
|
|
3490
|
-
|
|
5031
|
+
setSelectedGuideIdsPersisted,
|
|
3491
5032
|
setSelectedMeasurement,
|
|
3492
5033
|
setSelectedMeasurements,
|
|
3493
|
-
setStart
|
|
5034
|
+
setStart,
|
|
5035
|
+
textInspector,
|
|
5036
|
+
toolMode
|
|
3494
5037
|
]);
|
|
3495
|
-
const removeSelectedGuides = (0,
|
|
5038
|
+
const removeSelectedGuides = (0, import_react20.useCallback)(() => {
|
|
3496
5039
|
if (selectedGuideIds.length === 0) return false;
|
|
3497
5040
|
recordSnapshot();
|
|
3498
|
-
|
|
5041
|
+
setGuidesPersisted(
|
|
3499
5042
|
(prev) => prev.filter((guide) => !selectedGuideIds.includes(guide.id))
|
|
3500
5043
|
);
|
|
3501
|
-
|
|
5044
|
+
setSelectedGuideIdsPersisted([]);
|
|
3502
5045
|
return true;
|
|
3503
|
-
}, [
|
|
5046
|
+
}, [
|
|
5047
|
+
recordSnapshot,
|
|
5048
|
+
selectedGuideIds,
|
|
5049
|
+
setGuidesPersisted,
|
|
5050
|
+
setSelectedGuideIdsPersisted
|
|
5051
|
+
]);
|
|
3504
5052
|
useHotkeys({
|
|
5053
|
+
eventTarget: ownerWindow,
|
|
3505
5054
|
clearAll,
|
|
5055
|
+
undo,
|
|
5056
|
+
redo,
|
|
3506
5057
|
removeSelectedGuides,
|
|
3507
5058
|
setEnabled: setEnabledWithHistory,
|
|
3508
5059
|
setToolMode: setToolModeWithHistory,
|
|
5060
|
+
setRulersVisible: setRulersVisiblePersisted,
|
|
3509
5061
|
setAltPressed,
|
|
3510
5062
|
isOverlayActive: () => enabled && (toolMode !== "none" || toolbarActive),
|
|
3511
5063
|
setGuideOrientation: setGuideOrientationWithHistory,
|
|
3512
5064
|
onInteract: () => setToolbarActive(true)
|
|
3513
5065
|
});
|
|
3514
5066
|
useResizeSync({
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
5067
|
+
document: ownerDocument,
|
|
5068
|
+
window: ownerWindow,
|
|
5069
|
+
setMeasurements: setMeasurementsPersisted,
|
|
5070
|
+
setActiveMeasurement: setActiveMeasurementPersisted,
|
|
5071
|
+
setHeldDistances: setHeldDistancesPersisted,
|
|
3518
5072
|
setSelectedMeasurement,
|
|
3519
|
-
setGuides,
|
|
5073
|
+
setGuides: setGuidesPersisted,
|
|
3520
5074
|
selectedElementRef
|
|
3521
5075
|
});
|
|
5076
|
+
(0, import_react20.useEffect)(() => {
|
|
5077
|
+
const handleScroll = () => {
|
|
5078
|
+
const next = {
|
|
5079
|
+
x: ownerWindow.scrollX,
|
|
5080
|
+
y: ownerWindow.scrollY
|
|
5081
|
+
};
|
|
5082
|
+
const deltaX = next.x - guideScrollRef.current.x;
|
|
5083
|
+
const deltaY = next.y - guideScrollRef.current.y;
|
|
5084
|
+
guideScrollRef.current = next;
|
|
5085
|
+
if (deltaX === 0 && deltaY === 0) return;
|
|
5086
|
+
setGuidesPersisted(
|
|
5087
|
+
(prev) => prev.map((guide) => ({
|
|
5088
|
+
...guide,
|
|
5089
|
+
position: guide.position - (guide.orientation === "vertical" ? deltaX : deltaY)
|
|
5090
|
+
}))
|
|
5091
|
+
);
|
|
5092
|
+
};
|
|
5093
|
+
ownerWindow.addEventListener("scroll", handleScroll, true);
|
|
5094
|
+
return () => ownerWindow.removeEventListener("scroll", handleScroll, true);
|
|
5095
|
+
}, [ownerWindow, setGuidesPersisted]);
|
|
3522
5096
|
useLiveElementTracking({
|
|
5097
|
+
document: ownerDocument,
|
|
5098
|
+
window: ownerWindow,
|
|
3523
5099
|
enabled,
|
|
3524
5100
|
selectedElementRef,
|
|
3525
5101
|
hoverElementRef,
|
|
3526
5102
|
setSelectedMeasurement,
|
|
3527
5103
|
setSelectedMeasurements,
|
|
3528
5104
|
setHoverRect,
|
|
3529
|
-
setMeasurements,
|
|
3530
|
-
setActiveMeasurement,
|
|
3531
|
-
setHeldDistances
|
|
5105
|
+
setMeasurements: setMeasurementsPersisted,
|
|
5106
|
+
setActiveMeasurement: setActiveMeasurementPersisted,
|
|
5107
|
+
setHeldDistances: setHeldDistancesPersisted
|
|
3532
5108
|
});
|
|
3533
|
-
(0,
|
|
5109
|
+
(0, import_react20.useEffect)(() => {
|
|
3534
5110
|
if (!toolbarActive || toolMode !== "none") return;
|
|
3535
5111
|
const handlePointerDown2 = (event) => {
|
|
3536
5112
|
const toolbarNode = toolbarRef.current;
|
|
3537
5113
|
if (toolbarNode && toolbarNode.contains(event.target)) return;
|
|
3538
5114
|
setToolbarActive(false);
|
|
3539
5115
|
};
|
|
3540
|
-
|
|
5116
|
+
ownerWindow.addEventListener("pointerdown", handlePointerDown2);
|
|
3541
5117
|
return () => {
|
|
3542
|
-
|
|
5118
|
+
ownerWindow.removeEventListener("pointerdown", handlePointerDown2);
|
|
3543
5119
|
};
|
|
3544
|
-
}, [toolbarActive, toolMode]);
|
|
3545
|
-
(0,
|
|
3546
|
-
if (
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
5120
|
+
}, [ownerWindow, toolbarActive, toolMode]);
|
|
5121
|
+
(0, import_react20.useEffect)(() => {
|
|
5122
|
+
if (!enabled) return;
|
|
5123
|
+
const handleGuidePointerDown2 = (event) => {
|
|
5124
|
+
if (toolbarRef.current?.contains(event.target)) return;
|
|
5125
|
+
const guideTarget = event.composedPath().some(
|
|
5126
|
+
(target) => target instanceof ownerWindow.Element && target.hasAttribute("data-mesurer-guide")
|
|
5127
|
+
);
|
|
5128
|
+
if (guideTarget && toolMode !== "none") return;
|
|
5129
|
+
const point = { x: event.clientX, y: event.clientY };
|
|
5130
|
+
const guide = guides.find((candidate) => {
|
|
5131
|
+
const distance = candidate.orientation === "vertical" ? Math.abs(candidate.position - point.x) : Math.abs(candidate.position - point.y);
|
|
5132
|
+
return distance <= GUIDE_HITBOX_SIZE / 2;
|
|
5133
|
+
});
|
|
5134
|
+
if (!guide) return;
|
|
5135
|
+
if (event.button === 0 && !event.shiftKey && toolMode === "none") {
|
|
5136
|
+
guideDragRef.current = {
|
|
5137
|
+
id: guide.id,
|
|
5138
|
+
orientation: guide.orientation,
|
|
5139
|
+
pointerId: event.pointerId,
|
|
5140
|
+
commit: createActionCommit(),
|
|
5141
|
+
committed: false
|
|
5142
|
+
};
|
|
5143
|
+
}
|
|
5144
|
+
setSelectedGuideIdsPersisted(
|
|
5145
|
+
(prev) => event.shiftKey ? prev.includes(guide.id) ? prev.filter((id) => id !== guide.id) : [...prev, guide.id] : [guide.id]
|
|
5146
|
+
);
|
|
5147
|
+
};
|
|
5148
|
+
const handleGuidePointerMove = (event) => {
|
|
5149
|
+
const drag = guideDragRef.current;
|
|
5150
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
5151
|
+
const position = drag.orientation === "vertical" ? event.clientX : event.clientY;
|
|
5152
|
+
if (!drag.committed) {
|
|
5153
|
+
event.preventDefault();
|
|
5154
|
+
if (guideUserSelectRef.current === null) {
|
|
5155
|
+
guideUserSelectRef.current = ownerDocument.documentElement.style.userSelect;
|
|
5156
|
+
ownerDocument.documentElement.style.userSelect = "none";
|
|
5157
|
+
}
|
|
5158
|
+
ownerWindow.getSelection()?.removeAllRanges();
|
|
5159
|
+
drag.commit();
|
|
5160
|
+
drag.committed = true;
|
|
5161
|
+
}
|
|
5162
|
+
setGuidesPersisted(
|
|
5163
|
+
(prev) => prev.map(
|
|
5164
|
+
(guide) => guide.id === drag.id ? { ...guide, position } : guide
|
|
5165
|
+
)
|
|
5166
|
+
);
|
|
5167
|
+
};
|
|
5168
|
+
const handleGuidePointerEnd = (event) => {
|
|
5169
|
+
if (guideDragRef.current?.pointerId === event.pointerId) {
|
|
5170
|
+
guideDragRef.current = null;
|
|
5171
|
+
if (guideUserSelectRef.current !== null) {
|
|
5172
|
+
ownerDocument.documentElement.style.userSelect = guideUserSelectRef.current;
|
|
5173
|
+
guideUserSelectRef.current = null;
|
|
5174
|
+
}
|
|
5175
|
+
}
|
|
5176
|
+
};
|
|
5177
|
+
ownerWindow.addEventListener("pointerdown", handleGuidePointerDown2, true);
|
|
5178
|
+
ownerWindow.addEventListener("pointermove", handleGuidePointerMove, true);
|
|
5179
|
+
ownerWindow.addEventListener("pointerup", handleGuidePointerEnd, true);
|
|
5180
|
+
ownerWindow.addEventListener("pointercancel", handleGuidePointerEnd, true);
|
|
5181
|
+
return () => {
|
|
5182
|
+
ownerWindow.removeEventListener(
|
|
5183
|
+
"pointerdown",
|
|
5184
|
+
handleGuidePointerDown2,
|
|
5185
|
+
true
|
|
5186
|
+
);
|
|
5187
|
+
ownerWindow.removeEventListener("pointermove", handleGuidePointerMove, true);
|
|
5188
|
+
ownerWindow.removeEventListener("pointerup", handleGuidePointerEnd, true);
|
|
5189
|
+
ownerWindow.removeEventListener(
|
|
5190
|
+
"pointercancel",
|
|
5191
|
+
handleGuidePointerEnd,
|
|
5192
|
+
true
|
|
5193
|
+
);
|
|
5194
|
+
if (guideUserSelectRef.current !== null) {
|
|
5195
|
+
ownerDocument.documentElement.style.userSelect = guideUserSelectRef.current;
|
|
5196
|
+
guideUserSelectRef.current = null;
|
|
5197
|
+
}
|
|
5198
|
+
};
|
|
5199
|
+
}, [
|
|
5200
|
+
createActionCommit,
|
|
5201
|
+
enabled,
|
|
5202
|
+
guides,
|
|
5203
|
+
ownerWindow,
|
|
5204
|
+
setGuidesPersisted,
|
|
5205
|
+
setSelectedGuideIdsPersisted,
|
|
5206
|
+
toolMode
|
|
5207
|
+
]);
|
|
5208
|
+
(0, import_react20.useEffect)(() => {
|
|
5209
|
+
if (toolMode === "text-inspector") {
|
|
5210
|
+
textInspector.enable();
|
|
5211
|
+
} else {
|
|
5212
|
+
textInspector.disable();
|
|
5213
|
+
}
|
|
5214
|
+
}, [textInspector, toolMode]);
|
|
5215
|
+
(0, import_react20.useEffect)(() => {
|
|
5216
|
+
let style = ownerDocument.getElementById(XRAY_STYLE_ID);
|
|
5217
|
+
if (!style) {
|
|
5218
|
+
style = ownerDocument.createElement("style");
|
|
5219
|
+
style.id = XRAY_STYLE_ID;
|
|
5220
|
+
style.textContent = XRAY_STYLES;
|
|
5221
|
+
ownerDocument.head.appendChild(style);
|
|
5222
|
+
}
|
|
5223
|
+
if (toolMode === "xray") {
|
|
5224
|
+
ownerDocument.body.classList.add("xray-mode");
|
|
5225
|
+
} else {
|
|
5226
|
+
ownerDocument.body.classList.remove("xray-mode");
|
|
5227
|
+
}
|
|
5228
|
+
return () => {
|
|
5229
|
+
ownerDocument.body.classList.remove("xray-mode");
|
|
5230
|
+
};
|
|
5231
|
+
}, [ownerDocument, toolMode]);
|
|
5232
|
+
(0, import_react20.useEffect)(() => {
|
|
5233
|
+
return () => {
|
|
5234
|
+
textInspector.destroy();
|
|
5235
|
+
};
|
|
5236
|
+
}, [textInspector]);
|
|
5237
|
+
(0, import_react20.useEffect)(() => {
|
|
3550
5238
|
const hasSelectionAnimationState = !!selectionOriginRect || !!selectedMeasurement?.originRect || selectedMeasurements.some((measurement) => !!measurement.originRect);
|
|
3551
5239
|
if (!hasSelectionAnimationState) {
|
|
3552
5240
|
if (selectionAnimationCleanupTimeoutRef.current !== null) {
|
|
@@ -3575,6 +5263,12 @@ function MeasurerClient({
|
|
|
3575
5263
|
return changed ? next : prev;
|
|
3576
5264
|
});
|
|
3577
5265
|
}, MEASURE_TRANSITION_MS);
|
|
5266
|
+
return () => {
|
|
5267
|
+
if (selectionAnimationCleanupTimeoutRef.current !== null) {
|
|
5268
|
+
window.clearTimeout(selectionAnimationCleanupTimeoutRef.current);
|
|
5269
|
+
selectionAnimationCleanupTimeoutRef.current = null;
|
|
5270
|
+
}
|
|
5271
|
+
};
|
|
3578
5272
|
}, [
|
|
3579
5273
|
selectionOriginRect,
|
|
3580
5274
|
selectedMeasurement,
|
|
@@ -3583,13 +5277,6 @@ function MeasurerClient({
|
|
|
3583
5277
|
setSelectedMeasurements,
|
|
3584
5278
|
setSelectionOriginRect
|
|
3585
5279
|
]);
|
|
3586
|
-
(0, import_react19.useEffect)(() => {
|
|
3587
|
-
return () => {
|
|
3588
|
-
if (selectionAnimationCleanupTimeoutRef.current !== null) {
|
|
3589
|
-
window.clearTimeout(selectionAnimationCleanupTimeoutRef.current);
|
|
3590
|
-
}
|
|
3591
|
-
};
|
|
3592
|
-
}, []);
|
|
3593
5280
|
const displayedMeasurements = holdEnabled ? measurements : multiMeasureEnabled && measurements.length > 0 ? measurements : activeMeasurement ? [activeMeasurement] : [];
|
|
3594
5281
|
const {
|
|
3595
5282
|
activeRect,
|
|
@@ -3611,6 +5298,8 @@ function MeasurerClient({
|
|
|
3611
5298
|
hoverEdgeVisibility,
|
|
3612
5299
|
measurementEdgeVisibility
|
|
3613
5300
|
} = useMeasurerDerived({
|
|
5301
|
+
document: ownerDocument,
|
|
5302
|
+
window: ownerWindow,
|
|
3614
5303
|
start,
|
|
3615
5304
|
end,
|
|
3616
5305
|
selectedMeasurements,
|
|
@@ -3636,6 +5325,8 @@ function MeasurerClient({
|
|
|
3636
5325
|
handlePointerUp,
|
|
3637
5326
|
handlePointerLeave
|
|
3638
5327
|
} = useMeasurerPointer({
|
|
5328
|
+
document: ownerDocument,
|
|
5329
|
+
window: ownerWindow,
|
|
3639
5330
|
toolbarRef,
|
|
3640
5331
|
overlayRef,
|
|
3641
5332
|
selectionRectRef,
|
|
@@ -3661,15 +5352,15 @@ function MeasurerClient({
|
|
|
3661
5352
|
optionPairOverlay,
|
|
3662
5353
|
setAltPressed,
|
|
3663
5354
|
setGuidePreview,
|
|
3664
|
-
setSelectedGuideIds,
|
|
3665
|
-
setGuides,
|
|
5355
|
+
setSelectedGuideIds: setSelectedGuideIdsPersisted,
|
|
5356
|
+
setGuides: setGuidesPersisted,
|
|
3666
5357
|
setStart,
|
|
3667
5358
|
setEnd,
|
|
3668
5359
|
setIsDragging,
|
|
3669
|
-
setHeldDistances,
|
|
5360
|
+
setHeldDistances: setHeldDistancesPersisted,
|
|
3670
5361
|
setDraggingGuideId,
|
|
3671
|
-
setActiveMeasurement,
|
|
3672
|
-
setMeasurements,
|
|
5362
|
+
setActiveMeasurement: setActiveMeasurementPersisted,
|
|
5363
|
+
setMeasurements: setMeasurementsPersisted,
|
|
3673
5364
|
setSelectedMeasurements,
|
|
3674
5365
|
setSelectedMeasurement,
|
|
3675
5366
|
setSelectionOriginRect,
|
|
@@ -3679,27 +5370,65 @@ function MeasurerClient({
|
|
|
3679
5370
|
setHoverPointer,
|
|
3680
5371
|
clearSelectionRect
|
|
3681
5372
|
});
|
|
3682
|
-
const removeHeldDistance = (0,
|
|
5373
|
+
const removeHeldDistance = (0, import_react20.useCallback)(
|
|
3683
5374
|
(id) => {
|
|
3684
5375
|
recordSnapshot();
|
|
3685
|
-
|
|
5376
|
+
setHeldDistancesPersisted(
|
|
5377
|
+
(prev) => prev.filter((distance) => distance.id !== id)
|
|
5378
|
+
);
|
|
5379
|
+
},
|
|
5380
|
+
[recordSnapshot, setHeldDistancesPersisted]
|
|
5381
|
+
);
|
|
5382
|
+
const startGuideFromRuler = (0, import_react20.useCallback)(
|
|
5383
|
+
(orientation, position) => {
|
|
5384
|
+
const id = createId();
|
|
5385
|
+
const commit = createActionCommit();
|
|
5386
|
+
commit();
|
|
5387
|
+
setSelectedGuideIdsPersisted([]);
|
|
5388
|
+
setGuidesPersisted((prev) => [...prev, { id, orientation, position }]);
|
|
5389
|
+
return id;
|
|
5390
|
+
},
|
|
5391
|
+
[
|
|
5392
|
+
createActionCommit,
|
|
5393
|
+
setGuidesPersisted,
|
|
5394
|
+
setSelectedGuideIdsPersisted
|
|
5395
|
+
]
|
|
5396
|
+
);
|
|
5397
|
+
const moveGuideFromRuler = (0, import_react20.useCallback)(
|
|
5398
|
+
(id, position) => {
|
|
5399
|
+
setGuidesPersisted(
|
|
5400
|
+
(prev) => prev.map((guide) => guide.id === id ? { ...guide, position } : guide)
|
|
5401
|
+
);
|
|
3686
5402
|
},
|
|
3687
|
-
[
|
|
5403
|
+
[setGuidesPersisted]
|
|
3688
5404
|
);
|
|
3689
|
-
const
|
|
5405
|
+
const finishGuideFromRuler = (0, import_react20.useCallback)(
|
|
5406
|
+
(id) => {
|
|
5407
|
+
setSelectedGuideIdsPersisted([id]);
|
|
5408
|
+
},
|
|
5409
|
+
[setSelectedGuideIdsPersisted]
|
|
5410
|
+
);
|
|
5411
|
+
const cancelGuideFromRuler = (0, import_react20.useCallback)(
|
|
5412
|
+
(id) => {
|
|
5413
|
+
setGuidesPersisted((prev) => prev.filter((guide) => guide.id !== id));
|
|
5414
|
+
},
|
|
5415
|
+
[setGuidesPersisted]
|
|
5416
|
+
);
|
|
5417
|
+
const handleGuidePointerDown = (0, import_react20.useCallback)(
|
|
3690
5418
|
(guide, event) => {
|
|
3691
5419
|
const commit = createActionCommit();
|
|
3692
5420
|
if (!enabled) return;
|
|
3693
5421
|
event.stopPropagation();
|
|
5422
|
+
event.preventDefault();
|
|
3694
5423
|
if (event.shiftKey) {
|
|
3695
5424
|
commit();
|
|
3696
|
-
|
|
5425
|
+
setSelectedGuideIdsPersisted(
|
|
3697
5426
|
(prev) => prev.includes(guide.id) ? prev.filter((id) => id !== guide.id) : [...prev, guide.id]
|
|
3698
5427
|
);
|
|
3699
5428
|
return;
|
|
3700
5429
|
}
|
|
3701
5430
|
commit();
|
|
3702
|
-
|
|
5431
|
+
setSelectedGuideIdsPersisted([guide.id]);
|
|
3703
5432
|
scheduleGuideDragHold(guide.id, setDraggingGuideId);
|
|
3704
5433
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
3705
5434
|
},
|
|
@@ -3708,10 +5437,10 @@ function MeasurerClient({
|
|
|
3708
5437
|
enabled,
|
|
3709
5438
|
scheduleGuideDragHold,
|
|
3710
5439
|
setDraggingGuideId,
|
|
3711
|
-
|
|
5440
|
+
setSelectedGuideIdsPersisted
|
|
3712
5441
|
]
|
|
3713
5442
|
);
|
|
3714
|
-
const handleGuidePointerUp = (0,
|
|
5443
|
+
const handleGuidePointerUp = (0, import_react20.useCallback)(
|
|
3715
5444
|
(guide, event) => {
|
|
3716
5445
|
event.stopPropagation();
|
|
3717
5446
|
clearGuideDragHold();
|
|
@@ -3723,17 +5452,29 @@ function MeasurerClient({
|
|
|
3723
5452
|
[clearGuideDragHold, setDraggingGuideId]
|
|
3724
5453
|
);
|
|
3725
5454
|
return (0, import_react_dom.createPortal)(
|
|
3726
|
-
/* @__PURE__ */ (0,
|
|
5455
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3727
5456
|
"div",
|
|
3728
5457
|
{
|
|
3729
5458
|
ref: overlayRef,
|
|
3730
5459
|
className: "mesurer-root msr:pointer-events-none msr:fixed msr:inset-0 msr:z-50",
|
|
3731
5460
|
children: [
|
|
3732
|
-
/* @__PURE__ */ (0,
|
|
5461
|
+
enabled && rulersVisible ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5462
|
+
RulersOverlay,
|
|
5463
|
+
{
|
|
5464
|
+
onStartGuide: startGuideFromRuler,
|
|
5465
|
+
onMoveGuide: moveGuideFromRuler,
|
|
5466
|
+
onFinishGuide: finishGuideFromRuler,
|
|
5467
|
+
onCancelGuide: cancelGuideFromRuler,
|
|
5468
|
+
guides,
|
|
5469
|
+
selectedGuideIds
|
|
5470
|
+
}
|
|
5471
|
+
) : null,
|
|
5472
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3733
5473
|
MeasurerOverlay,
|
|
3734
5474
|
{
|
|
3735
5475
|
enabled,
|
|
3736
5476
|
toolMode,
|
|
5477
|
+
guidePointerEvents: enabled && (toolMode !== "none" || rulersVisible),
|
|
3737
5478
|
guidesEnabled,
|
|
3738
5479
|
altPressed,
|
|
3739
5480
|
isDragging,
|
|
@@ -3771,13 +5512,16 @@ function MeasurerClient({
|
|
|
3771
5512
|
onGuidePointerCancel: handleGuidePointerUp
|
|
3772
5513
|
}
|
|
3773
5514
|
),
|
|
3774
|
-
/* @__PURE__ */ (0,
|
|
5515
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3775
5516
|
Toolbar,
|
|
3776
5517
|
{
|
|
3777
5518
|
ref: toolbarRef,
|
|
5519
|
+
eventTarget: ownerWindow,
|
|
3778
5520
|
toolMode,
|
|
3779
5521
|
setEnabled: setEnabledWithHistory,
|
|
3780
5522
|
setToolMode: setToolModeWithHistory,
|
|
5523
|
+
rulersVisible,
|
|
5524
|
+
setRulersVisible: setRulersVisiblePersisted,
|
|
3781
5525
|
guideOrientation,
|
|
3782
5526
|
setGuideOrientation: setGuideOrientationWithHistory,
|
|
3783
5527
|
onInteract: () => setToolbarActive(true)
|
|
@@ -3794,25 +5538,29 @@ function Measurer({
|
|
|
3794
5538
|
guideColor = "oklch(0.63 0.26 29.23)",
|
|
3795
5539
|
hoverHighlightEnabled = true,
|
|
3796
5540
|
persistOnReload = false,
|
|
3797
|
-
portalTarget
|
|
5541
|
+
portalTarget,
|
|
5542
|
+
persistKey
|
|
3798
5543
|
}) {
|
|
3799
5544
|
if (typeof document !== "undefined") {
|
|
3800
5545
|
ensureMeasurerStyles(MESURER_STYLES, portalTarget);
|
|
3801
5546
|
}
|
|
3802
5547
|
const hydrated = useHydrated();
|
|
3803
5548
|
if (!hydrated) return null;
|
|
3804
|
-
return /* @__PURE__ */ (0,
|
|
5549
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3805
5550
|
MeasurerClient,
|
|
3806
5551
|
{
|
|
3807
5552
|
highlightColor,
|
|
3808
5553
|
guideColor,
|
|
3809
5554
|
hoverHighlightEnabled,
|
|
3810
5555
|
persistOnReload,
|
|
5556
|
+
persistKey,
|
|
3811
5557
|
portalTarget: portalTarget ?? document.body
|
|
3812
5558
|
}
|
|
3813
5559
|
);
|
|
3814
5560
|
}
|
|
3815
5561
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3816
5562
|
0 && (module.exports = {
|
|
3817
|
-
Measurer
|
|
5563
|
+
Measurer,
|
|
5564
|
+
TextInspector,
|
|
5565
|
+
createTextInspector
|
|
3818
5566
|
});
|