mesurer 0.0.9 → 0.0.10
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 +9 -0
- package/README.md +28 -7
- package/dist/index.cjs +2388 -539
- package/dist/index.d.cts +132 -2
- package/dist/index.d.ts +132 -2
- package/dist/index.js +2361 -515
- package/dist/styles.css +484 -0
- package/package.json +9 -8
package/dist/index.cjs
CHANGED
|
@@ -20,14 +20,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
MESURER_STORAGE_VERSION: () => MESURER_STORAGE_VERSION,
|
|
23
24
|
Measurer: () => Measurer,
|
|
24
25
|
TextInspector: () => TextInspector,
|
|
25
|
-
|
|
26
|
+
createLocalStoragePersistence: () => createLocalStoragePersistence,
|
|
27
|
+
createTextInspector: () => createTextInspector,
|
|
28
|
+
normalizeStoredSettings: () => normalizeStoredSettings,
|
|
29
|
+
normalizeStoredWorkspace: () => normalizeStoredWorkspace
|
|
26
30
|
});
|
|
27
31
|
module.exports = __toCommonJS(index_exports);
|
|
28
32
|
|
|
29
33
|
// measurer.tsx
|
|
30
|
-
var
|
|
34
|
+
var import_react23 = require("react");
|
|
31
35
|
var import_react_dom = require("react-dom");
|
|
32
36
|
|
|
33
37
|
// core/constants.ts
|
|
@@ -74,19 +78,760 @@ function ensureMeasurerStyles(cssText, target) {
|
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
// styles.generated.ts
|
|
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';
|
|
81
|
+
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-red-50: oklch(97.1% 0.013 17.38);\n --msr-color-red-200: oklch(88.5% 0.062 18.334);\n --msr-color-red-600: oklch(57.7% 0.245 27.325);\n --msr-color-black: #000;\n --msr-color-white: #fff;\n --msr-spacing: 0.25rem;\n --msr-font-weight-normal: 400;\n --msr-font-weight-medium: 500;\n --msr-font-weight-semibold: 600;\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-500: var(--color-ink-500);\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-1 {\n right: calc(var(--msr-spacing) * -1);\n }\n .msr\\:right-0 {\n right: calc(var(--msr-spacing) * 0);\n }\n .msr\\:right-\\[8px\\] {\n right: 8px;\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-\\[8px\\] {\n left: 8px;\n }\n .msr\\:left-\\[18px\\] {\n left: 18px;\n }\n .msr\\:z-10 {\n z-index: 10;\n }\n .msr\\:z-50 {\n z-index: 50;\n }\n .msr\\:z-\\[70\\] {\n z-index: 70;\n }\n .msr\\:z-\\[80\\] {\n z-index: 80;\n }\n .msr\\:z-\\[90\\] {\n z-index: 90;\n }\n .msr\\:col-span-2 {\n grid-column: span 2 / span 2;\n }\n .msr\\:mt-2 {\n margin-top: calc(var(--msr-spacing) * 2);\n }\n .msr\\:mb-1 {\n margin-bottom: calc(var(--msr-spacing) * 1);\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\\:ml-1 {\n margin-left: calc(var(--msr-spacing) * 1);\n }\n .msr\\:box-border {\n box-sizing: border-box;\n }\n .msr\\:block {\n display: block;\n }\n .msr\\:flex {\n display: flex;\n }\n .msr\\:grid {\n display: grid;\n }\n .msr\\:inline-flex {\n display: inline-flex;\n }\n .msr\\:size-3 {\n width: calc(var(--msr-spacing) * 3);\n height: calc(var(--msr-spacing) * 3);\n }\n .msr\\:size-4 {\n width: calc(var(--msr-spacing) * 4);\n height: calc(var(--msr-spacing) * 4);\n }\n .msr\\:size-8 {\n width: calc(var(--msr-spacing) * 8);\n height: calc(var(--msr-spacing) * 8);\n }\n .msr\\:size-\\[10px\\] {\n width: 10px;\n height: 10px;\n }\n .msr\\:size-\\[18px\\] {\n width: 18px;\n height: 18px;\n }\n .msr\\:size-full {\n width: 100%;\n height: 100%;\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-\\[14px\\] {\n height: 14px;\n }\n .msr\\:h-full {\n height: 100%;\n }\n .msr\\:h-px {\n height: 1px;\n }\n .msr\\:max-h-\\[min\\(70vh\\,34rem\\)\\] {\n max-height: min(70vh, 34rem);\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-9 {\n width: calc(var(--msr-spacing) * 9);\n }\n .msr\\:w-12 {\n width: calc(var(--msr-spacing) * 12);\n }\n .msr\\:w-44 {\n width: calc(var(--msr-spacing) * 44);\n }\n .msr\\:w-\\[18px\\] {\n width: 18px;\n }\n .msr\\:w-\\[26px\\] {\n width: 26px;\n }\n .msr\\:w-\\[272px\\] {\n width: 272px;\n }\n .msr\\:w-full {\n width: 100%;\n }\n .msr\\:w-px {\n width: 1px;\n }\n .msr\\:max-w-\\[calc\\(100vw-16px\\)\\] {\n max-width: calc(100vw - 16px);\n }\n .msr\\:min-w-0 {\n min-width: calc(var(--msr-spacing) * 0);\n }\n .msr\\:min-w-36 {\n min-width: calc(var(--msr-spacing) * 36);\n }\n .msr\\:flex-1 {\n flex: 1;\n }\n .msr\\:shrink-0 {\n flex-shrink: 0;\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\\:cursor-pointer {\n cursor: pointer;\n }\n .msr\\:touch-none {\n touch-action: none;\n }\n .msr\\:appearance-none {\n appearance: none;\n }\n .msr\\:grid-cols-\\[78px_156px\\] {\n grid-template-columns: 78px 156px;\n }\n .msr\\:flex-col {\n flex-direction: column;\n }\n .msr\\:items-center {\n align-items: center;\n }\n .msr\\:items-start {\n align-items: flex-start;\n }\n .msr\\:items-stretch {\n align-items: stretch;\n }\n .msr\\:justify-between {\n justify-content: space-between;\n }\n .msr\\:justify-center {\n justify-content: center;\n }\n .msr\\:justify-end {\n justify-content: flex-end;\n }\n .msr\\:gap-0 {\n gap: calc(var(--msr-spacing) * 0);\n }\n .msr\\:gap-1 {\n gap: calc(var(--msr-spacing) * 1);\n }\n .msr\\:gap-1\\.5 {\n gap: calc(var(--msr-spacing) * 1.5);\n }\n .msr\\:gap-2 {\n gap: calc(var(--msr-spacing) * 2);\n }\n .msr\\:gap-3 {\n gap: calc(var(--msr-spacing) * 3);\n }\n .msr\\:gap-px {\n gap: 1px;\n }\n .msr\\:gap-x-3 {\n column-gap: calc(var(--msr-spacing) * 3);\n }\n .msr\\:gap-y-1 {\n row-gap: calc(var(--msr-spacing) * 1);\n }\n .msr\\:justify-self-end {\n justify-self: flex-end;\n }\n .msr\\:overflow-hidden {\n overflow: hidden;\n }\n .msr\\:overflow-y-auto {\n overflow-y: auto;\n }\n .msr\\:rounded {\n border-radius: 0.25rem;\n }\n .msr\\:rounded-\\[3px\\] {\n border-radius: 3px;\n }\n .msr\\:rounded-\\[5px\\] {\n border-radius: 5px;\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-full {\n border-radius: calc(infinity * 1px);\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-0 {\n border-style: var(--tw-border-style);\n border-width: 0px;\n }\n .msr\\:border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n }\n .msr\\:border-t-2 {\n border-top-style: var(--tw-border-style);\n border-top-width: 2px;\n }\n .msr\\:border-b {\n border-bottom-style: var(--tw-border-style);\n border-bottom-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-dotted {\n --tw-border-style: dotted;\n border-style: dotted;\n }\n .msr\\:border-solid {\n --tw-border-style: solid;\n border-style: solid;\n }\n .msr\\:border-\\[\\#0d99ff\\] {\n border-color: #0d99ff;\n }\n .msr\\:border-\\[\\#2563eb\\]\\/70 {\n border-color: color-mix(in oklab, #2563eb 70%, transparent);\n }\n .msr\\:border-black\\/8 {\n border-color: var(--msr-color-black);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--msr-color-black) 8%, transparent);\n }\n }\n .msr\\:border-black\\/10 {\n border-color: var(--msr-color-black);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--msr-color-black) 10%, transparent);\n }\n }\n .msr\\:border-black\\/15 {\n border-color: var(--msr-color-black);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--msr-color-black) 15%, transparent);\n }\n }\n .msr\\:border-ink-200 {\n border-color: var(--msr-color-ink-200);\n }\n .msr\\:border-ink-700 {\n border-color: var(--msr-color-ink-700);\n }\n .msr\\:border-red-200 {\n border-color: var(--msr-color-red-200);\n }\n .msr\\:border-transparent {\n border-color: transparent;\n }\n .msr\\:bg-\\[\\#0d99ff\\] {\n background-color: #0d99ff;\n }\n .msr\\:bg-\\[\\#0d99ff\\]\\/10 {\n background-color: color-mix(in oklab, #0d99ff 10%, transparent);\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-50 {\n background-color: var(--msr-color-ink-50);\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\\:p-3 {\n padding: calc(var(--msr-spacing) * 3);\n }\n .msr\\:p-px {\n padding: 1px;\n }\n .msr\\:px-1 {\n padding-inline: calc(var(--msr-spacing) * 1);\n }\n .msr\\:px-1\\.5 {\n padding-inline: calc(var(--msr-spacing) * 1.5);\n }\n .msr\\:px-2 {\n padding-inline: calc(var(--msr-spacing) * 2);\n }\n .msr\\:py-0 {\n padding-block: calc(var(--msr-spacing) * 0);\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\\:py-2 {\n padding-block: calc(var(--msr-spacing) * 2);\n }\n .msr\\:pb-1 {\n padding-bottom: calc(var(--msr-spacing) * 1);\n }\n .msr\\:text-center {\n text-align: center;\n }\n .msr\\:text-left {\n text-align: left;\n }\n .msr\\:font-mono {\n font-family: var(--msr-font-mono);\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\\:leading-4 {\n --tw-leading: calc(var(--msr-spacing) * 4);\n line-height: calc(var(--msr-spacing) * 4);\n }\n .msr\\:leading-none {\n --tw-leading: 1;\n line-height: 1;\n }\n .msr\\:font-medium {\n --tw-font-weight: var(--msr-font-weight-medium);\n font-weight: var(--msr-font-weight-medium);\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-black\\/45 {\n color: var(--msr-color-black);\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, var(--msr-color-black) 45%, transparent);\n }\n }\n .msr\\:text-black\\/60 {\n color: var(--msr-color-black);\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, var(--msr-color-black) 60%, transparent);\n }\n }\n .msr\\:text-ink-50 {\n color: var(--msr-color-ink-50);\n }\n .msr\\:text-ink-500 {\n color: var(--msr-color-ink-500);\n }\n .msr\\:text-ink-700 {\n color: var(--msr-color-ink-700);\n }\n .msr\\:text-ink-900 {\n color: var(--msr-color-ink-900);\n }\n .msr\\:text-red-600 {\n color: var(--msr-color-red-600);\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\\:shadow-\\[0_0_0_1px_rgba\\(15\\,23\\,42\\,0\\.12\\)\\] {\n --tw-shadow: 0 0 0 1px var(--tw-shadow-color, rgba(15,23,42,0.12));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .msr\\:shadow-lg {\n --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .msr\\:shadow-sm {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .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-colors {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\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-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-shadow {\n transition-property: box-shadow;\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-transform {\n transition-property: transform, translate, scale, rotate;\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\\:group-hover\\:border-ink-200 {\n &:is(:where(.msr\\:group):hover *) {\n @media (hover: hover) {\n border-color: var(--msr-color-ink-200);\n }\n }\n }\n .msr\\:focus-within\\:rounded-l-\\[5px\\] {\n &:focus-within {\n border-top-left-radius: 5px;\n border-bottom-left-radius: 5px;\n }\n }\n .msr\\:focus-within\\:rounded-r-\\[5px\\] {\n &:focus-within {\n border-top-right-radius: 5px;\n border-bottom-right-radius: 5px;\n }\n }\n .msr\\:focus-within\\:outline {\n &:focus-within {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n }\n .msr\\:focus-within\\:outline-1 {\n &:focus-within {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n }\n .msr\\:focus-within\\:outline-offset-\\[-1px\\] {\n &:focus-within {\n outline-offset: -1px;\n }\n }\n .msr\\:focus-within\\:outline-\\[\\#0d99ff\\] {\n &:focus-within {\n outline-color: #0d99ff;\n }\n }\n .msr\\:hover\\:border-ink-200 {\n &:hover {\n @media (hover: hover) {\n border-color: var(--msr-color-ink-200);\n }\n }\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\\:bg-ink-50 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--msr-color-ink-50);\n }\n }\n }\n .msr\\:hover\\:bg-red-50 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--msr-color-red-50);\n }\n }\n }\n .msr\\:hover\\:text-black {\n &:hover {\n @media (hover: hover) {\n color: var(--msr-color-black);\n }\n }\n }\n .msr\\:hover\\:text-ink-700 {\n &:hover {\n @media (hover: hover) {\n color: var(--msr-color-ink-700);\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\\:hover\\:underline {\n &:hover {\n @media (hover: hover) {\n text-decoration-line: underline;\n }\n }\n }\n .msr\\:focus\\:shadow-\\[inset_0_0_0_1px_\\#0d99ff\\] {\n &:focus {\n --tw-shadow: inset 0 0 0 1px var(--tw-shadow-color, #0d99ff);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n .msr\\:focus\\:outline-none {\n &:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n }\n .msr\\:focus-visible\\:shadow-\\[inset_0_0_0_1px_\\#0d99ff\\] {\n &:focus-visible {\n --tw-shadow: inset 0 0 0 1px var(--tw-shadow-color, #0d99ff);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n .msr\\:focus-visible\\:shadow-\\[inset_0_0_0_1px_\\#ef4444\\] {\n &:focus-visible {\n --tw-shadow: inset 0 0 0 1px var(--tw-shadow-color, #ef4444);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n .msr\\:focus-visible\\:ring-1 {\n &:focus-visible {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n .msr\\:focus-visible\\:ring-\\[\\#0d99ff\\]\\/25 {\n &:focus-visible {\n --tw-ring-color: color-mix(in oklab, #0d99ff 25%, transparent);\n }\n }\n .msr\\:focus-visible\\:outline-none {\n &:focus-visible {\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-leading {\n syntax: "*";\n inherits: false;\n}\n@property --tw-font-weight {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ordinal {\n syntax: "*";\n inherits: false;\n}\n@property --tw-slashed-zero {\n syntax: "*";\n inherits: false;\n}\n@property --tw-numeric-figure {\n syntax: "*";\n inherits: false;\n}\n@property --tw-numeric-spacing {\n syntax: "*";\n inherits: false;\n}\n@property --tw-numeric-fraction {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: "<percentage>";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: "<percentage>";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: "<length>";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: "*";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-outline-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-duration {\n syntax: "*";\n inherits: false;\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-border-style: solid;\n --tw-leading: initial;\n --tw-font-weight: initial;\n --tw-ordinal: initial;\n --tw-slashed-zero: initial;\n --tw-numeric-figure: initial;\n --tw-numeric-spacing: initial;\n --tw-numeric-fraction: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-outline-style: solid;\n --tw-duration: initial;\n }\n }\n}\n';
|
|
78
82
|
|
|
79
83
|
// components/toolbar.tsx
|
|
80
|
-
var
|
|
84
|
+
var import_react3 = require("react");
|
|
81
85
|
|
|
82
86
|
// core/utils.ts
|
|
83
87
|
var formatValue = (value) => Math.round(value);
|
|
84
88
|
var cn = (...inputs) => inputs.filter(Boolean).join(" ");
|
|
85
89
|
var createId = () => typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`;
|
|
86
90
|
|
|
87
|
-
// components/
|
|
91
|
+
// components/settings-panel.tsx
|
|
92
|
+
var import_react2 = require("react");
|
|
93
|
+
|
|
94
|
+
// package.json
|
|
95
|
+
var package_default = {
|
|
96
|
+
name: "mesurer",
|
|
97
|
+
version: "0.0.10",
|
|
98
|
+
description: "Measure and align elements on any website.",
|
|
99
|
+
license: "MIT",
|
|
100
|
+
author: "Julien Thibeaut",
|
|
101
|
+
type: "module",
|
|
102
|
+
main: "./dist/index.cjs",
|
|
103
|
+
module: "./dist/index.js",
|
|
104
|
+
types: "./dist/index.d.ts",
|
|
105
|
+
exports: {
|
|
106
|
+
".": {
|
|
107
|
+
types: "./dist/index.d.ts",
|
|
108
|
+
import: "./dist/index.js",
|
|
109
|
+
require: "./dist/index.cjs"
|
|
110
|
+
},
|
|
111
|
+
"./styles.css": "./dist/styles.css",
|
|
112
|
+
"./package.json": "./package.json"
|
|
113
|
+
},
|
|
114
|
+
files: [
|
|
115
|
+
"dist",
|
|
116
|
+
"dist/styles.css",
|
|
117
|
+
"CHANGELOG.md",
|
|
118
|
+
"README.md",
|
|
119
|
+
"LICENSE"
|
|
120
|
+
],
|
|
121
|
+
sideEffects: [
|
|
122
|
+
"*.css"
|
|
123
|
+
],
|
|
124
|
+
publishConfig: {
|
|
125
|
+
access: "public"
|
|
126
|
+
},
|
|
127
|
+
homepage: "https://mesurer.dev",
|
|
128
|
+
repository: {
|
|
129
|
+
type: "git",
|
|
130
|
+
url: "https://github.com/ibelick/mesurer.git"
|
|
131
|
+
},
|
|
132
|
+
bugs: {
|
|
133
|
+
url: "https://github.com/ibelick/mesurer/issues"
|
|
134
|
+
},
|
|
135
|
+
scripts: {
|
|
136
|
+
build: "pnpm exec tailwindcss -i styles.css -o styles.generated.css && node scripts/generate-styles.mjs && tsup && pnpm exec tailwindcss -i styles.css -o dist/styles.css",
|
|
137
|
+
dev: "node scripts/dev.mjs",
|
|
138
|
+
typecheck: "tsc --noEmit",
|
|
139
|
+
prepublishOnly: "npm run typecheck && npm run build"
|
|
140
|
+
},
|
|
141
|
+
peerDependencies: {
|
|
142
|
+
react: ">=18.0.0",
|
|
143
|
+
"react-dom": ">=18.0.0"
|
|
144
|
+
},
|
|
145
|
+
devDependencies: {
|
|
146
|
+
"@tailwindcss/cli": "^4.2.2",
|
|
147
|
+
"@types/react": "^19.0.0",
|
|
148
|
+
"@types/react-dom": "^19.0.0",
|
|
149
|
+
react: "^19.0.0",
|
|
150
|
+
"react-dom": "^19.0.0",
|
|
151
|
+
tailwindcss: "^4.2.2",
|
|
152
|
+
tsup: "^8.5.0",
|
|
153
|
+
typescript: "^5.9.2"
|
|
154
|
+
},
|
|
155
|
+
keywords: [
|
|
156
|
+
"measurement",
|
|
157
|
+
"alignment"
|
|
158
|
+
]
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// core/colors.ts
|
|
162
|
+
var clamp = (value, min = 0, max = 1) => Math.min(max, Math.max(min, value));
|
|
163
|
+
var round = (value, digits = 2) => {
|
|
164
|
+
const factor = 10 ** digits;
|
|
165
|
+
return Math.round(value * factor) / factor;
|
|
166
|
+
};
|
|
167
|
+
var parseChannel = (value) => {
|
|
168
|
+
const trimmed = value.trim();
|
|
169
|
+
const numeric = trimmed.endsWith("%") ? trimmed.slice(0, -1).trim() : trimmed;
|
|
170
|
+
if (!/^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(numeric)) return null;
|
|
171
|
+
const parsed = Number.parseFloat(numeric);
|
|
172
|
+
if (!Number.isFinite(parsed)) return null;
|
|
173
|
+
if (trimmed.endsWith("%")) return clamp(parsed / 100) * 255;
|
|
174
|
+
return clamp(parsed / 255) * 255;
|
|
175
|
+
};
|
|
176
|
+
var parseAlpha = (value) => {
|
|
177
|
+
if (!value) return 1;
|
|
178
|
+
const trimmed = value.trim();
|
|
179
|
+
const numeric = trimmed.endsWith("%") ? trimmed.slice(0, -1).trim() : trimmed;
|
|
180
|
+
if (!/^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(numeric)) return null;
|
|
181
|
+
const parsed = Number.parseFloat(numeric);
|
|
182
|
+
if (!Number.isFinite(parsed)) return null;
|
|
183
|
+
return clamp(trimmed.endsWith("%") ? parsed / 100 : parsed);
|
|
184
|
+
};
|
|
185
|
+
var parseCssColor = (value) => {
|
|
186
|
+
const input = value.trim().toLowerCase();
|
|
187
|
+
if (!input || input === "transparent") return null;
|
|
188
|
+
if (input.startsWith("#")) {
|
|
189
|
+
const hex = input.slice(1);
|
|
190
|
+
const expanded = hex.length === 3 || hex.length === 4 ? hex.split("").map((digit) => digit + digit).join("") : hex;
|
|
191
|
+
if (![6, 8].includes(expanded.length) || !/^[\da-f]+$/.test(expanded)) return null;
|
|
192
|
+
return {
|
|
193
|
+
red: Number.parseInt(expanded.slice(0, 2), 16),
|
|
194
|
+
green: Number.parseInt(expanded.slice(2, 4), 16),
|
|
195
|
+
blue: Number.parseInt(expanded.slice(4, 6), 16),
|
|
196
|
+
alpha: expanded.length === 8 ? Number.parseInt(expanded.slice(6, 8), 16) / 255 : 1
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const match = input.match(/^rgba?\((.*)\)$/);
|
|
200
|
+
if (!match) return null;
|
|
201
|
+
const channels = match[1].replace(/\//g, " ").split(/[ ,]+/).filter(Boolean);
|
|
202
|
+
if (channels.length < 3 || channels.length > 4) return null;
|
|
203
|
+
const red = parseChannel(channels[0]);
|
|
204
|
+
const green = parseChannel(channels[1]);
|
|
205
|
+
const blue = parseChannel(channels[2]);
|
|
206
|
+
const alpha = parseAlpha(channels[3]);
|
|
207
|
+
if (red === null || green === null || blue === null || alpha === null) return null;
|
|
208
|
+
return { red, green, blue, alpha };
|
|
209
|
+
};
|
|
210
|
+
var toByte = (value) => Math.round(clamp(value / 255) * 255);
|
|
211
|
+
var colorToHex = (color) => {
|
|
212
|
+
const hex = [color.red, color.green, color.blue].map((channel) => toByte(channel).toString(16).padStart(2, "0")).join("");
|
|
213
|
+
if (color.alpha >= 0.999) return `#${hex}`;
|
|
214
|
+
return `#${hex}${Math.round(color.alpha * 255).toString(16).padStart(2, "0")}`;
|
|
215
|
+
};
|
|
216
|
+
var colorToRgb = (color) => {
|
|
217
|
+
const channels = `${toByte(color.red)}, ${toByte(color.green)}, ${toByte(color.blue)}`;
|
|
218
|
+
return color.alpha >= 0.999 ? `rgb(${channels})` : `rgba(${channels}, ${round(color.alpha, 3)})`;
|
|
219
|
+
};
|
|
220
|
+
var colorToHsl = (color) => {
|
|
221
|
+
const red = color.red / 255;
|
|
222
|
+
const green = color.green / 255;
|
|
223
|
+
const blue = color.blue / 255;
|
|
224
|
+
const max = Math.max(red, green, blue);
|
|
225
|
+
const min = Math.min(red, green, blue);
|
|
226
|
+
const lightness = (max + min) / 2;
|
|
227
|
+
const delta = max - min;
|
|
228
|
+
let hue = 0;
|
|
229
|
+
let saturation = 0;
|
|
230
|
+
if (delta !== 0) {
|
|
231
|
+
saturation = delta / (1 - Math.abs(2 * lightness - 1));
|
|
232
|
+
if (max === red) hue = (green - blue) / delta % 6;
|
|
233
|
+
else if (max === green) hue = (blue - red) / delta + 2;
|
|
234
|
+
else hue = (red - green) / delta + 4;
|
|
235
|
+
hue *= 60;
|
|
236
|
+
if (hue < 0) hue += 360;
|
|
237
|
+
}
|
|
238
|
+
const result = `hsl(${round(hue, 1)} ${round(saturation * 100, 1)}% ${round(lightness * 100, 1)}%`;
|
|
239
|
+
return color.alpha >= 0.999 ? `${result})` : `${result} / ${round(color.alpha, 3)})`;
|
|
240
|
+
};
|
|
241
|
+
var linearize = (value) => {
|
|
242
|
+
const normalized = value / 255;
|
|
243
|
+
return normalized <= 0.04045 ? normalized / 12.92 : ((normalized + 0.055) / 1.055) ** 2.4;
|
|
244
|
+
};
|
|
245
|
+
var colorToOklch = (color) => {
|
|
246
|
+
const red = linearize(color.red);
|
|
247
|
+
const green = linearize(color.green);
|
|
248
|
+
const blue = linearize(color.blue);
|
|
249
|
+
const l = 0.4122214708 * red + 0.5363325363 * green + 0.0514459929 * blue;
|
|
250
|
+
const m = 0.2119034982 * red + 0.6806995451 * green + 0.1073969566 * blue;
|
|
251
|
+
const s = 0.0883024619 * red + 0.2817188376 * green + 0.6299787005 * blue;
|
|
252
|
+
const lRoot = Math.cbrt(l);
|
|
253
|
+
const mRoot = Math.cbrt(m);
|
|
254
|
+
const sRoot = Math.cbrt(s);
|
|
255
|
+
const lightness = 0.2104542553 * lRoot + 0.793617785 * mRoot - 0.0040720468 * sRoot;
|
|
256
|
+
const a = 1.9779984951 * lRoot - 2.428592205 * mRoot + 0.4505937099 * sRoot;
|
|
257
|
+
const b = 0.0259040371 * lRoot + 0.7827717662 * mRoot - 0.808675766 * sRoot;
|
|
258
|
+
const chroma = Math.sqrt(a * a + b * b);
|
|
259
|
+
let hue = Math.atan2(b, a) * 180 / Math.PI;
|
|
260
|
+
if (hue < 0) hue += 360;
|
|
261
|
+
const result = `oklch(${round(lightness, 3)} ${round(chroma, 3)} ${round(hue, 1)}`;
|
|
262
|
+
return color.alpha >= 0.999 ? `${result})` : `${result} / ${round(color.alpha, 3)})`;
|
|
263
|
+
};
|
|
264
|
+
var formatColor = (color, format) => {
|
|
265
|
+
if (format === "hex") return colorToHex(color);
|
|
266
|
+
if (format === "rgb") return colorToRgb(color);
|
|
267
|
+
if (format === "hsl") return colorToHsl(color);
|
|
268
|
+
return colorToOklch(color);
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
// components/tooltip.tsx
|
|
272
|
+
var import_react = require("react");
|
|
88
273
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
89
|
-
var
|
|
274
|
+
var TOOLTIP_DELAY_MS = 800;
|
|
275
|
+
function Tooltip({
|
|
276
|
+
label,
|
|
277
|
+
shortcut,
|
|
278
|
+
visible,
|
|
279
|
+
instant = false,
|
|
280
|
+
side = "top",
|
|
281
|
+
className
|
|
282
|
+
}) {
|
|
283
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
284
|
+
"span",
|
|
285
|
+
{
|
|
286
|
+
role: "tooltip",
|
|
287
|
+
className: cn(
|
|
288
|
+
"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",
|
|
289
|
+
instant && "msr:transition-none",
|
|
290
|
+
side === "top" ? "msr:bottom-full msr:mb-2" : "msr:top-full msr:mt-2",
|
|
291
|
+
visible === void 0 ? null : visible ? "msr:opacity-100" : "msr:opacity-0",
|
|
292
|
+
className
|
|
293
|
+
),
|
|
294
|
+
children: [
|
|
295
|
+
label,
|
|
296
|
+
shortcut ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
297
|
+
" ",
|
|
298
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("kbd", { className: "msr:text-white/60", children: shortcut })
|
|
299
|
+
] }) : null
|
|
300
|
+
]
|
|
301
|
+
}
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
function useTooltip() {
|
|
305
|
+
const [visibleTooltipId, setVisibleTooltipId] = (0, import_react.useState)(null);
|
|
306
|
+
const timerRef = (0, import_react.useRef)(null);
|
|
307
|
+
const instantRef = (0, import_react.useRef)(false);
|
|
308
|
+
const [tooltipInstant, setTooltipInstant] = (0, import_react.useState)(false);
|
|
309
|
+
const clearTimer = (0, import_react.useCallback)(() => {
|
|
310
|
+
if (timerRef.current === null) return;
|
|
311
|
+
window.clearTimeout(timerRef.current);
|
|
312
|
+
timerRef.current = null;
|
|
313
|
+
}, []);
|
|
314
|
+
const onTooltipEnter = (0, import_react.useCallback)((id) => {
|
|
315
|
+
clearTimer();
|
|
316
|
+
if (instantRef.current) {
|
|
317
|
+
setTooltipInstant(true);
|
|
318
|
+
setVisibleTooltipId(id);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
setTooltipInstant(false);
|
|
322
|
+
timerRef.current = window.setTimeout(() => {
|
|
323
|
+
setVisibleTooltipId(id);
|
|
324
|
+
instantRef.current = true;
|
|
325
|
+
timerRef.current = null;
|
|
326
|
+
}, TOOLTIP_DELAY_MS);
|
|
327
|
+
}, [clearTimer]);
|
|
328
|
+
const onTooltipLeave = (0, import_react.useCallback)(() => {
|
|
329
|
+
clearTimer();
|
|
330
|
+
setVisibleTooltipId(null);
|
|
331
|
+
}, [clearTimer]);
|
|
332
|
+
const onTooltipContainerLeave = (0, import_react.useCallback)(() => {
|
|
333
|
+
clearTimer();
|
|
334
|
+
setVisibleTooltipId(null);
|
|
335
|
+
instantRef.current = false;
|
|
336
|
+
setTooltipInstant(false);
|
|
337
|
+
}, [clearTimer]);
|
|
338
|
+
return {
|
|
339
|
+
visibleTooltipId,
|
|
340
|
+
tooltipInstant,
|
|
341
|
+
onTooltipEnter,
|
|
342
|
+
onTooltipLeave,
|
|
343
|
+
onTooltipContainerLeave
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// components/settings-panel.tsx
|
|
348
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
349
|
+
var COLOR_FORMATS = ["hex", "rgb", "hsl", "oklch"];
|
|
350
|
+
var GUIDE_PATTERNS = [
|
|
351
|
+
{ value: "solid", label: "Solid" },
|
|
352
|
+
{ value: "dashed", label: "Dashed" },
|
|
353
|
+
{ value: "dotted", label: "Dotted" }
|
|
354
|
+
];
|
|
355
|
+
function ControlShell({ left, right }) {
|
|
356
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
357
|
+
"div",
|
|
358
|
+
{
|
|
359
|
+
className: "msr:group msr:flex msr:h-6 msr:w-full msr:min-w-0 msr:items-center msr:overflow-hidden msr:rounded-[5px] msr:border msr:border-transparent msr:bg-ink-50 msr:hover:border-ink-200",
|
|
360
|
+
children: [
|
|
361
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "msr:flex msr:h-full msr:min-w-0 msr:flex-1 msr:items-center msr:focus-within:rounded-l-[5px] msr:focus-within:outline msr:focus-within:outline-1 msr:focus-within:outline-[#0d99ff] msr:focus-within:outline-offset-[-1px]", children: left }),
|
|
362
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "msr:box-border msr:flex msr:h-full msr:w-12 msr:shrink-0 msr:items-center msr:border-l msr:border-transparent msr:group-hover:border-ink-200 msr:focus-within:rounded-r-[5px] msr:focus-within:outline msr:focus-within:outline-1 msr:focus-within:outline-[#0d99ff] msr:focus-within:outline-offset-[-1px]", children: right })
|
|
363
|
+
]
|
|
364
|
+
}
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
function SettingsSwitch({ label, checked, onChange }) {
|
|
368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
369
|
+
"button",
|
|
370
|
+
{
|
|
371
|
+
type: "button",
|
|
372
|
+
role: "switch",
|
|
373
|
+
"aria-checked": checked,
|
|
374
|
+
className: "msr:col-span-2 msr:grid msr:h-6 msr:w-full msr:grid-cols-[78px_156px] msr:items-center msr:gap-3 msr:text-left msr:text-[12px] msr:leading-none msr:text-ink-700",
|
|
375
|
+
onClick: () => onChange(!checked),
|
|
376
|
+
children: [
|
|
377
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: label }),
|
|
378
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
379
|
+
"span",
|
|
380
|
+
{
|
|
381
|
+
"aria-hidden": "true",
|
|
382
|
+
style: { justifySelf: "end" },
|
|
383
|
+
className: cn(
|
|
384
|
+
"msr:flex msr:h-[14px] msr:w-[26px] msr:shrink-0 msr:items-center msr:rounded-full msr:border msr:p-px msr:transition-colors",
|
|
385
|
+
checked ? "msr:border-[#0d99ff] msr:bg-[#0d99ff]" : "msr:border-ink-200 msr:bg-ink-50"
|
|
386
|
+
),
|
|
387
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
388
|
+
"span",
|
|
389
|
+
{
|
|
390
|
+
className: "msr:block msr:size-[10px] msr:shrink-0 msr:rounded-full msr:bg-white msr:shadow-sm msr:transition-transform",
|
|
391
|
+
style: { transform: `translateX(${checked ? 12 : 0}px)` }
|
|
392
|
+
}
|
|
393
|
+
)
|
|
394
|
+
}
|
|
395
|
+
)
|
|
396
|
+
]
|
|
397
|
+
}
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
function SliderControl({
|
|
401
|
+
label,
|
|
402
|
+
min,
|
|
403
|
+
max,
|
|
404
|
+
step,
|
|
405
|
+
value,
|
|
406
|
+
onChange,
|
|
407
|
+
formatValue: formatValue4 = (currentValue) => String(currentValue),
|
|
408
|
+
parseInput = (input) => Number(input)
|
|
409
|
+
}) {
|
|
410
|
+
const thumbSize = 12;
|
|
411
|
+
const thumbInset = 8;
|
|
412
|
+
const percentage = (value - min) / (max - min) * 100;
|
|
413
|
+
const [draftValue, setDraftValue] = (0, import_react2.useState)(formatValue4(value));
|
|
414
|
+
const [editing, setEditing] = (0, import_react2.useState)(false);
|
|
415
|
+
const commitDraft = () => {
|
|
416
|
+
const parsed = parseInput(draftValue);
|
|
417
|
+
if (Number.isFinite(parsed)) {
|
|
418
|
+
onChange(Math.min(max, Math.max(min, parsed)));
|
|
419
|
+
}
|
|
420
|
+
const next = Number.isFinite(parsed) ? Math.min(max, Math.max(min, parsed)) : value;
|
|
421
|
+
setDraftValue(formatValue4(next));
|
|
422
|
+
setEditing(false);
|
|
423
|
+
};
|
|
424
|
+
const updateFromPointer = (event) => {
|
|
425
|
+
event.stopPropagation();
|
|
426
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
427
|
+
const usableWidth = Math.max(1, rect.width - thumbInset * 2);
|
|
428
|
+
const ratio = Math.min(1, Math.max(0, (event.clientX - rect.left - thumbInset) / usableWidth));
|
|
429
|
+
const rawValue = min + ratio * (max - min);
|
|
430
|
+
const steppedValue = Math.round((rawValue - min) / step) * step + min;
|
|
431
|
+
onChange(Number(steppedValue.toFixed(4)));
|
|
432
|
+
};
|
|
433
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "msr:col-span-2 msr:grid msr:w-full msr:grid-cols-[78px_156px] msr:items-center msr:gap-3", children: [
|
|
434
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "msr:text-[11px] msr:font-medium msr:text-ink-700", children: label }),
|
|
435
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
436
|
+
ControlShell,
|
|
437
|
+
{
|
|
438
|
+
left: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
439
|
+
"div",
|
|
440
|
+
{
|
|
441
|
+
className: "msr:relative msr:min-w-0 msr:flex-1 msr:touch-none msr:select-none msr:px-2",
|
|
442
|
+
style: { height: 20 },
|
|
443
|
+
"data-slider-container": "true",
|
|
444
|
+
onPointerDown: (event) => {
|
|
445
|
+
event.stopPropagation();
|
|
446
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
447
|
+
updateFromPointer(event);
|
|
448
|
+
},
|
|
449
|
+
onPointerMove: (event) => {
|
|
450
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) updateFromPointer(event);
|
|
451
|
+
},
|
|
452
|
+
onPointerUp: (event) => {
|
|
453
|
+
event.stopPropagation();
|
|
454
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
455
|
+
},
|
|
456
|
+
onPointerCancel: (event) => {
|
|
457
|
+
event.stopPropagation();
|
|
458
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
459
|
+
},
|
|
460
|
+
onClick: (event) => event.stopPropagation(),
|
|
461
|
+
children: [
|
|
462
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
463
|
+
"div",
|
|
464
|
+
{
|
|
465
|
+
className: "msr:absolute msr:left-[8px] msr:right-[8px] msr:rounded-full",
|
|
466
|
+
style: { top: 8, height: 4, backgroundColor: "rgba(15, 23, 42, 0.16)" },
|
|
467
|
+
"aria-hidden": "true"
|
|
468
|
+
}
|
|
469
|
+
),
|
|
470
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
471
|
+
"div",
|
|
472
|
+
{
|
|
473
|
+
className: "msr:absolute msr:left-[8px] msr:rounded-full",
|
|
474
|
+
style: { top: 8, width: `calc(${percentage}% - ${percentage * thumbInset * 2 / 100}px)`, height: 4, backgroundColor: "#0d99ff" },
|
|
475
|
+
"aria-hidden": "true"
|
|
476
|
+
}
|
|
477
|
+
),
|
|
478
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
479
|
+
"div",
|
|
480
|
+
{
|
|
481
|
+
className: "msr:absolute msr:rounded-[5px] msr:bg-white msr:shadow-sm msr:transition-shadow msr:outline-none msr:focus-visible:ring-1 msr:focus-visible:ring-[#0d99ff]/25",
|
|
482
|
+
style: {
|
|
483
|
+
left: `calc(8px + (100% - 16px) * ${percentage / 100})`,
|
|
484
|
+
top: 4,
|
|
485
|
+
width: thumbSize,
|
|
486
|
+
height: thumbSize,
|
|
487
|
+
border: "0",
|
|
488
|
+
transform: "translateX(-50%)"
|
|
489
|
+
},
|
|
490
|
+
role: "slider",
|
|
491
|
+
tabIndex: 0,
|
|
492
|
+
"aria-label": label,
|
|
493
|
+
"aria-valuemin": min,
|
|
494
|
+
"aria-valuemax": max,
|
|
495
|
+
"aria-valuenow": value,
|
|
496
|
+
"aria-orientation": "horizontal",
|
|
497
|
+
onKeyDown: (event) => {
|
|
498
|
+
event.stopPropagation();
|
|
499
|
+
const direction = event.key === "ArrowRight" || event.key === "ArrowUp" ? 1 : event.key === "ArrowLeft" || event.key === "ArrowDown" ? -1 : 0;
|
|
500
|
+
if (event.key === "Home") onChange(min);
|
|
501
|
+
else if (event.key === "End") onChange(max);
|
|
502
|
+
else if (direction) {
|
|
503
|
+
event.preventDefault();
|
|
504
|
+
onChange(Number(Math.min(max, Math.max(min, value + direction * step)).toFixed(4)));
|
|
505
|
+
} else return;
|
|
506
|
+
event.preventDefault();
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
)
|
|
510
|
+
]
|
|
511
|
+
}
|
|
512
|
+
),
|
|
513
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
514
|
+
"input",
|
|
515
|
+
{
|
|
516
|
+
type: "text",
|
|
517
|
+
"aria-label": `${label} value`,
|
|
518
|
+
className: "msr:h-full msr:w-full msr:shrink-0 msr:border-0 msr:bg-transparent msr:px-2 msr:text-center msr:font-mono msr:text-[12px] msr:font-medium msr:tabular-nums msr:text-ink-700 msr:outline-none",
|
|
519
|
+
style: { boxSizing: "border-box", borderRadius: "0 5px 5px 0", lineHeight: "1rem" },
|
|
520
|
+
value: editing ? draftValue : formatValue4(value),
|
|
521
|
+
onFocus: () => {
|
|
522
|
+
setDraftValue(formatValue4(value));
|
|
523
|
+
setEditing(true);
|
|
524
|
+
},
|
|
525
|
+
onChange: (event) => {
|
|
526
|
+
const nextDraft = event.target.value;
|
|
527
|
+
setDraftValue(nextDraft);
|
|
528
|
+
const next = parseInput(nextDraft);
|
|
529
|
+
if (Number.isFinite(next)) onChange(Math.min(max, Math.max(min, next)));
|
|
530
|
+
},
|
|
531
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
532
|
+
onClick: (event) => event.stopPropagation(),
|
|
533
|
+
onBlur: () => {
|
|
534
|
+
commitDraft();
|
|
535
|
+
},
|
|
536
|
+
onKeyDown: (event) => {
|
|
537
|
+
event.stopPropagation();
|
|
538
|
+
if (event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
539
|
+
event.preventDefault();
|
|
540
|
+
const current = parseInput(event.currentTarget.value);
|
|
541
|
+
const direction = event.key === "ArrowUp" ? 1 : -1;
|
|
542
|
+
const next = Number(
|
|
543
|
+
Math.min(max, Math.max(min, (Number.isFinite(current) ? current : value) + direction * step)).toFixed(4)
|
|
544
|
+
);
|
|
545
|
+
setDraftValue(formatValue4(next));
|
|
546
|
+
onChange(next);
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
if (event.key === "Enter") {
|
|
550
|
+
event.preventDefault();
|
|
551
|
+
event.currentTarget.blur();
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
)
|
|
556
|
+
}
|
|
557
|
+
)
|
|
558
|
+
] });
|
|
559
|
+
}
|
|
560
|
+
function ColorField({ label, value, fallback, ownerWindow, onChange }) {
|
|
561
|
+
const parsed = parseCssColor(value);
|
|
562
|
+
const canvas = ownerWindow.document.createElement("canvas");
|
|
563
|
+
const context = canvas.getContext("2d");
|
|
564
|
+
if (context) context.fillStyle = value;
|
|
565
|
+
const serialized = typeof context?.fillStyle === "string" ? context.fillStyle : "";
|
|
566
|
+
const converted = serialized ? parseCssColor(serialized) : null;
|
|
567
|
+
const inputValue = parsed ?? converted ? colorToHex(parsed ?? converted).slice(0, 7) : fallback;
|
|
568
|
+
const sample = parsed ?? converted ?? parseCssColor(fallback);
|
|
569
|
+
const hexValue = sample ? colorToHex({ ...sample, alpha: 1 }).slice(1).toUpperCase() : "000000";
|
|
570
|
+
const alphaValue = sample ? Math.round(sample.alpha * 100) : 100;
|
|
571
|
+
const [hexDraft, setHexDraft] = (0, import_react2.useState)(hexValue);
|
|
572
|
+
const [alphaDraft, setAlphaDraft] = (0, import_react2.useState)(String(alphaValue));
|
|
573
|
+
const [hexFocused, setHexFocused] = (0, import_react2.useState)(false);
|
|
574
|
+
const [alphaFocused, setAlphaFocused] = (0, import_react2.useState)(false);
|
|
575
|
+
const updateColor = (nextHex, nextAlpha) => {
|
|
576
|
+
if (!/^[\da-f]{6}$/i.test(nextHex)) return;
|
|
577
|
+
const nextSample = parseCssColor(`#${nextHex}`);
|
|
578
|
+
if (!nextSample) return;
|
|
579
|
+
onChange(colorToHex({ ...nextSample, alpha: Math.min(100, Math.max(0, nextAlpha)) / 100 }));
|
|
580
|
+
};
|
|
581
|
+
const swatchColor = ownerWindow.CSS?.supports("color", value) ? value : fallback;
|
|
582
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "msr:col-span-2 msr:grid msr:w-full msr:grid-cols-[78px_156px] msr:items-center msr:gap-3 msr:text-[12px] msr:text-ink-700", children: [
|
|
583
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: label }),
|
|
584
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
585
|
+
ControlShell,
|
|
586
|
+
{
|
|
587
|
+
left: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
588
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
589
|
+
"span",
|
|
590
|
+
{
|
|
591
|
+
className: "msr:relative msr:ml-1 msr:block msr:size-4 msr:shrink-0 msr:overflow-hidden msr:rounded-[3px] msr:border msr:border-black/10",
|
|
592
|
+
style: { backgroundColor: swatchColor },
|
|
593
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
594
|
+
"input",
|
|
595
|
+
{
|
|
596
|
+
type: "color",
|
|
597
|
+
"aria-label": `${label} color picker`,
|
|
598
|
+
value: inputValue,
|
|
599
|
+
className: "msr:absolute msr:inset-0 msr:size-full msr:cursor-pointer msr:opacity-0",
|
|
600
|
+
onChange: (event) => onChange(event.target.value)
|
|
601
|
+
}
|
|
602
|
+
)
|
|
603
|
+
}
|
|
604
|
+
),
|
|
605
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
606
|
+
"input",
|
|
607
|
+
{
|
|
608
|
+
"aria-label": `${label} hex value`,
|
|
609
|
+
type: "text",
|
|
610
|
+
value: hexFocused ? hexDraft : hexValue,
|
|
611
|
+
maxLength: 6,
|
|
612
|
+
className: "msr:min-w-0 msr:flex-1 msr:bg-transparent msr:px-2 msr:font-mono msr:text-[12px] msr:tabular-nums msr:text-ink-700 msr:outline-none",
|
|
613
|
+
onFocus: () => {
|
|
614
|
+
setHexDraft(hexValue);
|
|
615
|
+
setHexFocused(true);
|
|
616
|
+
},
|
|
617
|
+
onBlur: () => setHexFocused(false),
|
|
618
|
+
onChange: (event) => {
|
|
619
|
+
const next = event.target.value.replace(/[^\da-f]/gi, "").slice(0, 6).toUpperCase();
|
|
620
|
+
setHexDraft(next);
|
|
621
|
+
updateColor(next, alphaFocused ? Number(alphaDraft) : alphaValue);
|
|
622
|
+
},
|
|
623
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
624
|
+
onClick: (event) => event.stopPropagation()
|
|
625
|
+
}
|
|
626
|
+
)
|
|
627
|
+
] }),
|
|
628
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
629
|
+
"input",
|
|
630
|
+
{
|
|
631
|
+
"aria-label": `${label} opacity value`,
|
|
632
|
+
type: "text",
|
|
633
|
+
inputMode: "numeric",
|
|
634
|
+
value: alphaFocused ? alphaDraft ? `${alphaDraft}%` : "" : `${alphaValue}%`,
|
|
635
|
+
maxLength: 4,
|
|
636
|
+
className: "msr:h-full msr:w-full msr:bg-transparent msr:px-1 msr:text-center msr:font-mono msr:text-[12px] msr:tabular-nums msr:text-ink-700 msr:outline-none",
|
|
637
|
+
onFocus: () => {
|
|
638
|
+
setAlphaDraft(String(alphaValue));
|
|
639
|
+
setAlphaFocused(true);
|
|
640
|
+
},
|
|
641
|
+
onBlur: () => setAlphaFocused(false),
|
|
642
|
+
onChange: (event) => {
|
|
643
|
+
const next = event.target.value.replace(/\D/g, "").slice(0, 3);
|
|
644
|
+
setAlphaDraft(next);
|
|
645
|
+
updateColor(hexFocused ? hexDraft : hexValue, Number(next));
|
|
646
|
+
},
|
|
647
|
+
onKeyDown: (event) => {
|
|
648
|
+
if (event.key !== "ArrowUp" && event.key !== "ArrowDown") return;
|
|
649
|
+
event.preventDefault();
|
|
650
|
+
event.stopPropagation();
|
|
651
|
+
const current = Number.parseInt(alphaFocused ? alphaDraft : String(alphaValue), 10);
|
|
652
|
+
const direction = event.key === "ArrowUp" ? 1 : -1;
|
|
653
|
+
const next = Math.min(100, Math.max(0, (Number.isFinite(current) ? current : 0) + direction));
|
|
654
|
+
setAlphaDraft(String(next));
|
|
655
|
+
updateColor(hexFocused ? hexDraft : hexValue, next);
|
|
656
|
+
},
|
|
657
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
658
|
+
onClick: (event) => event.stopPropagation()
|
|
659
|
+
}
|
|
660
|
+
)
|
|
661
|
+
}
|
|
662
|
+
)
|
|
663
|
+
] });
|
|
664
|
+
}
|
|
665
|
+
function SettingsPanel({
|
|
666
|
+
ownerWindow,
|
|
667
|
+
highlightColor,
|
|
668
|
+
setHighlightColor,
|
|
669
|
+
guideColor,
|
|
670
|
+
setGuideColor,
|
|
671
|
+
hoverHighlight,
|
|
672
|
+
setHoverHighlight,
|
|
673
|
+
persistOnReload,
|
|
674
|
+
setPersistOnReload,
|
|
675
|
+
colorFormats,
|
|
676
|
+
setColorFormats,
|
|
677
|
+
colorClickFormat,
|
|
678
|
+
setColorClickFormat,
|
|
679
|
+
snapEnabled,
|
|
680
|
+
setSnapEnabled,
|
|
681
|
+
snapGuidesEnabled,
|
|
682
|
+
setSnapGuidesEnabled,
|
|
683
|
+
selectNewGuideEnabled,
|
|
684
|
+
setSelectNewGuideEnabled,
|
|
685
|
+
multiMeasureEnabled,
|
|
686
|
+
setMultiMeasureEnabled,
|
|
687
|
+
guideStyle,
|
|
688
|
+
setGuideStyle,
|
|
689
|
+
rulerSettings,
|
|
690
|
+
setRulerSettings,
|
|
691
|
+
initialTab,
|
|
692
|
+
onResetSettings,
|
|
693
|
+
onClearWorkspace
|
|
694
|
+
}) {
|
|
695
|
+
const toggleFormat = (format) => {
|
|
696
|
+
setColorFormats((previous) => {
|
|
697
|
+
if (previous.includes(format)) {
|
|
698
|
+
if (previous.length === 1) return previous;
|
|
699
|
+
return previous.filter((item) => item !== format);
|
|
700
|
+
}
|
|
701
|
+
return [...previous, format];
|
|
702
|
+
});
|
|
703
|
+
};
|
|
704
|
+
const [activeTab, setActiveTab] = (0, import_react2.useState)(initialTab);
|
|
705
|
+
const patternTooltip = useTooltip();
|
|
706
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "msr:flex msr:max-h-[min(70vh,34rem)] msr:flex-col msr:gap-2 msr:overflow-y-auto", onPointerDown: (event) => event.stopPropagation(), children: [
|
|
707
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "msr:flex msr:h-6 msr:shrink-0 msr:select-none msr:items-stretch msr:gap-0 msr:rounded-[5px] msr:bg-ink-50 msr:p-px", role: "tablist", "aria-label": "Settings sections", children: [
|
|
708
|
+
["guides", "Guides"],
|
|
709
|
+
["select", "Select"],
|
|
710
|
+
["color-picker", "Color"],
|
|
711
|
+
["rulers", "Rulers"],
|
|
712
|
+
["general", "General"]
|
|
713
|
+
].map(([value, label]) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
714
|
+
"button",
|
|
715
|
+
{
|
|
716
|
+
type: "button",
|
|
717
|
+
role: "tab",
|
|
718
|
+
"aria-selected": activeTab === value,
|
|
719
|
+
className: cn(
|
|
720
|
+
"msr:relative msr:flex msr:min-w-0 msr:flex-1 msr:appearance-none msr:items-center msr:justify-center msr:whitespace-nowrap msr:px-1.5 msr:py-0 msr:text-[10px] msr:font-medium msr:transition-colors msr:focus-visible:outline-none msr:focus-visible:shadow-[inset_0_0_0_1px_#0d99ff]",
|
|
721
|
+
activeTab === value ? "msr:rounded-[5px] msr:bg-white msr:text-ink-900 msr:shadow-[0_0_0_1px_rgba(15,23,42,0.12)]" : "msr:rounded-[5px] msr:text-ink-500 msr:hover:text-ink-700"
|
|
722
|
+
),
|
|
723
|
+
onClick: () => setActiveTab(value),
|
|
724
|
+
children: label
|
|
725
|
+
},
|
|
726
|
+
value
|
|
727
|
+
)) }),
|
|
728
|
+
activeTab === "guides" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "msr:grid msr:grid-cols-[78px_156px] msr:items-center msr:gap-x-3 msr:gap-y-1", "aria-label": "Guide settings", children: [
|
|
729
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ColorField, { label: "Color", value: guideColor, fallback: "#f97316", ownerWindow, onChange: setGuideColor }),
|
|
730
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SliderControl, { label: "Weight", min: 1, max: 4, step: 1, value: guideStyle.width, formatValue: (value) => `${value}px`, parseInput: (input) => Number.parseFloat(input), onChange: (value) => setGuideStyle((style) => ({ ...style, width: value })) }),
|
|
731
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "msr:col-span-2 msr:grid msr:grid-cols-[78px_156px] msr:items-center msr:gap-3", children: [
|
|
732
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "msr:text-[12px] msr:text-ink-700", children: "Pattern" }),
|
|
733
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "msr:flex msr:gap-1", role: "radiogroup", "aria-label": "Guide pattern", onMouseLeave: patternTooltip.onTooltipContainerLeave, children: GUIDE_PATTERNS.map(({ value, label }) => {
|
|
734
|
+
const selected = guideStyle.pattern === value;
|
|
735
|
+
const tooltipId = `guide-pattern-${value}`;
|
|
736
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
737
|
+
"button",
|
|
738
|
+
{
|
|
739
|
+
type: "button",
|
|
740
|
+
role: "radio",
|
|
741
|
+
"aria-label": `${label} guide pattern`,
|
|
742
|
+
"aria-checked": selected,
|
|
743
|
+
className: cn(
|
|
744
|
+
"msr:relative msr:flex msr:h-6 msr:min-w-0 msr:flex-1 msr:items-center msr:justify-center msr:rounded-[5px] msr:border msr:px-1 msr:focus-visible:outline-none msr:focus-visible:shadow-[inset_0_0_0_1px_#0d99ff]",
|
|
745
|
+
selected ? "msr:border-[#0d99ff] msr:bg-[#0d99ff]/10" : "msr:border-ink-200 msr:bg-ink-50 msr:hover:bg-ink-100"
|
|
746
|
+
),
|
|
747
|
+
onClick: () => setGuideStyle((style) => ({ ...style, pattern: value })),
|
|
748
|
+
onMouseEnter: () => patternTooltip.onTooltipEnter(tooltipId),
|
|
749
|
+
onFocus: () => patternTooltip.onTooltipEnter(tooltipId),
|
|
750
|
+
onBlur: patternTooltip.onTooltipLeave,
|
|
751
|
+
children: [
|
|
752
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { "aria-hidden": "true", className: cn("msr:block msr:w-full msr:border-t-2 msr:border-ink-700", value === "dashed" ? "msr:border-dashed" : value === "dotted" ? "msr:border-dotted" : "msr:border-solid") }),
|
|
753
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Tooltip, { label, visible: patternTooltip.visibleTooltipId === tooltipId, instant: patternTooltip.tooltipInstant, className: "msr:z-10" })
|
|
754
|
+
]
|
|
755
|
+
},
|
|
756
|
+
value
|
|
757
|
+
);
|
|
758
|
+
}) })
|
|
759
|
+
] }),
|
|
760
|
+
guideStyle.pattern !== "solid" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
761
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SliderControl, { label: "Length", min: 2, max: 24, step: 1, value: guideStyle.dashLength, formatValue: (value) => `${value}px`, parseInput: (input) => Number.parseFloat(input), onChange: (value) => setGuideStyle((style) => ({ ...style, dashLength: value })) }),
|
|
762
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SliderControl, { label: "Gap", min: 0, max: 24, step: 1, value: guideStyle.gap, formatValue: (value) => `${value}px`, parseInput: (input) => Number.parseFloat(input), onChange: (value) => setGuideStyle((style) => ({ ...style, gap: value })) })
|
|
763
|
+
] }) : null,
|
|
764
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "msr:col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SettingsSwitch, { label: "Snap", checked: snapGuidesEnabled, onChange: setSnapGuidesEnabled }) }),
|
|
765
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "msr:col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SettingsSwitch, { label: "Highlight", checked: selectNewGuideEnabled, onChange: setSelectNewGuideEnabled }) })
|
|
766
|
+
] }) : null,
|
|
767
|
+
activeTab === "select" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "msr:grid msr:grid-cols-[78px_156px] msr:items-center msr:gap-x-3 msr:gap-y-1", "aria-label": "Selection settings", children: [
|
|
768
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ColorField, { label: "Color", value: highlightColor, fallback: "#0d99ff", ownerWindow, onChange: setHighlightColor }),
|
|
769
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "msr:col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SettingsSwitch, { label: "Hover", checked: hoverHighlight, onChange: setHoverHighlight }) }),
|
|
770
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "msr:col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SettingsSwitch, { label: "Element snap", checked: snapEnabled, onChange: setSnapEnabled }) }),
|
|
771
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "msr:col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SettingsSwitch, { label: "Stack", checked: multiMeasureEnabled, onChange: setMultiMeasureEnabled }) })
|
|
772
|
+
] }) : null,
|
|
773
|
+
activeTab === "color-picker" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "msr:grid msr:grid-cols-[78px_156px] msr:items-center msr:gap-x-3 msr:gap-y-1", "aria-label": "Color settings", children: [
|
|
774
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "msr:col-span-2 msr:grid msr:grid-cols-[78px_156px] msr:items-center msr:gap-3", children: [
|
|
775
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "msr:text-[12px] msr:text-ink-700", children: "Format" }),
|
|
776
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "msr:flex msr:min-w-0 msr:gap-1", children: COLOR_FORMATS.map((format) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
777
|
+
"button",
|
|
778
|
+
{
|
|
779
|
+
type: "button",
|
|
780
|
+
"aria-pressed": colorFormats.includes(format),
|
|
781
|
+
className: cn(
|
|
782
|
+
"msr:h-6 msr:min-w-0 msr:flex-1 msr:rounded-[5px] msr:border msr:px-1 msr:text-[11px] msr:focus-visible:outline-none msr:focus-visible:shadow-[inset_0_0_0_1px_#0d99ff]",
|
|
783
|
+
colorFormats.includes(format) ? "msr:border-[#0d99ff] msr:bg-[#0d99ff] msr:text-white" : "msr:border-ink-200 msr:text-ink-500 msr:hover:bg-ink-50"
|
|
784
|
+
),
|
|
785
|
+
onClick: () => toggleFormat(format),
|
|
786
|
+
children: format
|
|
787
|
+
},
|
|
788
|
+
format
|
|
789
|
+
)) })
|
|
790
|
+
] }),
|
|
791
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "msr:col-span-2 msr:flex msr:items-center msr:justify-between msr:gap-3 msr:text-[12px] msr:text-ink-700", children: [
|
|
792
|
+
"Copy",
|
|
793
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("select", { value: colorClickFormat, className: "msr:rounded-[5px] msr:border msr:border-ink-200 msr:bg-white msr:px-1.5 msr:py-1 msr:text-[11px] msr:outline-none msr:focus:shadow-[inset_0_0_0_1px_#0d99ff]", onChange: (event) => setColorClickFormat(event.target.value), children: COLOR_FORMATS.map((format) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: format, children: format }, format)) })
|
|
794
|
+
] })
|
|
795
|
+
] }) : null,
|
|
796
|
+
activeTab === "rulers" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "msr:grid msr:grid-cols-[78px_156px] msr:items-center msr:gap-x-3 msr:gap-y-1", "aria-label": "Ruler settings", children: [
|
|
797
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SliderControl, { label: "Opacity", min: 0.2, max: 1, step: 0.05, value: rulerSettings.opacity, formatValue: (value) => `${Math.round(value * 100)}%`, parseInput: (input) => Number.parseFloat(input) / 100, onChange: (value) => setRulerSettings((settings) => ({ ...settings, opacity: value })) }),
|
|
798
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "msr:col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SettingsSwitch, { label: "Edge reveal", checked: rulerSettings.edgeReveal, onChange: (edgeReveal) => setRulerSettings((settings) => ({ ...settings, edgeReveal })) }) })
|
|
799
|
+
] }) : null,
|
|
800
|
+
activeTab === "general" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "msr:grid msr:grid-cols-[78px_156px] msr:items-center msr:gap-x-3 msr:gap-y-1", "aria-label": "General settings", children: [
|
|
801
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "msr:col-span-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SettingsSwitch, { label: "Persist", checked: persistOnReload, onChange: setPersistOnReload }) }),
|
|
802
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "msr:col-span-2 msr:grid msr:h-6 msr:grid-cols-[78px_156px] msr:items-center msr:gap-3 msr:text-[12px] msr:text-ink-700", children: [
|
|
803
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Version" }),
|
|
804
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "msr:justify-self-end msr:font-mono msr:text-[11px] msr:tabular-nums msr:text-ink-700", children: package_default.version })
|
|
805
|
+
] }),
|
|
806
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "msr:col-span-2 msr:flex msr:justify-end msr:gap-1", children: [
|
|
807
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
808
|
+
"button",
|
|
809
|
+
{
|
|
810
|
+
type: "button",
|
|
811
|
+
"aria-label": "Reset settings to defaults",
|
|
812
|
+
className: "msr:rounded-[5px] msr:border msr:border-ink-200 msr:px-2 msr:py-1 msr:text-[11px] msr:text-ink-700 msr:hover:bg-ink-50 msr:focus-visible:outline-none msr:focus-visible:shadow-[inset_0_0_0_1px_#0d99ff]",
|
|
813
|
+
onClick: onResetSettings,
|
|
814
|
+
children: "Use defaults"
|
|
815
|
+
}
|
|
816
|
+
),
|
|
817
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
818
|
+
"button",
|
|
819
|
+
{
|
|
820
|
+
type: "button",
|
|
821
|
+
"aria-label": "Clear workspace",
|
|
822
|
+
className: "msr:rounded-[5px] msr:border msr:border-red-200 msr:px-2 msr:py-1 msr:text-[11px] msr:text-red-600 msr:hover:bg-red-50 msr:focus-visible:outline-none msr:focus-visible:shadow-[inset_0_0_0_1px_#ef4444]",
|
|
823
|
+
onClick: onClearWorkspace,
|
|
824
|
+
children: "Clear workspace"
|
|
825
|
+
}
|
|
826
|
+
)
|
|
827
|
+
] })
|
|
828
|
+
] }) : null
|
|
829
|
+
] });
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// components/icons.tsx
|
|
833
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
834
|
+
var IconBase = ({ size = 24, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
90
835
|
"svg",
|
|
91
836
|
{
|
|
92
837
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -94,12 +839,14 @@ var IconBase = ({ size = 24, ...props }) => /* @__PURE__ */ (0, import_jsx_runti
|
|
|
94
839
|
height: size,
|
|
95
840
|
viewBox: "0 0 256 256",
|
|
96
841
|
fill: "currentColor",
|
|
842
|
+
"aria-hidden": "true",
|
|
843
|
+
onDragStart: (event) => event.preventDefault(),
|
|
97
844
|
...props
|
|
98
845
|
}
|
|
99
846
|
);
|
|
100
|
-
var CursorIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0,
|
|
101
|
-
var RulerIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0,
|
|
102
|
-
var XrayIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0,
|
|
847
|
+
var CursorIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.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" }) });
|
|
848
|
+
var RulerIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.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" }) });
|
|
849
|
+
var XrayIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
103
850
|
"path",
|
|
104
851
|
{
|
|
105
852
|
fill: "none",
|
|
@@ -111,7 +858,7 @@ var XrayIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runti
|
|
|
111
858
|
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
859
|
}
|
|
113
860
|
) });
|
|
114
|
-
var RulersIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0,
|
|
861
|
+
var RulersIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
115
862
|
"path",
|
|
116
863
|
{
|
|
117
864
|
fill: "none",
|
|
@@ -122,10 +869,10 @@ var RulersIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_run
|
|
|
122
869
|
d: "M48 208V48h160M80 48v24m32-24v24m32-24v24m32-24v24M48 80h24M48 112h24m-24 32h24m-24 32h24"
|
|
123
870
|
}
|
|
124
871
|
) });
|
|
125
|
-
var CaretDownIcon = ({ size = 8, ...props }) => /* @__PURE__ */ (0,
|
|
126
|
-
var CheckIcon = ({ size = 12, ...props }) => /* @__PURE__ */ (0,
|
|
127
|
-
var MinusIcon = ({ size = 12, ...props }) => /* @__PURE__ */ (0,
|
|
128
|
-
var TextInspectorIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0,
|
|
872
|
+
var CaretDownIcon = ({ size = 8, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.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" }) });
|
|
873
|
+
var CheckIcon = ({ size = 12, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.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" }) });
|
|
874
|
+
var MinusIcon = ({ size = 12, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconBase, { size, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M228,128a12,12,0,0,1-12,12H40a12,12,0,0,1,0-24H216A12,12,0,0,1,228,128Z" }) });
|
|
875
|
+
var TextInspectorIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
129
876
|
"svg",
|
|
130
877
|
{
|
|
131
878
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -133,8 +880,10 @@ var TextInspectorIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_
|
|
|
133
880
|
height: size,
|
|
134
881
|
viewBox: "0 0 256 256",
|
|
135
882
|
fill: "currentColor",
|
|
883
|
+
"aria-hidden": "true",
|
|
884
|
+
onDragStart: (event) => event.preventDefault(),
|
|
136
885
|
...props,
|
|
137
|
-
children: /* @__PURE__ */ (0,
|
|
886
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
138
887
|
"text",
|
|
139
888
|
{
|
|
140
889
|
x: "50%",
|
|
@@ -150,9 +899,54 @@ var TextInspectorIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_
|
|
|
150
899
|
)
|
|
151
900
|
}
|
|
152
901
|
);
|
|
902
|
+
var ColorPickerIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
903
|
+
"svg",
|
|
904
|
+
{
|
|
905
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
906
|
+
width: size,
|
|
907
|
+
height: size,
|
|
908
|
+
viewBox: "0 0 24 24",
|
|
909
|
+
fill: "none",
|
|
910
|
+
...props,
|
|
911
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
912
|
+
"path",
|
|
913
|
+
{
|
|
914
|
+
fill: "currentColor",
|
|
915
|
+
fillRule: "evenodd",
|
|
916
|
+
transform: "translate(-1.44 -1.44) scale(1.12)",
|
|
917
|
+
d: "M15.16 5.658a2.25 2.25 0 0 1 3.18.001l.155.17a2.25 2.25 0 0 1 0 2.84l-.154.172-1.696 1.692a1.5 1.5 0 0 1 .02 1.913l-.104.114a1.5 1.5 0 0 1-2.007.103l-.02-.018-4.443 4.447a2.24 2.24 0 0 1-1.716.65l-.814.815a1.5 1.5 0 0 1-2.121-2.121l.816-.818a2.25 2.25 0 0 1 .653-1.708l4.443-4.446a1.5 1.5 0 0 1 .088-2.025l.114-.103a1.5 1.5 0 0 1 1.91.015zm-7.544 8.959a1.25 1.25 0 0 0-.358 1.021c.021.197-.014.406-.154.546l-.958.96a.5.5 0 0 0 .708.706l.955-.956c.14-.14.352-.176.55-.153.364.042.745-.077 1.025-.356l4.438-4.442-1.767-1.767zm10.018-8.251a1.25 1.25 0 0 0-1.768 0l-1.782 1.78-.065.06a.87.87 0 0 1-1.165-.06.5.5 0 0 0-.707.707l3 3a.5.5 0 0 0 .628.064l.079-.064a.5.5 0 0 0 0-.707l-.004-.004a.873.873 0 0 1 .004-1.23l1.78-1.778a1.25 1.25 0 0 0 0-1.768",
|
|
918
|
+
clipRule: "evenodd"
|
|
919
|
+
}
|
|
920
|
+
)
|
|
921
|
+
}
|
|
922
|
+
);
|
|
923
|
+
var GearIcon = ({ size = 20, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
924
|
+
"svg",
|
|
925
|
+
{
|
|
926
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
927
|
+
width: size,
|
|
928
|
+
height: size,
|
|
929
|
+
viewBox: "0 0 24 24",
|
|
930
|
+
fill: "none",
|
|
931
|
+
...props,
|
|
932
|
+
children: [
|
|
933
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
934
|
+
"path",
|
|
935
|
+
{
|
|
936
|
+
d: "M10.6504 5.81117C10.9939 4.39628 13.0061 4.39628 13.3496 5.81117C13.5715 6.72517 14.6187 7.15891 15.4219 6.66952C16.6652 5.91193 18.0881 7.33479 17.3305 8.57815C16.8411 9.38134 17.2748 10.4285 18.1888 10.6504C19.6037 10.9939 19.6037 13.0061 18.1888 13.3496C17.2748 13.5715 16.8411 14.6187 17.3305 15.4219C18.0881 16.6652 16.6652 18.0881 15.4219 17.3305C14.6187 16.8411 13.5715 17.2748 13.3496 18.1888C13.0061 19.6037 10.9939 19.6037 10.6504 18.1888C10.4285 17.2748 9.38135 16.8411 8.57815 17.3305C7.33479 18.0881 5.91193 16.6652 6.66952 15.4219C7.15891 14.6187 6.72517 13.5715 5.81117 13.3496C4.39628 13.0061 4.39628 10.9939 5.81117 10.6504C6.72517 10.4285 7.15891 9.38134 6.66952 8.57815C5.91193 7.33479 7.33479 5.91192 8.57815 6.66952C9.38135 7.15891 10.4285 6.72517 10.6504 5.81117Z",
|
|
937
|
+
stroke: "currentColor",
|
|
938
|
+
strokeWidth: "1",
|
|
939
|
+
strokeLinecap: "round",
|
|
940
|
+
strokeLinejoin: "round"
|
|
941
|
+
}
|
|
942
|
+
),
|
|
943
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "2.5", stroke: "currentColor", strokeWidth: "1" })
|
|
944
|
+
]
|
|
945
|
+
}
|
|
946
|
+
);
|
|
153
947
|
|
|
154
948
|
// components/toolbar.tsx
|
|
155
|
-
var
|
|
949
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
156
950
|
var TOOLBAR_TOOLTIP_DELAY_MS = 800;
|
|
157
951
|
var TOOLBAR_DRAG_SLOP = 6;
|
|
158
952
|
var GUIDE_MENU_WIDTH = 176;
|
|
@@ -170,61 +964,43 @@ function ToolbarButton({
|
|
|
170
964
|
onTooltipLeave,
|
|
171
965
|
children
|
|
172
966
|
}) {
|
|
173
|
-
return /* @__PURE__ */ (0,
|
|
967
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
174
968
|
"div",
|
|
175
969
|
{
|
|
176
970
|
className: "msr:relative",
|
|
177
971
|
onMouseEnter: () => onTooltipEnter(id),
|
|
178
972
|
onMouseLeave: () => onTooltipLeave(id),
|
|
179
973
|
children: [
|
|
180
|
-
/* @__PURE__ */ (0,
|
|
974
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
181
975
|
"button",
|
|
182
976
|
{
|
|
183
977
|
type: "button",
|
|
184
|
-
"aria-label": `${label} (${shortcut})`,
|
|
185
978
|
"aria-pressed": active,
|
|
186
|
-
|
|
979
|
+
"aria-label": `${label} (${shortcut})`,
|
|
187
980
|
className: cn(
|
|
188
|
-
"msr:flex msr:size-8 msr:items-center msr:justify-center msr:rounded-[8px] msr:outline-none",
|
|
981
|
+
"msr:flex msr:size-8 msr:select-none msr:items-center msr:justify-center msr:rounded-[8px] msr:outline-none",
|
|
189
982
|
active ? "msr:bg-[#0d99ff] msr:text-white" : "msr:bg-transparent msr:text-black msr:hover:bg-black/4"
|
|
190
983
|
),
|
|
191
984
|
onClick,
|
|
192
985
|
children
|
|
193
986
|
}
|
|
194
987
|
),
|
|
195
|
-
/* @__PURE__ */ (0,
|
|
196
|
-
"span",
|
|
197
|
-
{
|
|
198
|
-
className: cn(
|
|
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
|
-
),
|
|
203
|
-
tooltipSide === "top" ? "msr:bottom-full msr:mb-2" : "msr:top-full msr:mt-2",
|
|
204
|
-
tooltipVisible ? "msr:opacity-100" : "msr:opacity-0"
|
|
205
|
-
),
|
|
206
|
-
children: [
|
|
207
|
-
label,
|
|
208
|
-
" ",
|
|
209
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("kbd", { className: "msr:text-white/60", children: shortcut })
|
|
210
|
-
]
|
|
211
|
-
}
|
|
212
|
-
)
|
|
988
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tooltip, { label, shortcut, visible: tooltipVisible, instant: tooltipInstant, side: tooltipSide })
|
|
213
989
|
]
|
|
214
990
|
}
|
|
215
991
|
);
|
|
216
992
|
}
|
|
217
993
|
function useToolbarTooltip() {
|
|
218
|
-
const [visibleTooltipId, setVisibleTooltipId] = (0,
|
|
219
|
-
const timerRef = (0,
|
|
220
|
-
const instantRef = (0,
|
|
221
|
-
const [tooltipInstant, setTooltipInstant] = (0,
|
|
222
|
-
const clearTimer = (0,
|
|
994
|
+
const [visibleTooltipId, setVisibleTooltipId] = (0, import_react3.useState)(null);
|
|
995
|
+
const timerRef = (0, import_react3.useRef)(null);
|
|
996
|
+
const instantRef = (0, import_react3.useRef)(false);
|
|
997
|
+
const [tooltipInstant, setTooltipInstant] = (0, import_react3.useState)(false);
|
|
998
|
+
const clearTimer = (0, import_react3.useCallback)(() => {
|
|
223
999
|
if (timerRef.current === null) return;
|
|
224
1000
|
window.clearTimeout(timerRef.current);
|
|
225
1001
|
timerRef.current = null;
|
|
226
1002
|
}, []);
|
|
227
|
-
const onTooltipEnter = (0,
|
|
1003
|
+
const onTooltipEnter = (0, import_react3.useCallback)(
|
|
228
1004
|
(id) => {
|
|
229
1005
|
clearTimer();
|
|
230
1006
|
if (instantRef.current) {
|
|
@@ -241,14 +1017,14 @@ function useToolbarTooltip() {
|
|
|
241
1017
|
},
|
|
242
1018
|
[clearTimer]
|
|
243
1019
|
);
|
|
244
|
-
const onTooltipLeave = (0,
|
|
1020
|
+
const onTooltipLeave = (0, import_react3.useCallback)(
|
|
245
1021
|
(id) => {
|
|
246
1022
|
clearTimer();
|
|
247
1023
|
setVisibleTooltipId((prev) => prev === id ? null : prev);
|
|
248
1024
|
},
|
|
249
1025
|
[clearTimer]
|
|
250
1026
|
);
|
|
251
|
-
const onToolbarLeave = (0,
|
|
1027
|
+
const onToolbarLeave = (0, import_react3.useCallback)(() => {
|
|
252
1028
|
clearTimer();
|
|
253
1029
|
setVisibleTooltipId(null);
|
|
254
1030
|
instantRef.current = false;
|
|
@@ -263,10 +1039,11 @@ function useToolbarTooltip() {
|
|
|
263
1039
|
};
|
|
264
1040
|
}
|
|
265
1041
|
function useToolbarDrag(initialPosition, eventTarget) {
|
|
266
|
-
const [position, setPosition] = (0,
|
|
267
|
-
const suppressClickRef = (0,
|
|
268
|
-
const
|
|
269
|
-
const
|
|
1042
|
+
const [position, setPosition] = (0, import_react3.useState)(initialPosition);
|
|
1043
|
+
const suppressClickRef = (0, import_react3.useRef)(false);
|
|
1044
|
+
const previousUserSelectRef = (0, import_react3.useRef)(null);
|
|
1045
|
+
const detachListenersRef = (0, import_react3.useRef)(null);
|
|
1046
|
+
const dragRef = (0, import_react3.useRef)({
|
|
270
1047
|
active: false,
|
|
271
1048
|
didDrag: false,
|
|
272
1049
|
pointerId: -1,
|
|
@@ -277,12 +1054,28 @@ function useToolbarDrag(initialPosition, eventTarget) {
|
|
|
277
1054
|
width: 0,
|
|
278
1055
|
height: 0
|
|
279
1056
|
});
|
|
280
|
-
const
|
|
1057
|
+
const disableTextSelection = (0, import_react3.useCallback)(() => {
|
|
1058
|
+
if (previousUserSelectRef.current !== null) return;
|
|
1059
|
+
const root = eventTarget.document.documentElement;
|
|
1060
|
+
previousUserSelectRef.current = root.style.userSelect;
|
|
1061
|
+
root.style.setProperty("user-select", "none", "important");
|
|
1062
|
+
}, [eventTarget]);
|
|
1063
|
+
const restoreTextSelection = (0, import_react3.useCallback)(() => {
|
|
1064
|
+
const previous = previousUserSelectRef.current;
|
|
1065
|
+
if (previous === null) return;
|
|
1066
|
+
const root = eventTarget.document.documentElement;
|
|
1067
|
+
root.style.userSelect = previous;
|
|
1068
|
+
previousUserSelectRef.current = null;
|
|
1069
|
+
}, [eventTarget]);
|
|
1070
|
+
(0, import_react3.useEffect)(() => restoreTextSelection, [restoreTextSelection]);
|
|
1071
|
+
const onPointerDown = (0, import_react3.useCallback)(
|
|
281
1072
|
(event) => {
|
|
282
1073
|
if (event.button !== 0) return;
|
|
1074
|
+
disableTextSelection();
|
|
283
1075
|
if (detachListenersRef.current) {
|
|
284
1076
|
detachListenersRef.current();
|
|
285
1077
|
detachListenersRef.current = null;
|
|
1078
|
+
restoreTextSelection();
|
|
286
1079
|
}
|
|
287
1080
|
const state = dragRef.current;
|
|
288
1081
|
state.active = false;
|
|
@@ -317,6 +1110,7 @@ function useToolbarDrag(initialPosition, eventTarget) {
|
|
|
317
1110
|
if (current.pointerId !== endEvent.pointerId && current.pointerId !== -1)
|
|
318
1111
|
return;
|
|
319
1112
|
suppressClickRef.current = current.didDrag;
|
|
1113
|
+
restoreTextSelection();
|
|
320
1114
|
current.active = false;
|
|
321
1115
|
current.didDrag = false;
|
|
322
1116
|
current.pointerId = -1;
|
|
@@ -334,9 +1128,9 @@ function useToolbarDrag(initialPosition, eventTarget) {
|
|
|
334
1128
|
eventTarget.removeEventListener("pointercancel", handlePointerEnd);
|
|
335
1129
|
};
|
|
336
1130
|
},
|
|
337
|
-
[eventTarget, position.x, position.y]
|
|
1131
|
+
[disableTextSelection, eventTarget, position.x, position.y, restoreTextSelection]
|
|
338
1132
|
);
|
|
339
|
-
const onClickCapture = (0,
|
|
1133
|
+
const onClickCapture = (0, import_react3.useCallback)(
|
|
340
1134
|
(event) => {
|
|
341
1135
|
if (!suppressClickRef.current) return;
|
|
342
1136
|
event.preventDefault();
|
|
@@ -351,12 +1145,46 @@ function ToolbarComponent({
|
|
|
351
1145
|
toolMode,
|
|
352
1146
|
setEnabled,
|
|
353
1147
|
setToolMode,
|
|
1148
|
+
xrayVisible,
|
|
1149
|
+
setXrayVisible,
|
|
354
1150
|
rulersVisible,
|
|
355
1151
|
setRulersVisible,
|
|
356
1152
|
guideOrientation,
|
|
357
1153
|
setGuideOrientation,
|
|
358
1154
|
onInteract,
|
|
359
|
-
eventTarget
|
|
1155
|
+
eventTarget,
|
|
1156
|
+
colorPickerActive,
|
|
1157
|
+
setColorPickerActive,
|
|
1158
|
+
onColorPickerClick,
|
|
1159
|
+
settingsOpen,
|
|
1160
|
+
setSettingsOpen,
|
|
1161
|
+
highlightColor,
|
|
1162
|
+
setHighlightColor,
|
|
1163
|
+
guideColor,
|
|
1164
|
+
setGuideColor,
|
|
1165
|
+
hoverHighlight,
|
|
1166
|
+
setHoverHighlight,
|
|
1167
|
+
persistOnReload,
|
|
1168
|
+
setPersistOnReload,
|
|
1169
|
+
colorPickerFormats,
|
|
1170
|
+
setColorPickerFormats,
|
|
1171
|
+
colorPickerClickFormat,
|
|
1172
|
+
setColorPickerClickFormat,
|
|
1173
|
+
snapEnabled,
|
|
1174
|
+
setSnapEnabled,
|
|
1175
|
+
snapGuidesEnabled,
|
|
1176
|
+
setSnapGuidesEnabled,
|
|
1177
|
+
selectNewGuideEnabled,
|
|
1178
|
+
setSelectNewGuideEnabled,
|
|
1179
|
+
multiMeasureEnabled,
|
|
1180
|
+
setMultiMeasureEnabled,
|
|
1181
|
+
guideStyle,
|
|
1182
|
+
setGuideStyle,
|
|
1183
|
+
rulerSettings,
|
|
1184
|
+
setRulerSettings,
|
|
1185
|
+
initialSettingsTab,
|
|
1186
|
+
onResetSettings,
|
|
1187
|
+
onClearWorkspace
|
|
360
1188
|
}, ref) {
|
|
361
1189
|
const { position, onPointerDown, onClickCapture } = useToolbarDrag({
|
|
362
1190
|
x: 16,
|
|
@@ -369,11 +1197,13 @@ function ToolbarComponent({
|
|
|
369
1197
|
onTooltipLeave,
|
|
370
1198
|
onToolbarLeave
|
|
371
1199
|
} = useToolbarTooltip();
|
|
372
|
-
const [guideMenuOpen, setGuideMenuOpen] = (0,
|
|
373
|
-
const
|
|
374
|
-
const
|
|
375
|
-
const [
|
|
376
|
-
const
|
|
1200
|
+
const [guideMenuOpen, setGuideMenuOpen] = (0, import_react3.useState)(false);
|
|
1201
|
+
const settingsRef = (0, import_react3.useRef)(null);
|
|
1202
|
+
const guideMenuRef = (0, import_react3.useRef)(null);
|
|
1203
|
+
const [activeMenuIndex, setActiveMenuIndex] = (0, import_react3.useState)(0);
|
|
1204
|
+
const [menuAlign, setMenuAlign] = (0, import_react3.useState)("right");
|
|
1205
|
+
const tooltipsEnabled = !guideMenuOpen && !settingsOpen;
|
|
1206
|
+
const updateMenuAlign = (0, import_react3.useCallback)(() => {
|
|
377
1207
|
const anchorRect = guideMenuRef.current?.getBoundingClientRect();
|
|
378
1208
|
if (!anchorRect) return;
|
|
379
1209
|
const rightAlignedLeft = anchorRect.right - GUIDE_MENU_WIDTH;
|
|
@@ -393,34 +1223,50 @@ function ToolbarComponent({
|
|
|
393
1223
|
const nearBottom = viewportHeight > 0 && position.y > viewportHeight - 56;
|
|
394
1224
|
const tooltipSide = nearTop && !nearBottom ? "bottom" : "top";
|
|
395
1225
|
const menuSide = nearBottom ? "top" : "bottom";
|
|
396
|
-
const selectMode = (0,
|
|
1226
|
+
const selectMode = (0, import_react3.useCallback)(() => {
|
|
397
1227
|
setEnabled(true);
|
|
1228
|
+
setColorPickerActive(false);
|
|
398
1229
|
setToolMode((prev) => prev === "select" ? "none" : "select");
|
|
399
1230
|
onInteract();
|
|
400
|
-
}, [onInteract, setEnabled, setToolMode]);
|
|
401
|
-
const guidesMode = (0,
|
|
1231
|
+
}, [onInteract, setColorPickerActive, setEnabled, setToolMode]);
|
|
1232
|
+
const guidesMode = (0, import_react3.useCallback)(() => {
|
|
402
1233
|
setEnabled(true);
|
|
1234
|
+
setColorPickerActive(false);
|
|
403
1235
|
setToolMode((prev) => prev === "guides" ? "none" : "guides");
|
|
404
1236
|
onInteract();
|
|
405
|
-
}, [onInteract, setEnabled, setToolMode]);
|
|
406
|
-
const textInspectorMode = (0,
|
|
1237
|
+
}, [onInteract, setColorPickerActive, setEnabled, setToolMode]);
|
|
1238
|
+
const textInspectorMode = (0, import_react3.useCallback)(() => {
|
|
407
1239
|
setEnabled(true);
|
|
1240
|
+
setColorPickerActive(false);
|
|
408
1241
|
setToolMode(
|
|
409
1242
|
(prev) => prev === "text-inspector" ? "none" : "text-inspector"
|
|
410
1243
|
);
|
|
411
1244
|
onInteract();
|
|
412
|
-
}, [onInteract, setEnabled, setToolMode]);
|
|
413
|
-
const xrayMode = (0,
|
|
1245
|
+
}, [onInteract, setColorPickerActive, setEnabled, setToolMode]);
|
|
1246
|
+
const xrayMode = (0, import_react3.useCallback)(() => {
|
|
414
1247
|
setEnabled(true);
|
|
415
|
-
|
|
1248
|
+
setColorPickerActive(false);
|
|
1249
|
+
setXrayVisible((prev) => !prev);
|
|
416
1250
|
onInteract();
|
|
417
|
-
}, [onInteract, setEnabled,
|
|
418
|
-
const
|
|
1251
|
+
}, [onInteract, setColorPickerActive, setEnabled, setXrayVisible]);
|
|
1252
|
+
const colorPickerMode = (0, import_react3.useCallback)(() => {
|
|
419
1253
|
setEnabled(true);
|
|
1254
|
+
setToolMode("none");
|
|
1255
|
+
if (colorPickerActive) {
|
|
1256
|
+
setColorPickerActive(false);
|
|
1257
|
+
} else {
|
|
1258
|
+
setColorPickerActive(true);
|
|
1259
|
+
onColorPickerClick();
|
|
1260
|
+
}
|
|
1261
|
+
onInteract();
|
|
1262
|
+
}, [colorPickerActive, onColorPickerClick, onInteract, setColorPickerActive, setEnabled, setToolMode]);
|
|
1263
|
+
const rulersMode = (0, import_react3.useCallback)(() => {
|
|
1264
|
+
setEnabled(true);
|
|
1265
|
+
setColorPickerActive(false);
|
|
420
1266
|
setRulersVisible((prev) => !prev);
|
|
421
1267
|
onInteract();
|
|
422
|
-
}, [onInteract, setEnabled, setRulersVisible]);
|
|
423
|
-
const selectGuideOrientation = (0,
|
|
1268
|
+
}, [onInteract, setColorPickerActive, setEnabled, setRulersVisible]);
|
|
1269
|
+
const selectGuideOrientation = (0, import_react3.useCallback)(
|
|
424
1270
|
(orientation) => {
|
|
425
1271
|
setEnabled(true);
|
|
426
1272
|
setToolMode("guides");
|
|
@@ -430,30 +1276,34 @@ function ToolbarComponent({
|
|
|
430
1276
|
},
|
|
431
1277
|
[onInteract, setEnabled, setGuideOrientation, setToolMode]
|
|
432
1278
|
);
|
|
433
|
-
(0,
|
|
434
|
-
if (!guideMenuOpen) return;
|
|
435
|
-
const frame = eventTarget.requestAnimationFrame(() => {
|
|
1279
|
+
(0, import_react3.useLayoutEffect)(() => {
|
|
1280
|
+
if (!guideMenuOpen && !settingsOpen) return;
|
|
1281
|
+
const frame = guideMenuOpen ? eventTarget.requestAnimationFrame(() => {
|
|
436
1282
|
guideMenuRef.current?.querySelector("[role='menu']")?.focus();
|
|
437
|
-
});
|
|
1283
|
+
}) : 0;
|
|
438
1284
|
const handlePointerDown = (event) => {
|
|
439
|
-
const menu = guideMenuRef.current;
|
|
440
|
-
if (!menu) return;
|
|
441
1285
|
const path = event.composedPath();
|
|
442
|
-
if (
|
|
443
|
-
|
|
1286
|
+
if (guideMenuOpen) {
|
|
1287
|
+
const menu = guideMenuRef.current;
|
|
1288
|
+
if (menu && !path.includes(menu)) setGuideMenuOpen(false);
|
|
1289
|
+
}
|
|
1290
|
+
if (settingsOpen) {
|
|
1291
|
+
const settings = settingsRef.current;
|
|
1292
|
+
if (settings && !path.includes(settings)) setSettingsOpen(false);
|
|
1293
|
+
}
|
|
444
1294
|
};
|
|
445
1295
|
const handleResize = () => {
|
|
446
|
-
updateMenuAlign();
|
|
1296
|
+
if (guideMenuOpen) updateMenuAlign();
|
|
447
1297
|
};
|
|
448
1298
|
eventTarget.addEventListener("pointerdown", handlePointerDown);
|
|
449
|
-
eventTarget.addEventListener("resize", handleResize);
|
|
1299
|
+
if (guideMenuOpen) eventTarget.addEventListener("resize", handleResize);
|
|
450
1300
|
return () => {
|
|
451
|
-
eventTarget.cancelAnimationFrame(frame);
|
|
1301
|
+
if (frame) eventTarget.cancelAnimationFrame(frame);
|
|
452
1302
|
eventTarget.removeEventListener("pointerdown", handlePointerDown);
|
|
453
1303
|
eventTarget.removeEventListener("resize", handleResize);
|
|
454
1304
|
};
|
|
455
|
-
}, [eventTarget, guideMenuOpen, guideOrientation, updateMenuAlign]);
|
|
456
|
-
return /* @__PURE__ */ (0,
|
|
1305
|
+
}, [eventTarget, guideMenuOpen, guideOrientation, settingsOpen, updateMenuAlign]);
|
|
1306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
457
1307
|
"div",
|
|
458
1308
|
{
|
|
459
1309
|
ref,
|
|
@@ -466,7 +1316,7 @@ function ToolbarComponent({
|
|
|
466
1316
|
onClickCapture,
|
|
467
1317
|
onMouseLeave: onToolbarLeave,
|
|
468
1318
|
children: [
|
|
469
|
-
/* @__PURE__ */ (0,
|
|
1319
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
470
1320
|
ToolbarButton,
|
|
471
1321
|
{
|
|
472
1322
|
id: "select",
|
|
@@ -474,31 +1324,47 @@ function ToolbarComponent({
|
|
|
474
1324
|
label: "Select",
|
|
475
1325
|
shortcut: "S",
|
|
476
1326
|
onClick: selectMode,
|
|
477
|
-
tooltipVisible: visibleTooltipId === "select",
|
|
1327
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "select",
|
|
478
1328
|
tooltipInstant,
|
|
479
1329
|
tooltipSide,
|
|
480
1330
|
onTooltipEnter,
|
|
481
1331
|
onTooltipLeave,
|
|
482
|
-
children: /* @__PURE__ */ (0,
|
|
1332
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CursorIcon, { size: 20 })
|
|
483
1333
|
}
|
|
484
1334
|
),
|
|
485
|
-
/* @__PURE__ */ (0,
|
|
1335
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
486
1336
|
ToolbarButton,
|
|
487
1337
|
{
|
|
488
1338
|
id: "xray",
|
|
489
|
-
active:
|
|
1339
|
+
active: xrayVisible,
|
|
490
1340
|
label: "X-ray",
|
|
491
1341
|
shortcut: "X",
|
|
492
1342
|
onClick: xrayMode,
|
|
493
|
-
tooltipVisible: visibleTooltipId === "xray",
|
|
1343
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "xray",
|
|
494
1344
|
tooltipInstant,
|
|
495
1345
|
tooltipSide,
|
|
496
1346
|
onTooltipEnter,
|
|
497
1347
|
onTooltipLeave,
|
|
498
|
-
children: /* @__PURE__ */ (0,
|
|
1348
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(XrayIcon, { size: 20 })
|
|
499
1349
|
}
|
|
500
1350
|
),
|
|
501
|
-
/* @__PURE__ */ (0,
|
|
1351
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1352
|
+
ToolbarButton,
|
|
1353
|
+
{
|
|
1354
|
+
id: "color-picker",
|
|
1355
|
+
active: colorPickerActive,
|
|
1356
|
+
label: "Color picker",
|
|
1357
|
+
shortcut: "P",
|
|
1358
|
+
onClick: colorPickerMode,
|
|
1359
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "color-picker",
|
|
1360
|
+
tooltipInstant,
|
|
1361
|
+
tooltipSide,
|
|
1362
|
+
onTooltipEnter,
|
|
1363
|
+
onTooltipLeave,
|
|
1364
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ColorPickerIcon, { size: 20, "aria-hidden": "true" })
|
|
1365
|
+
}
|
|
1366
|
+
),
|
|
1367
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
502
1368
|
ToolbarButton,
|
|
503
1369
|
{
|
|
504
1370
|
id: "rulers",
|
|
@@ -506,15 +1372,15 @@ function ToolbarComponent({
|
|
|
506
1372
|
label: "Rulers",
|
|
507
1373
|
shortcut: "R",
|
|
508
1374
|
onClick: rulersMode,
|
|
509
|
-
tooltipVisible: visibleTooltipId === "rulers",
|
|
1375
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "rulers",
|
|
510
1376
|
tooltipInstant,
|
|
511
1377
|
tooltipSide,
|
|
512
1378
|
onTooltipEnter,
|
|
513
1379
|
onTooltipLeave,
|
|
514
|
-
children: /* @__PURE__ */ (0,
|
|
1380
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RulersIcon, { size: 20 })
|
|
515
1381
|
}
|
|
516
1382
|
),
|
|
517
|
-
/* @__PURE__ */ (0,
|
|
1383
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
518
1384
|
ToolbarButton,
|
|
519
1385
|
{
|
|
520
1386
|
id: "text-inspector",
|
|
@@ -522,15 +1388,15 @@ function ToolbarComponent({
|
|
|
522
1388
|
label: "Text inspector",
|
|
523
1389
|
shortcut: "A",
|
|
524
1390
|
onClick: textInspectorMode,
|
|
525
|
-
tooltipVisible: visibleTooltipId === "text-inspector",
|
|
1391
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "text-inspector",
|
|
526
1392
|
tooltipInstant,
|
|
527
1393
|
tooltipSide,
|
|
528
1394
|
onTooltipEnter,
|
|
529
1395
|
onTooltipLeave,
|
|
530
|
-
children: /* @__PURE__ */ (0,
|
|
1396
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TextInspectorIcon, { size: 20, "aria-hidden": "true" })
|
|
531
1397
|
}
|
|
532
1398
|
),
|
|
533
|
-
/* @__PURE__ */ (0,
|
|
1399
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
534
1400
|
ToolbarButton,
|
|
535
1401
|
{
|
|
536
1402
|
id: "guides",
|
|
@@ -538,12 +1404,12 @@ function ToolbarComponent({
|
|
|
538
1404
|
label: "Guides",
|
|
539
1405
|
shortcut: "G",
|
|
540
1406
|
onClick: guidesMode,
|
|
541
|
-
tooltipVisible: visibleTooltipId === "guides",
|
|
1407
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "guides",
|
|
542
1408
|
tooltipInstant,
|
|
543
1409
|
tooltipSide,
|
|
544
1410
|
onTooltipEnter,
|
|
545
1411
|
onTooltipLeave,
|
|
546
|
-
children: /* @__PURE__ */ (0,
|
|
1412
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
547
1413
|
RulerIcon,
|
|
548
1414
|
{
|
|
549
1415
|
size: 20,
|
|
@@ -554,7 +1420,7 @@ function ToolbarComponent({
|
|
|
554
1420
|
)
|
|
555
1421
|
}
|
|
556
1422
|
),
|
|
557
|
-
/* @__PURE__ */ (0,
|
|
1423
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
558
1424
|
"div",
|
|
559
1425
|
{
|
|
560
1426
|
className: "msr:group msr:relative msr:-ml-1 msr:flex msr:items-stretch",
|
|
@@ -562,12 +1428,11 @@ function ToolbarComponent({
|
|
|
562
1428
|
onMouseEnter: () => onTooltipEnter("guide-menu"),
|
|
563
1429
|
onMouseLeave: () => onTooltipLeave("guide-menu"),
|
|
564
1430
|
children: [
|
|
565
|
-
/* @__PURE__ */ (0,
|
|
1431
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
566
1432
|
"button",
|
|
567
1433
|
{
|
|
568
1434
|
type: "button",
|
|
569
1435
|
"aria-label": "Guide orientation menu",
|
|
570
|
-
title: "Guide orientation",
|
|
571
1436
|
className: cn(
|
|
572
1437
|
"msr:flex msr:h-8 msr:w-4 msr:items-center msr:justify-center msr:rounded-[6px] msr:outline-none msr:hover:bg-black/10",
|
|
573
1438
|
guideMenuOpen ? "msr:bg-black/10 msr:text-black" : "msr:text-black"
|
|
@@ -582,21 +1447,21 @@ function ToolbarComponent({
|
|
|
582
1447
|
return !prev;
|
|
583
1448
|
});
|
|
584
1449
|
},
|
|
585
|
-
children: /* @__PURE__ */ (0,
|
|
1450
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CaretDownIcon, { size: 8 })
|
|
586
1451
|
}
|
|
587
1452
|
),
|
|
588
|
-
/* @__PURE__ */ (0,
|
|
1453
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
589
1454
|
"span",
|
|
590
1455
|
{
|
|
591
1456
|
className: cn(
|
|
592
1457
|
"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",
|
|
593
1458
|
tooltipSide === "top" ? "msr:bottom-full msr:mb-2" : "msr:top-full msr:mt-2",
|
|
594
|
-
visibleTooltipId === "guide-menu" &&
|
|
1459
|
+
visibleTooltipId === "guide-menu" && tooltipsEnabled ? "msr:opacity-100" : "msr:opacity-0"
|
|
595
1460
|
),
|
|
596
1461
|
children: "Orientation Guide"
|
|
597
1462
|
}
|
|
598
1463
|
),
|
|
599
|
-
guideMenuOpen ? /* @__PURE__ */ (0,
|
|
1464
|
+
guideMenuOpen ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
600
1465
|
"div",
|
|
601
1466
|
{
|
|
602
1467
|
className: cn(
|
|
@@ -637,7 +1502,7 @@ function ToolbarComponent({
|
|
|
637
1502
|
}
|
|
638
1503
|
},
|
|
639
1504
|
children: [
|
|
640
|
-
/* @__PURE__ */ (0,
|
|
1505
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
641
1506
|
"button",
|
|
642
1507
|
{
|
|
643
1508
|
type: "button",
|
|
@@ -647,7 +1512,7 @@ function ToolbarComponent({
|
|
|
647
1512
|
),
|
|
648
1513
|
onClick: () => selectGuideOrientation("horizontal"),
|
|
649
1514
|
children: [
|
|
650
|
-
/* @__PURE__ */ (0,
|
|
1515
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
651
1516
|
CheckIcon,
|
|
652
1517
|
{
|
|
653
1518
|
size: 12,
|
|
@@ -656,13 +1521,13 @@ function ToolbarComponent({
|
|
|
656
1521
|
)
|
|
657
1522
|
}
|
|
658
1523
|
),
|
|
659
|
-
/* @__PURE__ */ (0,
|
|
660
|
-
/* @__PURE__ */ (0,
|
|
661
|
-
/* @__PURE__ */ (0,
|
|
1524
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MinusIcon, { size: 12 }),
|
|
1525
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "msr:flex-1", children: "Horizontal" }),
|
|
1526
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "H" })
|
|
662
1527
|
]
|
|
663
1528
|
}
|
|
664
1529
|
),
|
|
665
|
-
/* @__PURE__ */ (0,
|
|
1530
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
666
1531
|
"button",
|
|
667
1532
|
{
|
|
668
1533
|
type: "button",
|
|
@@ -672,7 +1537,7 @@ function ToolbarComponent({
|
|
|
672
1537
|
),
|
|
673
1538
|
onClick: () => selectGuideOrientation("vertical"),
|
|
674
1539
|
children: [
|
|
675
|
-
/* @__PURE__ */ (0,
|
|
1540
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
676
1541
|
CheckIcon,
|
|
677
1542
|
{
|
|
678
1543
|
size: 12,
|
|
@@ -681,35 +1546,310 @@ function ToolbarComponent({
|
|
|
681
1546
|
)
|
|
682
1547
|
}
|
|
683
1548
|
),
|
|
684
|
-
/* @__PURE__ */ (0,
|
|
685
|
-
/* @__PURE__ */ (0,
|
|
686
|
-
/* @__PURE__ */ (0,
|
|
1549
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MinusIcon, { size: 12, className: "msr:rotate-90" }),
|
|
1550
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "msr:flex-1", children: "Vertical" }),
|
|
1551
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "V" })
|
|
687
1552
|
]
|
|
688
1553
|
}
|
|
689
1554
|
)
|
|
690
1555
|
]
|
|
691
1556
|
}
|
|
692
|
-
) : null
|
|
1557
|
+
) : null
|
|
1558
|
+
]
|
|
1559
|
+
}
|
|
1560
|
+
),
|
|
1561
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { ref: settingsRef, className: "msr:relative msr:flex", children: [
|
|
1562
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1563
|
+
ToolbarButton,
|
|
1564
|
+
{
|
|
1565
|
+
id: "settings",
|
|
1566
|
+
active: settingsOpen,
|
|
1567
|
+
label: "Settings",
|
|
1568
|
+
shortcut: "\u2318/Ctrl+,",
|
|
1569
|
+
onClick: () => {
|
|
1570
|
+
onInteract();
|
|
1571
|
+
setSettingsOpen((previous) => !previous);
|
|
1572
|
+
},
|
|
1573
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "settings",
|
|
1574
|
+
tooltipInstant,
|
|
1575
|
+
tooltipSide,
|
|
1576
|
+
onTooltipEnter,
|
|
1577
|
+
onTooltipLeave,
|
|
1578
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(GearIcon, { size: 20, "aria-hidden": "true" })
|
|
1579
|
+
}
|
|
1580
|
+
),
|
|
1581
|
+
settingsOpen ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1582
|
+
"div",
|
|
1583
|
+
{
|
|
1584
|
+
className: cn(
|
|
1585
|
+
"mesurer-menu-surface msr:absolute msr:-right-1 msr:z-[70] msr:box-border msr:w-[272px] msr:max-w-[calc(100vw-16px)] msr:rounded-lg msr:border msr:border-ink-200 msr:bg-white msr:p-3",
|
|
1586
|
+
menuSide === "bottom" ? "msr:top-full msr:mt-2" : "msr:bottom-full msr:mb-2"
|
|
1587
|
+
),
|
|
1588
|
+
"data-mesurer-inspector-ui": "true",
|
|
1589
|
+
role: "dialog",
|
|
1590
|
+
"aria-label": "Settings",
|
|
1591
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
1592
|
+
onPointerMove: (event) => event.stopPropagation(),
|
|
1593
|
+
onPointerUp: (event) => event.stopPropagation(),
|
|
1594
|
+
onClick: (event) => event.stopPropagation(),
|
|
1595
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1596
|
+
SettingsPanel,
|
|
1597
|
+
{
|
|
1598
|
+
ownerWindow: eventTarget,
|
|
1599
|
+
highlightColor,
|
|
1600
|
+
setHighlightColor,
|
|
1601
|
+
guideColor,
|
|
1602
|
+
setGuideColor,
|
|
1603
|
+
hoverHighlight,
|
|
1604
|
+
setHoverHighlight,
|
|
1605
|
+
persistOnReload,
|
|
1606
|
+
setPersistOnReload,
|
|
1607
|
+
colorFormats: colorPickerFormats,
|
|
1608
|
+
setColorFormats: setColorPickerFormats,
|
|
1609
|
+
colorClickFormat: colorPickerClickFormat,
|
|
1610
|
+
setColorClickFormat: setColorPickerClickFormat,
|
|
1611
|
+
snapEnabled,
|
|
1612
|
+
setSnapEnabled,
|
|
1613
|
+
snapGuidesEnabled,
|
|
1614
|
+
setSnapGuidesEnabled,
|
|
1615
|
+
selectNewGuideEnabled,
|
|
1616
|
+
setSelectNewGuideEnabled,
|
|
1617
|
+
multiMeasureEnabled,
|
|
1618
|
+
setMultiMeasureEnabled,
|
|
1619
|
+
guideStyle,
|
|
1620
|
+
setGuideStyle,
|
|
1621
|
+
rulerSettings,
|
|
1622
|
+
setRulerSettings,
|
|
1623
|
+
initialTab: initialSettingsTab,
|
|
1624
|
+
onResetSettings,
|
|
1625
|
+
onClearWorkspace
|
|
1626
|
+
}
|
|
1627
|
+
)
|
|
1628
|
+
}
|
|
1629
|
+
) : null
|
|
1630
|
+
] })
|
|
1631
|
+
]
|
|
1632
|
+
}
|
|
1633
|
+
);
|
|
1634
|
+
}
|
|
1635
|
+
var Toolbar = (0, import_react3.memo)((0, import_react3.forwardRef)(ToolbarComponent));
|
|
1636
|
+
|
|
1637
|
+
// components/color-picker.tsx
|
|
1638
|
+
var import_react4 = require("react");
|
|
1639
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1640
|
+
function CopyableColorValue({
|
|
1641
|
+
id,
|
|
1642
|
+
value,
|
|
1643
|
+
copiedId,
|
|
1644
|
+
onCopy,
|
|
1645
|
+
onTooltipEnter,
|
|
1646
|
+
tooltip,
|
|
1647
|
+
className
|
|
1648
|
+
}) {
|
|
1649
|
+
const copied = copiedId === id;
|
|
1650
|
+
const showTooltip = tooltip.visibleTooltipId === id || copied && tooltip.visibleTooltipId === null;
|
|
1651
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1652
|
+
"span",
|
|
1653
|
+
{
|
|
1654
|
+
className: "msr:relative msr:inline-flex",
|
|
1655
|
+
onMouseLeave: tooltip.onTooltipLeave,
|
|
1656
|
+
children: [
|
|
1657
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1658
|
+
"button",
|
|
1659
|
+
{
|
|
1660
|
+
type: "button",
|
|
1661
|
+
className,
|
|
1662
|
+
onMouseEnter: () => onTooltipEnter(id),
|
|
1663
|
+
onFocus: () => onTooltipEnter(id),
|
|
1664
|
+
onBlur: tooltip.onTooltipLeave,
|
|
1665
|
+
onClick: onCopy,
|
|
1666
|
+
children: value
|
|
1667
|
+
}
|
|
1668
|
+
),
|
|
1669
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1670
|
+
Tooltip,
|
|
1671
|
+
{
|
|
1672
|
+
label: copied ? "Copied!" : "Click to copy",
|
|
1673
|
+
visible: showTooltip,
|
|
1674
|
+
instant: copied || tooltip.tooltipInstant,
|
|
1675
|
+
side: "bottom",
|
|
1676
|
+
className: "msr:z-10"
|
|
1677
|
+
}
|
|
1678
|
+
)
|
|
1679
|
+
]
|
|
1680
|
+
}
|
|
1681
|
+
);
|
|
1682
|
+
}
|
|
1683
|
+
function ColorPicker({
|
|
1684
|
+
active,
|
|
1685
|
+
sample,
|
|
1686
|
+
unsupported,
|
|
1687
|
+
formats,
|
|
1688
|
+
favoriteFormat,
|
|
1689
|
+
ownerWindow,
|
|
1690
|
+
toolbarRef,
|
|
1691
|
+
onClose
|
|
1692
|
+
}) {
|
|
1693
|
+
const panelRef = (0, import_react4.useRef)(null);
|
|
1694
|
+
const copyTimeoutRef = (0, import_react4.useRef)(null);
|
|
1695
|
+
const [copiedId, setCopiedId] = (0, import_react4.useState)(null);
|
|
1696
|
+
const tooltip = useTooltip();
|
|
1697
|
+
const copyValue = (0, import_react4.useCallback)(
|
|
1698
|
+
(id, value) => {
|
|
1699
|
+
const clipboardWrite = ownerWindow.navigator.clipboard?.writeText(value);
|
|
1700
|
+
void clipboardWrite?.catch(() => void 0);
|
|
1701
|
+
tooltip.onTooltipLeave();
|
|
1702
|
+
setCopiedId(id);
|
|
1703
|
+
if (copyTimeoutRef.current !== null) {
|
|
1704
|
+
ownerWindow.clearTimeout(copyTimeoutRef.current);
|
|
1705
|
+
}
|
|
1706
|
+
copyTimeoutRef.current = ownerWindow.setTimeout(() => {
|
|
1707
|
+
copyTimeoutRef.current = null;
|
|
1708
|
+
setCopiedId(null);
|
|
1709
|
+
}, 1500);
|
|
1710
|
+
},
|
|
1711
|
+
[ownerWindow, tooltip]
|
|
1712
|
+
);
|
|
1713
|
+
const handleTooltipEnter = (0, import_react4.useCallback)(
|
|
1714
|
+
(id) => {
|
|
1715
|
+
if (copiedId !== null && copiedId !== id) {
|
|
1716
|
+
if (copyTimeoutRef.current !== null) {
|
|
1717
|
+
ownerWindow.clearTimeout(copyTimeoutRef.current);
|
|
1718
|
+
copyTimeoutRef.current = null;
|
|
1719
|
+
}
|
|
1720
|
+
setCopiedId(null);
|
|
1721
|
+
}
|
|
1722
|
+
tooltip.onTooltipEnter(id);
|
|
1723
|
+
},
|
|
1724
|
+
[copiedId, ownerWindow, tooltip]
|
|
1725
|
+
);
|
|
1726
|
+
(0, import_react4.useLayoutEffect)(() => {
|
|
1727
|
+
if (!active) return;
|
|
1728
|
+
const panel = panelRef.current;
|
|
1729
|
+
const toolbar = toolbarRef.current;
|
|
1730
|
+
if (!panel || !toolbar) return;
|
|
1731
|
+
let frame = 0;
|
|
1732
|
+
const updatePosition = () => {
|
|
1733
|
+
const toolbarRect = toolbar.getBoundingClientRect();
|
|
1734
|
+
const panelRect = panel.getBoundingClientRect();
|
|
1735
|
+
const left = Math.min(
|
|
1736
|
+
Math.max(8, toolbarRect.left),
|
|
1737
|
+
ownerWindow.innerWidth - panelRect.width - 8
|
|
1738
|
+
);
|
|
1739
|
+
const belowTop = toolbarRect.bottom + 8;
|
|
1740
|
+
const aboveTop = toolbarRect.top - panelRect.height - 8;
|
|
1741
|
+
const top = belowTop + panelRect.height <= ownerWindow.innerHeight ? belowTop : Math.max(8, aboveTop);
|
|
1742
|
+
panel.style.left = `${left}px`;
|
|
1743
|
+
panel.style.top = `${top}px`;
|
|
1744
|
+
frame = ownerWindow.requestAnimationFrame(updatePosition);
|
|
1745
|
+
};
|
|
1746
|
+
frame = ownerWindow.requestAnimationFrame(updatePosition);
|
|
1747
|
+
return () => ownerWindow.cancelAnimationFrame(frame);
|
|
1748
|
+
}, [active, ownerWindow, toolbarRef, formats, sample, unsupported, favoriteFormat]);
|
|
1749
|
+
(0, import_react4.useLayoutEffect)(() => {
|
|
1750
|
+
return () => {
|
|
1751
|
+
if (copyTimeoutRef.current !== null) {
|
|
1752
|
+
ownerWindow.clearTimeout(copyTimeoutRef.current);
|
|
1753
|
+
}
|
|
1754
|
+
};
|
|
1755
|
+
}, [ownerWindow]);
|
|
1756
|
+
if (!active || !sample && !unsupported) return null;
|
|
1757
|
+
const headerFormat = formats.includes(favoriteFormat) ? favoriteFormat : formats[0];
|
|
1758
|
+
const secondaryFormats = headerFormat ? formats.filter((format) => format !== headerFormat) : [];
|
|
1759
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1760
|
+
"div",
|
|
1761
|
+
{
|
|
1762
|
+
ref: panelRef,
|
|
1763
|
+
className: "mesurer-color-picker msr:pointer-events-auto msr:fixed msr:z-[80] msr:min-w-36 msr:rounded-lg msr:border msr:border-black/10 msr:bg-white msr:px-2 msr:py-2 msr:font-mono msr:text-[10px] msr:leading-4 msr:shadow-lg",
|
|
1764
|
+
role: "dialog",
|
|
1765
|
+
"aria-label": "Selected color values",
|
|
1766
|
+
onMouseLeave: tooltip.onTooltipContainerLeave,
|
|
1767
|
+
children: unsupported ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "msr:flex msr:items-start msr:gap-2", children: [
|
|
1768
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "msr:text-black/60", children: "Color picker is not supported in this browser." }),
|
|
1769
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1770
|
+
"button",
|
|
1771
|
+
{
|
|
1772
|
+
type: "button",
|
|
1773
|
+
className: "msr:text-black/45 msr:hover:text-black",
|
|
1774
|
+
"aria-label": "Close color picker message",
|
|
1775
|
+
onClick: onClose,
|
|
1776
|
+
children: "x"
|
|
1777
|
+
}
|
|
1778
|
+
)
|
|
1779
|
+
] }) : sample ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1780
|
+
headerFormat ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1781
|
+
"div",
|
|
1782
|
+
{
|
|
1783
|
+
className: secondaryFormats.length > 0 ? "msr:mb-1 msr:flex msr:items-center msr:gap-1.5 msr:border-b msr:border-black/8 msr:pb-1" : "msr:flex msr:items-center msr:gap-1.5",
|
|
1784
|
+
children: [
|
|
1785
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1786
|
+
"span",
|
|
1787
|
+
{
|
|
1788
|
+
className: "msr:size-3 msr:shrink-0 msr:rounded-full msr:border msr:border-black/15",
|
|
1789
|
+
style: { backgroundColor: colorToHex(sample) },
|
|
1790
|
+
"aria-hidden": "true"
|
|
1791
|
+
}
|
|
1792
|
+
),
|
|
1793
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1794
|
+
CopyableColorValue,
|
|
1795
|
+
{
|
|
1796
|
+
id: headerFormat,
|
|
1797
|
+
value: formatColor(sample, headerFormat),
|
|
1798
|
+
copiedId,
|
|
1799
|
+
onCopy: () => copyValue(headerFormat, formatColor(sample, headerFormat)),
|
|
1800
|
+
onTooltipEnter: handleTooltipEnter,
|
|
1801
|
+
tooltip,
|
|
1802
|
+
className: "msr:font-medium msr:tabular-nums msr:text-black msr:hover:underline"
|
|
1803
|
+
}
|
|
1804
|
+
)
|
|
693
1805
|
]
|
|
694
1806
|
}
|
|
695
|
-
)
|
|
696
|
-
|
|
1807
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "msr:flex msr:items-center", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1808
|
+
"span",
|
|
1809
|
+
{
|
|
1810
|
+
className: "msr:size-3 msr:shrink-0 msr:rounded-full msr:border msr:border-black/15",
|
|
1811
|
+
style: { backgroundColor: colorToHex(sample) },
|
|
1812
|
+
"aria-hidden": "true"
|
|
1813
|
+
}
|
|
1814
|
+
) }),
|
|
1815
|
+
secondaryFormats.map((format) => {
|
|
1816
|
+
const value = formatColor(sample, format);
|
|
1817
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "msr:flex msr:items-center msr:gap-2", children: [
|
|
1818
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "msr:w-9 msr:text-black/45", children: format }),
|
|
1819
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1820
|
+
CopyableColorValue,
|
|
1821
|
+
{
|
|
1822
|
+
id: format,
|
|
1823
|
+
value,
|
|
1824
|
+
copiedId,
|
|
1825
|
+
onCopy: () => copyValue(format, value),
|
|
1826
|
+
onTooltipEnter: handleTooltipEnter,
|
|
1827
|
+
tooltip,
|
|
1828
|
+
className: "msr:tabular-nums msr:text-black msr:hover:underline"
|
|
1829
|
+
}
|
|
1830
|
+
)
|
|
1831
|
+
] }, format);
|
|
1832
|
+
})
|
|
1833
|
+
] }) : null
|
|
697
1834
|
}
|
|
698
1835
|
);
|
|
699
1836
|
}
|
|
700
|
-
var Toolbar = (0, import_react.memo)((0, import_react.forwardRef)(ToolbarComponent));
|
|
701
1837
|
|
|
702
1838
|
// components/rulers-overlay.tsx
|
|
703
|
-
var
|
|
704
|
-
var
|
|
1839
|
+
var import_react5 = require("react");
|
|
1840
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
705
1841
|
var RULER_SIZE = 18;
|
|
706
1842
|
var RULER_LENGTH = 4e3;
|
|
707
1843
|
var TICK_STEP = 5;
|
|
1844
|
+
var RULER_EDGE_REVEAL_DISTANCE = 32;
|
|
1845
|
+
var RULER_FADE_MS = 100;
|
|
708
1846
|
var ticks = Array.from(
|
|
709
1847
|
{ length: RULER_LENGTH / TICK_STEP + 1 },
|
|
710
1848
|
(_, index) => index * TICK_STEP
|
|
711
1849
|
);
|
|
712
|
-
var RulersOverlay = (0,
|
|
1850
|
+
var RulersOverlay = (0, import_react5.memo)(function RulersOverlay2({
|
|
1851
|
+
ownerWindow,
|
|
1852
|
+
settings,
|
|
713
1853
|
onStartGuide,
|
|
714
1854
|
onMoveGuide,
|
|
715
1855
|
onFinishGuide,
|
|
@@ -717,9 +1857,26 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
717
1857
|
guides,
|
|
718
1858
|
selectedGuideIds
|
|
719
1859
|
}) {
|
|
720
|
-
const [dragPosition, setDragPosition] = (0,
|
|
721
|
-
const [dragOrientation, setDragOrientation] = (0,
|
|
722
|
-
const
|
|
1860
|
+
const [dragPosition, setDragPosition] = (0, import_react5.useState)(null);
|
|
1861
|
+
const [dragOrientation, setDragOrientation] = (0, import_react5.useState)(null);
|
|
1862
|
+
const [nearEdge, setNearEdge] = (0, import_react5.useState)(false);
|
|
1863
|
+
const dragRef = (0, import_react5.useRef)(null);
|
|
1864
|
+
(0, import_react5.useEffect)(() => {
|
|
1865
|
+
if (!settings.edgeReveal) return;
|
|
1866
|
+
const handlePointerMove = (event) => {
|
|
1867
|
+
const pointer = event;
|
|
1868
|
+
const nearHorizontalEdge = pointer.clientX <= RULER_EDGE_REVEAL_DISTANCE || pointer.clientX >= ownerWindow.innerWidth - RULER_EDGE_REVEAL_DISTANCE;
|
|
1869
|
+
const nearVerticalEdge = pointer.clientY <= RULER_EDGE_REVEAL_DISTANCE || pointer.clientY >= ownerWindow.innerHeight - RULER_EDGE_REVEAL_DISTANCE;
|
|
1870
|
+
setNearEdge(nearHorizontalEdge || nearVerticalEdge);
|
|
1871
|
+
};
|
|
1872
|
+
ownerWindow.document.addEventListener("pointermove", handlePointerMove, true);
|
|
1873
|
+
ownerWindow.document.addEventListener("mousemove", handlePointerMove, true);
|
|
1874
|
+
return () => {
|
|
1875
|
+
ownerWindow.document.removeEventListener("pointermove", handlePointerMove, true);
|
|
1876
|
+
ownerWindow.document.removeEventListener("mousemove", handlePointerMove, true);
|
|
1877
|
+
};
|
|
1878
|
+
}, [ownerWindow, settings.edgeReveal]);
|
|
1879
|
+
const showRulers = !settings.edgeReveal || nearEdge;
|
|
723
1880
|
const beginGuideDrag = (orientation, event) => {
|
|
724
1881
|
if (event.button !== 0) return;
|
|
725
1882
|
event.stopPropagation();
|
|
@@ -769,13 +1926,18 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
769
1926
|
const selectedHorizontalGuides = guides.filter(
|
|
770
1927
|
(guide) => guide.orientation === "horizontal" && selectedGuideIds.includes(guide.id)
|
|
771
1928
|
);
|
|
772
|
-
return /* @__PURE__ */ (0,
|
|
1929
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
773
1930
|
"div",
|
|
774
1931
|
{
|
|
775
1932
|
"aria-hidden": "true",
|
|
1933
|
+
"data-mesurer-rulers": "true",
|
|
776
1934
|
className: "msr:pointer-events-none msr:absolute msr:inset-0 msr:select-none msr:text-[9px] msr:text-[#64748b]",
|
|
1935
|
+
style: {
|
|
1936
|
+
opacity: showRulers ? settings.opacity : 0,
|
|
1937
|
+
transition: `opacity ${RULER_FADE_MS}ms ease`
|
|
1938
|
+
},
|
|
777
1939
|
children: [
|
|
778
|
-
/* @__PURE__ */ (0,
|
|
1940
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
779
1941
|
"div",
|
|
780
1942
|
{
|
|
781
1943
|
className: "msr:absolute msr:left-[18px] msr:right-0 msr:top-0 msr:overflow-hidden msr:bg-white",
|
|
@@ -783,13 +1945,13 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
783
1945
|
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.12)",
|
|
784
1946
|
height: RULER_SIZE,
|
|
785
1947
|
cursor: "ns-resize",
|
|
786
|
-
pointerEvents: "auto"
|
|
1948
|
+
pointerEvents: showRulers ? "auto" : "none"
|
|
787
1949
|
},
|
|
788
1950
|
onPointerDown: (event) => beginGuideDrag("horizontal", event),
|
|
789
1951
|
onPointerMove: moveGuide,
|
|
790
1952
|
onPointerUp: finishGuideDrag,
|
|
791
1953
|
onPointerCancel: cancelGuideDrag,
|
|
792
|
-
children: /* @__PURE__ */ (0,
|
|
1954
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
793
1955
|
"svg",
|
|
794
1956
|
{
|
|
795
1957
|
className: "msr:block msr:h-6",
|
|
@@ -797,7 +1959,7 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
797
1959
|
height: RULER_SIZE,
|
|
798
1960
|
viewBox: `0 0 ${RULER_LENGTH} ${RULER_SIZE}`,
|
|
799
1961
|
children: [
|
|
800
|
-
/* @__PURE__ */ (0,
|
|
1962
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
801
1963
|
"linearGradient",
|
|
802
1964
|
{
|
|
803
1965
|
id: "ruler-label-fade-x",
|
|
@@ -805,18 +1967,18 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
805
1967
|
x2: "100%",
|
|
806
1968
|
gradientUnits: "objectBoundingBox",
|
|
807
1969
|
children: [
|
|
808
|
-
/* @__PURE__ */ (0,
|
|
809
|
-
/* @__PURE__ */ (0,
|
|
810
|
-
/* @__PURE__ */ (0,
|
|
811
|
-
/* @__PURE__ */ (0,
|
|
1970
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("stop", { offset: "0", stopColor: "white", stopOpacity: "0" }),
|
|
1971
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("stop", { offset: "0.2", stopColor: "white" }),
|
|
1972
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("stop", { offset: "0.8", stopColor: "white" }),
|
|
1973
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
|
|
812
1974
|
]
|
|
813
1975
|
}
|
|
814
1976
|
) }),
|
|
815
1977
|
ticks.map((x) => {
|
|
816
1978
|
const major = x % 100 === 0;
|
|
817
1979
|
const medium = x % 50 === 0;
|
|
818
|
-
return /* @__PURE__ */ (0,
|
|
819
|
-
/* @__PURE__ */ (0,
|
|
1980
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("g", { children: [
|
|
1981
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
820
1982
|
"line",
|
|
821
1983
|
{
|
|
822
1984
|
x1: x,
|
|
@@ -827,11 +1989,11 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
827
1989
|
strokeWidth: "1"
|
|
828
1990
|
}
|
|
829
1991
|
),
|
|
830
|
-
major ? /* @__PURE__ */ (0,
|
|
1992
|
+
major ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("text", { x, y: "8", textAnchor: "middle", fill: "currentColor", children: x }) : null
|
|
831
1993
|
] }, x);
|
|
832
1994
|
}),
|
|
833
|
-
selectedVerticalGuides.map((guide) => /* @__PURE__ */ (0,
|
|
834
|
-
/* @__PURE__ */ (0,
|
|
1995
|
+
selectedVerticalGuides.map((guide) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("g", { children: [
|
|
1996
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
835
1997
|
"rect",
|
|
836
1998
|
{
|
|
837
1999
|
x: guide.position - RULER_SIZE - 8,
|
|
@@ -841,7 +2003,7 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
841
2003
|
fill: "url(#ruler-label-fade-x)"
|
|
842
2004
|
}
|
|
843
2005
|
),
|
|
844
|
-
/* @__PURE__ */ (0,
|
|
2006
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
845
2007
|
"text",
|
|
846
2008
|
{
|
|
847
2009
|
x: guide.position - RULER_SIZE + 16,
|
|
@@ -853,8 +2015,8 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
853
2015
|
}
|
|
854
2016
|
)
|
|
855
2017
|
] }, guide.id)),
|
|
856
|
-
dragOrientation === "vertical" && dragPosition !== null ? /* @__PURE__ */ (0,
|
|
857
|
-
/* @__PURE__ */ (0,
|
|
2018
|
+
dragOrientation === "vertical" && dragPosition !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("g", { children: [
|
|
2019
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
858
2020
|
"rect",
|
|
859
2021
|
{
|
|
860
2022
|
x: dragPosition - RULER_SIZE - 8,
|
|
@@ -864,7 +2026,7 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
864
2026
|
fill: "url(#ruler-label-fade-x)"
|
|
865
2027
|
}
|
|
866
2028
|
),
|
|
867
|
-
/* @__PURE__ */ (0,
|
|
2029
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
868
2030
|
"text",
|
|
869
2031
|
{
|
|
870
2032
|
x: dragPosition - RULER_SIZE + 16,
|
|
@@ -881,7 +2043,7 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
881
2043
|
)
|
|
882
2044
|
}
|
|
883
2045
|
),
|
|
884
|
-
/* @__PURE__ */ (0,
|
|
2046
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
885
2047
|
"div",
|
|
886
2048
|
{
|
|
887
2049
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:top-[18px] msr:w-[18px] msr:overflow-hidden msr:bg-white",
|
|
@@ -889,13 +2051,13 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
889
2051
|
boxShadow: "1px 0 3px rgba(0, 0, 0, 0.12)",
|
|
890
2052
|
width: RULER_SIZE,
|
|
891
2053
|
cursor: "ew-resize",
|
|
892
|
-
pointerEvents: "auto"
|
|
2054
|
+
pointerEvents: showRulers ? "auto" : "none"
|
|
893
2055
|
},
|
|
894
2056
|
onPointerDown: (event) => beginGuideDrag("vertical", event),
|
|
895
2057
|
onPointerMove: moveGuide,
|
|
896
2058
|
onPointerUp: finishGuideDrag,
|
|
897
2059
|
onPointerCancel: cancelGuideDrag,
|
|
898
|
-
children: /* @__PURE__ */ (0,
|
|
2060
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
899
2061
|
"svg",
|
|
900
2062
|
{
|
|
901
2063
|
className: "msr:block msr:w-6",
|
|
@@ -903,7 +2065,7 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
903
2065
|
height: RULER_LENGTH,
|
|
904
2066
|
viewBox: `0 0 ${RULER_SIZE} ${RULER_LENGTH}`,
|
|
905
2067
|
children: [
|
|
906
|
-
/* @__PURE__ */ (0,
|
|
2068
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
907
2069
|
"linearGradient",
|
|
908
2070
|
{
|
|
909
2071
|
id: "ruler-label-fade-y",
|
|
@@ -911,18 +2073,18 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
911
2073
|
y2: "100%",
|
|
912
2074
|
gradientUnits: "objectBoundingBox",
|
|
913
2075
|
children: [
|
|
914
|
-
/* @__PURE__ */ (0,
|
|
915
|
-
/* @__PURE__ */ (0,
|
|
916
|
-
/* @__PURE__ */ (0,
|
|
917
|
-
/* @__PURE__ */ (0,
|
|
2076
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("stop", { offset: "0", stopColor: "white", stopOpacity: "0" }),
|
|
2077
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("stop", { offset: "0.2", stopColor: "white" }),
|
|
2078
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("stop", { offset: "0.8", stopColor: "white" }),
|
|
2079
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
|
|
918
2080
|
]
|
|
919
2081
|
}
|
|
920
2082
|
) }),
|
|
921
2083
|
ticks.map((y) => {
|
|
922
2084
|
const major = y % 100 === 0;
|
|
923
2085
|
const medium = y % 50 === 0;
|
|
924
|
-
return /* @__PURE__ */ (0,
|
|
925
|
-
/* @__PURE__ */ (0,
|
|
2086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("g", { children: [
|
|
2087
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
926
2088
|
"line",
|
|
927
2089
|
{
|
|
928
2090
|
x1: RULER_SIZE,
|
|
@@ -933,7 +2095,7 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
933
2095
|
strokeWidth: "1"
|
|
934
2096
|
}
|
|
935
2097
|
),
|
|
936
|
-
major ? /* @__PURE__ */ (0,
|
|
2098
|
+
major ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
937
2099
|
"text",
|
|
938
2100
|
{
|
|
939
2101
|
x: "8",
|
|
@@ -945,8 +2107,8 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
945
2107
|
) : null
|
|
946
2108
|
] }, y);
|
|
947
2109
|
}),
|
|
948
|
-
selectedHorizontalGuides.map((guide) => /* @__PURE__ */ (0,
|
|
949
|
-
/* @__PURE__ */ (0,
|
|
2110
|
+
selectedHorizontalGuides.map((guide) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("g", { children: [
|
|
2111
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
950
2112
|
"rect",
|
|
951
2113
|
{
|
|
952
2114
|
x: "-3",
|
|
@@ -956,7 +2118,7 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
956
2118
|
fill: "url(#ruler-label-fade-y)"
|
|
957
2119
|
}
|
|
958
2120
|
),
|
|
959
|
-
/* @__PURE__ */ (0,
|
|
2121
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
960
2122
|
"text",
|
|
961
2123
|
{
|
|
962
2124
|
x: "9",
|
|
@@ -969,8 +2131,8 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
969
2131
|
}
|
|
970
2132
|
)
|
|
971
2133
|
] }, guide.id)),
|
|
972
|
-
dragOrientation === "horizontal" && dragPosition !== null ? /* @__PURE__ */ (0,
|
|
973
|
-
/* @__PURE__ */ (0,
|
|
2134
|
+
dragOrientation === "horizontal" && dragPosition !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("g", { children: [
|
|
2135
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
974
2136
|
"rect",
|
|
975
2137
|
{
|
|
976
2138
|
x: "-3",
|
|
@@ -980,7 +2142,7 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
980
2142
|
fill: "url(#ruler-label-fade-y)"
|
|
981
2143
|
}
|
|
982
2144
|
),
|
|
983
|
-
/* @__PURE__ */ (0,
|
|
2145
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
984
2146
|
"text",
|
|
985
2147
|
{
|
|
986
2148
|
x: "9",
|
|
@@ -998,34 +2160,34 @@ var RulersOverlay = (0, import_react2.memo)(function RulersOverlay2({
|
|
|
998
2160
|
)
|
|
999
2161
|
}
|
|
1000
2162
|
),
|
|
1001
|
-
/* @__PURE__ */ (0,
|
|
2163
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "msr:absolute msr:left-0 msr:top-0 msr:size-[18px] msr:bg-white" })
|
|
1002
2164
|
]
|
|
1003
2165
|
}
|
|
1004
2166
|
);
|
|
1005
2167
|
});
|
|
1006
2168
|
|
|
1007
2169
|
// hooks/use-drag-state.ts
|
|
1008
|
-
var
|
|
2170
|
+
var import_react6 = require("react");
|
|
1009
2171
|
var useDragState = () => {
|
|
1010
|
-
const [start, setStart] = (0,
|
|
1011
|
-
const [end, setEnd] = (0,
|
|
1012
|
-
const [isDragging, setIsDragging] = (0,
|
|
2172
|
+
const [start, setStart] = (0, import_react6.useState)(null);
|
|
2173
|
+
const [end, setEnd] = (0, import_react6.useState)(null);
|
|
2174
|
+
const [isDragging, setIsDragging] = (0, import_react6.useState)(false);
|
|
1013
2175
|
return { start, setStart, end, setEnd, isDragging, setIsDragging };
|
|
1014
2176
|
};
|
|
1015
2177
|
|
|
1016
2178
|
// hooks/use-guide-drag-hold.ts
|
|
1017
|
-
var
|
|
2179
|
+
var import_react7 = require("react");
|
|
1018
2180
|
var useGuideDragHold = (eventTarget) => {
|
|
1019
|
-
const guideDragHoldTimerRef = (0,
|
|
1020
|
-
const guideDragHoldGuideIdRef = (0,
|
|
1021
|
-
const clearGuideDragHold = (0,
|
|
2181
|
+
const guideDragHoldTimerRef = (0, import_react7.useRef)(null);
|
|
2182
|
+
const guideDragHoldGuideIdRef = (0, import_react7.useRef)(null);
|
|
2183
|
+
const clearGuideDragHold = (0, import_react7.useCallback)(() => {
|
|
1022
2184
|
if (guideDragHoldTimerRef.current !== null) {
|
|
1023
2185
|
eventTarget.clearTimeout(guideDragHoldTimerRef.current);
|
|
1024
2186
|
guideDragHoldTimerRef.current = null;
|
|
1025
2187
|
}
|
|
1026
2188
|
guideDragHoldGuideIdRef.current = null;
|
|
1027
2189
|
}, []);
|
|
1028
|
-
const scheduleGuideDragHold = (0,
|
|
2190
|
+
const scheduleGuideDragHold = (0, import_react7.useCallback)(
|
|
1029
2191
|
(id, onHold) => {
|
|
1030
2192
|
clearGuideDragHold();
|
|
1031
2193
|
guideDragHoldGuideIdRef.current = id;
|
|
@@ -1044,11 +2206,11 @@ var useGuideDragHold = (eventTarget) => {
|
|
|
1044
2206
|
};
|
|
1045
2207
|
|
|
1046
2208
|
// hooks/use-guide-state.ts
|
|
1047
|
-
var
|
|
2209
|
+
var import_react8 = require("react");
|
|
1048
2210
|
var useGuideState = (options = {}) => {
|
|
1049
|
-
const [guides, setGuides] = (0,
|
|
1050
|
-
const [draggingGuideId, setDraggingGuideId] = (0,
|
|
1051
|
-
const [selectedGuideIds, setSelectedGuideIds] = (0,
|
|
2211
|
+
const [guides, setGuides] = (0, import_react8.useState)(options.initialGuides ?? []);
|
|
2212
|
+
const [draggingGuideId, setDraggingGuideId] = (0, import_react8.useState)(null);
|
|
2213
|
+
const [selectedGuideIds, setSelectedGuideIds] = (0, import_react8.useState)(
|
|
1052
2214
|
options.initialSelectedGuideIds ?? []
|
|
1053
2215
|
);
|
|
1054
2216
|
return {
|
|
@@ -1062,67 +2224,91 @@ var useGuideState = (options = {}) => {
|
|
|
1062
2224
|
};
|
|
1063
2225
|
|
|
1064
2226
|
// hooks/use-hotkeys.ts
|
|
1065
|
-
var
|
|
2227
|
+
var import_react9 = require("react");
|
|
1066
2228
|
var useHotkeys = (options) => {
|
|
1067
|
-
(0,
|
|
2229
|
+
const optionsRef = (0, import_react9.useRef)(options);
|
|
2230
|
+
optionsRef.current = options;
|
|
2231
|
+
(0, import_react9.useEffect)(() => {
|
|
1068
2232
|
const target = options.eventTarget;
|
|
1069
2233
|
const handleKeyDown = (event) => {
|
|
2234
|
+
const current = optionsRef.current;
|
|
1070
2235
|
if (event.key === "Escape") {
|
|
1071
|
-
|
|
2236
|
+
if (current.isSettingsOpen()) {
|
|
2237
|
+
current.onToggleSettings();
|
|
2238
|
+
return;
|
|
2239
|
+
}
|
|
2240
|
+
if (current.isColorPickerActive()) {
|
|
2241
|
+
current.onCloseColorPicker();
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2244
|
+
current.clearAll();
|
|
1072
2245
|
return;
|
|
1073
2246
|
}
|
|
1074
2247
|
if (event.metaKey || event.ctrlKey) {
|
|
2248
|
+
if (event.key === ",") {
|
|
2249
|
+
event.preventDefault();
|
|
2250
|
+
current.onToggleSettings();
|
|
2251
|
+
current.onInteract();
|
|
2252
|
+
return;
|
|
2253
|
+
}
|
|
1075
2254
|
if (event.key.toLowerCase() !== "z") return;
|
|
1076
2255
|
if (event.shiftKey) {
|
|
1077
2256
|
event.preventDefault();
|
|
1078
|
-
|
|
2257
|
+
current.redo();
|
|
1079
2258
|
return;
|
|
1080
2259
|
}
|
|
1081
2260
|
event.preventDefault();
|
|
1082
|
-
|
|
2261
|
+
current.undo();
|
|
1083
2262
|
return;
|
|
1084
2263
|
}
|
|
1085
2264
|
if (event.key.toLowerCase() === "m") {
|
|
1086
|
-
|
|
2265
|
+
current.setEnabled((prev) => !prev);
|
|
1087
2266
|
}
|
|
1088
2267
|
const key = event.key.toLowerCase();
|
|
1089
|
-
if (
|
|
2268
|
+
if (key === "p") {
|
|
2269
|
+
event.preventDefault();
|
|
2270
|
+
current.onColorPicker();
|
|
2271
|
+
current.onInteract();
|
|
2272
|
+
return;
|
|
2273
|
+
}
|
|
2274
|
+
if (key === "x") {
|
|
2275
|
+
current.onToggleXray();
|
|
2276
|
+
current.onInteract();
|
|
2277
|
+
return;
|
|
2278
|
+
}
|
|
2279
|
+
if (current.isOverlayActive()) {
|
|
1090
2280
|
if (key === "a") {
|
|
1091
|
-
|
|
2281
|
+
current.setToolMode(
|
|
1092
2282
|
(prev) => prev === "text-inspector" ? "none" : "text-inspector"
|
|
1093
2283
|
);
|
|
1094
|
-
|
|
2284
|
+
current.onInteract();
|
|
1095
2285
|
}
|
|
1096
2286
|
if (key === "s") {
|
|
1097
|
-
|
|
1098
|
-
|
|
2287
|
+
current.setToolMode((prev) => prev === "select" ? "none" : "select");
|
|
2288
|
+
current.onInteract();
|
|
1099
2289
|
}
|
|
1100
2290
|
if (key === "g") {
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
}
|
|
1104
|
-
if (key === "x") {
|
|
1105
|
-
options.setToolMode((prev) => prev === "xray" ? "none" : "xray");
|
|
1106
|
-
options.onInteract();
|
|
2291
|
+
current.setToolMode((prev) => prev === "guides" ? "none" : "guides");
|
|
2292
|
+
current.onInteract();
|
|
1107
2293
|
}
|
|
1108
2294
|
if (key === "r") {
|
|
1109
|
-
|
|
1110
|
-
|
|
2295
|
+
current.setRulersVisible((prev) => !prev);
|
|
2296
|
+
current.onInteract();
|
|
1111
2297
|
}
|
|
1112
2298
|
if (key === "h") {
|
|
1113
|
-
|
|
1114
|
-
|
|
2299
|
+
current.setGuideOrientation("horizontal");
|
|
2300
|
+
current.onInteract();
|
|
1115
2301
|
}
|
|
1116
2302
|
if (key === "v") {
|
|
1117
|
-
|
|
1118
|
-
|
|
2303
|
+
current.setGuideOrientation("vertical");
|
|
2304
|
+
current.onInteract();
|
|
1119
2305
|
}
|
|
1120
2306
|
}
|
|
1121
2307
|
if (event.key === "Alt") {
|
|
1122
|
-
|
|
2308
|
+
current.setAltPressed(true);
|
|
1123
2309
|
}
|
|
1124
2310
|
if (event.key === "Backspace" || event.key === "Delete") {
|
|
1125
|
-
const removed =
|
|
2311
|
+
const removed = current.removeSelectedGuides();
|
|
1126
2312
|
if (removed) {
|
|
1127
2313
|
event.preventDefault();
|
|
1128
2314
|
}
|
|
@@ -1130,7 +2316,7 @@ var useHotkeys = (options) => {
|
|
|
1130
2316
|
};
|
|
1131
2317
|
const handleKeyUp = (event) => {
|
|
1132
2318
|
if (event.key === "Alt") {
|
|
1133
|
-
|
|
2319
|
+
optionsRef.current.setAltPressed(false);
|
|
1134
2320
|
}
|
|
1135
2321
|
};
|
|
1136
2322
|
target.addEventListener("keydown", handleKeyDown);
|
|
@@ -1139,11 +2325,11 @@ var useHotkeys = (options) => {
|
|
|
1139
2325
|
target.removeEventListener("keydown", handleKeyDown);
|
|
1140
2326
|
target.removeEventListener("keyup", handleKeyUp);
|
|
1141
2327
|
};
|
|
1142
|
-
}, [options]);
|
|
2328
|
+
}, [options.eventTarget]);
|
|
1143
2329
|
};
|
|
1144
2330
|
|
|
1145
2331
|
// hooks/use-live-element-tracking.ts
|
|
1146
|
-
var
|
|
2332
|
+
var import_react10 = require("react");
|
|
1147
2333
|
|
|
1148
2334
|
// core/geometry.ts
|
|
1149
2335
|
var getViewportSize = (ownerWindow) => ({
|
|
@@ -1169,7 +2355,7 @@ var getRectFromPoints = (start, end) => {
|
|
|
1169
2355
|
const height = Math.abs(start.y - end.y);
|
|
1170
2356
|
return { left, top, width, height };
|
|
1171
2357
|
};
|
|
1172
|
-
var
|
|
2358
|
+
var clamp2 = (value, min, max) => Math.max(min, Math.min(max, value));
|
|
1173
2359
|
var rectsOverlap = (rectA, rectB) => rectA.left < rectB.left + rectB.width && rectA.left + rectA.width > rectB.left && rectA.top < rectB.top + rectB.height && rectA.top + rectA.height > rectB.top;
|
|
1174
2360
|
var rectArea = (rect) => rect.width * rect.height;
|
|
1175
2361
|
var intersectionArea = (rectA, rectB) => {
|
|
@@ -1233,10 +2419,10 @@ var getDistanceOverlay = (rectA, rectB, elementRefA, elementRefB, ownerWindow =
|
|
|
1233
2419
|
}
|
|
1234
2420
|
}
|
|
1235
2421
|
const normalizedConnectors = connectors.map((segment) => ({
|
|
1236
|
-
x1:
|
|
1237
|
-
y1:
|
|
1238
|
-
x2:
|
|
1239
|
-
y2:
|
|
2422
|
+
x1: clamp2(segment.x1, 0, ownerWindow.innerWidth),
|
|
2423
|
+
y1: clamp2(segment.y1, 0, ownerWindow.innerHeight),
|
|
2424
|
+
x2: clamp2(segment.x2, 0, ownerWindow.innerWidth),
|
|
2425
|
+
y2: clamp2(segment.y2, 0, ownerWindow.innerHeight)
|
|
1240
2426
|
})).filter(
|
|
1241
2427
|
(segment) => Math.abs(segment.x1 - segment.x2) > 0.5 || Math.abs(segment.y1 - segment.y2) > 0.5
|
|
1242
2428
|
);
|
|
@@ -1403,19 +2589,23 @@ var updateMeasurementForResize = (measurement, viewport = getViewportSize(), own
|
|
|
1403
2589
|
|
|
1404
2590
|
// hooks/use-live-element-tracking.ts
|
|
1405
2591
|
var useLiveElementTracking = (params) => {
|
|
1406
|
-
const
|
|
1407
|
-
|
|
2592
|
+
const paramsRef = (0, import_react10.useRef)(params);
|
|
2593
|
+
paramsRef.current = params;
|
|
2594
|
+
const frameRef = (0, import_react10.useRef)(null);
|
|
2595
|
+
(0, import_react10.useEffect)(() => {
|
|
2596
|
+
const ownerWindow = params.window;
|
|
1408
2597
|
if (!params.enabled) {
|
|
1409
2598
|
if (frameRef.current) {
|
|
1410
|
-
|
|
2599
|
+
ownerWindow.cancelAnimationFrame(frameRef.current);
|
|
1411
2600
|
}
|
|
1412
2601
|
frameRef.current = null;
|
|
1413
2602
|
return;
|
|
1414
2603
|
}
|
|
1415
2604
|
const tick = () => {
|
|
1416
|
-
|
|
2605
|
+
const current = paramsRef.current;
|
|
2606
|
+
current.setMeasurements(
|
|
1417
2607
|
(prev) => prev.map((measurement) => {
|
|
1418
|
-
if (!measurement.elementRef || !
|
|
2608
|
+
if (!measurement.elementRef || !current.document.contains(measurement.elementRef)) {
|
|
1419
2609
|
return measurement;
|
|
1420
2610
|
}
|
|
1421
2611
|
const rect = getRectFromDom(measurement.elementRef);
|
|
@@ -1428,8 +2618,8 @@ var useLiveElementTracking = (params) => {
|
|
|
1428
2618
|
};
|
|
1429
2619
|
})
|
|
1430
2620
|
);
|
|
1431
|
-
|
|
1432
|
-
if (!prev?.elementRef || !
|
|
2621
|
+
current.setActiveMeasurement((prev) => {
|
|
2622
|
+
if (!prev?.elementRef || !current.document.contains(prev.elementRef))
|
|
1433
2623
|
return prev;
|
|
1434
2624
|
const rect = getRectFromDom(prev.elementRef);
|
|
1435
2625
|
if (rectAlmostEqual(rect, prev.rect)) return prev;
|
|
@@ -1440,10 +2630,10 @@ var useLiveElementTracking = (params) => {
|
|
|
1440
2630
|
originRect: void 0
|
|
1441
2631
|
};
|
|
1442
2632
|
});
|
|
1443
|
-
|
|
2633
|
+
current.setHeldDistances(
|
|
1444
2634
|
(prev) => prev.map((distance) => {
|
|
1445
|
-
const canTrackA = distance.elementRefA &&
|
|
1446
|
-
const canTrackB = distance.elementRefB &&
|
|
2635
|
+
const canTrackA = distance.elementRefA && current.document.contains(distance.elementRefA);
|
|
2636
|
+
const canTrackB = distance.elementRefB && current.document.contains(distance.elementRefB);
|
|
1447
2637
|
if (!canTrackA && !canTrackB) return distance;
|
|
1448
2638
|
const rectA = canTrackA ? getRectFromDom(distance.elementRefA) : distance.rectA;
|
|
1449
2639
|
const rectB = canTrackB ? getRectFromDom(distance.elementRefB) : distance.rectB;
|
|
@@ -1455,7 +2645,7 @@ var useLiveElementTracking = (params) => {
|
|
|
1455
2645
|
rectB,
|
|
1456
2646
|
distance.elementRefA,
|
|
1457
2647
|
distance.elementRefB,
|
|
1458
|
-
|
|
2648
|
+
ownerWindow
|
|
1459
2649
|
);
|
|
1460
2650
|
return {
|
|
1461
2651
|
...updated,
|
|
@@ -1463,62 +2653,71 @@ var useLiveElementTracking = (params) => {
|
|
|
1463
2653
|
};
|
|
1464
2654
|
})
|
|
1465
2655
|
);
|
|
1466
|
-
const selected =
|
|
1467
|
-
if (selected &&
|
|
1468
|
-
|
|
1469
|
-
const next = getInspectMeasurement(selected,
|
|
2656
|
+
const selected = current.selectedElementRef.current;
|
|
2657
|
+
if (current.selectionEnabled && selected && current.document.contains(selected)) {
|
|
2658
|
+
current.setSelectedMeasurement((prev) => {
|
|
2659
|
+
const next = getInspectMeasurement(selected, ownerWindow);
|
|
1470
2660
|
if (prev && rectAlmostEqual(prev.rect, next.rect)) return prev;
|
|
1471
2661
|
return next;
|
|
1472
2662
|
});
|
|
1473
2663
|
}
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
2664
|
+
if (current.selectionEnabled) {
|
|
2665
|
+
current.setSelectedMeasurements(
|
|
2666
|
+
(prev) => prev.map((measurement) => {
|
|
2667
|
+
if (!measurement.elementRef || !current.document.contains(measurement.elementRef)) {
|
|
2668
|
+
return measurement;
|
|
2669
|
+
}
|
|
2670
|
+
const next = getInspectMeasurement(measurement.elementRef, ownerWindow);
|
|
2671
|
+
if (rectAlmostEqual(next.rect, measurement.rect)) return measurement;
|
|
2672
|
+
return {
|
|
2673
|
+
...next,
|
|
2674
|
+
id: measurement.id
|
|
2675
|
+
};
|
|
2676
|
+
})
|
|
2677
|
+
);
|
|
2678
|
+
}
|
|
2679
|
+
const hover = current.hoverElementRef.current;
|
|
2680
|
+
if (current.selectionEnabled && hover && current.document.contains(hover)) {
|
|
1489
2681
|
const rect = getRectFromDom(hover);
|
|
1490
|
-
|
|
2682
|
+
current.setHoverRect(
|
|
1491
2683
|
(prev) => prev && rectAlmostEqual(prev, rect) ? prev : rect
|
|
1492
2684
|
);
|
|
1493
2685
|
}
|
|
1494
|
-
frameRef.current =
|
|
2686
|
+
frameRef.current = ownerWindow.requestAnimationFrame(tick);
|
|
1495
2687
|
};
|
|
1496
|
-
frameRef.current =
|
|
2688
|
+
frameRef.current = ownerWindow.requestAnimationFrame(tick);
|
|
1497
2689
|
return () => {
|
|
1498
2690
|
if (frameRef.current) {
|
|
1499
|
-
|
|
2691
|
+
ownerWindow.cancelAnimationFrame(frameRef.current);
|
|
1500
2692
|
}
|
|
1501
2693
|
frameRef.current = null;
|
|
1502
2694
|
};
|
|
1503
|
-
}, [params]);
|
|
2695
|
+
}, [params.enabled, params.window]);
|
|
1504
2696
|
};
|
|
1505
2697
|
|
|
1506
2698
|
// hooks/use-measure-toggles.ts
|
|
1507
|
-
var
|
|
2699
|
+
var import_react11 = require("react");
|
|
1508
2700
|
var useMeasureToggles = (options = {}) => {
|
|
1509
|
-
const [enabled, setEnabled] = (0,
|
|
1510
|
-
const [altPressed, setAltPressed] = (0,
|
|
1511
|
-
const [toolMode, setToolMode] = (0,
|
|
2701
|
+
const [enabled, setEnabled] = (0, import_react11.useState)(options.initialEnabled ?? true);
|
|
2702
|
+
const [altPressed, setAltPressed] = (0, import_react11.useState)(false);
|
|
2703
|
+
const [toolMode, setToolMode] = (0, import_react11.useState)(
|
|
1512
2704
|
options.initialToolMode ?? "none"
|
|
1513
2705
|
);
|
|
1514
|
-
const [rulersVisible, setRulersVisible] = (0,
|
|
2706
|
+
const [rulersVisible, setRulersVisible] = (0, import_react11.useState)(
|
|
1515
2707
|
options.initialRulersVisible ?? false
|
|
1516
2708
|
);
|
|
1517
2709
|
const holdEnabled = false;
|
|
1518
|
-
const multiMeasureEnabled =
|
|
1519
|
-
|
|
2710
|
+
const [multiMeasureEnabled, setMultiMeasureEnabled] = (0, import_react11.useState)(
|
|
2711
|
+
options.initialMultiMeasureEnabled ?? false
|
|
2712
|
+
);
|
|
2713
|
+
const [snapGuidesEnabled, setSnapGuidesEnabled] = (0, import_react11.useState)(
|
|
2714
|
+
options.initialSnapGuidesEnabled ?? true
|
|
2715
|
+
);
|
|
2716
|
+
const [selectNewGuideEnabled, setSelectNewGuideEnabled] = (0, import_react11.useState)(
|
|
2717
|
+
options.initialSelectNewGuideEnabled ?? true
|
|
2718
|
+
);
|
|
1520
2719
|
const guidesEnabled = toolMode === "guides";
|
|
1521
|
-
const snapEnabled = true;
|
|
2720
|
+
const [snapEnabled, setSnapEnabled] = (0, import_react11.useState)(options.initialSnapEnabled ?? true);
|
|
1522
2721
|
return {
|
|
1523
2722
|
enabled,
|
|
1524
2723
|
setEnabled,
|
|
@@ -1532,21 +2731,26 @@ var useMeasureToggles = (options = {}) => {
|
|
|
1532
2731
|
guidesEnabled,
|
|
1533
2732
|
multiMeasureEnabled,
|
|
1534
2733
|
snapGuidesEnabled,
|
|
1535
|
-
|
|
2734
|
+
setSnapGuidesEnabled,
|
|
2735
|
+
selectNewGuideEnabled,
|
|
2736
|
+
setSelectNewGuideEnabled,
|
|
2737
|
+
snapEnabled,
|
|
2738
|
+
setSnapEnabled,
|
|
2739
|
+
setMultiMeasureEnabled
|
|
1536
2740
|
};
|
|
1537
2741
|
};
|
|
1538
2742
|
|
|
1539
2743
|
// hooks/use-measurement-state.ts
|
|
1540
|
-
var
|
|
2744
|
+
var import_react12 = require("react");
|
|
1541
2745
|
var useMeasurementState = (options = {}) => {
|
|
1542
|
-
const [activeMeasurement, setActiveMeasurement] = (0,
|
|
1543
|
-
const [measurements, setMeasurements] = (0,
|
|
2746
|
+
const [activeMeasurement, setActiveMeasurement] = (0, import_react12.useState)(options.initialActiveMeasurement ?? null);
|
|
2747
|
+
const [measurements, setMeasurements] = (0, import_react12.useState)(
|
|
1544
2748
|
options.initialMeasurements ?? []
|
|
1545
2749
|
);
|
|
1546
|
-
const [selectedMeasurement, setSelectedMeasurement] = (0,
|
|
1547
|
-
const [selectedMeasurements, setSelectedMeasurements] = (0,
|
|
1548
|
-
const [hoverRect, setHoverRect] = (0,
|
|
1549
|
-
const [heldDistances, setHeldDistances] = (0,
|
|
2750
|
+
const [selectedMeasurement, setSelectedMeasurement] = (0, import_react12.useState)(null);
|
|
2751
|
+
const [selectedMeasurements, setSelectedMeasurements] = (0, import_react12.useState)([]);
|
|
2752
|
+
const [hoverRect, setHoverRect] = (0, import_react12.useState)(null);
|
|
2753
|
+
const [heldDistances, setHeldDistances] = (0, import_react12.useState)(
|
|
1550
2754
|
options.initialHeldDistances ?? []
|
|
1551
2755
|
);
|
|
1552
2756
|
return {
|
|
@@ -1566,7 +2770,7 @@ var useMeasurementState = (options = {}) => {
|
|
|
1566
2770
|
};
|
|
1567
2771
|
|
|
1568
2772
|
// hooks/use-measurer-derived.ts
|
|
1569
|
-
var
|
|
2773
|
+
var import_react13 = require("react");
|
|
1570
2774
|
|
|
1571
2775
|
// core/edge-visibility.ts
|
|
1572
2776
|
var rangesOverlap = (a1, a2, b1, b2) => Math.min(a2, b2) - Math.max(a1, b1) > 0;
|
|
@@ -1835,7 +3039,7 @@ var useMeasurerDerived = ({
|
|
|
1835
3039
|
highlightColor,
|
|
1836
3040
|
guideColor
|
|
1837
3041
|
}) => {
|
|
1838
|
-
const activeRect = (0,
|
|
3042
|
+
const activeRect = (0, import_react13.useMemo)(() => {
|
|
1839
3043
|
if (!start || !end) return null;
|
|
1840
3044
|
return {
|
|
1841
3045
|
left: Math.min(start.x, end.x),
|
|
@@ -1846,7 +3050,7 @@ var useMeasurerDerived = ({
|
|
|
1846
3050
|
}, [end, start]);
|
|
1847
3051
|
const activeWidth = activeRect ? formatValue(activeRect.width) : 0;
|
|
1848
3052
|
const activeHeight = activeRect ? formatValue(activeRect.height) : 0;
|
|
1849
|
-
const groupedSelection = (0,
|
|
3053
|
+
const groupedSelection = (0, import_react13.useMemo)(() => {
|
|
1850
3054
|
if (selectedMeasurements.length <= 1) return null;
|
|
1851
3055
|
const selectionKey = selectedMeasurements.map((measurement) => measurement.id).join("|");
|
|
1852
3056
|
const rects = selectedMeasurements.map((measurement) => measurement.rect);
|
|
@@ -1876,24 +3080,24 @@ var useMeasurerDerived = ({
|
|
|
1876
3080
|
originRect: selectionOriginRect ?? void 0
|
|
1877
3081
|
};
|
|
1878
3082
|
}, [selectedMeasurements, selectionOriginRect]);
|
|
1879
|
-
const displayedSelectedMeasurements = (0,
|
|
3083
|
+
const displayedSelectedMeasurements = (0, import_react13.useMemo)(
|
|
1880
3084
|
() => groupedSelection ? [groupedSelection] : selectedMeasurements.length > 0 ? selectedMeasurements : selectedMeasurement ? [selectedMeasurement] : [],
|
|
1881
3085
|
[groupedSelection, selectedMeasurement, selectedMeasurements]
|
|
1882
3086
|
);
|
|
1883
|
-
const selectedGuide = (0,
|
|
3087
|
+
const selectedGuide = (0, import_react13.useMemo)(
|
|
1884
3088
|
() => getSelectedGuide(guides, selectedGuideIds),
|
|
1885
3089
|
[guides, selectedGuideIds]
|
|
1886
3090
|
);
|
|
1887
|
-
const hoverGuide = (0,
|
|
3091
|
+
const hoverGuide = (0, import_react13.useMemo)(
|
|
1888
3092
|
() => getHoveredGuide(hoverPointer, guides),
|
|
1889
3093
|
[guides, hoverPointer]
|
|
1890
3094
|
);
|
|
1891
|
-
const primarySelectedMeasurement = (0,
|
|
3095
|
+
const primarySelectedMeasurement = (0, import_react13.useMemo)(
|
|
1892
3096
|
() => getPrimarySelectedMeasurement(selectedMeasurements, selectedMeasurement),
|
|
1893
3097
|
[selectedMeasurement, selectedMeasurements]
|
|
1894
3098
|
);
|
|
1895
3099
|
const effectivePrimarySelected = groupedSelection ?? primarySelectedMeasurement;
|
|
1896
|
-
const optionPairOverlay = (0,
|
|
3100
|
+
const optionPairOverlay = (0, import_react13.useMemo)(() => {
|
|
1897
3101
|
return getOptionPairOverlay({
|
|
1898
3102
|
altPressed,
|
|
1899
3103
|
primarySelectedMeasurement: effectivePrimarySelected,
|
|
@@ -1912,7 +3116,7 @@ var useMeasurerDerived = ({
|
|
|
1912
3116
|
selectedElement,
|
|
1913
3117
|
selectedGuide
|
|
1914
3118
|
]);
|
|
1915
|
-
const optionContainerLines = (0,
|
|
3119
|
+
const optionContainerLines = (0, import_react13.useMemo)(() => {
|
|
1916
3120
|
return getOptionContainerLines({
|
|
1917
3121
|
altPressed,
|
|
1918
3122
|
primarySelectedMeasurement: effectivePrimarySelected,
|
|
@@ -1931,7 +3135,7 @@ var useMeasurerDerived = ({
|
|
|
1931
3135
|
selectedElement,
|
|
1932
3136
|
selectedGuideIds
|
|
1933
3137
|
]);
|
|
1934
|
-
const guideDistanceOverlay = (0,
|
|
3138
|
+
const guideDistanceOverlay = (0, import_react13.useMemo)(() => {
|
|
1935
3139
|
if (!altPressed || !guidesEnabled) return null;
|
|
1936
3140
|
if (selectedGuide && hoverGuide && selectedGuide.id !== hoverGuide.id) {
|
|
1937
3141
|
return getDistanceOverlay(
|
|
@@ -1983,7 +3187,7 @@ var useMeasurerDerived = ({
|
|
|
1983
3187
|
guideColorHover,
|
|
1984
3188
|
guideColorDefault,
|
|
1985
3189
|
guideColorPreview
|
|
1986
|
-
} = (0,
|
|
3190
|
+
} = (0, import_react13.useMemo)(
|
|
1987
3191
|
() => ({
|
|
1988
3192
|
outlineColor: `color-mix(in oklch, ${highlightColor} 80%, transparent)`,
|
|
1989
3193
|
fillColor: `color-mix(in oklch, ${highlightColor} 8%, transparent)`,
|
|
@@ -1994,12 +3198,12 @@ var useMeasurerDerived = ({
|
|
|
1994
3198
|
}),
|
|
1995
3199
|
[guideColor, highlightColor]
|
|
1996
3200
|
);
|
|
1997
|
-
const selectedRects = (0,
|
|
3201
|
+
const selectedRects = (0, import_react13.useMemo)(
|
|
1998
3202
|
() => displayedSelectedMeasurements.map((measurement) => measurement.rect),
|
|
1999
3203
|
[displayedSelectedMeasurements]
|
|
2000
3204
|
);
|
|
2001
3205
|
const hoverRectToShow = hoverHighlightEnabled && hoverRect && selectedMeasurements.length <= 1 ? hoverRect : null;
|
|
2002
|
-
const selectionEdgeVisibility = (0,
|
|
3206
|
+
const selectionEdgeVisibility = (0, import_react13.useMemo)(
|
|
2003
3207
|
() => getEdgeVisibilityForRects(selectedRects),
|
|
2004
3208
|
[selectedRects]
|
|
2005
3209
|
);
|
|
@@ -2008,7 +3212,7 @@ var useMeasurerDerived = ({
|
|
|
2008
3212
|
selectedRects.length
|
|
2009
3213
|
);
|
|
2010
3214
|
const hoverEdgeVisibility = hoverRectToShow ? { top: true, right: true, bottom: true, left: true } : null;
|
|
2011
|
-
const measurementEdgeVisibility = (0,
|
|
3215
|
+
const measurementEdgeVisibility = (0, import_react13.useMemo)(
|
|
2012
3216
|
() => getEdgeVisibilityForRects(displayedMeasurements.map((m) => m.rect)),
|
|
2013
3217
|
[displayedMeasurements]
|
|
2014
3218
|
);
|
|
@@ -2036,7 +3240,7 @@ var useMeasurerDerived = ({
|
|
|
2036
3240
|
};
|
|
2037
3241
|
|
|
2038
3242
|
// hooks/use-measurer-history.ts
|
|
2039
|
-
var
|
|
3243
|
+
var import_react14 = require("react");
|
|
2040
3244
|
var HISTORY_LIMIT = 50;
|
|
2041
3245
|
var useMeasurerHistory = ({
|
|
2042
3246
|
toggles,
|
|
@@ -2082,10 +3286,10 @@ var useMeasurerHistory = ({
|
|
|
2082
3286
|
setSelectedElement,
|
|
2083
3287
|
clearSelectionRect
|
|
2084
3288
|
} = transient;
|
|
2085
|
-
const historyRef = (0,
|
|
2086
|
-
const futureRef = (0,
|
|
2087
|
-
const historySignatureRef = (0,
|
|
2088
|
-
const captureSnapshot = (0,
|
|
3289
|
+
const historyRef = (0, import_react14.useRef)([]);
|
|
3290
|
+
const futureRef = (0, import_react14.useRef)([]);
|
|
3291
|
+
const historySignatureRef = (0, import_react14.useRef)(null);
|
|
3292
|
+
const captureSnapshot = (0, import_react14.useCallback)(() => {
|
|
2089
3293
|
return {
|
|
2090
3294
|
enabled,
|
|
2091
3295
|
toolMode,
|
|
@@ -2112,7 +3316,7 @@ var useMeasurerHistory = ({
|
|
|
2112
3316
|
selectedMeasurements,
|
|
2113
3317
|
toolMode
|
|
2114
3318
|
]);
|
|
2115
|
-
const getSnapshotSignature = (0,
|
|
3319
|
+
const getSnapshotSignature = (0, import_react14.useCallback)((snapshot) => {
|
|
2116
3320
|
const serializeRect = (rect) => `${Math.round(rect.left)}:${Math.round(rect.top)}:${Math.round(rect.width)}:${Math.round(rect.height)}`;
|
|
2117
3321
|
return [
|
|
2118
3322
|
snapshot.enabled ? "1" : "0",
|
|
@@ -2128,7 +3332,7 @@ var useMeasurerHistory = ({
|
|
|
2128
3332
|
snapshot.draggingGuideId ?? ""
|
|
2129
3333
|
].join("|");
|
|
2130
3334
|
}, []);
|
|
2131
|
-
const recordSnapshot = (0,
|
|
3335
|
+
const recordSnapshot = (0, import_react14.useCallback)(() => {
|
|
2132
3336
|
const snapshot = captureSnapshot();
|
|
2133
3337
|
const signature = getSnapshotSignature(snapshot);
|
|
2134
3338
|
if (historySignatureRef.current === signature) return;
|
|
@@ -2139,7 +3343,7 @@ var useMeasurerHistory = ({
|
|
|
2139
3343
|
historyRef.current.shift();
|
|
2140
3344
|
}
|
|
2141
3345
|
}, [captureSnapshot, getSnapshotSignature]);
|
|
2142
|
-
const restoreSnapshot = (0,
|
|
3346
|
+
const restoreSnapshot = (0, import_react14.useCallback)(
|
|
2143
3347
|
(snapshot) => {
|
|
2144
3348
|
setEnabled(snapshot.enabled);
|
|
2145
3349
|
setToolMode(snapshot.toolMode);
|
|
@@ -2184,7 +3388,7 @@ var useMeasurerHistory = ({
|
|
|
2184
3388
|
setHoverElement
|
|
2185
3389
|
]
|
|
2186
3390
|
);
|
|
2187
|
-
const undo = (0,
|
|
3391
|
+
const undo = (0, import_react14.useCallback)(() => {
|
|
2188
3392
|
const previousSnapshot = historyRef.current.pop();
|
|
2189
3393
|
if (!previousSnapshot) return;
|
|
2190
3394
|
const currentSnapshot = captureSnapshot();
|
|
@@ -2195,7 +3399,7 @@ var useMeasurerHistory = ({
|
|
|
2195
3399
|
historySignatureRef.current = null;
|
|
2196
3400
|
restoreSnapshot(previousSnapshot);
|
|
2197
3401
|
}, [captureSnapshot, restoreSnapshot]);
|
|
2198
|
-
const redo = (0,
|
|
3402
|
+
const redo = (0, import_react14.useCallback)(() => {
|
|
2199
3403
|
const nextSnapshot = futureRef.current.pop();
|
|
2200
3404
|
if (!nextSnapshot) return;
|
|
2201
3405
|
historyRef.current.push(captureSnapshot());
|
|
@@ -2205,7 +3409,7 @@ var useMeasurerHistory = ({
|
|
|
2205
3409
|
historySignatureRef.current = null;
|
|
2206
3410
|
restoreSnapshot(nextSnapshot);
|
|
2207
3411
|
}, [captureSnapshot, restoreSnapshot]);
|
|
2208
|
-
const setToolModeWithHistory = (0,
|
|
3412
|
+
const setToolModeWithHistory = (0, import_react14.useCallback)(
|
|
2209
3413
|
(value) => {
|
|
2210
3414
|
setToolMode((prev) => {
|
|
2211
3415
|
const next = typeof value === "function" ? value(prev) : value;
|
|
@@ -2216,7 +3420,7 @@ var useMeasurerHistory = ({
|
|
|
2216
3420
|
},
|
|
2217
3421
|
[recordSnapshot, setToolMode]
|
|
2218
3422
|
);
|
|
2219
|
-
const setGuideOrientationWithHistory = (0,
|
|
3423
|
+
const setGuideOrientationWithHistory = (0, import_react14.useCallback)(
|
|
2220
3424
|
(value) => {
|
|
2221
3425
|
setGuideOrientation((prev) => {
|
|
2222
3426
|
const next = typeof value === "function" ? value(prev) : value;
|
|
@@ -2227,7 +3431,7 @@ var useMeasurerHistory = ({
|
|
|
2227
3431
|
},
|
|
2228
3432
|
[recordSnapshot, setGuideOrientation]
|
|
2229
3433
|
);
|
|
2230
|
-
const setEnabledWithHistory = (0,
|
|
3434
|
+
const setEnabledWithHistory = (0, import_react14.useCallback)(
|
|
2231
3435
|
(value) => {
|
|
2232
3436
|
setEnabled((prev) => {
|
|
2233
3437
|
const next = typeof value === "function" ? value(prev) : value;
|
|
@@ -2238,7 +3442,7 @@ var useMeasurerHistory = ({
|
|
|
2238
3442
|
},
|
|
2239
3443
|
[recordSnapshot, setEnabled]
|
|
2240
3444
|
);
|
|
2241
|
-
const createActionCommit = (0,
|
|
3445
|
+
const createActionCommit = (0, import_react14.useCallback)(() => {
|
|
2242
3446
|
let committed = false;
|
|
2243
3447
|
return () => {
|
|
2244
3448
|
if (committed) return;
|
|
@@ -2258,35 +3462,35 @@ var useMeasurerHistory = ({
|
|
|
2258
3462
|
};
|
|
2259
3463
|
|
|
2260
3464
|
// hooks/use-measurer-local-state.ts
|
|
2261
|
-
var
|
|
3465
|
+
var import_react15 = require("react");
|
|
2262
3466
|
var useMeasurerLocalState = ({
|
|
2263
3467
|
selectedElementRef,
|
|
2264
3468
|
hoverElementRef,
|
|
2265
3469
|
selectionRectRef
|
|
2266
3470
|
}) => {
|
|
2267
|
-
const [selectionOriginRect, setSelectionOriginRect] = (0,
|
|
3471
|
+
const [selectionOriginRect, setSelectionOriginRect] = (0, import_react15.useState)(
|
|
2268
3472
|
null
|
|
2269
3473
|
);
|
|
2270
|
-
const [hoverPointer, setHoverPointer] = (0,
|
|
2271
|
-
const [hoverElement, setHoverElementState] = (0,
|
|
3474
|
+
const [hoverPointer, setHoverPointer] = (0, import_react15.useState)(null);
|
|
3475
|
+
const [hoverElement, setHoverElementState] = (0, import_react15.useState)(
|
|
2272
3476
|
null
|
|
2273
3477
|
);
|
|
2274
|
-
const [selectedElement, setSelectedElementState] = (0,
|
|
2275
|
-
const setSelectedElement = (0,
|
|
3478
|
+
const [selectedElement, setSelectedElementState] = (0, import_react15.useState)(null);
|
|
3479
|
+
const setSelectedElement = (0, import_react15.useCallback)(
|
|
2276
3480
|
(element) => {
|
|
2277
3481
|
selectedElementRef.current = element;
|
|
2278
3482
|
setSelectedElementState(element);
|
|
2279
3483
|
},
|
|
2280
3484
|
[selectedElementRef]
|
|
2281
3485
|
);
|
|
2282
|
-
const setHoverElement = (0,
|
|
3486
|
+
const setHoverElement = (0, import_react15.useCallback)(
|
|
2283
3487
|
(element) => {
|
|
2284
3488
|
hoverElementRef.current = element;
|
|
2285
3489
|
setHoverElementState(element);
|
|
2286
3490
|
},
|
|
2287
3491
|
[hoverElementRef]
|
|
2288
3492
|
);
|
|
2289
|
-
const clearSelectionRect = (0,
|
|
3493
|
+
const clearSelectionRect = (0, import_react15.useCallback)(() => {
|
|
2290
3494
|
selectionRectRef.current = null;
|
|
2291
3495
|
setSelectionOriginRect(null);
|
|
2292
3496
|
}, [selectionRectRef]);
|
|
@@ -2304,7 +3508,7 @@ var useMeasurerLocalState = ({
|
|
|
2304
3508
|
};
|
|
2305
3509
|
|
|
2306
3510
|
// hooks/use-measurer-pointer.ts
|
|
2307
|
-
var
|
|
3511
|
+
var import_react16 = require("react");
|
|
2308
3512
|
|
|
2309
3513
|
// core/targets.ts
|
|
2310
3514
|
var pickMultiTargets = (selectionRect, items) => {
|
|
@@ -2507,10 +3711,12 @@ var useMeasurerPointer = ({
|
|
|
2507
3711
|
clearGuideDragHold,
|
|
2508
3712
|
scheduleGuideDragHold,
|
|
2509
3713
|
enabled,
|
|
3714
|
+
settingsOpen,
|
|
2510
3715
|
toolMode,
|
|
2511
3716
|
guidesEnabled,
|
|
2512
3717
|
snapEnabled,
|
|
2513
3718
|
snapGuidesEnabled,
|
|
3719
|
+
selectNewGuideEnabled,
|
|
2514
3720
|
altPressed,
|
|
2515
3721
|
guideOrientation,
|
|
2516
3722
|
hoverHighlightEnabled,
|
|
@@ -2543,24 +3749,24 @@ var useMeasurerPointer = ({
|
|
|
2543
3749
|
setHoverPointer,
|
|
2544
3750
|
clearSelectionRect
|
|
2545
3751
|
}) => {
|
|
2546
|
-
const hoverFrameRef = (0,
|
|
2547
|
-
const hoverPointRef = (0,
|
|
2548
|
-
const selectionCacheRef = (0,
|
|
3752
|
+
const hoverFrameRef = (0, import_react16.useRef)(null);
|
|
3753
|
+
const hoverPointRef = (0, import_react16.useRef)(null);
|
|
3754
|
+
const selectionCacheRef = (0, import_react16.useRef)({
|
|
2549
3755
|
key: "",
|
|
2550
3756
|
entries: [],
|
|
2551
3757
|
overlayNode: null,
|
|
2552
3758
|
frame: -1
|
|
2553
3759
|
});
|
|
2554
|
-
const shiftDragRef = (0,
|
|
2555
|
-
const shiftToggleElementRef = (0,
|
|
2556
|
-
(0,
|
|
3760
|
+
const shiftDragRef = (0, import_react16.useRef)(false);
|
|
3761
|
+
const shiftToggleElementRef = (0, import_react16.useRef)(null);
|
|
3762
|
+
(0, import_react16.useEffect)(() => {
|
|
2557
3763
|
return () => {
|
|
2558
3764
|
if (hoverFrameRef.current) {
|
|
2559
3765
|
window2.cancelAnimationFrame(hoverFrameRef.current);
|
|
2560
3766
|
}
|
|
2561
3767
|
};
|
|
2562
3768
|
}, []);
|
|
2563
|
-
const updateHoverTarget = (0,
|
|
3769
|
+
const updateHoverTarget = (0, import_react16.useCallback)(
|
|
2564
3770
|
(point) => {
|
|
2565
3771
|
const target = getTargetElement(point, overlayRef.current, document2);
|
|
2566
3772
|
if (target) {
|
|
@@ -2579,18 +3785,19 @@ var useMeasurerPointer = ({
|
|
|
2579
3785
|
},
|
|
2580
3786
|
[document2, overlayRef, setHoverElement, setHoverRect]
|
|
2581
3787
|
);
|
|
2582
|
-
const updateHoverElement = (0,
|
|
3788
|
+
const updateHoverElement = (0, import_react16.useCallback)(
|
|
2583
3789
|
(point) => {
|
|
2584
3790
|
const target = getTargetElement(point, overlayRef.current, document2);
|
|
2585
3791
|
setHoverElement(target);
|
|
2586
3792
|
},
|
|
2587
3793
|
[document2, overlayRef, setHoverElement]
|
|
2588
3794
|
);
|
|
2589
|
-
const handlePointerDown = (0,
|
|
3795
|
+
const handlePointerDown = (0, import_react16.useCallback)(
|
|
2590
3796
|
(event) => {
|
|
2591
3797
|
const commit = createActionCommit();
|
|
2592
3798
|
const toolbarNode = toolbarRef.current;
|
|
2593
3799
|
if (toolbarNode && toolbarNode.contains(event.target)) return;
|
|
3800
|
+
if (settingsOpen) return;
|
|
2594
3801
|
if (!enabled || event.button !== 0) return;
|
|
2595
3802
|
if (toolMode === "none") return;
|
|
2596
3803
|
clearSelectionRect();
|
|
@@ -2615,7 +3822,11 @@ var useMeasurerPointer = ({
|
|
|
2615
3822
|
return;
|
|
2616
3823
|
}
|
|
2617
3824
|
if (guidesEnabled) {
|
|
3825
|
+
event.preventDefault();
|
|
2618
3826
|
commit();
|
|
3827
|
+
setStart(null);
|
|
3828
|
+
setEnd(null);
|
|
3829
|
+
setIsDragging(false);
|
|
2619
3830
|
const position = getSnapGuidePosition({
|
|
2620
3831
|
orientation: guideOrientation,
|
|
2621
3832
|
point,
|
|
@@ -2626,7 +3837,7 @@ var useMeasurerPointer = ({
|
|
|
2626
3837
|
document: document2
|
|
2627
3838
|
});
|
|
2628
3839
|
const id = createId();
|
|
2629
|
-
setSelectedGuideIds([id]);
|
|
3840
|
+
setSelectedGuideIds(selectNewGuideEnabled ? [id] : []);
|
|
2630
3841
|
setGuides((prev) => [
|
|
2631
3842
|
...prev,
|
|
2632
3843
|
{ id, orientation: guideOrientation, position }
|
|
@@ -2651,12 +3862,14 @@ var useMeasurerPointer = ({
|
|
|
2651
3862
|
draggingGuideId,
|
|
2652
3863
|
document2,
|
|
2653
3864
|
enabled,
|
|
3865
|
+
settingsOpen,
|
|
2654
3866
|
guideOrientation,
|
|
2655
3867
|
guides,
|
|
2656
3868
|
guidesEnabled,
|
|
2657
3869
|
optionPairOverlay,
|
|
2658
3870
|
overlayRef,
|
|
2659
3871
|
scheduleGuideDragHold,
|
|
3872
|
+
selectNewGuideEnabled,
|
|
2660
3873
|
selectedGuideIds.length,
|
|
2661
3874
|
selectedMeasurements,
|
|
2662
3875
|
setDraggingGuideId,
|
|
@@ -2671,10 +3884,11 @@ var useMeasurerPointer = ({
|
|
|
2671
3884
|
toolbarRef
|
|
2672
3885
|
]
|
|
2673
3886
|
);
|
|
2674
|
-
const handlePointerMove = (0,
|
|
3887
|
+
const handlePointerMove = (0, import_react16.useCallback)(
|
|
2675
3888
|
(event) => {
|
|
2676
3889
|
const toolbarNode = toolbarRef.current;
|
|
2677
3890
|
if (toolbarNode && toolbarNode.contains(event.target)) return;
|
|
3891
|
+
if (settingsOpen) return;
|
|
2678
3892
|
if (!enabled) return;
|
|
2679
3893
|
if (toolMode === "none") {
|
|
2680
3894
|
if (hoverHighlightEnabled) {
|
|
@@ -2693,7 +3907,7 @@ var useMeasurerPointer = ({
|
|
|
2693
3907
|
if (!hoverFrameRef.current) {
|
|
2694
3908
|
hoverFrameRef.current = window2.requestAnimationFrame(() => {
|
|
2695
3909
|
const latest = hoverPointRef.current;
|
|
2696
|
-
if (latest && !draggingGuideId) {
|
|
3910
|
+
if (latest && !draggingGuideId && !guidesEnabled) {
|
|
2697
3911
|
if (hoverHighlightEnabled) {
|
|
2698
3912
|
updateHoverTarget(latest);
|
|
2699
3913
|
} else {
|
|
@@ -2743,6 +3957,7 @@ var useMeasurerPointer = ({
|
|
|
2743
3957
|
)
|
|
2744
3958
|
);
|
|
2745
3959
|
}
|
|
3960
|
+
if (guidesEnabled) return;
|
|
2746
3961
|
if (!start) return;
|
|
2747
3962
|
setEnd(point);
|
|
2748
3963
|
if (!isDragging) {
|
|
@@ -2758,6 +3973,7 @@ var useMeasurerPointer = ({
|
|
|
2758
3973
|
altPressed,
|
|
2759
3974
|
draggingGuideId,
|
|
2760
3975
|
enabled,
|
|
3976
|
+
settingsOpen,
|
|
2761
3977
|
hoverHighlightEnabled,
|
|
2762
3978
|
guides,
|
|
2763
3979
|
guidesEnabled,
|
|
@@ -2780,13 +3996,20 @@ var useMeasurerPointer = ({
|
|
|
2780
3996
|
updateHoverTarget
|
|
2781
3997
|
]
|
|
2782
3998
|
);
|
|
2783
|
-
const handlePointerUp = (0,
|
|
3999
|
+
const handlePointerUp = (0, import_react16.useCallback)(
|
|
2784
4000
|
(event) => {
|
|
2785
4001
|
const commit = createActionCommit();
|
|
2786
4002
|
const toolbarNode = toolbarRef.current;
|
|
2787
4003
|
if (toolbarNode && toolbarNode.contains(event.target)) return;
|
|
4004
|
+
if (settingsOpen) return;
|
|
2788
4005
|
if (!enabled) return;
|
|
2789
4006
|
clearGuideDragHold();
|
|
4007
|
+
if (guidesEnabled) {
|
|
4008
|
+
setStart(null);
|
|
4009
|
+
setEnd(null);
|
|
4010
|
+
setIsDragging(false);
|
|
4011
|
+
return;
|
|
4012
|
+
}
|
|
2790
4013
|
if (toolMode === "none") {
|
|
2791
4014
|
setStart(null);
|
|
2792
4015
|
setEnd(null);
|
|
@@ -2957,7 +4180,9 @@ var useMeasurerPointer = ({
|
|
|
2957
4180
|
createActionCommit,
|
|
2958
4181
|
draggingGuideId,
|
|
2959
4182
|
enabled,
|
|
4183
|
+
settingsOpen,
|
|
2960
4184
|
end,
|
|
4185
|
+
guidesEnabled,
|
|
2961
4186
|
hoverHighlightEnabled,
|
|
2962
4187
|
isDragging,
|
|
2963
4188
|
overlayRef,
|
|
@@ -2980,7 +4205,7 @@ var useMeasurerPointer = ({
|
|
|
2980
4205
|
toolbarRef
|
|
2981
4206
|
]
|
|
2982
4207
|
);
|
|
2983
|
-
const handlePointerLeave = (0,
|
|
4208
|
+
const handlePointerLeave = (0, import_react16.useCallback)(() => {
|
|
2984
4209
|
clearGuideDragHold();
|
|
2985
4210
|
setStart(null);
|
|
2986
4211
|
setEnd(null);
|
|
@@ -3004,54 +4229,58 @@ var useMeasurerPointer = ({
|
|
|
3004
4229
|
};
|
|
3005
4230
|
|
|
3006
4231
|
// hooks/use-overlay-refs.ts
|
|
3007
|
-
var
|
|
4232
|
+
var import_react17 = require("react");
|
|
3008
4233
|
var useOverlayRefs = () => {
|
|
3009
|
-
const overlayRef = (0,
|
|
3010
|
-
const selectedElementRef = (0,
|
|
3011
|
-
const hoverElementRef = (0,
|
|
4234
|
+
const overlayRef = (0, import_react17.useRef)(null);
|
|
4235
|
+
const selectedElementRef = (0, import_react17.useRef)(null);
|
|
4236
|
+
const hoverElementRef = (0, import_react17.useRef)(null);
|
|
3012
4237
|
return { overlayRef, selectedElementRef, hoverElementRef };
|
|
3013
4238
|
};
|
|
3014
4239
|
|
|
3015
4240
|
// hooks/use-resize-sync.ts
|
|
3016
|
-
var
|
|
4241
|
+
var import_react18 = require("react");
|
|
3017
4242
|
var useResizeSync = (params) => {
|
|
3018
|
-
const
|
|
3019
|
-
|
|
3020
|
-
(0,
|
|
4243
|
+
const paramsRef = (0, import_react18.useRef)(params);
|
|
4244
|
+
paramsRef.current = params;
|
|
4245
|
+
const resizeFrameRef = (0, import_react18.useRef)(null);
|
|
4246
|
+
const viewportRef = (0, import_react18.useRef)(getViewportSize(params.window));
|
|
4247
|
+
(0, import_react18.useEffect)(() => {
|
|
4248
|
+
const ownerWindow = params.window;
|
|
3021
4249
|
const handleResize = () => {
|
|
4250
|
+
const current = paramsRef.current;
|
|
3022
4251
|
if (resizeFrameRef.current) {
|
|
3023
|
-
|
|
4252
|
+
ownerWindow.cancelAnimationFrame(resizeFrameRef.current);
|
|
3024
4253
|
}
|
|
3025
|
-
resizeFrameRef.current =
|
|
3026
|
-
const viewport = getViewportSize(
|
|
4254
|
+
resizeFrameRef.current = ownerWindow.requestAnimationFrame(() => {
|
|
4255
|
+
const viewport = getViewportSize(ownerWindow);
|
|
3027
4256
|
const previousViewport = viewportRef.current;
|
|
3028
|
-
|
|
4257
|
+
current.setMeasurements(
|
|
3029
4258
|
(prev) => prev.map(
|
|
3030
|
-
(measurement) => updateMeasurementForResize(measurement, viewport,
|
|
4259
|
+
(measurement) => updateMeasurementForResize(measurement, viewport, current.document)
|
|
3031
4260
|
)
|
|
3032
4261
|
);
|
|
3033
|
-
|
|
3034
|
-
(prev) => prev ? updateMeasurementForResize(prev, viewport,
|
|
4262
|
+
current.setActiveMeasurement(
|
|
4263
|
+
(prev) => prev ? updateMeasurementForResize(prev, viewport, current.document) : prev
|
|
3035
4264
|
);
|
|
3036
|
-
|
|
4265
|
+
current.setHeldDistances(
|
|
3037
4266
|
(prev) => prev.map(
|
|
3038
4267
|
(distance) => updateDistanceForResize(
|
|
3039
4268
|
distance,
|
|
3040
4269
|
viewport,
|
|
3041
|
-
|
|
3042
|
-
|
|
4270
|
+
current.document,
|
|
4271
|
+
ownerWindow
|
|
3043
4272
|
)
|
|
3044
4273
|
)
|
|
3045
4274
|
);
|
|
3046
|
-
if (
|
|
3047
|
-
|
|
3048
|
-
getInspectMeasurement(
|
|
4275
|
+
if (current.selectedElementRef.current && current.document.contains(current.selectedElementRef.current)) {
|
|
4276
|
+
current.setSelectedMeasurement(
|
|
4277
|
+
getInspectMeasurement(current.selectedElementRef.current, ownerWindow)
|
|
3049
4278
|
);
|
|
3050
4279
|
}
|
|
3051
4280
|
if (previousViewport.width > 0 && previousViewport.height > 0) {
|
|
3052
4281
|
const scaleX = viewport.width / previousViewport.width;
|
|
3053
4282
|
const scaleY = viewport.height / previousViewport.height;
|
|
3054
|
-
|
|
4283
|
+
current.setGuides(
|
|
3055
4284
|
(prev) => prev.map(
|
|
3056
4285
|
(guide) => guide.orientation === "vertical" ? { ...guide, position: guide.position * scaleX } : { ...guide, position: guide.position * scaleY }
|
|
3057
4286
|
)
|
|
@@ -3060,27 +4289,27 @@ var useResizeSync = (params) => {
|
|
|
3060
4289
|
viewportRef.current = viewport;
|
|
3061
4290
|
});
|
|
3062
4291
|
};
|
|
3063
|
-
|
|
4292
|
+
ownerWindow.addEventListener("resize", handleResize);
|
|
3064
4293
|
return () => {
|
|
3065
4294
|
if (resizeFrameRef.current) {
|
|
3066
|
-
|
|
4295
|
+
ownerWindow.cancelAnimationFrame(resizeFrameRef.current);
|
|
3067
4296
|
}
|
|
3068
|
-
|
|
4297
|
+
ownerWindow.removeEventListener("resize", handleResize);
|
|
3069
4298
|
};
|
|
3070
|
-
}, [params]);
|
|
4299
|
+
}, [params.window]);
|
|
3071
4300
|
};
|
|
3072
4301
|
|
|
3073
4302
|
// render/measurer-overlay.tsx
|
|
3074
|
-
var
|
|
4303
|
+
var import_react22 = require("react");
|
|
3075
4304
|
|
|
3076
4305
|
// components/measure-tag.tsx
|
|
3077
|
-
var
|
|
4306
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
3078
4307
|
function MeasureTag({
|
|
3079
4308
|
children,
|
|
3080
4309
|
className = "",
|
|
3081
4310
|
style
|
|
3082
4311
|
}) {
|
|
3083
|
-
return /* @__PURE__ */ (0,
|
|
4312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3084
4313
|
"div",
|
|
3085
4314
|
{
|
|
3086
4315
|
className: cn(
|
|
@@ -3094,21 +4323,21 @@ function MeasureTag({
|
|
|
3094
4323
|
}
|
|
3095
4324
|
|
|
3096
4325
|
// components/measurement-box.tsx
|
|
3097
|
-
var
|
|
3098
|
-
var
|
|
4326
|
+
var import_react19 = require("react");
|
|
4327
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
3099
4328
|
var formatValue2 = (value) => Math.round(value);
|
|
3100
|
-
var MeasurementBox = (0,
|
|
4329
|
+
var MeasurementBox = (0, import_react19.memo)(function MeasurementBox2({
|
|
3101
4330
|
measurement,
|
|
3102
4331
|
transitionMs,
|
|
3103
4332
|
labelOffset,
|
|
3104
|
-
edgeVisibility
|
|
4333
|
+
edgeVisibility,
|
|
4334
|
+
outlineColor,
|
|
4335
|
+
fillColor
|
|
3105
4336
|
}) {
|
|
3106
4337
|
const edges = edgeVisibility ?? { top: true, right: true, bottom: true, left: true };
|
|
3107
4338
|
const displayRect = measurement.rect;
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "msr:pointer-events-none", children: [
|
|
3111
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
4339
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "msr:pointer-events-none", children: [
|
|
4340
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3112
4341
|
"div",
|
|
3113
4342
|
{
|
|
3114
4343
|
className: "msr:absolute",
|
|
@@ -3121,28 +4350,28 @@ var MeasurementBox = (0, import_react16.memo)(function MeasurementBox2({
|
|
|
3121
4350
|
transition: `left ${transitionMs}ms ease, top ${transitionMs}ms ease, width ${transitionMs}ms ease, height ${transitionMs}ms ease`
|
|
3122
4351
|
},
|
|
3123
4352
|
children: [
|
|
3124
|
-
edges.top ? /* @__PURE__ */ (0,
|
|
4353
|
+
edges.top ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3125
4354
|
"div",
|
|
3126
4355
|
{
|
|
3127
4356
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-px msr:w-full",
|
|
3128
4357
|
style: { backgroundColor: outlineColor }
|
|
3129
4358
|
}
|
|
3130
4359
|
) : null,
|
|
3131
|
-
edges.right ? /* @__PURE__ */ (0,
|
|
4360
|
+
edges.right ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3132
4361
|
"div",
|
|
3133
4362
|
{
|
|
3134
4363
|
className: "msr:absolute msr:right-0 msr:top-0 msr:h-full msr:w-px",
|
|
3135
4364
|
style: { backgroundColor: outlineColor }
|
|
3136
4365
|
}
|
|
3137
4366
|
) : null,
|
|
3138
|
-
edges.bottom ? /* @__PURE__ */ (0,
|
|
4367
|
+
edges.bottom ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3139
4368
|
"div",
|
|
3140
4369
|
{
|
|
3141
4370
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:h-px msr:w-full",
|
|
3142
4371
|
style: { backgroundColor: outlineColor }
|
|
3143
4372
|
}
|
|
3144
4373
|
) : null,
|
|
3145
|
-
edges.left ? /* @__PURE__ */ (0,
|
|
4374
|
+
edges.left ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3146
4375
|
"div",
|
|
3147
4376
|
{
|
|
3148
4377
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-full msr:w-px",
|
|
@@ -3152,7 +4381,7 @@ var MeasurementBox = (0, import_react16.memo)(function MeasurementBox2({
|
|
|
3152
4381
|
]
|
|
3153
4382
|
}
|
|
3154
4383
|
),
|
|
3155
|
-
/* @__PURE__ */ (0,
|
|
4384
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3156
4385
|
MeasureTag,
|
|
3157
4386
|
{
|
|
3158
4387
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3172,21 +4401,21 @@ var MeasurementBox = (0, import_react16.memo)(function MeasurementBox2({
|
|
|
3172
4401
|
});
|
|
3173
4402
|
|
|
3174
4403
|
// components/selected-measurement-box.tsx
|
|
3175
|
-
var
|
|
3176
|
-
var
|
|
4404
|
+
var import_react20 = require("react");
|
|
4405
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
3177
4406
|
var formatValue3 = (value) => Math.round(value);
|
|
3178
|
-
var SelectedMeasurementBox = (0,
|
|
4407
|
+
var SelectedMeasurementBox = (0, import_react20.memo)(function SelectedMeasurementBox2({
|
|
3179
4408
|
measurement,
|
|
3180
4409
|
transitionMs,
|
|
3181
4410
|
labelOffset,
|
|
3182
|
-
edgeVisibility
|
|
4411
|
+
edgeVisibility,
|
|
4412
|
+
outlineColor,
|
|
4413
|
+
fillColor
|
|
3183
4414
|
}) {
|
|
3184
4415
|
const edges = edgeVisibility ?? { top: true, right: true, bottom: true, left: true };
|
|
3185
4416
|
const displayRect = measurement.rect;
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "msr:pointer-events-none", children: [
|
|
3189
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
4417
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "msr:pointer-events-none", "data-mesurer-selected-measurement": "true", children: [
|
|
4418
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3190
4419
|
"div",
|
|
3191
4420
|
{
|
|
3192
4421
|
className: "msr:absolute",
|
|
@@ -3199,28 +4428,28 @@ var SelectedMeasurementBox = (0, import_react17.memo)(function SelectedMeasureme
|
|
|
3199
4428
|
transition: `left ${transitionMs}ms ease, top ${transitionMs}ms ease, width ${transitionMs}ms ease, height ${transitionMs}ms ease`
|
|
3200
4429
|
},
|
|
3201
4430
|
children: [
|
|
3202
|
-
edges.top ? /* @__PURE__ */ (0,
|
|
4431
|
+
edges.top ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3203
4432
|
"div",
|
|
3204
4433
|
{
|
|
3205
4434
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-px msr:w-full",
|
|
3206
4435
|
style: { backgroundColor: outlineColor }
|
|
3207
4436
|
}
|
|
3208
4437
|
) : null,
|
|
3209
|
-
edges.right ? /* @__PURE__ */ (0,
|
|
4438
|
+
edges.right ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3210
4439
|
"div",
|
|
3211
4440
|
{
|
|
3212
4441
|
className: "msr:absolute msr:right-0 msr:top-0 msr:h-full msr:w-px",
|
|
3213
4442
|
style: { backgroundColor: outlineColor }
|
|
3214
4443
|
}
|
|
3215
4444
|
) : null,
|
|
3216
|
-
edges.bottom ? /* @__PURE__ */ (0,
|
|
4445
|
+
edges.bottom ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3217
4446
|
"div",
|
|
3218
4447
|
{
|
|
3219
4448
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:h-px msr:w-full",
|
|
3220
4449
|
style: { backgroundColor: outlineColor }
|
|
3221
4450
|
}
|
|
3222
4451
|
) : null,
|
|
3223
|
-
edges.left ? /* @__PURE__ */ (0,
|
|
4452
|
+
edges.left ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3224
4453
|
"div",
|
|
3225
4454
|
{
|
|
3226
4455
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-full msr:w-px",
|
|
@@ -3230,7 +4459,7 @@ var SelectedMeasurementBox = (0, import_react17.memo)(function SelectedMeasureme
|
|
|
3230
4459
|
]
|
|
3231
4460
|
}
|
|
3232
4461
|
),
|
|
3233
|
-
/* @__PURE__ */ (0,
|
|
4462
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3234
4463
|
MeasureTag,
|
|
3235
4464
|
{
|
|
3236
4465
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3250,14 +4479,14 @@ var SelectedMeasurementBox = (0, import_react17.memo)(function SelectedMeasureme
|
|
|
3250
4479
|
});
|
|
3251
4480
|
|
|
3252
4481
|
// render/distance-overlay-item.tsx
|
|
3253
|
-
var
|
|
3254
|
-
var
|
|
3255
|
-
var DistanceOverlayItem = (0,
|
|
4482
|
+
var import_react21 = require("react");
|
|
4483
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4484
|
+
var DistanceOverlayItem = (0, import_react21.memo)(function DistanceOverlayItem2({
|
|
3256
4485
|
distance,
|
|
3257
4486
|
labelOffset,
|
|
3258
4487
|
onRemove
|
|
3259
4488
|
}) {
|
|
3260
|
-
return /* @__PURE__ */ (0,
|
|
4489
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3261
4490
|
"div",
|
|
3262
4491
|
{
|
|
3263
4492
|
className: onRemove ? "msr:pointer-events-auto" : "msr:pointer-events-none",
|
|
@@ -3266,7 +4495,7 @@ var DistanceOverlayItem = (0, import_react18.memo)(function DistanceOverlayItem2
|
|
|
3266
4495
|
onRemove(distance.id);
|
|
3267
4496
|
} : void 0,
|
|
3268
4497
|
children: [
|
|
3269
|
-
/* @__PURE__ */ (0,
|
|
4498
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3270
4499
|
"div",
|
|
3271
4500
|
{
|
|
3272
4501
|
className: "msr:absolute msr:rounded msr:border msr:border-[#2563eb]/70",
|
|
@@ -3278,7 +4507,7 @@ var DistanceOverlayItem = (0, import_react18.memo)(function DistanceOverlayItem2
|
|
|
3278
4507
|
}
|
|
3279
4508
|
}
|
|
3280
4509
|
),
|
|
3281
|
-
/* @__PURE__ */ (0,
|
|
4510
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3282
4511
|
"div",
|
|
3283
4512
|
{
|
|
3284
4513
|
className: "msr:absolute msr:rounded msr:border msr:border-[#2563eb]/70",
|
|
@@ -3291,7 +4520,7 @@ var DistanceOverlayItem = (0, import_react18.memo)(function DistanceOverlayItem2
|
|
|
3291
4520
|
}
|
|
3292
4521
|
),
|
|
3293
4522
|
distance.connectors.map(
|
|
3294
|
-
(connector, index) => Math.abs(connector.x1 - connector.x2) < 1 ? /* @__PURE__ */ (0,
|
|
4523
|
+
(connector, index) => Math.abs(connector.x1 - connector.x2) < 1 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3295
4524
|
"div",
|
|
3296
4525
|
{
|
|
3297
4526
|
className: "msr:absolute msr:border-l msr:border-dashed msr:border-[#2563eb]/70",
|
|
@@ -3302,7 +4531,7 @@ var DistanceOverlayItem = (0, import_react18.memo)(function DistanceOverlayItem2
|
|
|
3302
4531
|
}
|
|
3303
4532
|
},
|
|
3304
4533
|
`${distance.id}-connector-${index}`
|
|
3305
|
-
) : /* @__PURE__ */ (0,
|
|
4534
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3306
4535
|
"div",
|
|
3307
4536
|
{
|
|
3308
4537
|
className: "msr:absolute msr:border-t msr:border-dashed msr:border-[#2563eb]/70",
|
|
@@ -3315,8 +4544,8 @@ var DistanceOverlayItem = (0, import_react18.memo)(function DistanceOverlayItem2
|
|
|
3315
4544
|
`${distance.id}-connector-${index}`
|
|
3316
4545
|
)
|
|
3317
4546
|
),
|
|
3318
|
-
distance.horizontal && distance.horizontal.value > 0 ? /* @__PURE__ */ (0,
|
|
3319
|
-
/* @__PURE__ */ (0,
|
|
4547
|
+
distance.horizontal && distance.horizontal.value > 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
4548
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3320
4549
|
"div",
|
|
3321
4550
|
{
|
|
3322
4551
|
className: "msr:absolute msr:h-px msr:bg-[#2563eb]",
|
|
@@ -3327,7 +4556,7 @@ var DistanceOverlayItem = (0, import_react18.memo)(function DistanceOverlayItem2
|
|
|
3327
4556
|
}
|
|
3328
4557
|
}
|
|
3329
4558
|
),
|
|
3330
|
-
/* @__PURE__ */ (0,
|
|
4559
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3331
4560
|
MeasureTag,
|
|
3332
4561
|
{
|
|
3333
4562
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3339,8 +4568,8 @@ var DistanceOverlayItem = (0, import_react18.memo)(function DistanceOverlayItem2
|
|
|
3339
4568
|
}
|
|
3340
4569
|
)
|
|
3341
4570
|
] }) : null,
|
|
3342
|
-
distance.vertical && distance.vertical.value > 0 ? /* @__PURE__ */ (0,
|
|
3343
|
-
/* @__PURE__ */ (0,
|
|
4571
|
+
distance.vertical && distance.vertical.value > 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
4572
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3344
4573
|
"div",
|
|
3345
4574
|
{
|
|
3346
4575
|
className: "msr:absolute msr:w-px msr:bg-[#2563eb]",
|
|
@@ -3351,7 +4580,7 @@ var DistanceOverlayItem = (0, import_react18.memo)(function DistanceOverlayItem2
|
|
|
3351
4580
|
}
|
|
3352
4581
|
}
|
|
3353
4582
|
),
|
|
3354
|
-
/* @__PURE__ */ (0,
|
|
4583
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3355
4584
|
MeasureTag,
|
|
3356
4585
|
{
|
|
3357
4586
|
className: "msr:-translate-y-1/2 msr:bg-ink-900/90",
|
|
@@ -3369,9 +4598,10 @@ var DistanceOverlayItem = (0, import_react18.memo)(function DistanceOverlayItem2
|
|
|
3369
4598
|
});
|
|
3370
4599
|
|
|
3371
4600
|
// render/measurer-overlay.tsx
|
|
3372
|
-
var
|
|
3373
|
-
var MeasurerOverlay = (0,
|
|
4601
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4602
|
+
var MeasurerOverlay = (0, import_react22.memo)(function MeasurerOverlay2({
|
|
3374
4603
|
enabled,
|
|
4604
|
+
interactive = true,
|
|
3375
4605
|
toolMode,
|
|
3376
4606
|
guidePointerEvents,
|
|
3377
4607
|
guidesEnabled,
|
|
@@ -3401,6 +4631,7 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3401
4631
|
guideColorActive,
|
|
3402
4632
|
guideColorHover,
|
|
3403
4633
|
guideColorDefault,
|
|
4634
|
+
guideStyle,
|
|
3404
4635
|
onPointerDown,
|
|
3405
4636
|
onPointerMove,
|
|
3406
4637
|
onPointerUp,
|
|
@@ -3411,30 +4642,32 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3411
4642
|
onGuidePointerCancel
|
|
3412
4643
|
}) {
|
|
3413
4644
|
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,
|
|
4645
|
+
const overlayInteractive = interactive && overlayVisible && toolMode !== "none" && toolMode !== "text-inspector" && toolMode !== "xray" && toolMode !== "rulers";
|
|
4646
|
+
const selectionVisible = interactive && toolMode === "select";
|
|
4647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
3417
4648
|
"div",
|
|
3418
4649
|
{
|
|
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"}`,
|
|
4650
|
+
className: `msr:absolute msr:inset-0 msr:select-none ${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
4651
|
style: { pointerEvents: overlayInteractive ? "auto" : "none" },
|
|
3421
4652
|
onPointerDown,
|
|
3422
4653
|
onPointerMove,
|
|
3423
4654
|
onPointerUp,
|
|
3424
4655
|
onPointerLeave,
|
|
3425
4656
|
children: [
|
|
3426
|
-
selectionVisible ? displayedMeasurements.map((measurement, index) => /* @__PURE__ */ (0,
|
|
4657
|
+
selectionVisible ? displayedMeasurements.map((measurement, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3427
4658
|
MeasurementBox,
|
|
3428
4659
|
{
|
|
3429
4660
|
measurement,
|
|
3430
4661
|
transitionMs: MEASURE_TRANSITION_MS,
|
|
3431
4662
|
labelOffset: MEASURE_LABEL_OFFSET,
|
|
3432
|
-
edgeVisibility: measurementEdgeVisibility[index]
|
|
4663
|
+
edgeVisibility: measurementEdgeVisibility[index],
|
|
4664
|
+
outlineColor,
|
|
4665
|
+
fillColor
|
|
3433
4666
|
},
|
|
3434
4667
|
measurement.id
|
|
3435
4668
|
)) : null,
|
|
3436
|
-
selectionVisible && activeRect && isDragging ? /* @__PURE__ */ (0,
|
|
3437
|
-
/* @__PURE__ */ (0,
|
|
4669
|
+
selectionVisible && activeRect && isDragging ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
4670
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
3438
4671
|
"div",
|
|
3439
4672
|
{
|
|
3440
4673
|
className: "msr:pointer-events-none msr:absolute",
|
|
@@ -3446,28 +4679,28 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3446
4679
|
backgroundColor: fillColor
|
|
3447
4680
|
},
|
|
3448
4681
|
children: [
|
|
3449
|
-
/* @__PURE__ */ (0,
|
|
4682
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3450
4683
|
"div",
|
|
3451
4684
|
{
|
|
3452
4685
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-px msr:w-full",
|
|
3453
4686
|
style: { backgroundColor: outlineColor }
|
|
3454
4687
|
}
|
|
3455
4688
|
),
|
|
3456
|
-
/* @__PURE__ */ (0,
|
|
4689
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3457
4690
|
"div",
|
|
3458
4691
|
{
|
|
3459
4692
|
className: "msr:absolute msr:right-0 msr:top-0 msr:h-full msr:w-px",
|
|
3460
4693
|
style: { backgroundColor: outlineColor }
|
|
3461
4694
|
}
|
|
3462
4695
|
),
|
|
3463
|
-
/* @__PURE__ */ (0,
|
|
4696
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3464
4697
|
"div",
|
|
3465
4698
|
{
|
|
3466
4699
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:h-px msr:w-full",
|
|
3467
4700
|
style: { backgroundColor: outlineColor }
|
|
3468
4701
|
}
|
|
3469
4702
|
),
|
|
3470
|
-
/* @__PURE__ */ (0,
|
|
4703
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3471
4704
|
"div",
|
|
3472
4705
|
{
|
|
3473
4706
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-full msr:w-px",
|
|
@@ -3477,7 +4710,7 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3477
4710
|
]
|
|
3478
4711
|
}
|
|
3479
4712
|
),
|
|
3480
|
-
/* @__PURE__ */ (0,
|
|
4713
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
3481
4714
|
MeasureTag,
|
|
3482
4715
|
{
|
|
3483
4716
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3493,7 +4726,7 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3493
4726
|
}
|
|
3494
4727
|
)
|
|
3495
4728
|
] }) : null,
|
|
3496
|
-
selectionVisible && hoverRectToShow ? /* @__PURE__ */ (0,
|
|
4729
|
+
selectionVisible && hoverRectToShow ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
3497
4730
|
"div",
|
|
3498
4731
|
{
|
|
3499
4732
|
className: "msr:pointer-events-none msr:absolute",
|
|
@@ -3505,28 +4738,28 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3505
4738
|
backgroundColor: fillColor
|
|
3506
4739
|
},
|
|
3507
4740
|
children: [
|
|
3508
|
-
hoverEdgeVisibility?.top ? /* @__PURE__ */ (0,
|
|
4741
|
+
hoverEdgeVisibility?.top ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3509
4742
|
"div",
|
|
3510
4743
|
{
|
|
3511
4744
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-px msr:w-full",
|
|
3512
4745
|
style: { backgroundColor: outlineColor }
|
|
3513
4746
|
}
|
|
3514
4747
|
) : null,
|
|
3515
|
-
hoverEdgeVisibility?.right ? /* @__PURE__ */ (0,
|
|
4748
|
+
hoverEdgeVisibility?.right ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3516
4749
|
"div",
|
|
3517
4750
|
{
|
|
3518
4751
|
className: "msr:absolute msr:right-0 msr:top-0 msr:h-full msr:w-px",
|
|
3519
4752
|
style: { backgroundColor: outlineColor }
|
|
3520
4753
|
}
|
|
3521
4754
|
) : null,
|
|
3522
|
-
hoverEdgeVisibility?.bottom ? /* @__PURE__ */ (0,
|
|
4755
|
+
hoverEdgeVisibility?.bottom ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3523
4756
|
"div",
|
|
3524
4757
|
{
|
|
3525
4758
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:h-px msr:w-full",
|
|
3526
4759
|
style: { backgroundColor: outlineColor }
|
|
3527
4760
|
}
|
|
3528
4761
|
) : null,
|
|
3529
|
-
hoverEdgeVisibility?.left ? /* @__PURE__ */ (0,
|
|
4762
|
+
hoverEdgeVisibility?.left ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3530
4763
|
"div",
|
|
3531
4764
|
{
|
|
3532
4765
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-full msr:w-px",
|
|
@@ -3536,7 +4769,7 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3536
4769
|
]
|
|
3537
4770
|
}
|
|
3538
4771
|
) : null,
|
|
3539
|
-
guidesEnabled && guidePreview ? /* @__PURE__ */ (0,
|
|
4772
|
+
interactive && guidesEnabled && guidePreview ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3540
4773
|
"div",
|
|
3541
4774
|
{
|
|
3542
4775
|
className: "msr:pointer-events-none msr:absolute",
|
|
@@ -3551,7 +4784,7 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3551
4784
|
height: GUIDE_HITBOX_SIZE,
|
|
3552
4785
|
width: "100%"
|
|
3553
4786
|
},
|
|
3554
|
-
children: /* @__PURE__ */ (0,
|
|
4787
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3555
4788
|
"div",
|
|
3556
4789
|
{
|
|
3557
4790
|
className: "msr:absolute",
|
|
@@ -3572,17 +4805,19 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3572
4805
|
)
|
|
3573
4806
|
}
|
|
3574
4807
|
) : null,
|
|
3575
|
-
selectionVisible ? displayedSelectedMeasurements.map((measurement, index) => /* @__PURE__ */ (0,
|
|
4808
|
+
selectionVisible ? displayedSelectedMeasurements.map((measurement, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3576
4809
|
SelectedMeasurementBox,
|
|
3577
4810
|
{
|
|
3578
4811
|
measurement,
|
|
3579
4812
|
transitionMs: MEASURE_TRANSITION_MS,
|
|
3580
4813
|
labelOffset: MEASURE_LABEL_OFFSET,
|
|
3581
|
-
edgeVisibility: selectedEdgeVisibility[index]
|
|
4814
|
+
edgeVisibility: selectedEdgeVisibility[index],
|
|
4815
|
+
outlineColor,
|
|
4816
|
+
fillColor
|
|
3582
4817
|
},
|
|
3583
4818
|
measurement.id
|
|
3584
4819
|
)) : null,
|
|
3585
|
-
heldDistances.map((distance) => /* @__PURE__ */ (0,
|
|
4820
|
+
interactive ? heldDistances.map((distance) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3586
4821
|
DistanceOverlayItem,
|
|
3587
4822
|
{
|
|
3588
4823
|
distance,
|
|
@@ -3590,8 +4825,8 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3590
4825
|
onRemove: onRemoveHeldDistance
|
|
3591
4826
|
},
|
|
3592
4827
|
`held-${distance.id}`
|
|
3593
|
-
)),
|
|
3594
|
-
selectionVisible && altPressed && optionPairOverlay ? /* @__PURE__ */ (0,
|
|
4828
|
+
)) : null,
|
|
4829
|
+
selectionVisible && altPressed && optionPairOverlay ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3595
4830
|
DistanceOverlayItem,
|
|
3596
4831
|
{
|
|
3597
4832
|
distance: optionPairOverlay,
|
|
@@ -3599,7 +4834,7 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3599
4834
|
},
|
|
3600
4835
|
`option-${optionPairOverlay.id}`
|
|
3601
4836
|
) : null,
|
|
3602
|
-
guidesEnabled && altPressed && guideDistanceOverlay ? /* @__PURE__ */ (0,
|
|
4837
|
+
interactive && guidesEnabled && altPressed && guideDistanceOverlay ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3603
4838
|
DistanceOverlayItem,
|
|
3604
4839
|
{
|
|
3605
4840
|
distance: guideDistanceOverlay,
|
|
@@ -3607,9 +4842,9 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3607
4842
|
},
|
|
3608
4843
|
`guide-preview-${guideDistanceOverlay.id}`
|
|
3609
4844
|
) : null,
|
|
3610
|
-
selectionVisible && altPressed && optionContainerLines ? /* @__PURE__ */ (0,
|
|
3611
|
-
optionContainerLines.top.value > 0 ? /* @__PURE__ */ (0,
|
|
3612
|
-
/* @__PURE__ */ (0,
|
|
4845
|
+
selectionVisible && altPressed && optionContainerLines ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
4846
|
+
optionContainerLines.top.value > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
4847
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3613
4848
|
"div",
|
|
3614
4849
|
{
|
|
3615
4850
|
className: "msr:absolute msr:w-px msr:bg-[#2563eb]",
|
|
@@ -3620,7 +4855,7 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3620
4855
|
}
|
|
3621
4856
|
}
|
|
3622
4857
|
),
|
|
3623
|
-
/* @__PURE__ */ (0,
|
|
4858
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3624
4859
|
MeasureTag,
|
|
3625
4860
|
{
|
|
3626
4861
|
className: "msr:-translate-y-1/2 msr:bg-ink-900/90",
|
|
@@ -3632,8 +4867,8 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3632
4867
|
}
|
|
3633
4868
|
)
|
|
3634
4869
|
] }) : null,
|
|
3635
|
-
optionContainerLines.bottom.value > 0 ? /* @__PURE__ */ (0,
|
|
3636
|
-
/* @__PURE__ */ (0,
|
|
4870
|
+
optionContainerLines.bottom.value > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
4871
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3637
4872
|
"div",
|
|
3638
4873
|
{
|
|
3639
4874
|
className: "msr:absolute msr:w-px msr:bg-[#2563eb]",
|
|
@@ -3644,7 +4879,7 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3644
4879
|
}
|
|
3645
4880
|
}
|
|
3646
4881
|
),
|
|
3647
|
-
/* @__PURE__ */ (0,
|
|
4882
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3648
4883
|
MeasureTag,
|
|
3649
4884
|
{
|
|
3650
4885
|
className: "msr:-translate-y-1/2 msr:bg-ink-900/90",
|
|
@@ -3656,8 +4891,8 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3656
4891
|
}
|
|
3657
4892
|
)
|
|
3658
4893
|
] }) : null,
|
|
3659
|
-
optionContainerLines.left.value > 0 ? /* @__PURE__ */ (0,
|
|
3660
|
-
/* @__PURE__ */ (0,
|
|
4894
|
+
optionContainerLines.left.value > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
4895
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3661
4896
|
"div",
|
|
3662
4897
|
{
|
|
3663
4898
|
className: "msr:absolute msr:h-px msr:bg-[#2563eb]",
|
|
@@ -3668,7 +4903,7 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3668
4903
|
}
|
|
3669
4904
|
}
|
|
3670
4905
|
),
|
|
3671
|
-
/* @__PURE__ */ (0,
|
|
4906
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3672
4907
|
MeasureTag,
|
|
3673
4908
|
{
|
|
3674
4909
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3680,8 +4915,8 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3680
4915
|
}
|
|
3681
4916
|
)
|
|
3682
4917
|
] }) : null,
|
|
3683
|
-
optionContainerLines.right.value > 0 ? /* @__PURE__ */ (0,
|
|
3684
|
-
/* @__PURE__ */ (0,
|
|
4918
|
+
optionContainerLines.right.value > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
4919
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3685
4920
|
"div",
|
|
3686
4921
|
{
|
|
3687
4922
|
className: "msr:absolute msr:h-px msr:bg-[#2563eb]",
|
|
@@ -3692,7 +4927,7 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3692
4927
|
}
|
|
3693
4928
|
}
|
|
3694
4929
|
),
|
|
3695
|
-
/* @__PURE__ */ (0,
|
|
4930
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3696
4931
|
MeasureTag,
|
|
3697
4932
|
{
|
|
3698
4933
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3708,9 +4943,12 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3708
4943
|
guides.map((guide) => {
|
|
3709
4944
|
const isSelected = selectedGuideIds.includes(guide.id);
|
|
3710
4945
|
const isHovered = hoverGuide?.id === guide.id;
|
|
3711
|
-
const strokeWidth = isSelected || isHovered ? 2 : 1;
|
|
3712
4946
|
const strokeColor = isSelected ? guideColorActive : isHovered ? guideColorHover : guideColorDefault;
|
|
3713
|
-
|
|
4947
|
+
const strokeWidth = Math.max(guideStyle.width, isSelected || isHovered ? 2 : guideStyle.width);
|
|
4948
|
+
const isSolid = guideStyle.pattern === "solid";
|
|
4949
|
+
const backgroundImage = guideStyle.pattern === "solid" ? void 0 : guideStyle.pattern === "dotted" ? `radial-gradient(circle, ${strokeColor} 0 ${strokeWidth / 2}px, transparent ${strokeWidth / 2 + 0.5}px)` : `repeating-linear-gradient(${guide.orientation === "vertical" ? "to bottom" : "to right"}, ${strokeColor} 0 ${guideStyle.dashLength}px, transparent ${guideStyle.dashLength}px ${guideStyle.dashLength + guideStyle.gap}px)`;
|
|
4950
|
+
const backgroundSize = guideStyle.pattern === "dotted" ? guide.orientation === "vertical" ? `${strokeWidth}px ${guideStyle.dashLength + guideStyle.gap}px` : `${guideStyle.dashLength + guideStyle.gap}px ${strokeWidth}px` : void 0;
|
|
4951
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3714
4952
|
"div",
|
|
3715
4953
|
{
|
|
3716
4954
|
className: "msr:absolute",
|
|
@@ -3731,7 +4969,7 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3731
4969
|
onPointerDown: (event) => onGuidePointerDown(guide, event),
|
|
3732
4970
|
onPointerUp: (event) => onGuidePointerUp(guide, event),
|
|
3733
4971
|
onPointerCancel: (event) => onGuidePointerCancel(guide, event),
|
|
3734
|
-
children: /* @__PURE__ */ (0,
|
|
4972
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3735
4973
|
"div",
|
|
3736
4974
|
{
|
|
3737
4975
|
className: "msr:absolute",
|
|
@@ -3740,13 +4978,19 @@ var MeasurerOverlay = (0, import_react19.memo)(function MeasurerOverlay2({
|
|
|
3740
4978
|
top: 0,
|
|
3741
4979
|
width: strokeWidth,
|
|
3742
4980
|
height: "100%",
|
|
3743
|
-
backgroundColor: strokeColor
|
|
4981
|
+
backgroundColor: isSolid ? strokeColor : "transparent",
|
|
4982
|
+
backgroundImage,
|
|
4983
|
+
backgroundSize,
|
|
4984
|
+
opacity: guideStyle.opacity
|
|
3744
4985
|
} : {
|
|
3745
4986
|
top: GUIDE_HITBOX_SIZE / 2 - 1,
|
|
3746
4987
|
left: 0,
|
|
3747
4988
|
height: strokeWidth,
|
|
3748
4989
|
width: "100%",
|
|
3749
|
-
backgroundColor: strokeColor
|
|
4990
|
+
backgroundColor: isSolid ? strokeColor : "transparent",
|
|
4991
|
+
backgroundImage,
|
|
4992
|
+
backgroundSize,
|
|
4993
|
+
opacity: guideStyle.opacity
|
|
3750
4994
|
}
|
|
3751
4995
|
}
|
|
3752
4996
|
)
|
|
@@ -4267,6 +5511,7 @@ var createTextInspector = (options = {}, legacy = false) => {
|
|
|
4267
5511
|
if (!element) return false;
|
|
4268
5512
|
for (let node = element; node; node = node.parentElement) {
|
|
4269
5513
|
if (node.classList.contains("mesurer-toolbar-surface")) return true;
|
|
5514
|
+
if (node.hasAttribute("data-mesurer-inspector-ui")) return true;
|
|
4270
5515
|
}
|
|
4271
5516
|
return false;
|
|
4272
5517
|
};
|
|
@@ -4564,7 +5809,7 @@ var createTextInspector = (options = {}, legacy = false) => {
|
|
|
4564
5809
|
const isInspectorUIEvent = (event) => event.composedPath().some(
|
|
4565
5810
|
(node) => node instanceof HTMLElementConstructor && (() => {
|
|
4566
5811
|
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");
|
|
5812
|
+
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") || element.hasAttribute("data-mesurer-inspector-ui");
|
|
4568
5813
|
})()
|
|
4569
5814
|
);
|
|
4570
5815
|
const onClick = (event) => {
|
|
@@ -4647,8 +5892,223 @@ var createTextInspector = (options = {}, legacy = false) => {
|
|
|
4647
5892
|
};
|
|
4648
5893
|
var TextInspector = createTextInspector({}, true);
|
|
4649
5894
|
|
|
5895
|
+
// core/persistence.ts
|
|
5896
|
+
var MESURER_STORAGE_VERSION = 2;
|
|
5897
|
+
var DEFAULT_GUIDE_STYLE = {
|
|
5898
|
+
opacity: 1,
|
|
5899
|
+
width: 1,
|
|
5900
|
+
pattern: "solid",
|
|
5901
|
+
dashLength: 6,
|
|
5902
|
+
gap: 4
|
|
5903
|
+
};
|
|
5904
|
+
var DEFAULT_RULER_SETTINGS = {
|
|
5905
|
+
opacity: 1,
|
|
5906
|
+
edgeReveal: false
|
|
5907
|
+
};
|
|
5908
|
+
var isFormat = (value) => value === "hex" || value === "rgb" || value === "hsl" || value === "oklch";
|
|
5909
|
+
var normalizeGuideStyle = (value) => {
|
|
5910
|
+
if (!value || typeof value !== "object") return void 0;
|
|
5911
|
+
const input = value;
|
|
5912
|
+
return {
|
|
5913
|
+
opacity: typeof input.opacity === "number" ? Math.min(1, Math.max(0, input.opacity)) : DEFAULT_GUIDE_STYLE.opacity,
|
|
5914
|
+
width: typeof input.width === "number" ? Math.min(4, Math.max(1, input.width)) : DEFAULT_GUIDE_STYLE.width,
|
|
5915
|
+
pattern: input.pattern === "dashed" || input.pattern === "dotted" ? input.pattern : DEFAULT_GUIDE_STYLE.pattern,
|
|
5916
|
+
dashLength: typeof input.dashLength === "number" ? Math.min(24, Math.max(2, input.dashLength)) : DEFAULT_GUIDE_STYLE.dashLength,
|
|
5917
|
+
gap: typeof input.gap === "number" ? Math.min(24, Math.max(0, input.gap)) : DEFAULT_GUIDE_STYLE.gap
|
|
5918
|
+
};
|
|
5919
|
+
};
|
|
5920
|
+
var normalizeRulerSettings = (value) => {
|
|
5921
|
+
if (!value || typeof value !== "object") return void 0;
|
|
5922
|
+
const input = value;
|
|
5923
|
+
return {
|
|
5924
|
+
opacity: typeof input.opacity === "number" ? Math.min(1, Math.max(0.2, input.opacity)) : DEFAULT_RULER_SETTINGS.opacity,
|
|
5925
|
+
edgeReveal: typeof input.edgeReveal === "boolean" ? input.edgeReveal : DEFAULT_RULER_SETTINGS.edgeReveal
|
|
5926
|
+
};
|
|
5927
|
+
};
|
|
5928
|
+
var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
5929
|
+
var isRect = (value) => {
|
|
5930
|
+
if (!value || typeof value !== "object") return false;
|
|
5931
|
+
const rect = value;
|
|
5932
|
+
return isFiniteNumber(rect.left) && isFiniteNumber(rect.top) && isFiniteNumber(rect.width) && rect.width >= 0 && isFiniteNumber(rect.height) && rect.height >= 0;
|
|
5933
|
+
};
|
|
5934
|
+
var isNormalizedRect = (value) => isRect(value);
|
|
5935
|
+
var isMeasurement = (value) => {
|
|
5936
|
+
if (!value || typeof value !== "object") return false;
|
|
5937
|
+
const measurement = value;
|
|
5938
|
+
return typeof measurement.id === "string" && isRect(measurement.rect) && isNormalizedRect(measurement.normalizedRect) && isFiniteNumber(measurement.deltaX) && isFiniteNumber(measurement.deltaY) && (measurement.snapped === void 0 || typeof measurement.snapped === "boolean");
|
|
5939
|
+
};
|
|
5940
|
+
var isGuide = (value) => {
|
|
5941
|
+
if (!value || typeof value !== "object") return false;
|
|
5942
|
+
const guide = value;
|
|
5943
|
+
return typeof guide.id === "string" && (guide.orientation === "vertical" || guide.orientation === "horizontal") && isFiniteNumber(guide.position);
|
|
5944
|
+
};
|
|
5945
|
+
var isDistanceOverlay = (value) => {
|
|
5946
|
+
if (!value || typeof value !== "object") return false;
|
|
5947
|
+
const distance = value;
|
|
5948
|
+
const isDistanceLine = (line) => {
|
|
5949
|
+
if (line === null) return true;
|
|
5950
|
+
if (!line || typeof line !== "object") return false;
|
|
5951
|
+
const item = line;
|
|
5952
|
+
return isFiniteNumber(item.x1) && isFiniteNumber(item.x2) && isFiniteNumber(item.y) && isFiniteNumber(item.value);
|
|
5953
|
+
};
|
|
5954
|
+
const isVerticalLine = (line) => {
|
|
5955
|
+
if (line === null) return true;
|
|
5956
|
+
if (!line || typeof line !== "object") return false;
|
|
5957
|
+
const item = line;
|
|
5958
|
+
return isFiniteNumber(item.y1) && isFiniteNumber(item.y2) && isFiniteNumber(item.x) && isFiniteNumber(item.value);
|
|
5959
|
+
};
|
|
5960
|
+
return typeof distance.id === "string" && isRect(distance.rectA) && isRect(distance.rectB) && isNormalizedRect(distance.normalizedRectA) && isNormalizedRect(distance.normalizedRectB) && isDistanceLine(distance.horizontal) && isVerticalLine(distance.vertical) && Array.isArray(distance.connectors) && distance.connectors.every((connector) => {
|
|
5961
|
+
if (!connector || typeof connector !== "object") return false;
|
|
5962
|
+
const item = connector;
|
|
5963
|
+
return isFiniteNumber(item.x1) && isFiniteNumber(item.y1) && isFiniteNumber(item.x2) && isFiniteNumber(item.y2);
|
|
5964
|
+
});
|
|
5965
|
+
};
|
|
5966
|
+
var normalizeStoredSettings = (value) => {
|
|
5967
|
+
if (!value || typeof value !== "object") return {};
|
|
5968
|
+
const input = value;
|
|
5969
|
+
return {
|
|
5970
|
+
...typeof input.highlightColor === "string" ? { highlightColor: input.highlightColor } : {},
|
|
5971
|
+
...typeof input.guideColor === "string" ? { guideColor: input.guideColor } : {},
|
|
5972
|
+
...typeof input.hoverHighlightEnabled === "boolean" ? { hoverHighlightEnabled: input.hoverHighlightEnabled } : {},
|
|
5973
|
+
...Array.isArray(input.colorPickerFormats) && input.colorPickerFormats.some(isFormat) ? { colorPickerFormats: input.colorPickerFormats.filter(isFormat) } : {},
|
|
5974
|
+
...isFormat(input.colorPickerClickFormat) ? { colorPickerClickFormat: input.colorPickerClickFormat } : {},
|
|
5975
|
+
...typeof input.snapEnabled === "boolean" ? { snapEnabled: input.snapEnabled } : {},
|
|
5976
|
+
...typeof input.snapGuidesEnabled === "boolean" ? { snapGuidesEnabled: input.snapGuidesEnabled } : {},
|
|
5977
|
+
...typeof input.selectNewGuideEnabled === "boolean" ? { selectNewGuideEnabled: input.selectNewGuideEnabled } : {},
|
|
5978
|
+
...typeof input.multiMeasureEnabled === "boolean" ? { multiMeasureEnabled: input.multiMeasureEnabled } : {},
|
|
5979
|
+
...typeof input.persistOnReload === "boolean" ? { persistOnReload: input.persistOnReload } : {},
|
|
5980
|
+
...normalizeGuideStyle(input.guideStyle) ? { guideStyle: normalizeGuideStyle(input.guideStyle) } : {},
|
|
5981
|
+
...normalizeRulerSettings(input.rulerSettings) ? { rulerSettings: normalizeRulerSettings(input.rulerSettings) } : {}
|
|
5982
|
+
};
|
|
5983
|
+
};
|
|
5984
|
+
var normalizeStoredWorkspace = (value) => {
|
|
5985
|
+
if (!value || typeof value !== "object") return null;
|
|
5986
|
+
const input = value;
|
|
5987
|
+
if (typeof input.enabled !== "boolean" || input.toolMode !== "none" && input.toolMode !== "select" && input.toolMode !== "guides" && input.toolMode !== "text-inspector" && input.toolMode !== "xray" && input.toolMode !== "rulers" || typeof input.rulersVisible !== "boolean" || input.guideOrientation !== "vertical" && input.guideOrientation !== "horizontal" || !Array.isArray(input.guides) || !Array.isArray(input.selectedGuideIds) || !Array.isArray(input.measurements) || !Array.isArray(input.heldDistances)) return null;
|
|
5988
|
+
return {
|
|
5989
|
+
enabled: input.enabled,
|
|
5990
|
+
xrayVisible: typeof input.xrayVisible === "boolean" ? input.xrayVisible : input.toolMode === "xray",
|
|
5991
|
+
toolMode: input.toolMode,
|
|
5992
|
+
rulersVisible: input.rulersVisible,
|
|
5993
|
+
guideOrientation: input.guideOrientation,
|
|
5994
|
+
guides: input.guides.filter(isGuide),
|
|
5995
|
+
selectedGuideIds: input.selectedGuideIds.filter((id) => typeof id === "string"),
|
|
5996
|
+
measurements: input.measurements.filter(isMeasurement),
|
|
5997
|
+
activeMeasurement: isMeasurement(input.activeMeasurement) ? input.activeMeasurement : null,
|
|
5998
|
+
heldDistances: input.heldDistances.filter(isDistanceOverlay)
|
|
5999
|
+
};
|
|
6000
|
+
};
|
|
6001
|
+
var normalizePersistenceSnapshot = (value) => {
|
|
6002
|
+
if (!value || typeof value !== "object") return null;
|
|
6003
|
+
const record = value;
|
|
6004
|
+
if (record.version !== MESURER_STORAGE_VERSION) return null;
|
|
6005
|
+
return {
|
|
6006
|
+
settings: normalizeStoredSettings(record.settings),
|
|
6007
|
+
workspace: normalizeStoredWorkspace(record.workspace)
|
|
6008
|
+
};
|
|
6009
|
+
};
|
|
6010
|
+
var migrate = (record) => {
|
|
6011
|
+
if (record.version === MESURER_STORAGE_VERSION) {
|
|
6012
|
+
return normalizePersistenceSnapshot(record);
|
|
6013
|
+
}
|
|
6014
|
+
if (record.version !== 1) return null;
|
|
6015
|
+
return {
|
|
6016
|
+
settings: {},
|
|
6017
|
+
workspace: record.enabled === void 0 || !record.toolMode || !record.guideOrientation || !record.guides || !record.selectedGuideIds || !record.measurements || record.activeMeasurement === void 0 || !record.heldDistances ? null : normalizeStoredWorkspace({
|
|
6018
|
+
enabled: record.enabled,
|
|
6019
|
+
xrayVisible: record.toolMode === "xray",
|
|
6020
|
+
toolMode: record.toolMode,
|
|
6021
|
+
rulersVisible: record.rulersVisible ?? record.toolMode === "rulers",
|
|
6022
|
+
guideOrientation: record.guideOrientation,
|
|
6023
|
+
guides: record.guides,
|
|
6024
|
+
selectedGuideIds: record.selectedGuideIds,
|
|
6025
|
+
measurements: record.measurements,
|
|
6026
|
+
activeMeasurement: record.activeMeasurement,
|
|
6027
|
+
heldDistances: record.heldDistances
|
|
6028
|
+
})
|
|
6029
|
+
};
|
|
6030
|
+
};
|
|
6031
|
+
var createLocalStoragePersistence = (ownerWindow, workspaceKey, settingsKey = workspaceKey, legacyKey) => {
|
|
6032
|
+
let errorHandler;
|
|
6033
|
+
const readRecord = (key) => {
|
|
6034
|
+
try {
|
|
6035
|
+
const raw = ownerWindow.localStorage.getItem(key);
|
|
6036
|
+
if (!raw) return null;
|
|
6037
|
+
return migrate(JSON.parse(raw));
|
|
6038
|
+
} catch (error) {
|
|
6039
|
+
errorHandler?.(error);
|
|
6040
|
+
return null;
|
|
6041
|
+
}
|
|
6042
|
+
};
|
|
6043
|
+
const read = () => {
|
|
6044
|
+
const legacy = legacyKey ? readRecord(legacyKey) : null;
|
|
6045
|
+
const settingsRecord = readRecord(settingsKey);
|
|
6046
|
+
const workspaceRecord = readRecord(workspaceKey);
|
|
6047
|
+
if (!settingsRecord && !workspaceRecord && !legacy) return null;
|
|
6048
|
+
return {
|
|
6049
|
+
settings: settingsRecord?.settings ?? legacy?.settings ?? {},
|
|
6050
|
+
workspace: workspaceRecord?.workspace ?? legacy?.workspace ?? null
|
|
6051
|
+
};
|
|
6052
|
+
};
|
|
6053
|
+
const writeRecord = (key, snapshot) => {
|
|
6054
|
+
try {
|
|
6055
|
+
ownerWindow.localStorage.setItem(
|
|
6056
|
+
key,
|
|
6057
|
+
JSON.stringify({ version: MESURER_STORAGE_VERSION, ...snapshot })
|
|
6058
|
+
);
|
|
6059
|
+
} catch (error) {
|
|
6060
|
+
errorHandler?.(error);
|
|
6061
|
+
}
|
|
6062
|
+
};
|
|
6063
|
+
return {
|
|
6064
|
+
load: read,
|
|
6065
|
+
saveSettings: (settings) => {
|
|
6066
|
+
if (settingsKey === workspaceKey) {
|
|
6067
|
+
writeRecord(workspaceKey, { settings, workspace: read()?.workspace ?? null });
|
|
6068
|
+
return;
|
|
6069
|
+
}
|
|
6070
|
+
writeRecord(settingsKey, { settings, workspace: null });
|
|
6071
|
+
},
|
|
6072
|
+
saveWorkspace: (workspace) => {
|
|
6073
|
+
if (settingsKey === workspaceKey) {
|
|
6074
|
+
writeRecord(workspaceKey, { settings: read()?.settings ?? {}, workspace });
|
|
6075
|
+
return;
|
|
6076
|
+
}
|
|
6077
|
+
writeRecord(workspaceKey, { settings: {}, workspace });
|
|
6078
|
+
},
|
|
6079
|
+
clearWorkspace: () => {
|
|
6080
|
+
if (settingsKey === workspaceKey) {
|
|
6081
|
+
const current = read();
|
|
6082
|
+
if (current) writeRecord(workspaceKey, { settings: current.settings, workspace: null });
|
|
6083
|
+
return;
|
|
6084
|
+
}
|
|
6085
|
+
writeRecord(workspaceKey, { settings: {}, workspace: null });
|
|
6086
|
+
},
|
|
6087
|
+
clearSettings: () => {
|
|
6088
|
+
if (settingsKey === workspaceKey) {
|
|
6089
|
+
writeRecord(workspaceKey, { settings: {}, workspace: read()?.workspace ?? null });
|
|
6090
|
+
return;
|
|
6091
|
+
}
|
|
6092
|
+
writeRecord(settingsKey, { settings: {}, workspace: null });
|
|
6093
|
+
},
|
|
6094
|
+
setErrorHandler: (handler) => {
|
|
6095
|
+
errorHandler = handler;
|
|
6096
|
+
},
|
|
6097
|
+
subscribe: (listener) => {
|
|
6098
|
+
const handleStorage = (event) => {
|
|
6099
|
+
if (event.key !== settingsKey && event.key !== workspaceKey && event.key !== legacyKey) return;
|
|
6100
|
+
listener(read());
|
|
6101
|
+
};
|
|
6102
|
+
ownerWindow.addEventListener("storage", handleStorage);
|
|
6103
|
+
return () => {
|
|
6104
|
+
ownerWindow.removeEventListener("storage", handleStorage);
|
|
6105
|
+
};
|
|
6106
|
+
}
|
|
6107
|
+
};
|
|
6108
|
+
};
|
|
6109
|
+
|
|
4650
6110
|
// measurer.tsx
|
|
4651
|
-
var
|
|
6111
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4652
6112
|
var measurerInstanceCount = 0;
|
|
4653
6113
|
var XRAY_STYLE_ID = "mesurer-xray-styles";
|
|
4654
6114
|
var XRAY_STYLES = `
|
|
@@ -4660,13 +6120,17 @@ var XRAY_STYLES = `
|
|
|
4660
6120
|
.xray-mode .mesurer-root,
|
|
4661
6121
|
.xray-mode .mesurer-root *,
|
|
4662
6122
|
.xray-mode .mesurer-toolbar-surface,
|
|
4663
|
-
.xray-mode .mesurer-toolbar-surface
|
|
6123
|
+
.xray-mode .mesurer-toolbar-surface *,
|
|
6124
|
+
.xray-mode .mesurer-ti-box,
|
|
6125
|
+
.xray-mode .mesurer-ti-card,
|
|
6126
|
+
.xray-mode .mesurer-ti-card *,
|
|
6127
|
+
.xray-mode .mesurer-ti-close {
|
|
4664
6128
|
outline: none !important;
|
|
4665
6129
|
}
|
|
4666
6130
|
`;
|
|
4667
6131
|
var subscribeHydration = () => () => {
|
|
4668
6132
|
};
|
|
4669
|
-
var useHydrated = () => (0,
|
|
6133
|
+
var useHydrated = () => (0, import_react23.useSyncExternalStore)(
|
|
4670
6134
|
subscribeHydration,
|
|
4671
6135
|
() => true,
|
|
4672
6136
|
() => false
|
|
@@ -4680,70 +6144,112 @@ var stripDistance = (distance) => ({
|
|
|
4680
6144
|
elementRefA: void 0,
|
|
4681
6145
|
elementRefB: void 0
|
|
4682
6146
|
});
|
|
6147
|
+
var TAB_ID_KEY = "mesurer:tab-id";
|
|
6148
|
+
var SETTINGS_STORAGE_KEY = "mesurer-settings";
|
|
6149
|
+
var LEGACY_STORAGE_KEY = "mesurer-state";
|
|
6150
|
+
var getTabId = (ownerWindow) => {
|
|
6151
|
+
try {
|
|
6152
|
+
const existing = ownerWindow.sessionStorage.getItem(TAB_ID_KEY);
|
|
6153
|
+
if (existing) return existing;
|
|
6154
|
+
const id = ownerWindow.crypto.randomUUID();
|
|
6155
|
+
ownerWindow.sessionStorage.setItem(TAB_ID_KEY, id);
|
|
6156
|
+
return id;
|
|
6157
|
+
} catch {
|
|
6158
|
+
return "session";
|
|
6159
|
+
}
|
|
6160
|
+
};
|
|
6161
|
+
var sanitizeStoredSettings = (ownerWindow, settings) => {
|
|
6162
|
+
const supportsColor = (value) => value !== void 0 && ownerWindow.CSS?.supports("color", value) === true;
|
|
6163
|
+
return {
|
|
6164
|
+
...settings,
|
|
6165
|
+
...supportsColor(settings.highlightColor) ? {} : { highlightColor: void 0 },
|
|
6166
|
+
...supportsColor(settings.guideColor) ? {} : { guideColor: void 0 }
|
|
6167
|
+
};
|
|
6168
|
+
};
|
|
4683
6169
|
function MeasurerClient({
|
|
4684
6170
|
highlightColor,
|
|
4685
6171
|
guideColor,
|
|
4686
6172
|
hoverHighlightEnabled,
|
|
4687
6173
|
persistOnReload,
|
|
4688
6174
|
portalTarget,
|
|
4689
|
-
persistKey
|
|
6175
|
+
persistKey,
|
|
6176
|
+
colorPickerFormats,
|
|
6177
|
+
colorPickerClickFormat,
|
|
6178
|
+
snapEnabled: snapEnabledDefault,
|
|
6179
|
+
snapGuidesEnabled: snapGuidesEnabledDefault,
|
|
6180
|
+
selectNewGuideEnabled: selectNewGuideEnabledDefault,
|
|
6181
|
+
multiMeasureEnabled: multiMeasureEnabledDefault,
|
|
6182
|
+
guideStyle: guideStyleDefault,
|
|
6183
|
+
rulerSettings: rulerSettingsDefault,
|
|
6184
|
+
persistence,
|
|
6185
|
+
onPersistenceError
|
|
4690
6186
|
}) {
|
|
4691
|
-
const instanceIdRef = (0,
|
|
6187
|
+
const instanceIdRef = (0, import_react23.useRef)(null);
|
|
4692
6188
|
if (instanceIdRef.current === null) {
|
|
4693
6189
|
instanceIdRef.current = ++measurerInstanceCount;
|
|
4694
6190
|
}
|
|
4695
|
-
const storageKey = persistKey ?? (instanceIdRef.current === 1 ? "mesurer-state" : `mesurer-state-${instanceIdRef.current}`);
|
|
4696
6191
|
const ownerDocument = portalTarget.ownerDocument ?? document;
|
|
4697
6192
|
const ownerWindow = ownerDocument.defaultView ?? window;
|
|
4698
|
-
const
|
|
6193
|
+
const tabIdRef = (0, import_react23.useRef)(null);
|
|
6194
|
+
if (tabIdRef.current === null) tabIdRef.current = getTabId(ownerWindow);
|
|
6195
|
+
const storageKey = persistKey ?? (instanceIdRef.current === 1 ? `mesurer-state:${tabIdRef.current}` : `mesurer-state:${tabIdRef.current}:${instanceIdRef.current}`);
|
|
6196
|
+
const legacyStorageKey = persistKey ? void 0 : LEGACY_STORAGE_KEY;
|
|
6197
|
+
const guideScrollRef = (0, import_react23.useRef)({
|
|
4699
6198
|
x: ownerWindow.scrollX,
|
|
4700
6199
|
y: ownerWindow.scrollY
|
|
4701
6200
|
});
|
|
4702
|
-
const textInspectorRef = (0,
|
|
6201
|
+
const textInspectorRef = (0, import_react23.useRef)(null);
|
|
4703
6202
|
if (!textInspectorRef.current) {
|
|
4704
6203
|
textInspectorRef.current = createTextInspector({ portalTarget });
|
|
4705
6204
|
}
|
|
4706
6205
|
const textInspector = textInspectorRef.current;
|
|
4707
|
-
const selectionRectRef = (0,
|
|
4708
|
-
const toolbarRef = (0,
|
|
4709
|
-
const selectionAnimationCleanupTimeoutRef = (0,
|
|
4710
|
-
const guideDragRef = (0,
|
|
4711
|
-
const guideUserSelectRef = (0,
|
|
4712
|
-
const
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
const
|
|
4725
|
-
|
|
6206
|
+
const selectionRectRef = (0, import_react23.useRef)(null);
|
|
6207
|
+
const toolbarRef = (0, import_react23.useRef)(null);
|
|
6208
|
+
const selectionAnimationCleanupTimeoutRef = (0, import_react23.useRef)(null);
|
|
6209
|
+
const guideDragRef = (0, import_react23.useRef)(null);
|
|
6210
|
+
const guideUserSelectRef = (0, import_react23.useRef)(null);
|
|
6211
|
+
const persistenceErrorHandlerRef = (0, import_react23.useRef)(onPersistenceError);
|
|
6212
|
+
persistenceErrorHandlerRef.current = onPersistenceError;
|
|
6213
|
+
const activePersistence = (0, import_react23.useMemo)(() => {
|
|
6214
|
+
const next = persistence ?? createLocalStoragePersistence(ownerWindow, storageKey, SETTINGS_STORAGE_KEY, legacyStorageKey);
|
|
6215
|
+
next.setErrorHandler?.((error) => persistenceErrorHandlerRef.current?.(error));
|
|
6216
|
+
return next;
|
|
6217
|
+
}, [legacyStorageKey, ownerWindow, persistence, storageKey]);
|
|
6218
|
+
const storedState = (0, import_react23.useMemo)(
|
|
6219
|
+
() => activePersistence.load(),
|
|
6220
|
+
[activePersistence]
|
|
6221
|
+
);
|
|
6222
|
+
const persistedState = persistOnReload || storedState?.settings.persistOnReload ? storedState?.workspace ?? null : null;
|
|
6223
|
+
const persistedSettings = sanitizeStoredSettings(ownerWindow, storedState?.settings ?? {});
|
|
6224
|
+
(0, import_react23.useEffect)(() => {
|
|
6225
|
+
return () => activePersistence.setErrorHandler?.(void 0);
|
|
6226
|
+
}, [activePersistence]);
|
|
6227
|
+
const enabledRef = (0, import_react23.useRef)(false);
|
|
6228
|
+
const toolModeRef = (0, import_react23.useRef)(
|
|
4726
6229
|
persistedState?.toolMode === "rulers" ? "none" : persistedState?.toolMode ?? "none"
|
|
4727
6230
|
);
|
|
4728
|
-
const rulersVisibleRef = (0,
|
|
6231
|
+
const rulersVisibleRef = (0, import_react23.useRef)(
|
|
4729
6232
|
persistedState?.rulersVisible ?? persistedState?.toolMode === "rulers"
|
|
4730
6233
|
);
|
|
4731
|
-
const
|
|
6234
|
+
const xrayVisibleRef = (0, import_react23.useRef)(persistedState?.xrayVisible ?? persistedState?.toolMode === "xray");
|
|
6235
|
+
const guideOrientationRef = (0, import_react23.useRef)(
|
|
4732
6236
|
persistedState?.guideOrientation ?? "vertical"
|
|
4733
6237
|
);
|
|
4734
|
-
const measurementsRef = (0,
|
|
6238
|
+
const measurementsRef = (0, import_react23.useRef)(
|
|
4735
6239
|
persistedState?.measurements ?? []
|
|
4736
6240
|
);
|
|
4737
|
-
const activeMeasurementRef = (0,
|
|
6241
|
+
const activeMeasurementRef = (0, import_react23.useRef)(
|
|
4738
6242
|
persistedState?.activeMeasurement ?? null
|
|
4739
6243
|
);
|
|
4740
|
-
const heldDistancesRef = (0,
|
|
6244
|
+
const heldDistancesRef = (0, import_react23.useRef)(
|
|
4741
6245
|
persistedState?.heldDistances ?? []
|
|
4742
6246
|
);
|
|
4743
|
-
const guidesRef = (0,
|
|
4744
|
-
const selectedGuideIdsRef = (0,
|
|
6247
|
+
const guidesRef = (0, import_react23.useRef)(persistedState?.guides ?? []);
|
|
6248
|
+
const selectedGuideIdsRef = (0, import_react23.useRef)(
|
|
4745
6249
|
persistedState?.selectedGuideIds ?? []
|
|
4746
6250
|
);
|
|
6251
|
+
const workspacePersistTimeoutRef = (0, import_react23.useRef)(null);
|
|
6252
|
+
const applyingExternalPersistenceRef = (0, import_react23.useRef)(false);
|
|
4747
6253
|
const { overlayRef, selectedElementRef, hoverElementRef } = useOverlayRefs();
|
|
4748
6254
|
const {
|
|
4749
6255
|
selectionOriginRect,
|
|
@@ -4773,11 +6279,20 @@ function MeasurerClient({
|
|
|
4773
6279
|
setRulersVisible,
|
|
4774
6280
|
guidesEnabled,
|
|
4775
6281
|
multiMeasureEnabled,
|
|
4776
|
-
snapGuidesEnabled
|
|
6282
|
+
snapGuidesEnabled,
|
|
6283
|
+
setSnapGuidesEnabled,
|
|
6284
|
+
selectNewGuideEnabled,
|
|
6285
|
+
setSelectNewGuideEnabled,
|
|
6286
|
+
setSnapEnabled,
|
|
6287
|
+
setMultiMeasureEnabled
|
|
4777
6288
|
} = useMeasureToggles({
|
|
4778
6289
|
initialEnabled: persistedState?.enabled,
|
|
4779
6290
|
initialToolMode: persistedState?.toolMode === "rulers" ? "none" : persistedState?.toolMode,
|
|
4780
|
-
initialRulersVisible: persistedState?.rulersVisible ?? persistedState?.toolMode === "rulers"
|
|
6291
|
+
initialRulersVisible: persistedState?.rulersVisible ?? persistedState?.toolMode === "rulers",
|
|
6292
|
+
initialSnapEnabled: persistedSettings.snapEnabled ?? snapEnabledDefault,
|
|
6293
|
+
initialSnapGuidesEnabled: persistedSettings.snapGuidesEnabled ?? snapGuidesEnabledDefault,
|
|
6294
|
+
initialSelectNewGuideEnabled: persistedSettings.selectNewGuideEnabled ?? selectNewGuideEnabledDefault,
|
|
6295
|
+
initialMultiMeasureEnabled: persistedSettings.multiMeasureEnabled ?? multiMeasureEnabledDefault
|
|
4781
6296
|
});
|
|
4782
6297
|
const { start, setStart, end, setEnd, isDragging, setIsDragging } = useDragState();
|
|
4783
6298
|
const {
|
|
@@ -4809,11 +6324,58 @@ function MeasurerClient({
|
|
|
4809
6324
|
initialGuides: persistedState?.guides ?? [],
|
|
4810
6325
|
initialSelectedGuideIds: persistedState?.selectedGuideIds ?? []
|
|
4811
6326
|
});
|
|
4812
|
-
const [toolbarActive, setToolbarActive] = (0,
|
|
6327
|
+
const [toolbarActive, setToolbarActive] = (0, import_react23.useState)(true);
|
|
6328
|
+
const [colorPickerActive, setColorPickerActive] = (0, import_react23.useState)(false);
|
|
6329
|
+
const [colorPickerSample, setColorPickerSample] = (0, import_react23.useState)(null);
|
|
6330
|
+
const [colorPickerUnsupported, setColorPickerUnsupported] = (0, import_react23.useState)(false);
|
|
6331
|
+
const [settingsOpen, setSettingsOpen] = (0, import_react23.useState)(false);
|
|
6332
|
+
const [settingsHighlightColor, setSettingsHighlightColor] = (0, import_react23.useState)(
|
|
6333
|
+
persistedSettings.highlightColor ?? highlightColor
|
|
6334
|
+
);
|
|
6335
|
+
const [settingsGuideColor, setSettingsGuideColor] = (0, import_react23.useState)(
|
|
6336
|
+
persistedSettings.guideColor ?? guideColor
|
|
6337
|
+
);
|
|
6338
|
+
const [settingsHoverHighlight, setSettingsHoverHighlight] = (0, import_react23.useState)(
|
|
6339
|
+
persistedSettings.hoverHighlightEnabled ?? hoverHighlightEnabled
|
|
6340
|
+
);
|
|
6341
|
+
const [settingsPersistOnReload, setSettingsPersistOnReload] = (0, import_react23.useState)(
|
|
6342
|
+
persistedSettings.persistOnReload ?? persistOnReload
|
|
6343
|
+
);
|
|
6344
|
+
const [settingsColorFormats, setSettingsColorFormats] = (0, import_react23.useState)(
|
|
6345
|
+
persistedSettings.colorPickerFormats ?? colorPickerFormats
|
|
6346
|
+
);
|
|
6347
|
+
const [settingsColorClickFormat, setSettingsColorClickFormat] = (0, import_react23.useState)(
|
|
6348
|
+
persistedSettings.colorPickerClickFormat ?? colorPickerClickFormat
|
|
6349
|
+
);
|
|
6350
|
+
const [settingsGuideStyle, setSettingsGuideStyle] = (0, import_react23.useState)({
|
|
6351
|
+
...guideStyleDefault,
|
|
6352
|
+
...persistedSettings.guideStyle
|
|
6353
|
+
});
|
|
6354
|
+
const [settingsRulerSettings, setSettingsRulerSettings] = (0, import_react23.useState)({
|
|
6355
|
+
...rulerSettingsDefault,
|
|
6356
|
+
...persistedSettings.rulerSettings
|
|
6357
|
+
});
|
|
6358
|
+
const [xrayVisible, setXrayVisible] = (0, import_react23.useState)(xrayVisibleRef.current);
|
|
4813
6359
|
const { clearGuideDragHold, scheduleGuideDragHold } = useGuideDragHold(ownerWindow);
|
|
4814
|
-
const [guidePreview, setGuidePreview] = (0,
|
|
4815
|
-
const
|
|
6360
|
+
const [guidePreview, setGuidePreview] = (0, import_react23.useState)(null);
|
|
6361
|
+
const resetSettings = () => {
|
|
6362
|
+
setSettingsHighlightColor(highlightColor);
|
|
6363
|
+
setSettingsGuideColor(guideColor);
|
|
6364
|
+
setSettingsHoverHighlight(hoverHighlightEnabled);
|
|
6365
|
+
setSettingsPersistOnReload(persistOnReload);
|
|
6366
|
+
setSettingsColorFormats([...colorPickerFormats]);
|
|
6367
|
+
setSettingsColorClickFormat(colorPickerClickFormat);
|
|
6368
|
+
setSnapEnabled(snapEnabledDefault);
|
|
6369
|
+
setSnapGuidesEnabled(snapGuidesEnabledDefault);
|
|
6370
|
+
setSelectNewGuideEnabled(selectNewGuideEnabledDefault);
|
|
6371
|
+
setMultiMeasureEnabled(multiMeasureEnabledDefault);
|
|
6372
|
+
setSettingsGuideStyle({ ...guideStyleDefault });
|
|
6373
|
+
setSettingsRulerSettings({ ...rulerSettingsDefault });
|
|
6374
|
+
};
|
|
6375
|
+
const initialSettingsTab = colorPickerActive ? "color-picker" : rulersVisible ? "rulers" : toolMode === "guides" ? "guides" : toolMode === "select" || toolMode === "text-inspector" ? "select" : "general";
|
|
6376
|
+
const [guideOrientation, setGuideOrientation] = (0, import_react23.useState)(persistedState?.guideOrientation ?? "vertical");
|
|
4816
6377
|
enabledRef.current = enabled;
|
|
6378
|
+
xrayVisibleRef.current = xrayVisible;
|
|
4817
6379
|
toolModeRef.current = toolMode;
|
|
4818
6380
|
rulersVisibleRef.current = rulersVisible;
|
|
4819
6381
|
guideOrientationRef.current = guideOrientation;
|
|
@@ -4822,29 +6384,173 @@ function MeasurerClient({
|
|
|
4822
6384
|
heldDistancesRef.current = heldDistances;
|
|
4823
6385
|
guidesRef.current = guides;
|
|
4824
6386
|
selectedGuideIdsRef.current = selectedGuideIds;
|
|
4825
|
-
const
|
|
4826
|
-
if (!
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
6387
|
+
const saveWorkspace = (0, import_react23.useCallback)(() => {
|
|
6388
|
+
if (!settingsPersistOnReload) return;
|
|
6389
|
+
const workspace = {
|
|
6390
|
+
enabled: enabledRef.current,
|
|
6391
|
+
xrayVisible: xrayVisibleRef.current,
|
|
6392
|
+
toolMode: toolModeRef.current,
|
|
6393
|
+
rulersVisible: rulersVisibleRef.current,
|
|
6394
|
+
guideOrientation: guideOrientationRef.current,
|
|
6395
|
+
guides: guidesRef.current,
|
|
6396
|
+
selectedGuideIds: selectedGuideIdsRef.current,
|
|
6397
|
+
measurements: measurementsRef.current.map(stripMeasurement),
|
|
6398
|
+
activeMeasurement: activeMeasurementRef.current ? stripMeasurement(activeMeasurementRef.current) : null,
|
|
6399
|
+
heldDistances: heldDistancesRef.current.map(stripDistance)
|
|
6400
|
+
};
|
|
6401
|
+
activePersistence.saveWorkspace(workspace);
|
|
6402
|
+
}, [activePersistence, settingsPersistOnReload]);
|
|
6403
|
+
const persistState = (0, import_react23.useCallback)(() => {
|
|
6404
|
+
if (!settingsPersistOnReload) return;
|
|
6405
|
+
if (workspacePersistTimeoutRef.current !== null) {
|
|
6406
|
+
ownerWindow.clearTimeout(workspacePersistTimeoutRef.current);
|
|
6407
|
+
}
|
|
6408
|
+
workspacePersistTimeoutRef.current = ownerWindow.setTimeout(() => {
|
|
6409
|
+
workspacePersistTimeoutRef.current = null;
|
|
6410
|
+
saveWorkspace();
|
|
6411
|
+
}, 250);
|
|
6412
|
+
}, [ownerWindow, saveWorkspace, settingsPersistOnReload]);
|
|
6413
|
+
const persistSettings = (0, import_react23.useCallback)(() => {
|
|
6414
|
+
activePersistence.saveSettings({
|
|
6415
|
+
highlightColor: settingsHighlightColor,
|
|
6416
|
+
guideColor: settingsGuideColor,
|
|
6417
|
+
hoverHighlightEnabled: settingsHoverHighlight,
|
|
6418
|
+
colorPickerFormats: settingsColorFormats,
|
|
6419
|
+
colorPickerClickFormat: settingsColorClickFormat,
|
|
6420
|
+
snapEnabled,
|
|
6421
|
+
snapGuidesEnabled,
|
|
6422
|
+
selectNewGuideEnabled,
|
|
6423
|
+
multiMeasureEnabled,
|
|
6424
|
+
persistOnReload: settingsPersistOnReload,
|
|
6425
|
+
guideStyle: settingsGuideStyle,
|
|
6426
|
+
rulerSettings: settingsRulerSettings
|
|
6427
|
+
});
|
|
6428
|
+
}, [
|
|
6429
|
+
multiMeasureEnabled,
|
|
6430
|
+
selectNewGuideEnabled,
|
|
6431
|
+
settingsColorClickFormat,
|
|
6432
|
+
settingsColorFormats,
|
|
6433
|
+
settingsGuideColor,
|
|
6434
|
+
settingsHighlightColor,
|
|
6435
|
+
settingsHoverHighlight,
|
|
6436
|
+
settingsPersistOnReload,
|
|
6437
|
+
snapEnabled,
|
|
6438
|
+
snapGuidesEnabled,
|
|
6439
|
+
activePersistence,
|
|
6440
|
+
settingsGuideStyle,
|
|
6441
|
+
settingsRulerSettings
|
|
6442
|
+
]);
|
|
6443
|
+
(0, import_react23.useEffect)(() => {
|
|
6444
|
+
if (applyingExternalPersistenceRef.current) {
|
|
6445
|
+
applyingExternalPersistenceRef.current = false;
|
|
6446
|
+
return;
|
|
6447
|
+
}
|
|
6448
|
+
persistSettings();
|
|
6449
|
+
if (settingsPersistOnReload) persistState();
|
|
6450
|
+
}, [persistSettings, persistState, settingsPersistOnReload]);
|
|
6451
|
+
(0, import_react23.useEffect)(() => {
|
|
6452
|
+
if (!settingsPersistOnReload) return;
|
|
6453
|
+
const handleBeforeUnload = () => saveWorkspace();
|
|
6454
|
+
ownerWindow.addEventListener("beforeunload", handleBeforeUnload);
|
|
6455
|
+
return () => {
|
|
6456
|
+
ownerWindow.removeEventListener("beforeunload", handleBeforeUnload);
|
|
6457
|
+
if (workspacePersistTimeoutRef.current !== null) {
|
|
6458
|
+
ownerWindow.clearTimeout(workspacePersistTimeoutRef.current);
|
|
6459
|
+
workspacePersistTimeoutRef.current = null;
|
|
6460
|
+
saveWorkspace();
|
|
6461
|
+
}
|
|
6462
|
+
};
|
|
6463
|
+
}, [ownerWindow, saveWorkspace, settingsPersistOnReload]);
|
|
6464
|
+
const clearPersistedWorkspace = (0, import_react23.useCallback)(() => {
|
|
6465
|
+
enabledRef.current = false;
|
|
6466
|
+
toolModeRef.current = "none";
|
|
6467
|
+
rulersVisibleRef.current = false;
|
|
6468
|
+
xrayVisibleRef.current = false;
|
|
6469
|
+
guideOrientationRef.current = "vertical";
|
|
6470
|
+
measurementsRef.current = [];
|
|
6471
|
+
activeMeasurementRef.current = null;
|
|
6472
|
+
heldDistancesRef.current = [];
|
|
6473
|
+
guidesRef.current = [];
|
|
6474
|
+
selectedGuideIdsRef.current = [];
|
|
6475
|
+
setEnabled(false);
|
|
6476
|
+
setToolMode("none");
|
|
6477
|
+
setRulersVisible(false);
|
|
6478
|
+
setXrayVisible(false);
|
|
6479
|
+
setGuideOrientation("vertical");
|
|
6480
|
+
setMeasurements([]);
|
|
6481
|
+
setActiveMeasurement(null);
|
|
6482
|
+
setSelectedMeasurement(null);
|
|
6483
|
+
setSelectedMeasurements([]);
|
|
6484
|
+
setHeldDistances([]);
|
|
6485
|
+
setGuides([]);
|
|
6486
|
+
setSelectedGuideIds([]);
|
|
6487
|
+
}, [setActiveMeasurement, setEnabled, setGuideOrientation, setGuides, setHeldDistances, setMeasurements, setRulersVisible, setSelectedGuideIds, setSelectedMeasurement, setSelectedMeasurements, setToolMode]);
|
|
6488
|
+
const clearWorkspace = (0, import_react23.useCallback)(() => {
|
|
6489
|
+
clearPersistedWorkspace();
|
|
6490
|
+
activePersistence.clearWorkspace();
|
|
6491
|
+
}, [activePersistence, clearPersistedWorkspace]);
|
|
6492
|
+
const applyPersistedWorkspace = (0, import_react23.useCallback)((workspace) => {
|
|
6493
|
+
enabledRef.current = workspace.enabled;
|
|
6494
|
+
toolModeRef.current = workspace.toolMode;
|
|
6495
|
+
rulersVisibleRef.current = workspace.rulersVisible;
|
|
6496
|
+
xrayVisibleRef.current = workspace.xrayVisible;
|
|
6497
|
+
guideOrientationRef.current = workspace.guideOrientation;
|
|
6498
|
+
measurementsRef.current = workspace.measurements;
|
|
6499
|
+
activeMeasurementRef.current = workspace.activeMeasurement;
|
|
6500
|
+
heldDistancesRef.current = workspace.heldDistances;
|
|
6501
|
+
guidesRef.current = workspace.guides;
|
|
6502
|
+
selectedGuideIdsRef.current = workspace.selectedGuideIds;
|
|
6503
|
+
setEnabled(workspace.enabled);
|
|
6504
|
+
setToolMode(workspace.toolMode);
|
|
6505
|
+
setRulersVisible(workspace.rulersVisible);
|
|
6506
|
+
setXrayVisible(workspace.xrayVisible);
|
|
6507
|
+
setGuideOrientation(workspace.guideOrientation);
|
|
6508
|
+
setMeasurements(workspace.measurements);
|
|
6509
|
+
setActiveMeasurement(workspace.activeMeasurement);
|
|
6510
|
+
setGuides(workspace.guides);
|
|
6511
|
+
setSelectedGuideIds(workspace.selectedGuideIds);
|
|
6512
|
+
setHeldDistances(workspace.heldDistances);
|
|
6513
|
+
}, [setActiveMeasurement, setEnabled, setGuideOrientation, setGuides, setHeldDistances, setMeasurements, setRulersVisible, setSelectedGuideIds, setToolMode]);
|
|
6514
|
+
const applyPersistenceSnapshot = (0, import_react23.useCallback)((snapshot) => {
|
|
6515
|
+
if (!snapshot) {
|
|
6516
|
+
clearPersistedWorkspace();
|
|
6517
|
+
return;
|
|
6518
|
+
}
|
|
6519
|
+
applyingExternalPersistenceRef.current = true;
|
|
6520
|
+
const settings = sanitizeStoredSettings(ownerWindow, snapshot.settings);
|
|
6521
|
+
if (settings.highlightColor !== void 0) setSettingsHighlightColor(settings.highlightColor);
|
|
6522
|
+
if (settings.guideColor !== void 0) setSettingsGuideColor(settings.guideColor);
|
|
6523
|
+
if (settings.hoverHighlightEnabled !== void 0) setSettingsHoverHighlight(settings.hoverHighlightEnabled);
|
|
6524
|
+
if (settings.colorPickerFormats !== void 0) setSettingsColorFormats(settings.colorPickerFormats);
|
|
6525
|
+
if (settings.colorPickerClickFormat !== void 0) setSettingsColorClickFormat(settings.colorPickerClickFormat);
|
|
6526
|
+
if (settings.persistOnReload !== void 0) setSettingsPersistOnReload(settings.persistOnReload);
|
|
6527
|
+
if (settings.snapEnabled !== void 0) setSnapEnabled(settings.snapEnabled);
|
|
6528
|
+
if (settings.snapGuidesEnabled !== void 0) setSnapGuidesEnabled(settings.snapGuidesEnabled);
|
|
6529
|
+
if (settings.selectNewGuideEnabled !== void 0) setSelectNewGuideEnabled(settings.selectNewGuideEnabled);
|
|
6530
|
+
if (settings.multiMeasureEnabled !== void 0) setMultiMeasureEnabled(settings.multiMeasureEnabled);
|
|
6531
|
+
if (settings.guideStyle !== void 0) setSettingsGuideStyle({ ...guideStyleDefault, ...settings.guideStyle });
|
|
6532
|
+
if (settings.rulerSettings !== void 0) setSettingsRulerSettings({ ...rulerSettingsDefault, ...settings.rulerSettings });
|
|
6533
|
+
const workspace = snapshot.workspace;
|
|
6534
|
+
if (!workspace) {
|
|
6535
|
+
clearPersistedWorkspace();
|
|
6536
|
+
} else if (settings.persistOnReload ?? settingsPersistOnReload) {
|
|
6537
|
+
applyPersistedWorkspace(workspace);
|
|
4845
6538
|
}
|
|
4846
|
-
|
|
4847
|
-
|
|
6539
|
+
ownerWindow.setTimeout(() => {
|
|
6540
|
+
applyingExternalPersistenceRef.current = false;
|
|
6541
|
+
}, 0);
|
|
6542
|
+
}, [applyPersistedWorkspace, clearPersistedWorkspace, guideStyleDefault, ownerWindow, rulerSettingsDefault, setMultiMeasureEnabled, setSelectNewGuideEnabled, setSettingsColorClickFormat, setSettingsColorFormats, setSettingsGuideColor, setSettingsHighlightColor, setSettingsHoverHighlight, setSettingsPersistOnReload, setSnapEnabled, setSnapGuidesEnabled, settingsPersistOnReload]);
|
|
6543
|
+
const previousPersistenceRef = (0, import_react23.useRef)(activePersistence);
|
|
6544
|
+
(0, import_react23.useEffect)(() => {
|
|
6545
|
+
if (previousPersistenceRef.current === activePersistence) return;
|
|
6546
|
+
previousPersistenceRef.current = activePersistence;
|
|
6547
|
+
applyPersistenceSnapshot(storedState);
|
|
6548
|
+
}, [activePersistence, applyPersistenceSnapshot, storedState]);
|
|
6549
|
+
(0, import_react23.useEffect)(() => {
|
|
6550
|
+
const unsubscribe = activePersistence.subscribe?.(applyPersistenceSnapshot);
|
|
6551
|
+
return unsubscribe;
|
|
6552
|
+
}, [activePersistence, applyPersistenceSnapshot]);
|
|
6553
|
+
const setEnabledPersisted = (0, import_react23.useCallback)(
|
|
4848
6554
|
(value) => {
|
|
4849
6555
|
const next = typeof value === "function" ? value(enabledRef.current) : value;
|
|
4850
6556
|
if (Object.is(next, enabledRef.current)) return;
|
|
@@ -4854,7 +6560,7 @@ function MeasurerClient({
|
|
|
4854
6560
|
},
|
|
4855
6561
|
[persistState, setEnabled]
|
|
4856
6562
|
);
|
|
4857
|
-
const setRulersVisiblePersisted = (0,
|
|
6563
|
+
const setRulersVisiblePersisted = (0, import_react23.useCallback)(
|
|
4858
6564
|
(value) => {
|
|
4859
6565
|
const next = typeof value === "function" ? value(rulersVisibleRef.current) : value;
|
|
4860
6566
|
if (Object.is(next, rulersVisibleRef.current)) return;
|
|
@@ -4864,7 +6570,7 @@ function MeasurerClient({
|
|
|
4864
6570
|
},
|
|
4865
6571
|
[persistState, setRulersVisible]
|
|
4866
6572
|
);
|
|
4867
|
-
const setToolModePersisted = (0,
|
|
6573
|
+
const setToolModePersisted = (0, import_react23.useCallback)(
|
|
4868
6574
|
(value) => {
|
|
4869
6575
|
const next = typeof value === "function" ? value(toolModeRef.current) : value;
|
|
4870
6576
|
if (Object.is(next, toolModeRef.current)) return;
|
|
@@ -4879,7 +6585,7 @@ function MeasurerClient({
|
|
|
4879
6585
|
},
|
|
4880
6586
|
[persistState, setToolMode, textInspector]
|
|
4881
6587
|
);
|
|
4882
|
-
const setGuideOrientationPersisted = (0,
|
|
6588
|
+
const setGuideOrientationPersisted = (0, import_react23.useCallback)(
|
|
4883
6589
|
(value) => {
|
|
4884
6590
|
const next = typeof value === "function" ? value(guideOrientationRef.current) : value;
|
|
4885
6591
|
if (Object.is(next, guideOrientationRef.current)) return;
|
|
@@ -4889,7 +6595,7 @@ function MeasurerClient({
|
|
|
4889
6595
|
},
|
|
4890
6596
|
[persistState, setGuideOrientation]
|
|
4891
6597
|
);
|
|
4892
|
-
const setMeasurementsPersisted = (0,
|
|
6598
|
+
const setMeasurementsPersisted = (0, import_react23.useCallback)(
|
|
4893
6599
|
(value) => {
|
|
4894
6600
|
const next = typeof value === "function" ? value(measurementsRef.current) : value;
|
|
4895
6601
|
if (Object.is(next, measurementsRef.current)) return;
|
|
@@ -4899,7 +6605,7 @@ function MeasurerClient({
|
|
|
4899
6605
|
},
|
|
4900
6606
|
[persistState, setMeasurements]
|
|
4901
6607
|
);
|
|
4902
|
-
const setActiveMeasurementPersisted = (0,
|
|
6608
|
+
const setActiveMeasurementPersisted = (0, import_react23.useCallback)(
|
|
4903
6609
|
(value) => {
|
|
4904
6610
|
const next = typeof value === "function" ? value(activeMeasurementRef.current) : value;
|
|
4905
6611
|
if (Object.is(next, activeMeasurementRef.current)) return;
|
|
@@ -4909,7 +6615,7 @@ function MeasurerClient({
|
|
|
4909
6615
|
},
|
|
4910
6616
|
[persistState, setActiveMeasurement]
|
|
4911
6617
|
);
|
|
4912
|
-
const setHeldDistancesPersisted = (0,
|
|
6618
|
+
const setHeldDistancesPersisted = (0, import_react23.useCallback)(
|
|
4913
6619
|
(value) => {
|
|
4914
6620
|
const next = typeof value === "function" ? value(heldDistancesRef.current) : value;
|
|
4915
6621
|
if (Object.is(next, heldDistancesRef.current)) return;
|
|
@@ -4919,7 +6625,7 @@ function MeasurerClient({
|
|
|
4919
6625
|
},
|
|
4920
6626
|
[persistState, setHeldDistances]
|
|
4921
6627
|
);
|
|
4922
|
-
const setGuidesPersisted = (0,
|
|
6628
|
+
const setGuidesPersisted = (0, import_react23.useCallback)(
|
|
4923
6629
|
(value) => {
|
|
4924
6630
|
const next = typeof value === "function" ? value(guidesRef.current) : value;
|
|
4925
6631
|
if (Object.is(next, guidesRef.current)) return;
|
|
@@ -4929,7 +6635,7 @@ function MeasurerClient({
|
|
|
4929
6635
|
},
|
|
4930
6636
|
[persistState, setGuides]
|
|
4931
6637
|
);
|
|
4932
|
-
const setSelectedGuideIdsPersisted = (0,
|
|
6638
|
+
const setSelectedGuideIdsPersisted = (0, import_react23.useCallback)(
|
|
4933
6639
|
(value) => {
|
|
4934
6640
|
const next = typeof value === "function" ? value(selectedGuideIdsRef.current) : value;
|
|
4935
6641
|
if (Object.is(next, selectedGuideIdsRef.current)) return;
|
|
@@ -4987,15 +6693,15 @@ function MeasurerClient({
|
|
|
4987
6693
|
clearSelectionRect
|
|
4988
6694
|
}
|
|
4989
6695
|
});
|
|
4990
|
-
const undo = (0,
|
|
6696
|
+
const undo = (0, import_react23.useCallback)(() => {
|
|
4991
6697
|
if (toolMode === "text-inspector" && textInspector.undo()) return;
|
|
4992
6698
|
undoHistory();
|
|
4993
6699
|
}, [textInspector, toolMode, undoHistory]);
|
|
4994
|
-
const redo = (0,
|
|
6700
|
+
const redo = (0, import_react23.useCallback)(() => {
|
|
4995
6701
|
if (toolMode === "text-inspector" && textInspector.redo()) return;
|
|
4996
6702
|
redoHistory();
|
|
4997
6703
|
}, [redoHistory, textInspector, toolMode]);
|
|
4998
|
-
const clearAll = (0,
|
|
6704
|
+
const clearAll = (0, import_react23.useCallback)(() => {
|
|
4999
6705
|
if (toolMode === "text-inspector") {
|
|
5000
6706
|
textInspector.clear();
|
|
5001
6707
|
}
|
|
@@ -5035,7 +6741,7 @@ function MeasurerClient({
|
|
|
5035
6741
|
textInspector,
|
|
5036
6742
|
toolMode
|
|
5037
6743
|
]);
|
|
5038
|
-
const removeSelectedGuides = (0,
|
|
6744
|
+
const removeSelectedGuides = (0, import_react23.useCallback)(() => {
|
|
5039
6745
|
if (selectedGuideIds.length === 0) return false;
|
|
5040
6746
|
recordSnapshot();
|
|
5041
6747
|
setGuidesPersisted(
|
|
@@ -5049,6 +6755,29 @@ function MeasurerClient({
|
|
|
5049
6755
|
setGuidesPersisted,
|
|
5050
6756
|
setSelectedGuideIdsPersisted
|
|
5051
6757
|
]);
|
|
6758
|
+
const openColorPicker = (0, import_react23.useCallback)(async () => {
|
|
6759
|
+
const EyeDropper = ownerWindow.EyeDropper;
|
|
6760
|
+
setEnabledWithHistory(true);
|
|
6761
|
+
setToolModeWithHistory("none");
|
|
6762
|
+
setColorPickerActive(true);
|
|
6763
|
+
setColorPickerSample(null);
|
|
6764
|
+
setColorPickerUnsupported(!EyeDropper);
|
|
6765
|
+
if (!EyeDropper) return;
|
|
6766
|
+
try {
|
|
6767
|
+
const result = await new EyeDropper().open();
|
|
6768
|
+
const nextSample = parseCssColor(result.sRGBHex);
|
|
6769
|
+
if (!nextSample) return;
|
|
6770
|
+
setColorPickerSample(nextSample);
|
|
6771
|
+
const clipboardWrite = ownerWindow.navigator.clipboard?.writeText(
|
|
6772
|
+
formatColor(nextSample, settingsColorClickFormat)
|
|
6773
|
+
);
|
|
6774
|
+
void clipboardWrite?.catch(() => void 0);
|
|
6775
|
+
} catch (error) {
|
|
6776
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
6777
|
+
setColorPickerActive(false);
|
|
6778
|
+
}
|
|
6779
|
+
}
|
|
6780
|
+
}, [ownerWindow, setEnabledWithHistory, setToolModeWithHistory, settingsColorClickFormat]);
|
|
5052
6781
|
useHotkeys({
|
|
5053
6782
|
eventTarget: ownerWindow,
|
|
5054
6783
|
clearAll,
|
|
@@ -5061,7 +6790,13 @@ function MeasurerClient({
|
|
|
5061
6790
|
setAltPressed,
|
|
5062
6791
|
isOverlayActive: () => enabled && (toolMode !== "none" || toolbarActive),
|
|
5063
6792
|
setGuideOrientation: setGuideOrientationWithHistory,
|
|
5064
|
-
onInteract: () => setToolbarActive(true)
|
|
6793
|
+
onInteract: () => setToolbarActive(true),
|
|
6794
|
+
onColorPicker: openColorPicker,
|
|
6795
|
+
onToggleXray: () => setXrayVisible((previous) => !previous),
|
|
6796
|
+
onToggleSettings: () => setSettingsOpen((previous) => !previous),
|
|
6797
|
+
isSettingsOpen: () => settingsOpen,
|
|
6798
|
+
onCloseColorPicker: () => setColorPickerActive(false),
|
|
6799
|
+
isColorPickerActive: () => colorPickerActive
|
|
5065
6800
|
});
|
|
5066
6801
|
useResizeSync({
|
|
5067
6802
|
document: ownerDocument,
|
|
@@ -5073,7 +6808,7 @@ function MeasurerClient({
|
|
|
5073
6808
|
setGuides: setGuidesPersisted,
|
|
5074
6809
|
selectedElementRef
|
|
5075
6810
|
});
|
|
5076
|
-
(0,
|
|
6811
|
+
(0, import_react23.useEffect)(() => {
|
|
5077
6812
|
const handleScroll = () => {
|
|
5078
6813
|
const next = {
|
|
5079
6814
|
x: ownerWindow.scrollX,
|
|
@@ -5097,6 +6832,7 @@ function MeasurerClient({
|
|
|
5097
6832
|
document: ownerDocument,
|
|
5098
6833
|
window: ownerWindow,
|
|
5099
6834
|
enabled,
|
|
6835
|
+
selectionEnabled: toolMode === "select" && !settingsOpen,
|
|
5100
6836
|
selectedElementRef,
|
|
5101
6837
|
hoverElementRef,
|
|
5102
6838
|
setSelectedMeasurement,
|
|
@@ -5106,7 +6842,7 @@ function MeasurerClient({
|
|
|
5106
6842
|
setActiveMeasurement: setActiveMeasurementPersisted,
|
|
5107
6843
|
setHeldDistances: setHeldDistancesPersisted
|
|
5108
6844
|
});
|
|
5109
|
-
(0,
|
|
6845
|
+
(0, import_react23.useEffect)(() => {
|
|
5110
6846
|
if (!toolbarActive || toolMode !== "none") return;
|
|
5111
6847
|
const handlePointerDown2 = (event) => {
|
|
5112
6848
|
const toolbarNode = toolbarRef.current;
|
|
@@ -5118,9 +6854,10 @@ function MeasurerClient({
|
|
|
5118
6854
|
ownerWindow.removeEventListener("pointerdown", handlePointerDown2);
|
|
5119
6855
|
};
|
|
5120
6856
|
}, [ownerWindow, toolbarActive, toolMode]);
|
|
5121
|
-
(0,
|
|
6857
|
+
(0, import_react23.useEffect)(() => {
|
|
5122
6858
|
if (!enabled) return;
|
|
5123
6859
|
const handleGuidePointerDown2 = (event) => {
|
|
6860
|
+
if (settingsOpen) return;
|
|
5124
6861
|
if (toolbarRef.current?.contains(event.target)) return;
|
|
5125
6862
|
const guideTarget = event.composedPath().some(
|
|
5126
6863
|
(target) => target instanceof ownerWindow.Element && target.hasAttribute("data-mesurer-guide")
|
|
@@ -5203,16 +6940,30 @@ function MeasurerClient({
|
|
|
5203
6940
|
ownerWindow,
|
|
5204
6941
|
setGuidesPersisted,
|
|
5205
6942
|
setSelectedGuideIdsPersisted,
|
|
6943
|
+
settingsOpen,
|
|
5206
6944
|
toolMode
|
|
5207
6945
|
]);
|
|
5208
|
-
(0,
|
|
5209
|
-
if (toolMode === "text-inspector") {
|
|
6946
|
+
(0, import_react23.useEffect)(() => {
|
|
6947
|
+
if (toolMode === "text-inspector" && !settingsOpen) {
|
|
5210
6948
|
textInspector.enable();
|
|
5211
6949
|
} else {
|
|
5212
6950
|
textInspector.disable();
|
|
5213
6951
|
}
|
|
5214
|
-
}, [textInspector, toolMode]);
|
|
5215
|
-
(0,
|
|
6952
|
+
}, [settingsOpen, textInspector, toolMode]);
|
|
6953
|
+
const selectionContextRef = (0, import_react23.useRef)({ toolMode, settingsOpen });
|
|
6954
|
+
if (selectionContextRef.current.toolMode !== toolMode || selectionContextRef.current.settingsOpen !== settingsOpen) {
|
|
6955
|
+
selectionContextRef.current = { toolMode, settingsOpen };
|
|
6956
|
+
if (!(toolMode === "select" && !settingsOpen)) {
|
|
6957
|
+
setSelectedElement(null);
|
|
6958
|
+
setHoverElement(null);
|
|
6959
|
+
setHoverRect(null);
|
|
6960
|
+
setHoverPointer(null);
|
|
6961
|
+
setSelectedMeasurement(null);
|
|
6962
|
+
setSelectedMeasurements([]);
|
|
6963
|
+
clearSelectionRect();
|
|
6964
|
+
}
|
|
6965
|
+
}
|
|
6966
|
+
(0, import_react23.useEffect)(() => {
|
|
5216
6967
|
let style = ownerDocument.getElementById(XRAY_STYLE_ID);
|
|
5217
6968
|
if (!style) {
|
|
5218
6969
|
style = ownerDocument.createElement("style");
|
|
@@ -5220,7 +6971,7 @@ function MeasurerClient({
|
|
|
5220
6971
|
style.textContent = XRAY_STYLES;
|
|
5221
6972
|
ownerDocument.head.appendChild(style);
|
|
5222
6973
|
}
|
|
5223
|
-
if (
|
|
6974
|
+
if (xrayVisible) {
|
|
5224
6975
|
ownerDocument.body.classList.add("xray-mode");
|
|
5225
6976
|
} else {
|
|
5226
6977
|
ownerDocument.body.classList.remove("xray-mode");
|
|
@@ -5228,13 +6979,13 @@ function MeasurerClient({
|
|
|
5228
6979
|
return () => {
|
|
5229
6980
|
ownerDocument.body.classList.remove("xray-mode");
|
|
5230
6981
|
};
|
|
5231
|
-
}, [ownerDocument,
|
|
5232
|
-
(0,
|
|
6982
|
+
}, [ownerDocument, xrayVisible]);
|
|
6983
|
+
(0, import_react23.useEffect)(() => {
|
|
5233
6984
|
return () => {
|
|
5234
6985
|
textInspector.destroy();
|
|
5235
6986
|
};
|
|
5236
6987
|
}, [textInspector]);
|
|
5237
|
-
(0,
|
|
6988
|
+
(0, import_react23.useEffect)(() => {
|
|
5238
6989
|
const hasSelectionAnimationState = !!selectionOriginRect || !!selectedMeasurement?.originRect || selectedMeasurements.some((measurement) => !!measurement.originRect);
|
|
5239
6990
|
if (!hasSelectionAnimationState) {
|
|
5240
6991
|
if (selectionAnimationCleanupTimeoutRef.current !== null) {
|
|
@@ -5315,9 +7066,9 @@ function MeasurerClient({
|
|
|
5315
7066
|
guidesEnabled,
|
|
5316
7067
|
guidePreview,
|
|
5317
7068
|
displayedMeasurements,
|
|
5318
|
-
hoverHighlightEnabled,
|
|
5319
|
-
highlightColor,
|
|
5320
|
-
guideColor
|
|
7069
|
+
hoverHighlightEnabled: settingsHoverHighlight,
|
|
7070
|
+
highlightColor: settingsHighlightColor,
|
|
7071
|
+
guideColor: settingsGuideColor
|
|
5321
7072
|
});
|
|
5322
7073
|
const {
|
|
5323
7074
|
handlePointerDown,
|
|
@@ -5334,10 +7085,12 @@ function MeasurerClient({
|
|
|
5334
7085
|
clearGuideDragHold,
|
|
5335
7086
|
scheduleGuideDragHold,
|
|
5336
7087
|
enabled,
|
|
7088
|
+
settingsOpen,
|
|
5337
7089
|
toolMode,
|
|
5338
7090
|
guidesEnabled,
|
|
5339
7091
|
snapEnabled,
|
|
5340
7092
|
snapGuidesEnabled,
|
|
7093
|
+
selectNewGuideEnabled,
|
|
5341
7094
|
altPressed,
|
|
5342
7095
|
guideOrientation,
|
|
5343
7096
|
hoverHighlightEnabled,
|
|
@@ -5370,7 +7123,7 @@ function MeasurerClient({
|
|
|
5370
7123
|
setHoverPointer,
|
|
5371
7124
|
clearSelectionRect
|
|
5372
7125
|
});
|
|
5373
|
-
const removeHeldDistance = (0,
|
|
7126
|
+
const removeHeldDistance = (0, import_react23.useCallback)(
|
|
5374
7127
|
(id) => {
|
|
5375
7128
|
recordSnapshot();
|
|
5376
7129
|
setHeldDistancesPersisted(
|
|
@@ -5379,42 +7132,62 @@ function MeasurerClient({
|
|
|
5379
7132
|
},
|
|
5380
7133
|
[recordSnapshot, setHeldDistancesPersisted]
|
|
5381
7134
|
);
|
|
5382
|
-
const
|
|
7135
|
+
const snapGuidePosition = (0, import_react23.useCallback)(
|
|
7136
|
+
(orientation, position, draggingGuideId2 = null) => getSnapGuidePosition({
|
|
7137
|
+
orientation,
|
|
7138
|
+
point: orientation === "vertical" ? { x: position, y: 0 } : { x: 0, y: position },
|
|
7139
|
+
snapGuidesEnabled,
|
|
7140
|
+
overlayNode: overlayRef.current,
|
|
7141
|
+
guides,
|
|
7142
|
+
draggingGuideId: draggingGuideId2,
|
|
7143
|
+
document: ownerDocument
|
|
7144
|
+
}),
|
|
7145
|
+
[guides, ownerDocument, overlayRef, snapGuidesEnabled]
|
|
7146
|
+
);
|
|
7147
|
+
const startGuideFromRuler = (0, import_react23.useCallback)(
|
|
5383
7148
|
(orientation, position) => {
|
|
5384
7149
|
const id = createId();
|
|
5385
7150
|
const commit = createActionCommit();
|
|
5386
7151
|
commit();
|
|
5387
7152
|
setSelectedGuideIdsPersisted([]);
|
|
5388
|
-
setGuidesPersisted((prev) => [
|
|
7153
|
+
setGuidesPersisted((prev) => [
|
|
7154
|
+
...prev,
|
|
7155
|
+
{ id, orientation, position: snapGuidePosition(orientation, position) }
|
|
7156
|
+
]);
|
|
5389
7157
|
return id;
|
|
5390
7158
|
},
|
|
5391
7159
|
[
|
|
5392
7160
|
createActionCommit,
|
|
5393
7161
|
setGuidesPersisted,
|
|
5394
|
-
setSelectedGuideIdsPersisted
|
|
7162
|
+
setSelectedGuideIdsPersisted,
|
|
7163
|
+
snapGuidePosition
|
|
5395
7164
|
]
|
|
5396
7165
|
);
|
|
5397
|
-
const moveGuideFromRuler = (0,
|
|
7166
|
+
const moveGuideFromRuler = (0, import_react23.useCallback)(
|
|
5398
7167
|
(id, position) => {
|
|
5399
7168
|
setGuidesPersisted(
|
|
5400
|
-
(prev) => prev.map(
|
|
7169
|
+
(prev) => prev.map(
|
|
7170
|
+
(guide) => guide.id === id ? { ...guide, position: snapGuidePosition(guide.orientation, position, id) } : guide
|
|
7171
|
+
)
|
|
5401
7172
|
);
|
|
5402
7173
|
},
|
|
5403
|
-
[setGuidesPersisted]
|
|
7174
|
+
[setGuidesPersisted, snapGuidePosition]
|
|
5404
7175
|
);
|
|
5405
|
-
const finishGuideFromRuler = (0,
|
|
7176
|
+
const finishGuideFromRuler = (0, import_react23.useCallback)(
|
|
5406
7177
|
(id) => {
|
|
5407
|
-
|
|
7178
|
+
if (selectNewGuideEnabled) {
|
|
7179
|
+
setSelectedGuideIdsPersisted([id]);
|
|
7180
|
+
}
|
|
5408
7181
|
},
|
|
5409
|
-
[setSelectedGuideIdsPersisted]
|
|
7182
|
+
[selectNewGuideEnabled, setSelectedGuideIdsPersisted]
|
|
5410
7183
|
);
|
|
5411
|
-
const cancelGuideFromRuler = (0,
|
|
7184
|
+
const cancelGuideFromRuler = (0, import_react23.useCallback)(
|
|
5412
7185
|
(id) => {
|
|
5413
7186
|
setGuidesPersisted((prev) => prev.filter((guide) => guide.id !== id));
|
|
5414
7187
|
},
|
|
5415
7188
|
[setGuidesPersisted]
|
|
5416
7189
|
);
|
|
5417
|
-
const handleGuidePointerDown = (0,
|
|
7190
|
+
const handleGuidePointerDown = (0, import_react23.useCallback)(
|
|
5418
7191
|
(guide, event) => {
|
|
5419
7192
|
const commit = createActionCommit();
|
|
5420
7193
|
if (!enabled) return;
|
|
@@ -5440,7 +7213,7 @@ function MeasurerClient({
|
|
|
5440
7213
|
setSelectedGuideIdsPersisted
|
|
5441
7214
|
]
|
|
5442
7215
|
);
|
|
5443
|
-
const handleGuidePointerUp = (0,
|
|
7216
|
+
const handleGuidePointerUp = (0, import_react23.useCallback)(
|
|
5444
7217
|
(guide, event) => {
|
|
5445
7218
|
event.stopPropagation();
|
|
5446
7219
|
clearGuideDragHold();
|
|
@@ -5451,16 +7224,19 @@ function MeasurerClient({
|
|
|
5451
7224
|
},
|
|
5452
7225
|
[clearGuideDragHold, setDraggingGuideId]
|
|
5453
7226
|
);
|
|
7227
|
+
const overlayInteractive = enabled && !settingsOpen;
|
|
5454
7228
|
return (0, import_react_dom.createPortal)(
|
|
5455
|
-
/* @__PURE__ */ (0,
|
|
7229
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
5456
7230
|
"div",
|
|
5457
7231
|
{
|
|
5458
7232
|
ref: overlayRef,
|
|
5459
7233
|
className: "mesurer-root msr:pointer-events-none msr:fixed msr:inset-0 msr:z-50",
|
|
5460
7234
|
children: [
|
|
5461
|
-
enabled && rulersVisible ? /* @__PURE__ */ (0,
|
|
7235
|
+
enabled && rulersVisible && !settingsOpen ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5462
7236
|
RulersOverlay,
|
|
5463
7237
|
{
|
|
7238
|
+
ownerWindow,
|
|
7239
|
+
settings: settingsRulerSettings,
|
|
5464
7240
|
onStartGuide: startGuideFromRuler,
|
|
5465
7241
|
onMoveGuide: moveGuideFromRuler,
|
|
5466
7242
|
onFinishGuide: finishGuideFromRuler,
|
|
@@ -5469,12 +7245,13 @@ function MeasurerClient({
|
|
|
5469
7245
|
selectedGuideIds
|
|
5470
7246
|
}
|
|
5471
7247
|
) : null,
|
|
5472
|
-
/* @__PURE__ */ (0,
|
|
7248
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5473
7249
|
MeasurerOverlay,
|
|
5474
7250
|
{
|
|
5475
|
-
enabled,
|
|
7251
|
+
enabled: enabled && (!settingsOpen || guides.length > 0),
|
|
7252
|
+
interactive: overlayInteractive,
|
|
5476
7253
|
toolMode,
|
|
5477
|
-
guidePointerEvents:
|
|
7254
|
+
guidePointerEvents: overlayInteractive && (toolMode !== "none" || rulersVisible),
|
|
5478
7255
|
guidesEnabled,
|
|
5479
7256
|
altPressed,
|
|
5480
7257
|
isDragging,
|
|
@@ -5502,6 +7279,7 @@ function MeasurerClient({
|
|
|
5502
7279
|
guideColorActive,
|
|
5503
7280
|
guideColorHover,
|
|
5504
7281
|
guideColorDefault,
|
|
7282
|
+
guideStyle: settingsGuideStyle,
|
|
5505
7283
|
onPointerDown: handlePointerDown,
|
|
5506
7284
|
onPointerMove: handlePointerMove,
|
|
5507
7285
|
onPointerUp: handlePointerUp,
|
|
@@ -5512,7 +7290,20 @@ function MeasurerClient({
|
|
|
5512
7290
|
onGuidePointerCancel: handleGuidePointerUp
|
|
5513
7291
|
}
|
|
5514
7292
|
),
|
|
5515
|
-
/* @__PURE__ */ (0,
|
|
7293
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7294
|
+
ColorPicker,
|
|
7295
|
+
{
|
|
7296
|
+
active: colorPickerActive,
|
|
7297
|
+
sample: colorPickerSample,
|
|
7298
|
+
unsupported: colorPickerUnsupported,
|
|
7299
|
+
ownerWindow,
|
|
7300
|
+
toolbarRef,
|
|
7301
|
+
formats: settingsColorFormats,
|
|
7302
|
+
favoriteFormat: settingsColorClickFormat,
|
|
7303
|
+
onClose: () => setColorPickerActive(false)
|
|
7304
|
+
}
|
|
7305
|
+
),
|
|
7306
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5516
7307
|
Toolbar,
|
|
5517
7308
|
{
|
|
5518
7309
|
ref: toolbarRef,
|
|
@@ -5520,11 +7311,45 @@ function MeasurerClient({
|
|
|
5520
7311
|
toolMode,
|
|
5521
7312
|
setEnabled: setEnabledWithHistory,
|
|
5522
7313
|
setToolMode: setToolModeWithHistory,
|
|
7314
|
+
xrayVisible,
|
|
7315
|
+
setXrayVisible,
|
|
5523
7316
|
rulersVisible,
|
|
5524
7317
|
setRulersVisible: setRulersVisiblePersisted,
|
|
5525
7318
|
guideOrientation,
|
|
5526
7319
|
setGuideOrientation: setGuideOrientationWithHistory,
|
|
5527
|
-
onInteract: () => setToolbarActive(true)
|
|
7320
|
+
onInteract: () => setToolbarActive(true),
|
|
7321
|
+
colorPickerActive,
|
|
7322
|
+
setColorPickerActive,
|
|
7323
|
+
onColorPickerClick: openColorPicker,
|
|
7324
|
+
settingsOpen,
|
|
7325
|
+
setSettingsOpen,
|
|
7326
|
+
highlightColor: settingsHighlightColor,
|
|
7327
|
+
setHighlightColor: setSettingsHighlightColor,
|
|
7328
|
+
guideColor: settingsGuideColor,
|
|
7329
|
+
setGuideColor: setSettingsGuideColor,
|
|
7330
|
+
hoverHighlight: settingsHoverHighlight,
|
|
7331
|
+
setHoverHighlight: setSettingsHoverHighlight,
|
|
7332
|
+
persistOnReload: settingsPersistOnReload,
|
|
7333
|
+
setPersistOnReload: setSettingsPersistOnReload,
|
|
7334
|
+
colorPickerFormats: settingsColorFormats,
|
|
7335
|
+
setColorPickerFormats: setSettingsColorFormats,
|
|
7336
|
+
colorPickerClickFormat: settingsColorClickFormat,
|
|
7337
|
+
setColorPickerClickFormat: setSettingsColorClickFormat,
|
|
7338
|
+
snapEnabled,
|
|
7339
|
+
setSnapEnabled,
|
|
7340
|
+
snapGuidesEnabled,
|
|
7341
|
+
setSnapGuidesEnabled,
|
|
7342
|
+
selectNewGuideEnabled,
|
|
7343
|
+
setSelectNewGuideEnabled,
|
|
7344
|
+
multiMeasureEnabled,
|
|
7345
|
+
setMultiMeasureEnabled,
|
|
7346
|
+
guideStyle: settingsGuideStyle,
|
|
7347
|
+
setGuideStyle: setSettingsGuideStyle,
|
|
7348
|
+
rulerSettings: settingsRulerSettings,
|
|
7349
|
+
setRulerSettings: setSettingsRulerSettings,
|
|
7350
|
+
initialSettingsTab,
|
|
7351
|
+
onResetSettings: resetSettings,
|
|
7352
|
+
onClearWorkspace: clearWorkspace
|
|
5528
7353
|
}
|
|
5529
7354
|
)
|
|
5530
7355
|
]
|
|
@@ -5539,14 +7364,24 @@ function Measurer({
|
|
|
5539
7364
|
hoverHighlightEnabled = true,
|
|
5540
7365
|
persistOnReload = false,
|
|
5541
7366
|
portalTarget,
|
|
5542
|
-
persistKey
|
|
7367
|
+
persistKey,
|
|
7368
|
+
colorPickerFormats = ["hex", "rgb", "oklch"],
|
|
7369
|
+
colorPickerClickFormat = "hex",
|
|
7370
|
+
snapEnabled = true,
|
|
7371
|
+
snapGuidesEnabled = true,
|
|
7372
|
+
selectNewGuideEnabled = true,
|
|
7373
|
+
multiMeasureEnabled = false,
|
|
7374
|
+
guideStyle,
|
|
7375
|
+
rulerSettings,
|
|
7376
|
+
persistence,
|
|
7377
|
+
onPersistenceError
|
|
5543
7378
|
}) {
|
|
5544
7379
|
if (typeof document !== "undefined") {
|
|
5545
7380
|
ensureMeasurerStyles(MESURER_STYLES, portalTarget);
|
|
5546
7381
|
}
|
|
5547
7382
|
const hydrated = useHydrated();
|
|
5548
7383
|
if (!hydrated) return null;
|
|
5549
|
-
return /* @__PURE__ */ (0,
|
|
7384
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5550
7385
|
MeasurerClient,
|
|
5551
7386
|
{
|
|
5552
7387
|
highlightColor,
|
|
@@ -5554,13 +7389,27 @@ function Measurer({
|
|
|
5554
7389
|
hoverHighlightEnabled,
|
|
5555
7390
|
persistOnReload,
|
|
5556
7391
|
persistKey,
|
|
7392
|
+
colorPickerFormats,
|
|
7393
|
+
colorPickerClickFormat,
|
|
7394
|
+
snapEnabled,
|
|
7395
|
+
snapGuidesEnabled,
|
|
7396
|
+
selectNewGuideEnabled,
|
|
7397
|
+
multiMeasureEnabled,
|
|
7398
|
+
guideStyle: { ...DEFAULT_GUIDE_STYLE, ...guideStyle },
|
|
7399
|
+
rulerSettings: { ...DEFAULT_RULER_SETTINGS, ...rulerSettings },
|
|
7400
|
+
persistence,
|
|
7401
|
+
onPersistenceError,
|
|
5557
7402
|
portalTarget: portalTarget ?? document.body
|
|
5558
7403
|
}
|
|
5559
7404
|
);
|
|
5560
7405
|
}
|
|
5561
7406
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5562
7407
|
0 && (module.exports = {
|
|
7408
|
+
MESURER_STORAGE_VERSION,
|
|
5563
7409
|
Measurer,
|
|
5564
7410
|
TextInspector,
|
|
5565
|
-
|
|
7411
|
+
createLocalStoragePersistence,
|
|
7412
|
+
createTextInspector,
|
|
7413
|
+
normalizeStoredSettings,
|
|
7414
|
+
normalizeStoredWorkspace
|
|
5566
7415
|
});
|