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.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// measurer.tsx
|
|
2
2
|
import {
|
|
3
|
-
useCallback as
|
|
4
|
-
useEffect as
|
|
3
|
+
useCallback as useCallback8,
|
|
4
|
+
useEffect as useEffect7,
|
|
5
5
|
useMemo as useMemo2,
|
|
6
|
-
useRef as
|
|
7
|
-
useState as
|
|
6
|
+
useRef as useRef12,
|
|
7
|
+
useState as useState11,
|
|
8
8
|
useSyncExternalStore
|
|
9
9
|
} from "react";
|
|
10
10
|
import { createPortal } from "react-dom";
|
|
@@ -53,16 +53,17 @@ function ensureMeasurerStyles(cssText, target) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// styles.generated.ts
|
|
56
|
-
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';
|
|
56
|
+
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';
|
|
57
57
|
|
|
58
58
|
// components/toolbar.tsx
|
|
59
59
|
import {
|
|
60
60
|
forwardRef,
|
|
61
61
|
memo,
|
|
62
|
-
useCallback,
|
|
62
|
+
useCallback as useCallback2,
|
|
63
|
+
useEffect,
|
|
63
64
|
useLayoutEffect,
|
|
64
|
-
useRef,
|
|
65
|
-
useState
|
|
65
|
+
useRef as useRef2,
|
|
66
|
+
useState as useState3
|
|
66
67
|
} from "react";
|
|
67
68
|
|
|
68
69
|
// core/utils.ts
|
|
@@ -70,9 +71,750 @@ var formatValue = (value) => Math.round(value);
|
|
|
70
71
|
var cn = (...inputs) => inputs.filter(Boolean).join(" ");
|
|
71
72
|
var createId = () => typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`;
|
|
72
73
|
|
|
74
|
+
// components/settings-panel.tsx
|
|
75
|
+
import { useState as useState2 } from "react";
|
|
76
|
+
|
|
77
|
+
// package.json
|
|
78
|
+
var package_default = {
|
|
79
|
+
name: "mesurer",
|
|
80
|
+
version: "0.0.10",
|
|
81
|
+
description: "Measure and align elements on any website.",
|
|
82
|
+
license: "MIT",
|
|
83
|
+
author: "Julien Thibeaut",
|
|
84
|
+
type: "module",
|
|
85
|
+
main: "./dist/index.cjs",
|
|
86
|
+
module: "./dist/index.js",
|
|
87
|
+
types: "./dist/index.d.ts",
|
|
88
|
+
exports: {
|
|
89
|
+
".": {
|
|
90
|
+
types: "./dist/index.d.ts",
|
|
91
|
+
import: "./dist/index.js",
|
|
92
|
+
require: "./dist/index.cjs"
|
|
93
|
+
},
|
|
94
|
+
"./styles.css": "./dist/styles.css",
|
|
95
|
+
"./package.json": "./package.json"
|
|
96
|
+
},
|
|
97
|
+
files: [
|
|
98
|
+
"dist",
|
|
99
|
+
"dist/styles.css",
|
|
100
|
+
"CHANGELOG.md",
|
|
101
|
+
"README.md",
|
|
102
|
+
"LICENSE"
|
|
103
|
+
],
|
|
104
|
+
sideEffects: [
|
|
105
|
+
"*.css"
|
|
106
|
+
],
|
|
107
|
+
publishConfig: {
|
|
108
|
+
access: "public"
|
|
109
|
+
},
|
|
110
|
+
homepage: "https://mesurer.dev",
|
|
111
|
+
repository: {
|
|
112
|
+
type: "git",
|
|
113
|
+
url: "https://github.com/ibelick/mesurer.git"
|
|
114
|
+
},
|
|
115
|
+
bugs: {
|
|
116
|
+
url: "https://github.com/ibelick/mesurer/issues"
|
|
117
|
+
},
|
|
118
|
+
scripts: {
|
|
119
|
+
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",
|
|
120
|
+
dev: "node scripts/dev.mjs",
|
|
121
|
+
typecheck: "tsc --noEmit",
|
|
122
|
+
prepublishOnly: "npm run typecheck && npm run build"
|
|
123
|
+
},
|
|
124
|
+
peerDependencies: {
|
|
125
|
+
react: ">=18.0.0",
|
|
126
|
+
"react-dom": ">=18.0.0"
|
|
127
|
+
},
|
|
128
|
+
devDependencies: {
|
|
129
|
+
"@tailwindcss/cli": "^4.2.2",
|
|
130
|
+
"@types/react": "^19.0.0",
|
|
131
|
+
"@types/react-dom": "^19.0.0",
|
|
132
|
+
react: "^19.0.0",
|
|
133
|
+
"react-dom": "^19.0.0",
|
|
134
|
+
tailwindcss: "^4.2.2",
|
|
135
|
+
tsup: "^8.5.0",
|
|
136
|
+
typescript: "^5.9.2"
|
|
137
|
+
},
|
|
138
|
+
keywords: [
|
|
139
|
+
"measurement",
|
|
140
|
+
"alignment"
|
|
141
|
+
]
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// core/colors.ts
|
|
145
|
+
var clamp = (value, min = 0, max = 1) => Math.min(max, Math.max(min, value));
|
|
146
|
+
var round = (value, digits = 2) => {
|
|
147
|
+
const factor = 10 ** digits;
|
|
148
|
+
return Math.round(value * factor) / factor;
|
|
149
|
+
};
|
|
150
|
+
var parseChannel = (value) => {
|
|
151
|
+
const trimmed = value.trim();
|
|
152
|
+
const numeric = trimmed.endsWith("%") ? trimmed.slice(0, -1).trim() : trimmed;
|
|
153
|
+
if (!/^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(numeric)) return null;
|
|
154
|
+
const parsed = Number.parseFloat(numeric);
|
|
155
|
+
if (!Number.isFinite(parsed)) return null;
|
|
156
|
+
if (trimmed.endsWith("%")) return clamp(parsed / 100) * 255;
|
|
157
|
+
return clamp(parsed / 255) * 255;
|
|
158
|
+
};
|
|
159
|
+
var parseAlpha = (value) => {
|
|
160
|
+
if (!value) return 1;
|
|
161
|
+
const trimmed = value.trim();
|
|
162
|
+
const numeric = trimmed.endsWith("%") ? trimmed.slice(0, -1).trim() : trimmed;
|
|
163
|
+
if (!/^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(numeric)) return null;
|
|
164
|
+
const parsed = Number.parseFloat(numeric);
|
|
165
|
+
if (!Number.isFinite(parsed)) return null;
|
|
166
|
+
return clamp(trimmed.endsWith("%") ? parsed / 100 : parsed);
|
|
167
|
+
};
|
|
168
|
+
var parseCssColor = (value) => {
|
|
169
|
+
const input = value.trim().toLowerCase();
|
|
170
|
+
if (!input || input === "transparent") return null;
|
|
171
|
+
if (input.startsWith("#")) {
|
|
172
|
+
const hex = input.slice(1);
|
|
173
|
+
const expanded = hex.length === 3 || hex.length === 4 ? hex.split("").map((digit) => digit + digit).join("") : hex;
|
|
174
|
+
if (![6, 8].includes(expanded.length) || !/^[\da-f]+$/.test(expanded)) return null;
|
|
175
|
+
return {
|
|
176
|
+
red: Number.parseInt(expanded.slice(0, 2), 16),
|
|
177
|
+
green: Number.parseInt(expanded.slice(2, 4), 16),
|
|
178
|
+
blue: Number.parseInt(expanded.slice(4, 6), 16),
|
|
179
|
+
alpha: expanded.length === 8 ? Number.parseInt(expanded.slice(6, 8), 16) / 255 : 1
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
const match = input.match(/^rgba?\((.*)\)$/);
|
|
183
|
+
if (!match) return null;
|
|
184
|
+
const channels = match[1].replace(/\//g, " ").split(/[ ,]+/).filter(Boolean);
|
|
185
|
+
if (channels.length < 3 || channels.length > 4) return null;
|
|
186
|
+
const red = parseChannel(channels[0]);
|
|
187
|
+
const green = parseChannel(channels[1]);
|
|
188
|
+
const blue = parseChannel(channels[2]);
|
|
189
|
+
const alpha = parseAlpha(channels[3]);
|
|
190
|
+
if (red === null || green === null || blue === null || alpha === null) return null;
|
|
191
|
+
return { red, green, blue, alpha };
|
|
192
|
+
};
|
|
193
|
+
var toByte = (value) => Math.round(clamp(value / 255) * 255);
|
|
194
|
+
var colorToHex = (color) => {
|
|
195
|
+
const hex = [color.red, color.green, color.blue].map((channel) => toByte(channel).toString(16).padStart(2, "0")).join("");
|
|
196
|
+
if (color.alpha >= 0.999) return `#${hex}`;
|
|
197
|
+
return `#${hex}${Math.round(color.alpha * 255).toString(16).padStart(2, "0")}`;
|
|
198
|
+
};
|
|
199
|
+
var colorToRgb = (color) => {
|
|
200
|
+
const channels = `${toByte(color.red)}, ${toByte(color.green)}, ${toByte(color.blue)}`;
|
|
201
|
+
return color.alpha >= 0.999 ? `rgb(${channels})` : `rgba(${channels}, ${round(color.alpha, 3)})`;
|
|
202
|
+
};
|
|
203
|
+
var colorToHsl = (color) => {
|
|
204
|
+
const red = color.red / 255;
|
|
205
|
+
const green = color.green / 255;
|
|
206
|
+
const blue = color.blue / 255;
|
|
207
|
+
const max = Math.max(red, green, blue);
|
|
208
|
+
const min = Math.min(red, green, blue);
|
|
209
|
+
const lightness = (max + min) / 2;
|
|
210
|
+
const delta = max - min;
|
|
211
|
+
let hue = 0;
|
|
212
|
+
let saturation = 0;
|
|
213
|
+
if (delta !== 0) {
|
|
214
|
+
saturation = delta / (1 - Math.abs(2 * lightness - 1));
|
|
215
|
+
if (max === red) hue = (green - blue) / delta % 6;
|
|
216
|
+
else if (max === green) hue = (blue - red) / delta + 2;
|
|
217
|
+
else hue = (red - green) / delta + 4;
|
|
218
|
+
hue *= 60;
|
|
219
|
+
if (hue < 0) hue += 360;
|
|
220
|
+
}
|
|
221
|
+
const result = `hsl(${round(hue, 1)} ${round(saturation * 100, 1)}% ${round(lightness * 100, 1)}%`;
|
|
222
|
+
return color.alpha >= 0.999 ? `${result})` : `${result} / ${round(color.alpha, 3)})`;
|
|
223
|
+
};
|
|
224
|
+
var linearize = (value) => {
|
|
225
|
+
const normalized = value / 255;
|
|
226
|
+
return normalized <= 0.04045 ? normalized / 12.92 : ((normalized + 0.055) / 1.055) ** 2.4;
|
|
227
|
+
};
|
|
228
|
+
var colorToOklch = (color) => {
|
|
229
|
+
const red = linearize(color.red);
|
|
230
|
+
const green = linearize(color.green);
|
|
231
|
+
const blue = linearize(color.blue);
|
|
232
|
+
const l = 0.4122214708 * red + 0.5363325363 * green + 0.0514459929 * blue;
|
|
233
|
+
const m = 0.2119034982 * red + 0.6806995451 * green + 0.1073969566 * blue;
|
|
234
|
+
const s = 0.0883024619 * red + 0.2817188376 * green + 0.6299787005 * blue;
|
|
235
|
+
const lRoot = Math.cbrt(l);
|
|
236
|
+
const mRoot = Math.cbrt(m);
|
|
237
|
+
const sRoot = Math.cbrt(s);
|
|
238
|
+
const lightness = 0.2104542553 * lRoot + 0.793617785 * mRoot - 0.0040720468 * sRoot;
|
|
239
|
+
const a = 1.9779984951 * lRoot - 2.428592205 * mRoot + 0.4505937099 * sRoot;
|
|
240
|
+
const b = 0.0259040371 * lRoot + 0.7827717662 * mRoot - 0.808675766 * sRoot;
|
|
241
|
+
const chroma = Math.sqrt(a * a + b * b);
|
|
242
|
+
let hue = Math.atan2(b, a) * 180 / Math.PI;
|
|
243
|
+
if (hue < 0) hue += 360;
|
|
244
|
+
const result = `oklch(${round(lightness, 3)} ${round(chroma, 3)} ${round(hue, 1)}`;
|
|
245
|
+
return color.alpha >= 0.999 ? `${result})` : `${result} / ${round(color.alpha, 3)})`;
|
|
246
|
+
};
|
|
247
|
+
var formatColor = (color, format) => {
|
|
248
|
+
if (format === "hex") return colorToHex(color);
|
|
249
|
+
if (format === "rgb") return colorToRgb(color);
|
|
250
|
+
if (format === "hsl") return colorToHsl(color);
|
|
251
|
+
return colorToOklch(color);
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// components/tooltip.tsx
|
|
255
|
+
import { useCallback, useRef, useState } from "react";
|
|
256
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
257
|
+
var TOOLTIP_DELAY_MS = 800;
|
|
258
|
+
function Tooltip({
|
|
259
|
+
label,
|
|
260
|
+
shortcut,
|
|
261
|
+
visible,
|
|
262
|
+
instant = false,
|
|
263
|
+
side = "top",
|
|
264
|
+
className
|
|
265
|
+
}) {
|
|
266
|
+
return /* @__PURE__ */ jsxs(
|
|
267
|
+
"span",
|
|
268
|
+
{
|
|
269
|
+
role: "tooltip",
|
|
270
|
+
className: cn(
|
|
271
|
+
"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",
|
|
272
|
+
instant && "msr:transition-none",
|
|
273
|
+
side === "top" ? "msr:bottom-full msr:mb-2" : "msr:top-full msr:mt-2",
|
|
274
|
+
visible === void 0 ? null : visible ? "msr:opacity-100" : "msr:opacity-0",
|
|
275
|
+
className
|
|
276
|
+
),
|
|
277
|
+
children: [
|
|
278
|
+
label,
|
|
279
|
+
shortcut ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
280
|
+
" ",
|
|
281
|
+
/* @__PURE__ */ jsx("kbd", { className: "msr:text-white/60", children: shortcut })
|
|
282
|
+
] }) : null
|
|
283
|
+
]
|
|
284
|
+
}
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
function useTooltip() {
|
|
288
|
+
const [visibleTooltipId, setVisibleTooltipId] = useState(null);
|
|
289
|
+
const timerRef = useRef(null);
|
|
290
|
+
const instantRef = useRef(false);
|
|
291
|
+
const [tooltipInstant, setTooltipInstant] = useState(false);
|
|
292
|
+
const clearTimer = useCallback(() => {
|
|
293
|
+
if (timerRef.current === null) return;
|
|
294
|
+
window.clearTimeout(timerRef.current);
|
|
295
|
+
timerRef.current = null;
|
|
296
|
+
}, []);
|
|
297
|
+
const onTooltipEnter = useCallback((id) => {
|
|
298
|
+
clearTimer();
|
|
299
|
+
if (instantRef.current) {
|
|
300
|
+
setTooltipInstant(true);
|
|
301
|
+
setVisibleTooltipId(id);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
setTooltipInstant(false);
|
|
305
|
+
timerRef.current = window.setTimeout(() => {
|
|
306
|
+
setVisibleTooltipId(id);
|
|
307
|
+
instantRef.current = true;
|
|
308
|
+
timerRef.current = null;
|
|
309
|
+
}, TOOLTIP_DELAY_MS);
|
|
310
|
+
}, [clearTimer]);
|
|
311
|
+
const onTooltipLeave = useCallback(() => {
|
|
312
|
+
clearTimer();
|
|
313
|
+
setVisibleTooltipId(null);
|
|
314
|
+
}, [clearTimer]);
|
|
315
|
+
const onTooltipContainerLeave = useCallback(() => {
|
|
316
|
+
clearTimer();
|
|
317
|
+
setVisibleTooltipId(null);
|
|
318
|
+
instantRef.current = false;
|
|
319
|
+
setTooltipInstant(false);
|
|
320
|
+
}, [clearTimer]);
|
|
321
|
+
return {
|
|
322
|
+
visibleTooltipId,
|
|
323
|
+
tooltipInstant,
|
|
324
|
+
onTooltipEnter,
|
|
325
|
+
onTooltipLeave,
|
|
326
|
+
onTooltipContainerLeave
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// components/settings-panel.tsx
|
|
331
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
332
|
+
var COLOR_FORMATS = ["hex", "rgb", "hsl", "oklch"];
|
|
333
|
+
var GUIDE_PATTERNS = [
|
|
334
|
+
{ value: "solid", label: "Solid" },
|
|
335
|
+
{ value: "dashed", label: "Dashed" },
|
|
336
|
+
{ value: "dotted", label: "Dotted" }
|
|
337
|
+
];
|
|
338
|
+
function ControlShell({ left, right }) {
|
|
339
|
+
return /* @__PURE__ */ jsxs2(
|
|
340
|
+
"div",
|
|
341
|
+
{
|
|
342
|
+
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",
|
|
343
|
+
children: [
|
|
344
|
+
/* @__PURE__ */ jsx2("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 }),
|
|
345
|
+
/* @__PURE__ */ jsx2("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 })
|
|
346
|
+
]
|
|
347
|
+
}
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
function SettingsSwitch({ label, checked, onChange }) {
|
|
351
|
+
return /* @__PURE__ */ jsxs2(
|
|
352
|
+
"button",
|
|
353
|
+
{
|
|
354
|
+
type: "button",
|
|
355
|
+
role: "switch",
|
|
356
|
+
"aria-checked": checked,
|
|
357
|
+
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",
|
|
358
|
+
onClick: () => onChange(!checked),
|
|
359
|
+
children: [
|
|
360
|
+
/* @__PURE__ */ jsx2("span", { children: label }),
|
|
361
|
+
/* @__PURE__ */ jsx2(
|
|
362
|
+
"span",
|
|
363
|
+
{
|
|
364
|
+
"aria-hidden": "true",
|
|
365
|
+
style: { justifySelf: "end" },
|
|
366
|
+
className: cn(
|
|
367
|
+
"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",
|
|
368
|
+
checked ? "msr:border-[#0d99ff] msr:bg-[#0d99ff]" : "msr:border-ink-200 msr:bg-ink-50"
|
|
369
|
+
),
|
|
370
|
+
children: /* @__PURE__ */ jsx2(
|
|
371
|
+
"span",
|
|
372
|
+
{
|
|
373
|
+
className: "msr:block msr:size-[10px] msr:shrink-0 msr:rounded-full msr:bg-white msr:shadow-sm msr:transition-transform",
|
|
374
|
+
style: { transform: `translateX(${checked ? 12 : 0}px)` }
|
|
375
|
+
}
|
|
376
|
+
)
|
|
377
|
+
}
|
|
378
|
+
)
|
|
379
|
+
]
|
|
380
|
+
}
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
function SliderControl({
|
|
384
|
+
label,
|
|
385
|
+
min,
|
|
386
|
+
max,
|
|
387
|
+
step,
|
|
388
|
+
value,
|
|
389
|
+
onChange,
|
|
390
|
+
formatValue: formatValue4 = (currentValue) => String(currentValue),
|
|
391
|
+
parseInput = (input) => Number(input)
|
|
392
|
+
}) {
|
|
393
|
+
const thumbSize = 12;
|
|
394
|
+
const thumbInset = 8;
|
|
395
|
+
const percentage = (value - min) / (max - min) * 100;
|
|
396
|
+
const [draftValue, setDraftValue] = useState2(formatValue4(value));
|
|
397
|
+
const [editing, setEditing] = useState2(false);
|
|
398
|
+
const commitDraft = () => {
|
|
399
|
+
const parsed = parseInput(draftValue);
|
|
400
|
+
if (Number.isFinite(parsed)) {
|
|
401
|
+
onChange(Math.min(max, Math.max(min, parsed)));
|
|
402
|
+
}
|
|
403
|
+
const next = Number.isFinite(parsed) ? Math.min(max, Math.max(min, parsed)) : value;
|
|
404
|
+
setDraftValue(formatValue4(next));
|
|
405
|
+
setEditing(false);
|
|
406
|
+
};
|
|
407
|
+
const updateFromPointer = (event) => {
|
|
408
|
+
event.stopPropagation();
|
|
409
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
410
|
+
const usableWidth = Math.max(1, rect.width - thumbInset * 2);
|
|
411
|
+
const ratio = Math.min(1, Math.max(0, (event.clientX - rect.left - thumbInset) / usableWidth));
|
|
412
|
+
const rawValue = min + ratio * (max - min);
|
|
413
|
+
const steppedValue = Math.round((rawValue - min) / step) * step + min;
|
|
414
|
+
onChange(Number(steppedValue.toFixed(4)));
|
|
415
|
+
};
|
|
416
|
+
return /* @__PURE__ */ jsxs2("div", { className: "msr:col-span-2 msr:grid msr:w-full msr:grid-cols-[78px_156px] msr:items-center msr:gap-3", children: [
|
|
417
|
+
/* @__PURE__ */ jsx2("span", { className: "msr:text-[11px] msr:font-medium msr:text-ink-700", children: label }),
|
|
418
|
+
/* @__PURE__ */ jsx2(
|
|
419
|
+
ControlShell,
|
|
420
|
+
{
|
|
421
|
+
left: /* @__PURE__ */ jsxs2(
|
|
422
|
+
"div",
|
|
423
|
+
{
|
|
424
|
+
className: "msr:relative msr:min-w-0 msr:flex-1 msr:touch-none msr:select-none msr:px-2",
|
|
425
|
+
style: { height: 20 },
|
|
426
|
+
"data-slider-container": "true",
|
|
427
|
+
onPointerDown: (event) => {
|
|
428
|
+
event.stopPropagation();
|
|
429
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
430
|
+
updateFromPointer(event);
|
|
431
|
+
},
|
|
432
|
+
onPointerMove: (event) => {
|
|
433
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) updateFromPointer(event);
|
|
434
|
+
},
|
|
435
|
+
onPointerUp: (event) => {
|
|
436
|
+
event.stopPropagation();
|
|
437
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
438
|
+
},
|
|
439
|
+
onPointerCancel: (event) => {
|
|
440
|
+
event.stopPropagation();
|
|
441
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
442
|
+
},
|
|
443
|
+
onClick: (event) => event.stopPropagation(),
|
|
444
|
+
children: [
|
|
445
|
+
/* @__PURE__ */ jsx2(
|
|
446
|
+
"div",
|
|
447
|
+
{
|
|
448
|
+
className: "msr:absolute msr:left-[8px] msr:right-[8px] msr:rounded-full",
|
|
449
|
+
style: { top: 8, height: 4, backgroundColor: "rgba(15, 23, 42, 0.16)" },
|
|
450
|
+
"aria-hidden": "true"
|
|
451
|
+
}
|
|
452
|
+
),
|
|
453
|
+
/* @__PURE__ */ jsx2(
|
|
454
|
+
"div",
|
|
455
|
+
{
|
|
456
|
+
className: "msr:absolute msr:left-[8px] msr:rounded-full",
|
|
457
|
+
style: { top: 8, width: `calc(${percentage}% - ${percentage * thumbInset * 2 / 100}px)`, height: 4, backgroundColor: "#0d99ff" },
|
|
458
|
+
"aria-hidden": "true"
|
|
459
|
+
}
|
|
460
|
+
),
|
|
461
|
+
/* @__PURE__ */ jsx2(
|
|
462
|
+
"div",
|
|
463
|
+
{
|
|
464
|
+
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",
|
|
465
|
+
style: {
|
|
466
|
+
left: `calc(8px + (100% - 16px) * ${percentage / 100})`,
|
|
467
|
+
top: 4,
|
|
468
|
+
width: thumbSize,
|
|
469
|
+
height: thumbSize,
|
|
470
|
+
border: "0",
|
|
471
|
+
transform: "translateX(-50%)"
|
|
472
|
+
},
|
|
473
|
+
role: "slider",
|
|
474
|
+
tabIndex: 0,
|
|
475
|
+
"aria-label": label,
|
|
476
|
+
"aria-valuemin": min,
|
|
477
|
+
"aria-valuemax": max,
|
|
478
|
+
"aria-valuenow": value,
|
|
479
|
+
"aria-orientation": "horizontal",
|
|
480
|
+
onKeyDown: (event) => {
|
|
481
|
+
event.stopPropagation();
|
|
482
|
+
const direction = event.key === "ArrowRight" || event.key === "ArrowUp" ? 1 : event.key === "ArrowLeft" || event.key === "ArrowDown" ? -1 : 0;
|
|
483
|
+
if (event.key === "Home") onChange(min);
|
|
484
|
+
else if (event.key === "End") onChange(max);
|
|
485
|
+
else if (direction) {
|
|
486
|
+
event.preventDefault();
|
|
487
|
+
onChange(Number(Math.min(max, Math.max(min, value + direction * step)).toFixed(4)));
|
|
488
|
+
} else return;
|
|
489
|
+
event.preventDefault();
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
)
|
|
493
|
+
]
|
|
494
|
+
}
|
|
495
|
+
),
|
|
496
|
+
right: /* @__PURE__ */ jsx2(
|
|
497
|
+
"input",
|
|
498
|
+
{
|
|
499
|
+
type: "text",
|
|
500
|
+
"aria-label": `${label} value`,
|
|
501
|
+
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",
|
|
502
|
+
style: { boxSizing: "border-box", borderRadius: "0 5px 5px 0", lineHeight: "1rem" },
|
|
503
|
+
value: editing ? draftValue : formatValue4(value),
|
|
504
|
+
onFocus: () => {
|
|
505
|
+
setDraftValue(formatValue4(value));
|
|
506
|
+
setEditing(true);
|
|
507
|
+
},
|
|
508
|
+
onChange: (event) => {
|
|
509
|
+
const nextDraft = event.target.value;
|
|
510
|
+
setDraftValue(nextDraft);
|
|
511
|
+
const next = parseInput(nextDraft);
|
|
512
|
+
if (Number.isFinite(next)) onChange(Math.min(max, Math.max(min, next)));
|
|
513
|
+
},
|
|
514
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
515
|
+
onClick: (event) => event.stopPropagation(),
|
|
516
|
+
onBlur: () => {
|
|
517
|
+
commitDraft();
|
|
518
|
+
},
|
|
519
|
+
onKeyDown: (event) => {
|
|
520
|
+
event.stopPropagation();
|
|
521
|
+
if (event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
522
|
+
event.preventDefault();
|
|
523
|
+
const current = parseInput(event.currentTarget.value);
|
|
524
|
+
const direction = event.key === "ArrowUp" ? 1 : -1;
|
|
525
|
+
const next = Number(
|
|
526
|
+
Math.min(max, Math.max(min, (Number.isFinite(current) ? current : value) + direction * step)).toFixed(4)
|
|
527
|
+
);
|
|
528
|
+
setDraftValue(formatValue4(next));
|
|
529
|
+
onChange(next);
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
if (event.key === "Enter") {
|
|
533
|
+
event.preventDefault();
|
|
534
|
+
event.currentTarget.blur();
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
)
|
|
539
|
+
}
|
|
540
|
+
)
|
|
541
|
+
] });
|
|
542
|
+
}
|
|
543
|
+
function ColorField({ label, value, fallback, ownerWindow, onChange }) {
|
|
544
|
+
const parsed = parseCssColor(value);
|
|
545
|
+
const canvas = ownerWindow.document.createElement("canvas");
|
|
546
|
+
const context = canvas.getContext("2d");
|
|
547
|
+
if (context) context.fillStyle = value;
|
|
548
|
+
const serialized = typeof context?.fillStyle === "string" ? context.fillStyle : "";
|
|
549
|
+
const converted = serialized ? parseCssColor(serialized) : null;
|
|
550
|
+
const inputValue = parsed ?? converted ? colorToHex(parsed ?? converted).slice(0, 7) : fallback;
|
|
551
|
+
const sample = parsed ?? converted ?? parseCssColor(fallback);
|
|
552
|
+
const hexValue = sample ? colorToHex({ ...sample, alpha: 1 }).slice(1).toUpperCase() : "000000";
|
|
553
|
+
const alphaValue = sample ? Math.round(sample.alpha * 100) : 100;
|
|
554
|
+
const [hexDraft, setHexDraft] = useState2(hexValue);
|
|
555
|
+
const [alphaDraft, setAlphaDraft] = useState2(String(alphaValue));
|
|
556
|
+
const [hexFocused, setHexFocused] = useState2(false);
|
|
557
|
+
const [alphaFocused, setAlphaFocused] = useState2(false);
|
|
558
|
+
const updateColor = (nextHex, nextAlpha) => {
|
|
559
|
+
if (!/^[\da-f]{6}$/i.test(nextHex)) return;
|
|
560
|
+
const nextSample = parseCssColor(`#${nextHex}`);
|
|
561
|
+
if (!nextSample) return;
|
|
562
|
+
onChange(colorToHex({ ...nextSample, alpha: Math.min(100, Math.max(0, nextAlpha)) / 100 }));
|
|
563
|
+
};
|
|
564
|
+
const swatchColor = ownerWindow.CSS?.supports("color", value) ? value : fallback;
|
|
565
|
+
return /* @__PURE__ */ jsxs2("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: [
|
|
566
|
+
/* @__PURE__ */ jsx2("span", { children: label }),
|
|
567
|
+
/* @__PURE__ */ jsx2(
|
|
568
|
+
ControlShell,
|
|
569
|
+
{
|
|
570
|
+
left: /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
571
|
+
/* @__PURE__ */ jsx2(
|
|
572
|
+
"span",
|
|
573
|
+
{
|
|
574
|
+
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",
|
|
575
|
+
style: { backgroundColor: swatchColor },
|
|
576
|
+
children: /* @__PURE__ */ jsx2(
|
|
577
|
+
"input",
|
|
578
|
+
{
|
|
579
|
+
type: "color",
|
|
580
|
+
"aria-label": `${label} color picker`,
|
|
581
|
+
value: inputValue,
|
|
582
|
+
className: "msr:absolute msr:inset-0 msr:size-full msr:cursor-pointer msr:opacity-0",
|
|
583
|
+
onChange: (event) => onChange(event.target.value)
|
|
584
|
+
}
|
|
585
|
+
)
|
|
586
|
+
}
|
|
587
|
+
),
|
|
588
|
+
/* @__PURE__ */ jsx2(
|
|
589
|
+
"input",
|
|
590
|
+
{
|
|
591
|
+
"aria-label": `${label} hex value`,
|
|
592
|
+
type: "text",
|
|
593
|
+
value: hexFocused ? hexDraft : hexValue,
|
|
594
|
+
maxLength: 6,
|
|
595
|
+
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",
|
|
596
|
+
onFocus: () => {
|
|
597
|
+
setHexDraft(hexValue);
|
|
598
|
+
setHexFocused(true);
|
|
599
|
+
},
|
|
600
|
+
onBlur: () => setHexFocused(false),
|
|
601
|
+
onChange: (event) => {
|
|
602
|
+
const next = event.target.value.replace(/[^\da-f]/gi, "").slice(0, 6).toUpperCase();
|
|
603
|
+
setHexDraft(next);
|
|
604
|
+
updateColor(next, alphaFocused ? Number(alphaDraft) : alphaValue);
|
|
605
|
+
},
|
|
606
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
607
|
+
onClick: (event) => event.stopPropagation()
|
|
608
|
+
}
|
|
609
|
+
)
|
|
610
|
+
] }),
|
|
611
|
+
right: /* @__PURE__ */ jsx2(
|
|
612
|
+
"input",
|
|
613
|
+
{
|
|
614
|
+
"aria-label": `${label} opacity value`,
|
|
615
|
+
type: "text",
|
|
616
|
+
inputMode: "numeric",
|
|
617
|
+
value: alphaFocused ? alphaDraft ? `${alphaDraft}%` : "" : `${alphaValue}%`,
|
|
618
|
+
maxLength: 4,
|
|
619
|
+
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",
|
|
620
|
+
onFocus: () => {
|
|
621
|
+
setAlphaDraft(String(alphaValue));
|
|
622
|
+
setAlphaFocused(true);
|
|
623
|
+
},
|
|
624
|
+
onBlur: () => setAlphaFocused(false),
|
|
625
|
+
onChange: (event) => {
|
|
626
|
+
const next = event.target.value.replace(/\D/g, "").slice(0, 3);
|
|
627
|
+
setAlphaDraft(next);
|
|
628
|
+
updateColor(hexFocused ? hexDraft : hexValue, Number(next));
|
|
629
|
+
},
|
|
630
|
+
onKeyDown: (event) => {
|
|
631
|
+
if (event.key !== "ArrowUp" && event.key !== "ArrowDown") return;
|
|
632
|
+
event.preventDefault();
|
|
633
|
+
event.stopPropagation();
|
|
634
|
+
const current = Number.parseInt(alphaFocused ? alphaDraft : String(alphaValue), 10);
|
|
635
|
+
const direction = event.key === "ArrowUp" ? 1 : -1;
|
|
636
|
+
const next = Math.min(100, Math.max(0, (Number.isFinite(current) ? current : 0) + direction));
|
|
637
|
+
setAlphaDraft(String(next));
|
|
638
|
+
updateColor(hexFocused ? hexDraft : hexValue, next);
|
|
639
|
+
},
|
|
640
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
641
|
+
onClick: (event) => event.stopPropagation()
|
|
642
|
+
}
|
|
643
|
+
)
|
|
644
|
+
}
|
|
645
|
+
)
|
|
646
|
+
] });
|
|
647
|
+
}
|
|
648
|
+
function SettingsPanel({
|
|
649
|
+
ownerWindow,
|
|
650
|
+
highlightColor,
|
|
651
|
+
setHighlightColor,
|
|
652
|
+
guideColor,
|
|
653
|
+
setGuideColor,
|
|
654
|
+
hoverHighlight,
|
|
655
|
+
setHoverHighlight,
|
|
656
|
+
persistOnReload,
|
|
657
|
+
setPersistOnReload,
|
|
658
|
+
colorFormats,
|
|
659
|
+
setColorFormats,
|
|
660
|
+
colorClickFormat,
|
|
661
|
+
setColorClickFormat,
|
|
662
|
+
snapEnabled,
|
|
663
|
+
setSnapEnabled,
|
|
664
|
+
snapGuidesEnabled,
|
|
665
|
+
setSnapGuidesEnabled,
|
|
666
|
+
selectNewGuideEnabled,
|
|
667
|
+
setSelectNewGuideEnabled,
|
|
668
|
+
multiMeasureEnabled,
|
|
669
|
+
setMultiMeasureEnabled,
|
|
670
|
+
guideStyle,
|
|
671
|
+
setGuideStyle,
|
|
672
|
+
rulerSettings,
|
|
673
|
+
setRulerSettings,
|
|
674
|
+
initialTab,
|
|
675
|
+
onResetSettings,
|
|
676
|
+
onClearWorkspace
|
|
677
|
+
}) {
|
|
678
|
+
const toggleFormat = (format) => {
|
|
679
|
+
setColorFormats((previous) => {
|
|
680
|
+
if (previous.includes(format)) {
|
|
681
|
+
if (previous.length === 1) return previous;
|
|
682
|
+
return previous.filter((item) => item !== format);
|
|
683
|
+
}
|
|
684
|
+
return [...previous, format];
|
|
685
|
+
});
|
|
686
|
+
};
|
|
687
|
+
const [activeTab, setActiveTab] = useState2(initialTab);
|
|
688
|
+
const patternTooltip = useTooltip();
|
|
689
|
+
return /* @__PURE__ */ jsxs2("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: [
|
|
690
|
+
/* @__PURE__ */ jsx2("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: [
|
|
691
|
+
["guides", "Guides"],
|
|
692
|
+
["select", "Select"],
|
|
693
|
+
["color-picker", "Color"],
|
|
694
|
+
["rulers", "Rulers"],
|
|
695
|
+
["general", "General"]
|
|
696
|
+
].map(([value, label]) => /* @__PURE__ */ jsx2(
|
|
697
|
+
"button",
|
|
698
|
+
{
|
|
699
|
+
type: "button",
|
|
700
|
+
role: "tab",
|
|
701
|
+
"aria-selected": activeTab === value,
|
|
702
|
+
className: cn(
|
|
703
|
+
"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]",
|
|
704
|
+
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"
|
|
705
|
+
),
|
|
706
|
+
onClick: () => setActiveTab(value),
|
|
707
|
+
children: label
|
|
708
|
+
},
|
|
709
|
+
value
|
|
710
|
+
)) }),
|
|
711
|
+
activeTab === "guides" ? /* @__PURE__ */ jsxs2("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: [
|
|
712
|
+
/* @__PURE__ */ jsx2(ColorField, { label: "Color", value: guideColor, fallback: "#f97316", ownerWindow, onChange: setGuideColor }),
|
|
713
|
+
/* @__PURE__ */ jsx2(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 })) }),
|
|
714
|
+
/* @__PURE__ */ jsxs2("div", { className: "msr:col-span-2 msr:grid msr:grid-cols-[78px_156px] msr:items-center msr:gap-3", children: [
|
|
715
|
+
/* @__PURE__ */ jsx2("span", { className: "msr:text-[12px] msr:text-ink-700", children: "Pattern" }),
|
|
716
|
+
/* @__PURE__ */ jsx2("div", { className: "msr:flex msr:gap-1", role: "radiogroup", "aria-label": "Guide pattern", onMouseLeave: patternTooltip.onTooltipContainerLeave, children: GUIDE_PATTERNS.map(({ value, label }) => {
|
|
717
|
+
const selected = guideStyle.pattern === value;
|
|
718
|
+
const tooltipId = `guide-pattern-${value}`;
|
|
719
|
+
return /* @__PURE__ */ jsxs2(
|
|
720
|
+
"button",
|
|
721
|
+
{
|
|
722
|
+
type: "button",
|
|
723
|
+
role: "radio",
|
|
724
|
+
"aria-label": `${label} guide pattern`,
|
|
725
|
+
"aria-checked": selected,
|
|
726
|
+
className: cn(
|
|
727
|
+
"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]",
|
|
728
|
+
selected ? "msr:border-[#0d99ff] msr:bg-[#0d99ff]/10" : "msr:border-ink-200 msr:bg-ink-50 msr:hover:bg-ink-100"
|
|
729
|
+
),
|
|
730
|
+
onClick: () => setGuideStyle((style) => ({ ...style, pattern: value })),
|
|
731
|
+
onMouseEnter: () => patternTooltip.onTooltipEnter(tooltipId),
|
|
732
|
+
onFocus: () => patternTooltip.onTooltipEnter(tooltipId),
|
|
733
|
+
onBlur: patternTooltip.onTooltipLeave,
|
|
734
|
+
children: [
|
|
735
|
+
/* @__PURE__ */ jsx2("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") }),
|
|
736
|
+
/* @__PURE__ */ jsx2(Tooltip, { label, visible: patternTooltip.visibleTooltipId === tooltipId, instant: patternTooltip.tooltipInstant, className: "msr:z-10" })
|
|
737
|
+
]
|
|
738
|
+
},
|
|
739
|
+
value
|
|
740
|
+
);
|
|
741
|
+
}) })
|
|
742
|
+
] }),
|
|
743
|
+
guideStyle.pattern !== "solid" ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
744
|
+
/* @__PURE__ */ jsx2(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 })) }),
|
|
745
|
+
/* @__PURE__ */ jsx2(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 })) })
|
|
746
|
+
] }) : null,
|
|
747
|
+
/* @__PURE__ */ jsx2("div", { className: "msr:col-span-2", children: /* @__PURE__ */ jsx2(SettingsSwitch, { label: "Snap", checked: snapGuidesEnabled, onChange: setSnapGuidesEnabled }) }),
|
|
748
|
+
/* @__PURE__ */ jsx2("div", { className: "msr:col-span-2", children: /* @__PURE__ */ jsx2(SettingsSwitch, { label: "Highlight", checked: selectNewGuideEnabled, onChange: setSelectNewGuideEnabled }) })
|
|
749
|
+
] }) : null,
|
|
750
|
+
activeTab === "select" ? /* @__PURE__ */ jsxs2("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: [
|
|
751
|
+
/* @__PURE__ */ jsx2(ColorField, { label: "Color", value: highlightColor, fallback: "#0d99ff", ownerWindow, onChange: setHighlightColor }),
|
|
752
|
+
/* @__PURE__ */ jsx2("div", { className: "msr:col-span-2", children: /* @__PURE__ */ jsx2(SettingsSwitch, { label: "Hover", checked: hoverHighlight, onChange: setHoverHighlight }) }),
|
|
753
|
+
/* @__PURE__ */ jsx2("div", { className: "msr:col-span-2", children: /* @__PURE__ */ jsx2(SettingsSwitch, { label: "Element snap", checked: snapEnabled, onChange: setSnapEnabled }) }),
|
|
754
|
+
/* @__PURE__ */ jsx2("div", { className: "msr:col-span-2", children: /* @__PURE__ */ jsx2(SettingsSwitch, { label: "Stack", checked: multiMeasureEnabled, onChange: setMultiMeasureEnabled }) })
|
|
755
|
+
] }) : null,
|
|
756
|
+
activeTab === "color-picker" ? /* @__PURE__ */ jsxs2("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: [
|
|
757
|
+
/* @__PURE__ */ jsxs2("div", { className: "msr:col-span-2 msr:grid msr:grid-cols-[78px_156px] msr:items-center msr:gap-3", children: [
|
|
758
|
+
/* @__PURE__ */ jsx2("span", { className: "msr:text-[12px] msr:text-ink-700", children: "Format" }),
|
|
759
|
+
/* @__PURE__ */ jsx2("div", { className: "msr:flex msr:min-w-0 msr:gap-1", children: COLOR_FORMATS.map((format) => /* @__PURE__ */ jsx2(
|
|
760
|
+
"button",
|
|
761
|
+
{
|
|
762
|
+
type: "button",
|
|
763
|
+
"aria-pressed": colorFormats.includes(format),
|
|
764
|
+
className: cn(
|
|
765
|
+
"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]",
|
|
766
|
+
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"
|
|
767
|
+
),
|
|
768
|
+
onClick: () => toggleFormat(format),
|
|
769
|
+
children: format
|
|
770
|
+
},
|
|
771
|
+
format
|
|
772
|
+
)) })
|
|
773
|
+
] }),
|
|
774
|
+
/* @__PURE__ */ jsxs2("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: [
|
|
775
|
+
"Copy",
|
|
776
|
+
/* @__PURE__ */ jsx2("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__ */ jsx2("option", { value: format, children: format }, format)) })
|
|
777
|
+
] })
|
|
778
|
+
] }) : null,
|
|
779
|
+
activeTab === "rulers" ? /* @__PURE__ */ jsxs2("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: [
|
|
780
|
+
/* @__PURE__ */ jsx2(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 })) }),
|
|
781
|
+
/* @__PURE__ */ jsx2("div", { className: "msr:col-span-2", children: /* @__PURE__ */ jsx2(SettingsSwitch, { label: "Edge reveal", checked: rulerSettings.edgeReveal, onChange: (edgeReveal) => setRulerSettings((settings) => ({ ...settings, edgeReveal })) }) })
|
|
782
|
+
] }) : null,
|
|
783
|
+
activeTab === "general" ? /* @__PURE__ */ jsxs2("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: [
|
|
784
|
+
/* @__PURE__ */ jsx2("div", { className: "msr:col-span-2", children: /* @__PURE__ */ jsx2(SettingsSwitch, { label: "Persist", checked: persistOnReload, onChange: setPersistOnReload }) }),
|
|
785
|
+
/* @__PURE__ */ jsxs2("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: [
|
|
786
|
+
/* @__PURE__ */ jsx2("span", { children: "Version" }),
|
|
787
|
+
/* @__PURE__ */ jsx2("span", { className: "msr:justify-self-end msr:font-mono msr:text-[11px] msr:tabular-nums msr:text-ink-700", children: package_default.version })
|
|
788
|
+
] }),
|
|
789
|
+
/* @__PURE__ */ jsxs2("div", { className: "msr:col-span-2 msr:flex msr:justify-end msr:gap-1", children: [
|
|
790
|
+
/* @__PURE__ */ jsx2(
|
|
791
|
+
"button",
|
|
792
|
+
{
|
|
793
|
+
type: "button",
|
|
794
|
+
"aria-label": "Reset settings to defaults",
|
|
795
|
+
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]",
|
|
796
|
+
onClick: onResetSettings,
|
|
797
|
+
children: "Use defaults"
|
|
798
|
+
}
|
|
799
|
+
),
|
|
800
|
+
/* @__PURE__ */ jsx2(
|
|
801
|
+
"button",
|
|
802
|
+
{
|
|
803
|
+
type: "button",
|
|
804
|
+
"aria-label": "Clear workspace",
|
|
805
|
+
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]",
|
|
806
|
+
onClick: onClearWorkspace,
|
|
807
|
+
children: "Clear workspace"
|
|
808
|
+
}
|
|
809
|
+
)
|
|
810
|
+
] })
|
|
811
|
+
] }) : null
|
|
812
|
+
] });
|
|
813
|
+
}
|
|
814
|
+
|
|
73
815
|
// components/icons.tsx
|
|
74
|
-
import { jsx } from "react/jsx-runtime";
|
|
75
|
-
var IconBase = ({ size = 24, ...props }) => /* @__PURE__ */
|
|
816
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
817
|
+
var IconBase = ({ size = 24, ...props }) => /* @__PURE__ */ jsx3(
|
|
76
818
|
"svg",
|
|
77
819
|
{
|
|
78
820
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -80,12 +822,14 @@ var IconBase = ({ size = 24, ...props }) => /* @__PURE__ */ jsx(
|
|
|
80
822
|
height: size,
|
|
81
823
|
viewBox: "0 0 256 256",
|
|
82
824
|
fill: "currentColor",
|
|
825
|
+
"aria-hidden": "true",
|
|
826
|
+
onDragStart: (event) => event.preventDefault(),
|
|
83
827
|
...props
|
|
84
828
|
}
|
|
85
829
|
);
|
|
86
|
-
var CursorIcon = ({ size = 20, ...props }) => /* @__PURE__ */
|
|
87
|
-
var RulerIcon = ({ size = 20, ...props }) => /* @__PURE__ */
|
|
88
|
-
var XrayIcon = ({ size = 20, ...props }) => /* @__PURE__ */
|
|
830
|
+
var CursorIcon = ({ size = 20, ...props }) => /* @__PURE__ */ jsx3(IconBase, { size, ...props, children: /* @__PURE__ */ jsx3("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" }) });
|
|
831
|
+
var RulerIcon = ({ size = 20, ...props }) => /* @__PURE__ */ jsx3(IconBase, { size, ...props, children: /* @__PURE__ */ jsx3("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" }) });
|
|
832
|
+
var XrayIcon = ({ size = 20, ...props }) => /* @__PURE__ */ jsx3(IconBase, { size, ...props, children: /* @__PURE__ */ jsx3(
|
|
89
833
|
"path",
|
|
90
834
|
{
|
|
91
835
|
fill: "none",
|
|
@@ -97,7 +841,7 @@ var XrayIcon = ({ size = 20, ...props }) => /* @__PURE__ */ jsx(IconBase, { size
|
|
|
97
841
|
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"
|
|
98
842
|
}
|
|
99
843
|
) });
|
|
100
|
-
var RulersIcon = ({ size = 20, ...props }) => /* @__PURE__ */
|
|
844
|
+
var RulersIcon = ({ size = 20, ...props }) => /* @__PURE__ */ jsx3(IconBase, { size, ...props, children: /* @__PURE__ */ jsx3(
|
|
101
845
|
"path",
|
|
102
846
|
{
|
|
103
847
|
fill: "none",
|
|
@@ -108,10 +852,10 @@ var RulersIcon = ({ size = 20, ...props }) => /* @__PURE__ */ jsx(IconBase, { si
|
|
|
108
852
|
d: "M48 208V48h160M80 48v24m32-24v24m32-24v24m32-24v24M48 80h24M48 112h24m-24 32h24m-24 32h24"
|
|
109
853
|
}
|
|
110
854
|
) });
|
|
111
|
-
var CaretDownIcon = ({ size = 8, ...props }) => /* @__PURE__ */
|
|
112
|
-
var CheckIcon = ({ size = 12, ...props }) => /* @__PURE__ */
|
|
113
|
-
var MinusIcon = ({ size = 12, ...props }) => /* @__PURE__ */
|
|
114
|
-
var TextInspectorIcon = ({ size = 20, ...props }) => /* @__PURE__ */
|
|
855
|
+
var CaretDownIcon = ({ size = 8, ...props }) => /* @__PURE__ */ jsx3(IconBase, { size, ...props, children: /* @__PURE__ */ jsx3("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" }) });
|
|
856
|
+
var CheckIcon = ({ size = 12, ...props }) => /* @__PURE__ */ jsx3(IconBase, { size, ...props, children: /* @__PURE__ */ jsx3("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" }) });
|
|
857
|
+
var MinusIcon = ({ size = 12, ...props }) => /* @__PURE__ */ jsx3(IconBase, { size, ...props, children: /* @__PURE__ */ jsx3("path", { d: "M228,128a12,12,0,0,1-12,12H40a12,12,0,0,1,0-24H216A12,12,0,0,1,228,128Z" }) });
|
|
858
|
+
var TextInspectorIcon = ({ size = 20, ...props }) => /* @__PURE__ */ jsx3(
|
|
115
859
|
"svg",
|
|
116
860
|
{
|
|
117
861
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -119,8 +863,10 @@ var TextInspectorIcon = ({ size = 20, ...props }) => /* @__PURE__ */ jsx(
|
|
|
119
863
|
height: size,
|
|
120
864
|
viewBox: "0 0 256 256",
|
|
121
865
|
fill: "currentColor",
|
|
866
|
+
"aria-hidden": "true",
|
|
867
|
+
onDragStart: (event) => event.preventDefault(),
|
|
122
868
|
...props,
|
|
123
|
-
children: /* @__PURE__ */
|
|
869
|
+
children: /* @__PURE__ */ jsx3(
|
|
124
870
|
"text",
|
|
125
871
|
{
|
|
126
872
|
x: "50%",
|
|
@@ -136,9 +882,54 @@ var TextInspectorIcon = ({ size = 20, ...props }) => /* @__PURE__ */ jsx(
|
|
|
136
882
|
)
|
|
137
883
|
}
|
|
138
884
|
);
|
|
885
|
+
var ColorPickerIcon = ({ size = 20, ...props }) => /* @__PURE__ */ jsx3(
|
|
886
|
+
"svg",
|
|
887
|
+
{
|
|
888
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
889
|
+
width: size,
|
|
890
|
+
height: size,
|
|
891
|
+
viewBox: "0 0 24 24",
|
|
892
|
+
fill: "none",
|
|
893
|
+
...props,
|
|
894
|
+
children: /* @__PURE__ */ jsx3(
|
|
895
|
+
"path",
|
|
896
|
+
{
|
|
897
|
+
fill: "currentColor",
|
|
898
|
+
fillRule: "evenodd",
|
|
899
|
+
transform: "translate(-1.44 -1.44) scale(1.12)",
|
|
900
|
+
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",
|
|
901
|
+
clipRule: "evenodd"
|
|
902
|
+
}
|
|
903
|
+
)
|
|
904
|
+
}
|
|
905
|
+
);
|
|
906
|
+
var GearIcon = ({ size = 20, ...props }) => /* @__PURE__ */ jsxs3(
|
|
907
|
+
"svg",
|
|
908
|
+
{
|
|
909
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
910
|
+
width: size,
|
|
911
|
+
height: size,
|
|
912
|
+
viewBox: "0 0 24 24",
|
|
913
|
+
fill: "none",
|
|
914
|
+
...props,
|
|
915
|
+
children: [
|
|
916
|
+
/* @__PURE__ */ jsx3(
|
|
917
|
+
"path",
|
|
918
|
+
{
|
|
919
|
+
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",
|
|
920
|
+
stroke: "currentColor",
|
|
921
|
+
strokeWidth: "1",
|
|
922
|
+
strokeLinecap: "round",
|
|
923
|
+
strokeLinejoin: "round"
|
|
924
|
+
}
|
|
925
|
+
),
|
|
926
|
+
/* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "2.5", stroke: "currentColor", strokeWidth: "1" })
|
|
927
|
+
]
|
|
928
|
+
}
|
|
929
|
+
);
|
|
139
930
|
|
|
140
931
|
// components/toolbar.tsx
|
|
141
|
-
import { jsx as
|
|
932
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
142
933
|
var TOOLBAR_TOOLTIP_DELAY_MS = 800;
|
|
143
934
|
var TOOLBAR_DRAG_SLOP = 6;
|
|
144
935
|
var GUIDE_MENU_WIDTH = 176;
|
|
@@ -156,61 +947,43 @@ function ToolbarButton({
|
|
|
156
947
|
onTooltipLeave,
|
|
157
948
|
children
|
|
158
949
|
}) {
|
|
159
|
-
return /* @__PURE__ */
|
|
950
|
+
return /* @__PURE__ */ jsxs4(
|
|
160
951
|
"div",
|
|
161
952
|
{
|
|
162
953
|
className: "msr:relative",
|
|
163
954
|
onMouseEnter: () => onTooltipEnter(id),
|
|
164
955
|
onMouseLeave: () => onTooltipLeave(id),
|
|
165
956
|
children: [
|
|
166
|
-
/* @__PURE__ */
|
|
957
|
+
/* @__PURE__ */ jsx4(
|
|
167
958
|
"button",
|
|
168
959
|
{
|
|
169
960
|
type: "button",
|
|
170
|
-
"aria-label": `${label} (${shortcut})`,
|
|
171
961
|
"aria-pressed": active,
|
|
172
|
-
|
|
962
|
+
"aria-label": `${label} (${shortcut})`,
|
|
173
963
|
className: cn(
|
|
174
|
-
"msr:flex msr:size-8 msr:items-center msr:justify-center msr:rounded-[8px] msr:outline-none",
|
|
964
|
+
"msr:flex msr:size-8 msr:select-none msr:items-center msr:justify-center msr:rounded-[8px] msr:outline-none",
|
|
175
965
|
active ? "msr:bg-[#0d99ff] msr:text-white" : "msr:bg-transparent msr:text-black msr:hover:bg-black/4"
|
|
176
966
|
),
|
|
177
967
|
onClick,
|
|
178
968
|
children
|
|
179
969
|
}
|
|
180
970
|
),
|
|
181
|
-
/* @__PURE__ */
|
|
182
|
-
"span",
|
|
183
|
-
{
|
|
184
|
-
className: cn(
|
|
185
|
-
cn(
|
|
186
|
-
"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",
|
|
187
|
-
tooltipInstant && "msr:transition-none"
|
|
188
|
-
),
|
|
189
|
-
tooltipSide === "top" ? "msr:bottom-full msr:mb-2" : "msr:top-full msr:mt-2",
|
|
190
|
-
tooltipVisible ? "msr:opacity-100" : "msr:opacity-0"
|
|
191
|
-
),
|
|
192
|
-
children: [
|
|
193
|
-
label,
|
|
194
|
-
" ",
|
|
195
|
-
/* @__PURE__ */ jsx2("kbd", { className: "msr:text-white/60", children: shortcut })
|
|
196
|
-
]
|
|
197
|
-
}
|
|
198
|
-
)
|
|
971
|
+
/* @__PURE__ */ jsx4(Tooltip, { label, shortcut, visible: tooltipVisible, instant: tooltipInstant, side: tooltipSide })
|
|
199
972
|
]
|
|
200
973
|
}
|
|
201
974
|
);
|
|
202
975
|
}
|
|
203
976
|
function useToolbarTooltip() {
|
|
204
|
-
const [visibleTooltipId, setVisibleTooltipId] =
|
|
205
|
-
const timerRef =
|
|
206
|
-
const instantRef =
|
|
207
|
-
const [tooltipInstant, setTooltipInstant] =
|
|
208
|
-
const clearTimer =
|
|
977
|
+
const [visibleTooltipId, setVisibleTooltipId] = useState3(null);
|
|
978
|
+
const timerRef = useRef2(null);
|
|
979
|
+
const instantRef = useRef2(false);
|
|
980
|
+
const [tooltipInstant, setTooltipInstant] = useState3(false);
|
|
981
|
+
const clearTimer = useCallback2(() => {
|
|
209
982
|
if (timerRef.current === null) return;
|
|
210
983
|
window.clearTimeout(timerRef.current);
|
|
211
984
|
timerRef.current = null;
|
|
212
985
|
}, []);
|
|
213
|
-
const onTooltipEnter =
|
|
986
|
+
const onTooltipEnter = useCallback2(
|
|
214
987
|
(id) => {
|
|
215
988
|
clearTimer();
|
|
216
989
|
if (instantRef.current) {
|
|
@@ -227,14 +1000,14 @@ function useToolbarTooltip() {
|
|
|
227
1000
|
},
|
|
228
1001
|
[clearTimer]
|
|
229
1002
|
);
|
|
230
|
-
const onTooltipLeave =
|
|
1003
|
+
const onTooltipLeave = useCallback2(
|
|
231
1004
|
(id) => {
|
|
232
1005
|
clearTimer();
|
|
233
1006
|
setVisibleTooltipId((prev) => prev === id ? null : prev);
|
|
234
1007
|
},
|
|
235
1008
|
[clearTimer]
|
|
236
1009
|
);
|
|
237
|
-
const onToolbarLeave =
|
|
1010
|
+
const onToolbarLeave = useCallback2(() => {
|
|
238
1011
|
clearTimer();
|
|
239
1012
|
setVisibleTooltipId(null);
|
|
240
1013
|
instantRef.current = false;
|
|
@@ -249,10 +1022,11 @@ function useToolbarTooltip() {
|
|
|
249
1022
|
};
|
|
250
1023
|
}
|
|
251
1024
|
function useToolbarDrag(initialPosition, eventTarget) {
|
|
252
|
-
const [position, setPosition] =
|
|
253
|
-
const suppressClickRef =
|
|
254
|
-
const
|
|
255
|
-
const
|
|
1025
|
+
const [position, setPosition] = useState3(initialPosition);
|
|
1026
|
+
const suppressClickRef = useRef2(false);
|
|
1027
|
+
const previousUserSelectRef = useRef2(null);
|
|
1028
|
+
const detachListenersRef = useRef2(null);
|
|
1029
|
+
const dragRef = useRef2({
|
|
256
1030
|
active: false,
|
|
257
1031
|
didDrag: false,
|
|
258
1032
|
pointerId: -1,
|
|
@@ -263,12 +1037,28 @@ function useToolbarDrag(initialPosition, eventTarget) {
|
|
|
263
1037
|
width: 0,
|
|
264
1038
|
height: 0
|
|
265
1039
|
});
|
|
266
|
-
const
|
|
1040
|
+
const disableTextSelection = useCallback2(() => {
|
|
1041
|
+
if (previousUserSelectRef.current !== null) return;
|
|
1042
|
+
const root = eventTarget.document.documentElement;
|
|
1043
|
+
previousUserSelectRef.current = root.style.userSelect;
|
|
1044
|
+
root.style.setProperty("user-select", "none", "important");
|
|
1045
|
+
}, [eventTarget]);
|
|
1046
|
+
const restoreTextSelection = useCallback2(() => {
|
|
1047
|
+
const previous = previousUserSelectRef.current;
|
|
1048
|
+
if (previous === null) return;
|
|
1049
|
+
const root = eventTarget.document.documentElement;
|
|
1050
|
+
root.style.userSelect = previous;
|
|
1051
|
+
previousUserSelectRef.current = null;
|
|
1052
|
+
}, [eventTarget]);
|
|
1053
|
+
useEffect(() => restoreTextSelection, [restoreTextSelection]);
|
|
1054
|
+
const onPointerDown = useCallback2(
|
|
267
1055
|
(event) => {
|
|
268
1056
|
if (event.button !== 0) return;
|
|
1057
|
+
disableTextSelection();
|
|
269
1058
|
if (detachListenersRef.current) {
|
|
270
1059
|
detachListenersRef.current();
|
|
271
1060
|
detachListenersRef.current = null;
|
|
1061
|
+
restoreTextSelection();
|
|
272
1062
|
}
|
|
273
1063
|
const state = dragRef.current;
|
|
274
1064
|
state.active = false;
|
|
@@ -303,6 +1093,7 @@ function useToolbarDrag(initialPosition, eventTarget) {
|
|
|
303
1093
|
if (current.pointerId !== endEvent.pointerId && current.pointerId !== -1)
|
|
304
1094
|
return;
|
|
305
1095
|
suppressClickRef.current = current.didDrag;
|
|
1096
|
+
restoreTextSelection();
|
|
306
1097
|
current.active = false;
|
|
307
1098
|
current.didDrag = false;
|
|
308
1099
|
current.pointerId = -1;
|
|
@@ -320,9 +1111,9 @@ function useToolbarDrag(initialPosition, eventTarget) {
|
|
|
320
1111
|
eventTarget.removeEventListener("pointercancel", handlePointerEnd);
|
|
321
1112
|
};
|
|
322
1113
|
},
|
|
323
|
-
[eventTarget, position.x, position.y]
|
|
1114
|
+
[disableTextSelection, eventTarget, position.x, position.y, restoreTextSelection]
|
|
324
1115
|
);
|
|
325
|
-
const onClickCapture =
|
|
1116
|
+
const onClickCapture = useCallback2(
|
|
326
1117
|
(event) => {
|
|
327
1118
|
if (!suppressClickRef.current) return;
|
|
328
1119
|
event.preventDefault();
|
|
@@ -337,12 +1128,46 @@ function ToolbarComponent({
|
|
|
337
1128
|
toolMode,
|
|
338
1129
|
setEnabled,
|
|
339
1130
|
setToolMode,
|
|
1131
|
+
xrayVisible,
|
|
1132
|
+
setXrayVisible,
|
|
340
1133
|
rulersVisible,
|
|
341
1134
|
setRulersVisible,
|
|
342
1135
|
guideOrientation,
|
|
343
1136
|
setGuideOrientation,
|
|
344
1137
|
onInteract,
|
|
345
|
-
eventTarget
|
|
1138
|
+
eventTarget,
|
|
1139
|
+
colorPickerActive,
|
|
1140
|
+
setColorPickerActive,
|
|
1141
|
+
onColorPickerClick,
|
|
1142
|
+
settingsOpen,
|
|
1143
|
+
setSettingsOpen,
|
|
1144
|
+
highlightColor,
|
|
1145
|
+
setHighlightColor,
|
|
1146
|
+
guideColor,
|
|
1147
|
+
setGuideColor,
|
|
1148
|
+
hoverHighlight,
|
|
1149
|
+
setHoverHighlight,
|
|
1150
|
+
persistOnReload,
|
|
1151
|
+
setPersistOnReload,
|
|
1152
|
+
colorPickerFormats,
|
|
1153
|
+
setColorPickerFormats,
|
|
1154
|
+
colorPickerClickFormat,
|
|
1155
|
+
setColorPickerClickFormat,
|
|
1156
|
+
snapEnabled,
|
|
1157
|
+
setSnapEnabled,
|
|
1158
|
+
snapGuidesEnabled,
|
|
1159
|
+
setSnapGuidesEnabled,
|
|
1160
|
+
selectNewGuideEnabled,
|
|
1161
|
+
setSelectNewGuideEnabled,
|
|
1162
|
+
multiMeasureEnabled,
|
|
1163
|
+
setMultiMeasureEnabled,
|
|
1164
|
+
guideStyle,
|
|
1165
|
+
setGuideStyle,
|
|
1166
|
+
rulerSettings,
|
|
1167
|
+
setRulerSettings,
|
|
1168
|
+
initialSettingsTab,
|
|
1169
|
+
onResetSettings,
|
|
1170
|
+
onClearWorkspace
|
|
346
1171
|
}, ref) {
|
|
347
1172
|
const { position, onPointerDown, onClickCapture } = useToolbarDrag({
|
|
348
1173
|
x: 16,
|
|
@@ -355,11 +1180,13 @@ function ToolbarComponent({
|
|
|
355
1180
|
onTooltipLeave,
|
|
356
1181
|
onToolbarLeave
|
|
357
1182
|
} = useToolbarTooltip();
|
|
358
|
-
const [guideMenuOpen, setGuideMenuOpen] =
|
|
359
|
-
const
|
|
360
|
-
const
|
|
361
|
-
const [
|
|
362
|
-
const
|
|
1183
|
+
const [guideMenuOpen, setGuideMenuOpen] = useState3(false);
|
|
1184
|
+
const settingsRef = useRef2(null);
|
|
1185
|
+
const guideMenuRef = useRef2(null);
|
|
1186
|
+
const [activeMenuIndex, setActiveMenuIndex] = useState3(0);
|
|
1187
|
+
const [menuAlign, setMenuAlign] = useState3("right");
|
|
1188
|
+
const tooltipsEnabled = !guideMenuOpen && !settingsOpen;
|
|
1189
|
+
const updateMenuAlign = useCallback2(() => {
|
|
363
1190
|
const anchorRect = guideMenuRef.current?.getBoundingClientRect();
|
|
364
1191
|
if (!anchorRect) return;
|
|
365
1192
|
const rightAlignedLeft = anchorRect.right - GUIDE_MENU_WIDTH;
|
|
@@ -379,34 +1206,50 @@ function ToolbarComponent({
|
|
|
379
1206
|
const nearBottom = viewportHeight > 0 && position.y > viewportHeight - 56;
|
|
380
1207
|
const tooltipSide = nearTop && !nearBottom ? "bottom" : "top";
|
|
381
1208
|
const menuSide = nearBottom ? "top" : "bottom";
|
|
382
|
-
const selectMode =
|
|
1209
|
+
const selectMode = useCallback2(() => {
|
|
383
1210
|
setEnabled(true);
|
|
1211
|
+
setColorPickerActive(false);
|
|
384
1212
|
setToolMode((prev) => prev === "select" ? "none" : "select");
|
|
385
1213
|
onInteract();
|
|
386
|
-
}, [onInteract, setEnabled, setToolMode]);
|
|
387
|
-
const guidesMode =
|
|
1214
|
+
}, [onInteract, setColorPickerActive, setEnabled, setToolMode]);
|
|
1215
|
+
const guidesMode = useCallback2(() => {
|
|
388
1216
|
setEnabled(true);
|
|
1217
|
+
setColorPickerActive(false);
|
|
389
1218
|
setToolMode((prev) => prev === "guides" ? "none" : "guides");
|
|
390
1219
|
onInteract();
|
|
391
|
-
}, [onInteract, setEnabled, setToolMode]);
|
|
392
|
-
const textInspectorMode =
|
|
1220
|
+
}, [onInteract, setColorPickerActive, setEnabled, setToolMode]);
|
|
1221
|
+
const textInspectorMode = useCallback2(() => {
|
|
393
1222
|
setEnabled(true);
|
|
1223
|
+
setColorPickerActive(false);
|
|
394
1224
|
setToolMode(
|
|
395
1225
|
(prev) => prev === "text-inspector" ? "none" : "text-inspector"
|
|
396
1226
|
);
|
|
397
1227
|
onInteract();
|
|
398
|
-
}, [onInteract, setEnabled, setToolMode]);
|
|
399
|
-
const xrayMode =
|
|
1228
|
+
}, [onInteract, setColorPickerActive, setEnabled, setToolMode]);
|
|
1229
|
+
const xrayMode = useCallback2(() => {
|
|
400
1230
|
setEnabled(true);
|
|
401
|
-
|
|
1231
|
+
setColorPickerActive(false);
|
|
1232
|
+
setXrayVisible((prev) => !prev);
|
|
402
1233
|
onInteract();
|
|
403
|
-
}, [onInteract, setEnabled,
|
|
404
|
-
const
|
|
1234
|
+
}, [onInteract, setColorPickerActive, setEnabled, setXrayVisible]);
|
|
1235
|
+
const colorPickerMode = useCallback2(() => {
|
|
405
1236
|
setEnabled(true);
|
|
1237
|
+
setToolMode("none");
|
|
1238
|
+
if (colorPickerActive) {
|
|
1239
|
+
setColorPickerActive(false);
|
|
1240
|
+
} else {
|
|
1241
|
+
setColorPickerActive(true);
|
|
1242
|
+
onColorPickerClick();
|
|
1243
|
+
}
|
|
1244
|
+
onInteract();
|
|
1245
|
+
}, [colorPickerActive, onColorPickerClick, onInteract, setColorPickerActive, setEnabled, setToolMode]);
|
|
1246
|
+
const rulersMode = useCallback2(() => {
|
|
1247
|
+
setEnabled(true);
|
|
1248
|
+
setColorPickerActive(false);
|
|
406
1249
|
setRulersVisible((prev) => !prev);
|
|
407
1250
|
onInteract();
|
|
408
|
-
}, [onInteract, setEnabled, setRulersVisible]);
|
|
409
|
-
const selectGuideOrientation =
|
|
1251
|
+
}, [onInteract, setColorPickerActive, setEnabled, setRulersVisible]);
|
|
1252
|
+
const selectGuideOrientation = useCallback2(
|
|
410
1253
|
(orientation) => {
|
|
411
1254
|
setEnabled(true);
|
|
412
1255
|
setToolMode("guides");
|
|
@@ -417,29 +1260,33 @@ function ToolbarComponent({
|
|
|
417
1260
|
[onInteract, setEnabled, setGuideOrientation, setToolMode]
|
|
418
1261
|
);
|
|
419
1262
|
useLayoutEffect(() => {
|
|
420
|
-
if (!guideMenuOpen) return;
|
|
421
|
-
const frame = eventTarget.requestAnimationFrame(() => {
|
|
1263
|
+
if (!guideMenuOpen && !settingsOpen) return;
|
|
1264
|
+
const frame = guideMenuOpen ? eventTarget.requestAnimationFrame(() => {
|
|
422
1265
|
guideMenuRef.current?.querySelector("[role='menu']")?.focus();
|
|
423
|
-
});
|
|
1266
|
+
}) : 0;
|
|
424
1267
|
const handlePointerDown = (event) => {
|
|
425
|
-
const menu = guideMenuRef.current;
|
|
426
|
-
if (!menu) return;
|
|
427
1268
|
const path = event.composedPath();
|
|
428
|
-
if (
|
|
429
|
-
|
|
1269
|
+
if (guideMenuOpen) {
|
|
1270
|
+
const menu = guideMenuRef.current;
|
|
1271
|
+
if (menu && !path.includes(menu)) setGuideMenuOpen(false);
|
|
1272
|
+
}
|
|
1273
|
+
if (settingsOpen) {
|
|
1274
|
+
const settings = settingsRef.current;
|
|
1275
|
+
if (settings && !path.includes(settings)) setSettingsOpen(false);
|
|
1276
|
+
}
|
|
430
1277
|
};
|
|
431
1278
|
const handleResize = () => {
|
|
432
|
-
updateMenuAlign();
|
|
1279
|
+
if (guideMenuOpen) updateMenuAlign();
|
|
433
1280
|
};
|
|
434
1281
|
eventTarget.addEventListener("pointerdown", handlePointerDown);
|
|
435
|
-
eventTarget.addEventListener("resize", handleResize);
|
|
1282
|
+
if (guideMenuOpen) eventTarget.addEventListener("resize", handleResize);
|
|
436
1283
|
return () => {
|
|
437
|
-
eventTarget.cancelAnimationFrame(frame);
|
|
1284
|
+
if (frame) eventTarget.cancelAnimationFrame(frame);
|
|
438
1285
|
eventTarget.removeEventListener("pointerdown", handlePointerDown);
|
|
439
1286
|
eventTarget.removeEventListener("resize", handleResize);
|
|
440
1287
|
};
|
|
441
|
-
}, [eventTarget, guideMenuOpen, guideOrientation, updateMenuAlign]);
|
|
442
|
-
return /* @__PURE__ */
|
|
1288
|
+
}, [eventTarget, guideMenuOpen, guideOrientation, settingsOpen, updateMenuAlign]);
|
|
1289
|
+
return /* @__PURE__ */ jsxs4(
|
|
443
1290
|
"div",
|
|
444
1291
|
{
|
|
445
1292
|
ref,
|
|
@@ -452,7 +1299,7 @@ function ToolbarComponent({
|
|
|
452
1299
|
onClickCapture,
|
|
453
1300
|
onMouseLeave: onToolbarLeave,
|
|
454
1301
|
children: [
|
|
455
|
-
/* @__PURE__ */
|
|
1302
|
+
/* @__PURE__ */ jsx4(
|
|
456
1303
|
ToolbarButton,
|
|
457
1304
|
{
|
|
458
1305
|
id: "select",
|
|
@@ -460,31 +1307,47 @@ function ToolbarComponent({
|
|
|
460
1307
|
label: "Select",
|
|
461
1308
|
shortcut: "S",
|
|
462
1309
|
onClick: selectMode,
|
|
463
|
-
tooltipVisible: visibleTooltipId === "select",
|
|
1310
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "select",
|
|
464
1311
|
tooltipInstant,
|
|
465
1312
|
tooltipSide,
|
|
466
1313
|
onTooltipEnter,
|
|
467
1314
|
onTooltipLeave,
|
|
468
|
-
children: /* @__PURE__ */
|
|
1315
|
+
children: /* @__PURE__ */ jsx4(CursorIcon, { size: 20 })
|
|
469
1316
|
}
|
|
470
1317
|
),
|
|
471
|
-
/* @__PURE__ */
|
|
1318
|
+
/* @__PURE__ */ jsx4(
|
|
472
1319
|
ToolbarButton,
|
|
473
1320
|
{
|
|
474
1321
|
id: "xray",
|
|
475
|
-
active:
|
|
1322
|
+
active: xrayVisible,
|
|
476
1323
|
label: "X-ray",
|
|
477
1324
|
shortcut: "X",
|
|
478
1325
|
onClick: xrayMode,
|
|
479
|
-
tooltipVisible: visibleTooltipId === "xray",
|
|
1326
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "xray",
|
|
480
1327
|
tooltipInstant,
|
|
481
1328
|
tooltipSide,
|
|
482
1329
|
onTooltipEnter,
|
|
483
1330
|
onTooltipLeave,
|
|
484
|
-
children: /* @__PURE__ */
|
|
1331
|
+
children: /* @__PURE__ */ jsx4(XrayIcon, { size: 20 })
|
|
485
1332
|
}
|
|
486
1333
|
),
|
|
487
|
-
/* @__PURE__ */
|
|
1334
|
+
/* @__PURE__ */ jsx4(
|
|
1335
|
+
ToolbarButton,
|
|
1336
|
+
{
|
|
1337
|
+
id: "color-picker",
|
|
1338
|
+
active: colorPickerActive,
|
|
1339
|
+
label: "Color picker",
|
|
1340
|
+
shortcut: "P",
|
|
1341
|
+
onClick: colorPickerMode,
|
|
1342
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "color-picker",
|
|
1343
|
+
tooltipInstant,
|
|
1344
|
+
tooltipSide,
|
|
1345
|
+
onTooltipEnter,
|
|
1346
|
+
onTooltipLeave,
|
|
1347
|
+
children: /* @__PURE__ */ jsx4(ColorPickerIcon, { size: 20, "aria-hidden": "true" })
|
|
1348
|
+
}
|
|
1349
|
+
),
|
|
1350
|
+
/* @__PURE__ */ jsx4(
|
|
488
1351
|
ToolbarButton,
|
|
489
1352
|
{
|
|
490
1353
|
id: "rulers",
|
|
@@ -492,15 +1355,15 @@ function ToolbarComponent({
|
|
|
492
1355
|
label: "Rulers",
|
|
493
1356
|
shortcut: "R",
|
|
494
1357
|
onClick: rulersMode,
|
|
495
|
-
tooltipVisible: visibleTooltipId === "rulers",
|
|
1358
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "rulers",
|
|
496
1359
|
tooltipInstant,
|
|
497
1360
|
tooltipSide,
|
|
498
1361
|
onTooltipEnter,
|
|
499
1362
|
onTooltipLeave,
|
|
500
|
-
children: /* @__PURE__ */
|
|
1363
|
+
children: /* @__PURE__ */ jsx4(RulersIcon, { size: 20 })
|
|
501
1364
|
}
|
|
502
1365
|
),
|
|
503
|
-
/* @__PURE__ */
|
|
1366
|
+
/* @__PURE__ */ jsx4(
|
|
504
1367
|
ToolbarButton,
|
|
505
1368
|
{
|
|
506
1369
|
id: "text-inspector",
|
|
@@ -508,15 +1371,15 @@ function ToolbarComponent({
|
|
|
508
1371
|
label: "Text inspector",
|
|
509
1372
|
shortcut: "A",
|
|
510
1373
|
onClick: textInspectorMode,
|
|
511
|
-
tooltipVisible: visibleTooltipId === "text-inspector",
|
|
1374
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "text-inspector",
|
|
512
1375
|
tooltipInstant,
|
|
513
1376
|
tooltipSide,
|
|
514
1377
|
onTooltipEnter,
|
|
515
1378
|
onTooltipLeave,
|
|
516
|
-
children: /* @__PURE__ */
|
|
1379
|
+
children: /* @__PURE__ */ jsx4(TextInspectorIcon, { size: 20, "aria-hidden": "true" })
|
|
517
1380
|
}
|
|
518
1381
|
),
|
|
519
|
-
/* @__PURE__ */
|
|
1382
|
+
/* @__PURE__ */ jsx4(
|
|
520
1383
|
ToolbarButton,
|
|
521
1384
|
{
|
|
522
1385
|
id: "guides",
|
|
@@ -524,12 +1387,12 @@ function ToolbarComponent({
|
|
|
524
1387
|
label: "Guides",
|
|
525
1388
|
shortcut: "G",
|
|
526
1389
|
onClick: guidesMode,
|
|
527
|
-
tooltipVisible: visibleTooltipId === "guides",
|
|
1390
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "guides",
|
|
528
1391
|
tooltipInstant,
|
|
529
1392
|
tooltipSide,
|
|
530
1393
|
onTooltipEnter,
|
|
531
1394
|
onTooltipLeave,
|
|
532
|
-
children: /* @__PURE__ */
|
|
1395
|
+
children: /* @__PURE__ */ jsx4(
|
|
533
1396
|
RulerIcon,
|
|
534
1397
|
{
|
|
535
1398
|
size: 20,
|
|
@@ -540,7 +1403,7 @@ function ToolbarComponent({
|
|
|
540
1403
|
)
|
|
541
1404
|
}
|
|
542
1405
|
),
|
|
543
|
-
/* @__PURE__ */
|
|
1406
|
+
/* @__PURE__ */ jsxs4(
|
|
544
1407
|
"div",
|
|
545
1408
|
{
|
|
546
1409
|
className: "msr:group msr:relative msr:-ml-1 msr:flex msr:items-stretch",
|
|
@@ -548,12 +1411,11 @@ function ToolbarComponent({
|
|
|
548
1411
|
onMouseEnter: () => onTooltipEnter("guide-menu"),
|
|
549
1412
|
onMouseLeave: () => onTooltipLeave("guide-menu"),
|
|
550
1413
|
children: [
|
|
551
|
-
/* @__PURE__ */
|
|
1414
|
+
/* @__PURE__ */ jsx4(
|
|
552
1415
|
"button",
|
|
553
1416
|
{
|
|
554
1417
|
type: "button",
|
|
555
1418
|
"aria-label": "Guide orientation menu",
|
|
556
|
-
title: "Guide orientation",
|
|
557
1419
|
className: cn(
|
|
558
1420
|
"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",
|
|
559
1421
|
guideMenuOpen ? "msr:bg-black/10 msr:text-black" : "msr:text-black"
|
|
@@ -568,21 +1430,21 @@ function ToolbarComponent({
|
|
|
568
1430
|
return !prev;
|
|
569
1431
|
});
|
|
570
1432
|
},
|
|
571
|
-
children: /* @__PURE__ */
|
|
1433
|
+
children: /* @__PURE__ */ jsx4(CaretDownIcon, { size: 8 })
|
|
572
1434
|
}
|
|
573
1435
|
),
|
|
574
|
-
/* @__PURE__ */
|
|
1436
|
+
/* @__PURE__ */ jsx4(
|
|
575
1437
|
"span",
|
|
576
1438
|
{
|
|
577
1439
|
className: cn(
|
|
578
1440
|
"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",
|
|
579
1441
|
tooltipSide === "top" ? "msr:bottom-full msr:mb-2" : "msr:top-full msr:mt-2",
|
|
580
|
-
visibleTooltipId === "guide-menu" &&
|
|
1442
|
+
visibleTooltipId === "guide-menu" && tooltipsEnabled ? "msr:opacity-100" : "msr:opacity-0"
|
|
581
1443
|
),
|
|
582
1444
|
children: "Orientation Guide"
|
|
583
1445
|
}
|
|
584
1446
|
),
|
|
585
|
-
guideMenuOpen ? /* @__PURE__ */
|
|
1447
|
+
guideMenuOpen ? /* @__PURE__ */ jsxs4(
|
|
586
1448
|
"div",
|
|
587
1449
|
{
|
|
588
1450
|
className: cn(
|
|
@@ -623,7 +1485,7 @@ function ToolbarComponent({
|
|
|
623
1485
|
}
|
|
624
1486
|
},
|
|
625
1487
|
children: [
|
|
626
|
-
/* @__PURE__ */
|
|
1488
|
+
/* @__PURE__ */ jsxs4(
|
|
627
1489
|
"button",
|
|
628
1490
|
{
|
|
629
1491
|
type: "button",
|
|
@@ -633,7 +1495,7 @@ function ToolbarComponent({
|
|
|
633
1495
|
),
|
|
634
1496
|
onClick: () => selectGuideOrientation("horizontal"),
|
|
635
1497
|
children: [
|
|
636
|
-
/* @__PURE__ */
|
|
1498
|
+
/* @__PURE__ */ jsx4(
|
|
637
1499
|
CheckIcon,
|
|
638
1500
|
{
|
|
639
1501
|
size: 12,
|
|
@@ -642,13 +1504,13 @@ function ToolbarComponent({
|
|
|
642
1504
|
)
|
|
643
1505
|
}
|
|
644
1506
|
),
|
|
645
|
-
/* @__PURE__ */
|
|
646
|
-
/* @__PURE__ */
|
|
647
|
-
/* @__PURE__ */
|
|
1507
|
+
/* @__PURE__ */ jsx4(MinusIcon, { size: 12 }),
|
|
1508
|
+
/* @__PURE__ */ jsx4("span", { className: "msr:flex-1", children: "Horizontal" }),
|
|
1509
|
+
/* @__PURE__ */ jsx4("span", { children: "H" })
|
|
648
1510
|
]
|
|
649
1511
|
}
|
|
650
1512
|
),
|
|
651
|
-
/* @__PURE__ */
|
|
1513
|
+
/* @__PURE__ */ jsxs4(
|
|
652
1514
|
"button",
|
|
653
1515
|
{
|
|
654
1516
|
type: "button",
|
|
@@ -658,7 +1520,7 @@ function ToolbarComponent({
|
|
|
658
1520
|
),
|
|
659
1521
|
onClick: () => selectGuideOrientation("vertical"),
|
|
660
1522
|
children: [
|
|
661
|
-
/* @__PURE__ */
|
|
1523
|
+
/* @__PURE__ */ jsx4(
|
|
662
1524
|
CheckIcon,
|
|
663
1525
|
{
|
|
664
1526
|
size: 12,
|
|
@@ -667,9 +1529,9 @@ function ToolbarComponent({
|
|
|
667
1529
|
)
|
|
668
1530
|
}
|
|
669
1531
|
),
|
|
670
|
-
/* @__PURE__ */
|
|
671
|
-
/* @__PURE__ */
|
|
672
|
-
/* @__PURE__ */
|
|
1532
|
+
/* @__PURE__ */ jsx4(MinusIcon, { size: 12, className: "msr:rotate-90" }),
|
|
1533
|
+
/* @__PURE__ */ jsx4("span", { className: "msr:flex-1", children: "Vertical" }),
|
|
1534
|
+
/* @__PURE__ */ jsx4("span", { children: "V" })
|
|
673
1535
|
]
|
|
674
1536
|
}
|
|
675
1537
|
)
|
|
@@ -678,24 +1540,299 @@ function ToolbarComponent({
|
|
|
678
1540
|
) : null
|
|
679
1541
|
]
|
|
680
1542
|
}
|
|
1543
|
+
),
|
|
1544
|
+
/* @__PURE__ */ jsxs4("div", { ref: settingsRef, className: "msr:relative msr:flex", children: [
|
|
1545
|
+
/* @__PURE__ */ jsx4(
|
|
1546
|
+
ToolbarButton,
|
|
1547
|
+
{
|
|
1548
|
+
id: "settings",
|
|
1549
|
+
active: settingsOpen,
|
|
1550
|
+
label: "Settings",
|
|
1551
|
+
shortcut: "\u2318/Ctrl+,",
|
|
1552
|
+
onClick: () => {
|
|
1553
|
+
onInteract();
|
|
1554
|
+
setSettingsOpen((previous) => !previous);
|
|
1555
|
+
},
|
|
1556
|
+
tooltipVisible: tooltipsEnabled && visibleTooltipId === "settings",
|
|
1557
|
+
tooltipInstant,
|
|
1558
|
+
tooltipSide,
|
|
1559
|
+
onTooltipEnter,
|
|
1560
|
+
onTooltipLeave,
|
|
1561
|
+
children: /* @__PURE__ */ jsx4(GearIcon, { size: 20, "aria-hidden": "true" })
|
|
1562
|
+
}
|
|
1563
|
+
),
|
|
1564
|
+
settingsOpen ? /* @__PURE__ */ jsx4(
|
|
1565
|
+
"div",
|
|
1566
|
+
{
|
|
1567
|
+
className: cn(
|
|
1568
|
+
"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",
|
|
1569
|
+
menuSide === "bottom" ? "msr:top-full msr:mt-2" : "msr:bottom-full msr:mb-2"
|
|
1570
|
+
),
|
|
1571
|
+
"data-mesurer-inspector-ui": "true",
|
|
1572
|
+
role: "dialog",
|
|
1573
|
+
"aria-label": "Settings",
|
|
1574
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
1575
|
+
onPointerMove: (event) => event.stopPropagation(),
|
|
1576
|
+
onPointerUp: (event) => event.stopPropagation(),
|
|
1577
|
+
onClick: (event) => event.stopPropagation(),
|
|
1578
|
+
children: /* @__PURE__ */ jsx4(
|
|
1579
|
+
SettingsPanel,
|
|
1580
|
+
{
|
|
1581
|
+
ownerWindow: eventTarget,
|
|
1582
|
+
highlightColor,
|
|
1583
|
+
setHighlightColor,
|
|
1584
|
+
guideColor,
|
|
1585
|
+
setGuideColor,
|
|
1586
|
+
hoverHighlight,
|
|
1587
|
+
setHoverHighlight,
|
|
1588
|
+
persistOnReload,
|
|
1589
|
+
setPersistOnReload,
|
|
1590
|
+
colorFormats: colorPickerFormats,
|
|
1591
|
+
setColorFormats: setColorPickerFormats,
|
|
1592
|
+
colorClickFormat: colorPickerClickFormat,
|
|
1593
|
+
setColorClickFormat: setColorPickerClickFormat,
|
|
1594
|
+
snapEnabled,
|
|
1595
|
+
setSnapEnabled,
|
|
1596
|
+
snapGuidesEnabled,
|
|
1597
|
+
setSnapGuidesEnabled,
|
|
1598
|
+
selectNewGuideEnabled,
|
|
1599
|
+
setSelectNewGuideEnabled,
|
|
1600
|
+
multiMeasureEnabled,
|
|
1601
|
+
setMultiMeasureEnabled,
|
|
1602
|
+
guideStyle,
|
|
1603
|
+
setGuideStyle,
|
|
1604
|
+
rulerSettings,
|
|
1605
|
+
setRulerSettings,
|
|
1606
|
+
initialTab: initialSettingsTab,
|
|
1607
|
+
onResetSettings,
|
|
1608
|
+
onClearWorkspace
|
|
1609
|
+
}
|
|
1610
|
+
)
|
|
1611
|
+
}
|
|
1612
|
+
) : null
|
|
1613
|
+
] })
|
|
1614
|
+
]
|
|
1615
|
+
}
|
|
1616
|
+
);
|
|
1617
|
+
}
|
|
1618
|
+
var Toolbar = memo(forwardRef(ToolbarComponent));
|
|
1619
|
+
|
|
1620
|
+
// components/color-picker.tsx
|
|
1621
|
+
import { useCallback as useCallback3, useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState4 } from "react";
|
|
1622
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1623
|
+
function CopyableColorValue({
|
|
1624
|
+
id,
|
|
1625
|
+
value,
|
|
1626
|
+
copiedId,
|
|
1627
|
+
onCopy,
|
|
1628
|
+
onTooltipEnter,
|
|
1629
|
+
tooltip,
|
|
1630
|
+
className
|
|
1631
|
+
}) {
|
|
1632
|
+
const copied = copiedId === id;
|
|
1633
|
+
const showTooltip = tooltip.visibleTooltipId === id || copied && tooltip.visibleTooltipId === null;
|
|
1634
|
+
return /* @__PURE__ */ jsxs5(
|
|
1635
|
+
"span",
|
|
1636
|
+
{
|
|
1637
|
+
className: "msr:relative msr:inline-flex",
|
|
1638
|
+
onMouseLeave: tooltip.onTooltipLeave,
|
|
1639
|
+
children: [
|
|
1640
|
+
/* @__PURE__ */ jsx5(
|
|
1641
|
+
"button",
|
|
1642
|
+
{
|
|
1643
|
+
type: "button",
|
|
1644
|
+
className,
|
|
1645
|
+
onMouseEnter: () => onTooltipEnter(id),
|
|
1646
|
+
onFocus: () => onTooltipEnter(id),
|
|
1647
|
+
onBlur: tooltip.onTooltipLeave,
|
|
1648
|
+
onClick: onCopy,
|
|
1649
|
+
children: value
|
|
1650
|
+
}
|
|
1651
|
+
),
|
|
1652
|
+
/* @__PURE__ */ jsx5(
|
|
1653
|
+
Tooltip,
|
|
1654
|
+
{
|
|
1655
|
+
label: copied ? "Copied!" : "Click to copy",
|
|
1656
|
+
visible: showTooltip,
|
|
1657
|
+
instant: copied || tooltip.tooltipInstant,
|
|
1658
|
+
side: "bottom",
|
|
1659
|
+
className: "msr:z-10"
|
|
1660
|
+
}
|
|
681
1661
|
)
|
|
682
1662
|
]
|
|
683
1663
|
}
|
|
684
1664
|
);
|
|
685
1665
|
}
|
|
686
|
-
|
|
1666
|
+
function ColorPicker({
|
|
1667
|
+
active,
|
|
1668
|
+
sample,
|
|
1669
|
+
unsupported,
|
|
1670
|
+
formats,
|
|
1671
|
+
favoriteFormat,
|
|
1672
|
+
ownerWindow,
|
|
1673
|
+
toolbarRef,
|
|
1674
|
+
onClose
|
|
1675
|
+
}) {
|
|
1676
|
+
const panelRef = useRef3(null);
|
|
1677
|
+
const copyTimeoutRef = useRef3(null);
|
|
1678
|
+
const [copiedId, setCopiedId] = useState4(null);
|
|
1679
|
+
const tooltip = useTooltip();
|
|
1680
|
+
const copyValue = useCallback3(
|
|
1681
|
+
(id, value) => {
|
|
1682
|
+
const clipboardWrite = ownerWindow.navigator.clipboard?.writeText(value);
|
|
1683
|
+
void clipboardWrite?.catch(() => void 0);
|
|
1684
|
+
tooltip.onTooltipLeave();
|
|
1685
|
+
setCopiedId(id);
|
|
1686
|
+
if (copyTimeoutRef.current !== null) {
|
|
1687
|
+
ownerWindow.clearTimeout(copyTimeoutRef.current);
|
|
1688
|
+
}
|
|
1689
|
+
copyTimeoutRef.current = ownerWindow.setTimeout(() => {
|
|
1690
|
+
copyTimeoutRef.current = null;
|
|
1691
|
+
setCopiedId(null);
|
|
1692
|
+
}, 1500);
|
|
1693
|
+
},
|
|
1694
|
+
[ownerWindow, tooltip]
|
|
1695
|
+
);
|
|
1696
|
+
const handleTooltipEnter = useCallback3(
|
|
1697
|
+
(id) => {
|
|
1698
|
+
if (copiedId !== null && copiedId !== id) {
|
|
1699
|
+
if (copyTimeoutRef.current !== null) {
|
|
1700
|
+
ownerWindow.clearTimeout(copyTimeoutRef.current);
|
|
1701
|
+
copyTimeoutRef.current = null;
|
|
1702
|
+
}
|
|
1703
|
+
setCopiedId(null);
|
|
1704
|
+
}
|
|
1705
|
+
tooltip.onTooltipEnter(id);
|
|
1706
|
+
},
|
|
1707
|
+
[copiedId, ownerWindow, tooltip]
|
|
1708
|
+
);
|
|
1709
|
+
useLayoutEffect2(() => {
|
|
1710
|
+
if (!active) return;
|
|
1711
|
+
const panel = panelRef.current;
|
|
1712
|
+
const toolbar = toolbarRef.current;
|
|
1713
|
+
if (!panel || !toolbar) return;
|
|
1714
|
+
let frame = 0;
|
|
1715
|
+
const updatePosition = () => {
|
|
1716
|
+
const toolbarRect = toolbar.getBoundingClientRect();
|
|
1717
|
+
const panelRect = panel.getBoundingClientRect();
|
|
1718
|
+
const left = Math.min(
|
|
1719
|
+
Math.max(8, toolbarRect.left),
|
|
1720
|
+
ownerWindow.innerWidth - panelRect.width - 8
|
|
1721
|
+
);
|
|
1722
|
+
const belowTop = toolbarRect.bottom + 8;
|
|
1723
|
+
const aboveTop = toolbarRect.top - panelRect.height - 8;
|
|
1724
|
+
const top = belowTop + panelRect.height <= ownerWindow.innerHeight ? belowTop : Math.max(8, aboveTop);
|
|
1725
|
+
panel.style.left = `${left}px`;
|
|
1726
|
+
panel.style.top = `${top}px`;
|
|
1727
|
+
frame = ownerWindow.requestAnimationFrame(updatePosition);
|
|
1728
|
+
};
|
|
1729
|
+
frame = ownerWindow.requestAnimationFrame(updatePosition);
|
|
1730
|
+
return () => ownerWindow.cancelAnimationFrame(frame);
|
|
1731
|
+
}, [active, ownerWindow, toolbarRef, formats, sample, unsupported, favoriteFormat]);
|
|
1732
|
+
useLayoutEffect2(() => {
|
|
1733
|
+
return () => {
|
|
1734
|
+
if (copyTimeoutRef.current !== null) {
|
|
1735
|
+
ownerWindow.clearTimeout(copyTimeoutRef.current);
|
|
1736
|
+
}
|
|
1737
|
+
};
|
|
1738
|
+
}, [ownerWindow]);
|
|
1739
|
+
if (!active || !sample && !unsupported) return null;
|
|
1740
|
+
const headerFormat = formats.includes(favoriteFormat) ? favoriteFormat : formats[0];
|
|
1741
|
+
const secondaryFormats = headerFormat ? formats.filter((format) => format !== headerFormat) : [];
|
|
1742
|
+
return /* @__PURE__ */ jsx5(
|
|
1743
|
+
"div",
|
|
1744
|
+
{
|
|
1745
|
+
ref: panelRef,
|
|
1746
|
+
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",
|
|
1747
|
+
role: "dialog",
|
|
1748
|
+
"aria-label": "Selected color values",
|
|
1749
|
+
onMouseLeave: tooltip.onTooltipContainerLeave,
|
|
1750
|
+
children: unsupported ? /* @__PURE__ */ jsxs5("div", { className: "msr:flex msr:items-start msr:gap-2", children: [
|
|
1751
|
+
/* @__PURE__ */ jsx5("span", { className: "msr:text-black/60", children: "Color picker is not supported in this browser." }),
|
|
1752
|
+
/* @__PURE__ */ jsx5(
|
|
1753
|
+
"button",
|
|
1754
|
+
{
|
|
1755
|
+
type: "button",
|
|
1756
|
+
className: "msr:text-black/45 msr:hover:text-black",
|
|
1757
|
+
"aria-label": "Close color picker message",
|
|
1758
|
+
onClick: onClose,
|
|
1759
|
+
children: "x"
|
|
1760
|
+
}
|
|
1761
|
+
)
|
|
1762
|
+
] }) : sample ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1763
|
+
headerFormat ? /* @__PURE__ */ jsxs5(
|
|
1764
|
+
"div",
|
|
1765
|
+
{
|
|
1766
|
+
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",
|
|
1767
|
+
children: [
|
|
1768
|
+
/* @__PURE__ */ jsx5(
|
|
1769
|
+
"span",
|
|
1770
|
+
{
|
|
1771
|
+
className: "msr:size-3 msr:shrink-0 msr:rounded-full msr:border msr:border-black/15",
|
|
1772
|
+
style: { backgroundColor: colorToHex(sample) },
|
|
1773
|
+
"aria-hidden": "true"
|
|
1774
|
+
}
|
|
1775
|
+
),
|
|
1776
|
+
/* @__PURE__ */ jsx5(
|
|
1777
|
+
CopyableColorValue,
|
|
1778
|
+
{
|
|
1779
|
+
id: headerFormat,
|
|
1780
|
+
value: formatColor(sample, headerFormat),
|
|
1781
|
+
copiedId,
|
|
1782
|
+
onCopy: () => copyValue(headerFormat, formatColor(sample, headerFormat)),
|
|
1783
|
+
onTooltipEnter: handleTooltipEnter,
|
|
1784
|
+
tooltip,
|
|
1785
|
+
className: "msr:font-medium msr:tabular-nums msr:text-black msr:hover:underline"
|
|
1786
|
+
}
|
|
1787
|
+
)
|
|
1788
|
+
]
|
|
1789
|
+
}
|
|
1790
|
+
) : /* @__PURE__ */ jsx5("div", { className: "msr:flex msr:items-center", children: /* @__PURE__ */ jsx5(
|
|
1791
|
+
"span",
|
|
1792
|
+
{
|
|
1793
|
+
className: "msr:size-3 msr:shrink-0 msr:rounded-full msr:border msr:border-black/15",
|
|
1794
|
+
style: { backgroundColor: colorToHex(sample) },
|
|
1795
|
+
"aria-hidden": "true"
|
|
1796
|
+
}
|
|
1797
|
+
) }),
|
|
1798
|
+
secondaryFormats.map((format) => {
|
|
1799
|
+
const value = formatColor(sample, format);
|
|
1800
|
+
return /* @__PURE__ */ jsxs5("div", { className: "msr:flex msr:items-center msr:gap-2", children: [
|
|
1801
|
+
/* @__PURE__ */ jsx5("span", { className: "msr:w-9 msr:text-black/45", children: format }),
|
|
1802
|
+
/* @__PURE__ */ jsx5(
|
|
1803
|
+
CopyableColorValue,
|
|
1804
|
+
{
|
|
1805
|
+
id: format,
|
|
1806
|
+
value,
|
|
1807
|
+
copiedId,
|
|
1808
|
+
onCopy: () => copyValue(format, value),
|
|
1809
|
+
onTooltipEnter: handleTooltipEnter,
|
|
1810
|
+
tooltip,
|
|
1811
|
+
className: "msr:tabular-nums msr:text-black msr:hover:underline"
|
|
1812
|
+
}
|
|
1813
|
+
)
|
|
1814
|
+
] }, format);
|
|
1815
|
+
})
|
|
1816
|
+
] }) : null
|
|
1817
|
+
}
|
|
1818
|
+
);
|
|
1819
|
+
}
|
|
687
1820
|
|
|
688
1821
|
// components/rulers-overlay.tsx
|
|
689
|
-
import { memo as memo2, useRef as
|
|
690
|
-
import { jsx as
|
|
1822
|
+
import { memo as memo2, useEffect as useEffect2, useRef as useRef4, useState as useState5 } from "react";
|
|
1823
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
691
1824
|
var RULER_SIZE = 18;
|
|
692
1825
|
var RULER_LENGTH = 4e3;
|
|
693
1826
|
var TICK_STEP = 5;
|
|
1827
|
+
var RULER_EDGE_REVEAL_DISTANCE = 32;
|
|
1828
|
+
var RULER_FADE_MS = 100;
|
|
694
1829
|
var ticks = Array.from(
|
|
695
1830
|
{ length: RULER_LENGTH / TICK_STEP + 1 },
|
|
696
1831
|
(_, index) => index * TICK_STEP
|
|
697
1832
|
);
|
|
698
1833
|
var RulersOverlay = memo2(function RulersOverlay2({
|
|
1834
|
+
ownerWindow,
|
|
1835
|
+
settings,
|
|
699
1836
|
onStartGuide,
|
|
700
1837
|
onMoveGuide,
|
|
701
1838
|
onFinishGuide,
|
|
@@ -703,9 +1840,26 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
703
1840
|
guides,
|
|
704
1841
|
selectedGuideIds
|
|
705
1842
|
}) {
|
|
706
|
-
const [dragPosition, setDragPosition] =
|
|
707
|
-
const [dragOrientation, setDragOrientation] =
|
|
708
|
-
const
|
|
1843
|
+
const [dragPosition, setDragPosition] = useState5(null);
|
|
1844
|
+
const [dragOrientation, setDragOrientation] = useState5(null);
|
|
1845
|
+
const [nearEdge, setNearEdge] = useState5(false);
|
|
1846
|
+
const dragRef = useRef4(null);
|
|
1847
|
+
useEffect2(() => {
|
|
1848
|
+
if (!settings.edgeReveal) return;
|
|
1849
|
+
const handlePointerMove = (event) => {
|
|
1850
|
+
const pointer = event;
|
|
1851
|
+
const nearHorizontalEdge = pointer.clientX <= RULER_EDGE_REVEAL_DISTANCE || pointer.clientX >= ownerWindow.innerWidth - RULER_EDGE_REVEAL_DISTANCE;
|
|
1852
|
+
const nearVerticalEdge = pointer.clientY <= RULER_EDGE_REVEAL_DISTANCE || pointer.clientY >= ownerWindow.innerHeight - RULER_EDGE_REVEAL_DISTANCE;
|
|
1853
|
+
setNearEdge(nearHorizontalEdge || nearVerticalEdge);
|
|
1854
|
+
};
|
|
1855
|
+
ownerWindow.document.addEventListener("pointermove", handlePointerMove, true);
|
|
1856
|
+
ownerWindow.document.addEventListener("mousemove", handlePointerMove, true);
|
|
1857
|
+
return () => {
|
|
1858
|
+
ownerWindow.document.removeEventListener("pointermove", handlePointerMove, true);
|
|
1859
|
+
ownerWindow.document.removeEventListener("mousemove", handlePointerMove, true);
|
|
1860
|
+
};
|
|
1861
|
+
}, [ownerWindow, settings.edgeReveal]);
|
|
1862
|
+
const showRulers = !settings.edgeReveal || nearEdge;
|
|
709
1863
|
const beginGuideDrag = (orientation, event) => {
|
|
710
1864
|
if (event.button !== 0) return;
|
|
711
1865
|
event.stopPropagation();
|
|
@@ -755,13 +1909,18 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
755
1909
|
const selectedHorizontalGuides = guides.filter(
|
|
756
1910
|
(guide) => guide.orientation === "horizontal" && selectedGuideIds.includes(guide.id)
|
|
757
1911
|
);
|
|
758
|
-
return /* @__PURE__ */
|
|
1912
|
+
return /* @__PURE__ */ jsxs6(
|
|
759
1913
|
"div",
|
|
760
1914
|
{
|
|
761
1915
|
"aria-hidden": "true",
|
|
1916
|
+
"data-mesurer-rulers": "true",
|
|
762
1917
|
className: "msr:pointer-events-none msr:absolute msr:inset-0 msr:select-none msr:text-[9px] msr:text-[#64748b]",
|
|
1918
|
+
style: {
|
|
1919
|
+
opacity: showRulers ? settings.opacity : 0,
|
|
1920
|
+
transition: `opacity ${RULER_FADE_MS}ms ease`
|
|
1921
|
+
},
|
|
763
1922
|
children: [
|
|
764
|
-
/* @__PURE__ */
|
|
1923
|
+
/* @__PURE__ */ jsx6(
|
|
765
1924
|
"div",
|
|
766
1925
|
{
|
|
767
1926
|
className: "msr:absolute msr:left-[18px] msr:right-0 msr:top-0 msr:overflow-hidden msr:bg-white",
|
|
@@ -769,13 +1928,13 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
769
1928
|
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.12)",
|
|
770
1929
|
height: RULER_SIZE,
|
|
771
1930
|
cursor: "ns-resize",
|
|
772
|
-
pointerEvents: "auto"
|
|
1931
|
+
pointerEvents: showRulers ? "auto" : "none"
|
|
773
1932
|
},
|
|
774
1933
|
onPointerDown: (event) => beginGuideDrag("horizontal", event),
|
|
775
1934
|
onPointerMove: moveGuide,
|
|
776
1935
|
onPointerUp: finishGuideDrag,
|
|
777
1936
|
onPointerCancel: cancelGuideDrag,
|
|
778
|
-
children: /* @__PURE__ */
|
|
1937
|
+
children: /* @__PURE__ */ jsxs6(
|
|
779
1938
|
"svg",
|
|
780
1939
|
{
|
|
781
1940
|
className: "msr:block msr:h-6",
|
|
@@ -783,7 +1942,7 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
783
1942
|
height: RULER_SIZE,
|
|
784
1943
|
viewBox: `0 0 ${RULER_LENGTH} ${RULER_SIZE}`,
|
|
785
1944
|
children: [
|
|
786
|
-
/* @__PURE__ */
|
|
1945
|
+
/* @__PURE__ */ jsx6("defs", { children: /* @__PURE__ */ jsxs6(
|
|
787
1946
|
"linearGradient",
|
|
788
1947
|
{
|
|
789
1948
|
id: "ruler-label-fade-x",
|
|
@@ -791,18 +1950,18 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
791
1950
|
x2: "100%",
|
|
792
1951
|
gradientUnits: "objectBoundingBox",
|
|
793
1952
|
children: [
|
|
794
|
-
/* @__PURE__ */
|
|
795
|
-
/* @__PURE__ */
|
|
796
|
-
/* @__PURE__ */
|
|
797
|
-
/* @__PURE__ */
|
|
1953
|
+
/* @__PURE__ */ jsx6("stop", { offset: "0", stopColor: "white", stopOpacity: "0" }),
|
|
1954
|
+
/* @__PURE__ */ jsx6("stop", { offset: "0.2", stopColor: "white" }),
|
|
1955
|
+
/* @__PURE__ */ jsx6("stop", { offset: "0.8", stopColor: "white" }),
|
|
1956
|
+
/* @__PURE__ */ jsx6("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
|
|
798
1957
|
]
|
|
799
1958
|
}
|
|
800
1959
|
) }),
|
|
801
1960
|
ticks.map((x) => {
|
|
802
1961
|
const major = x % 100 === 0;
|
|
803
1962
|
const medium = x % 50 === 0;
|
|
804
|
-
return /* @__PURE__ */
|
|
805
|
-
/* @__PURE__ */
|
|
1963
|
+
return /* @__PURE__ */ jsxs6("g", { children: [
|
|
1964
|
+
/* @__PURE__ */ jsx6(
|
|
806
1965
|
"line",
|
|
807
1966
|
{
|
|
808
1967
|
x1: x,
|
|
@@ -813,11 +1972,11 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
813
1972
|
strokeWidth: "1"
|
|
814
1973
|
}
|
|
815
1974
|
),
|
|
816
|
-
major ? /* @__PURE__ */
|
|
1975
|
+
major ? /* @__PURE__ */ jsx6("text", { x, y: "8", textAnchor: "middle", fill: "currentColor", children: x }) : null
|
|
817
1976
|
] }, x);
|
|
818
1977
|
}),
|
|
819
|
-
selectedVerticalGuides.map((guide) => /* @__PURE__ */
|
|
820
|
-
/* @__PURE__ */
|
|
1978
|
+
selectedVerticalGuides.map((guide) => /* @__PURE__ */ jsxs6("g", { children: [
|
|
1979
|
+
/* @__PURE__ */ jsx6(
|
|
821
1980
|
"rect",
|
|
822
1981
|
{
|
|
823
1982
|
x: guide.position - RULER_SIZE - 8,
|
|
@@ -827,7 +1986,7 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
827
1986
|
fill: "url(#ruler-label-fade-x)"
|
|
828
1987
|
}
|
|
829
1988
|
),
|
|
830
|
-
/* @__PURE__ */
|
|
1989
|
+
/* @__PURE__ */ jsx6(
|
|
831
1990
|
"text",
|
|
832
1991
|
{
|
|
833
1992
|
x: guide.position - RULER_SIZE + 16,
|
|
@@ -839,8 +1998,8 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
839
1998
|
}
|
|
840
1999
|
)
|
|
841
2000
|
] }, guide.id)),
|
|
842
|
-
dragOrientation === "vertical" && dragPosition !== null ? /* @__PURE__ */
|
|
843
|
-
/* @__PURE__ */
|
|
2001
|
+
dragOrientation === "vertical" && dragPosition !== null ? /* @__PURE__ */ jsxs6("g", { children: [
|
|
2002
|
+
/* @__PURE__ */ jsx6(
|
|
844
2003
|
"rect",
|
|
845
2004
|
{
|
|
846
2005
|
x: dragPosition - RULER_SIZE - 8,
|
|
@@ -850,7 +2009,7 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
850
2009
|
fill: "url(#ruler-label-fade-x)"
|
|
851
2010
|
}
|
|
852
2011
|
),
|
|
853
|
-
/* @__PURE__ */
|
|
2012
|
+
/* @__PURE__ */ jsx6(
|
|
854
2013
|
"text",
|
|
855
2014
|
{
|
|
856
2015
|
x: dragPosition - RULER_SIZE + 16,
|
|
@@ -867,7 +2026,7 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
867
2026
|
)
|
|
868
2027
|
}
|
|
869
2028
|
),
|
|
870
|
-
/* @__PURE__ */
|
|
2029
|
+
/* @__PURE__ */ jsx6(
|
|
871
2030
|
"div",
|
|
872
2031
|
{
|
|
873
2032
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:top-[18px] msr:w-[18px] msr:overflow-hidden msr:bg-white",
|
|
@@ -875,13 +2034,13 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
875
2034
|
boxShadow: "1px 0 3px rgba(0, 0, 0, 0.12)",
|
|
876
2035
|
width: RULER_SIZE,
|
|
877
2036
|
cursor: "ew-resize",
|
|
878
|
-
pointerEvents: "auto"
|
|
2037
|
+
pointerEvents: showRulers ? "auto" : "none"
|
|
879
2038
|
},
|
|
880
2039
|
onPointerDown: (event) => beginGuideDrag("vertical", event),
|
|
881
2040
|
onPointerMove: moveGuide,
|
|
882
2041
|
onPointerUp: finishGuideDrag,
|
|
883
2042
|
onPointerCancel: cancelGuideDrag,
|
|
884
|
-
children: /* @__PURE__ */
|
|
2043
|
+
children: /* @__PURE__ */ jsxs6(
|
|
885
2044
|
"svg",
|
|
886
2045
|
{
|
|
887
2046
|
className: "msr:block msr:w-6",
|
|
@@ -889,7 +2048,7 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
889
2048
|
height: RULER_LENGTH,
|
|
890
2049
|
viewBox: `0 0 ${RULER_SIZE} ${RULER_LENGTH}`,
|
|
891
2050
|
children: [
|
|
892
|
-
/* @__PURE__ */
|
|
2051
|
+
/* @__PURE__ */ jsx6("defs", { children: /* @__PURE__ */ jsxs6(
|
|
893
2052
|
"linearGradient",
|
|
894
2053
|
{
|
|
895
2054
|
id: "ruler-label-fade-y",
|
|
@@ -897,18 +2056,18 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
897
2056
|
y2: "100%",
|
|
898
2057
|
gradientUnits: "objectBoundingBox",
|
|
899
2058
|
children: [
|
|
900
|
-
/* @__PURE__ */
|
|
901
|
-
/* @__PURE__ */
|
|
902
|
-
/* @__PURE__ */
|
|
903
|
-
/* @__PURE__ */
|
|
2059
|
+
/* @__PURE__ */ jsx6("stop", { offset: "0", stopColor: "white", stopOpacity: "0" }),
|
|
2060
|
+
/* @__PURE__ */ jsx6("stop", { offset: "0.2", stopColor: "white" }),
|
|
2061
|
+
/* @__PURE__ */ jsx6("stop", { offset: "0.8", stopColor: "white" }),
|
|
2062
|
+
/* @__PURE__ */ jsx6("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
|
|
904
2063
|
]
|
|
905
2064
|
}
|
|
906
2065
|
) }),
|
|
907
2066
|
ticks.map((y) => {
|
|
908
2067
|
const major = y % 100 === 0;
|
|
909
2068
|
const medium = y % 50 === 0;
|
|
910
|
-
return /* @__PURE__ */
|
|
911
|
-
/* @__PURE__ */
|
|
2069
|
+
return /* @__PURE__ */ jsxs6("g", { children: [
|
|
2070
|
+
/* @__PURE__ */ jsx6(
|
|
912
2071
|
"line",
|
|
913
2072
|
{
|
|
914
2073
|
x1: RULER_SIZE,
|
|
@@ -919,7 +2078,7 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
919
2078
|
strokeWidth: "1"
|
|
920
2079
|
}
|
|
921
2080
|
),
|
|
922
|
-
major ? /* @__PURE__ */
|
|
2081
|
+
major ? /* @__PURE__ */ jsx6(
|
|
923
2082
|
"text",
|
|
924
2083
|
{
|
|
925
2084
|
x: "8",
|
|
@@ -931,8 +2090,8 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
931
2090
|
) : null
|
|
932
2091
|
] }, y);
|
|
933
2092
|
}),
|
|
934
|
-
selectedHorizontalGuides.map((guide) => /* @__PURE__ */
|
|
935
|
-
/* @__PURE__ */
|
|
2093
|
+
selectedHorizontalGuides.map((guide) => /* @__PURE__ */ jsxs6("g", { children: [
|
|
2094
|
+
/* @__PURE__ */ jsx6(
|
|
936
2095
|
"rect",
|
|
937
2096
|
{
|
|
938
2097
|
x: "-3",
|
|
@@ -942,7 +2101,7 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
942
2101
|
fill: "url(#ruler-label-fade-y)"
|
|
943
2102
|
}
|
|
944
2103
|
),
|
|
945
|
-
/* @__PURE__ */
|
|
2104
|
+
/* @__PURE__ */ jsx6(
|
|
946
2105
|
"text",
|
|
947
2106
|
{
|
|
948
2107
|
x: "9",
|
|
@@ -955,8 +2114,8 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
955
2114
|
}
|
|
956
2115
|
)
|
|
957
2116
|
] }, guide.id)),
|
|
958
|
-
dragOrientation === "horizontal" && dragPosition !== null ? /* @__PURE__ */
|
|
959
|
-
/* @__PURE__ */
|
|
2117
|
+
dragOrientation === "horizontal" && dragPosition !== null ? /* @__PURE__ */ jsxs6("g", { children: [
|
|
2118
|
+
/* @__PURE__ */ jsx6(
|
|
960
2119
|
"rect",
|
|
961
2120
|
{
|
|
962
2121
|
x: "-3",
|
|
@@ -966,7 +2125,7 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
966
2125
|
fill: "url(#ruler-label-fade-y)"
|
|
967
2126
|
}
|
|
968
2127
|
),
|
|
969
|
-
/* @__PURE__ */
|
|
2128
|
+
/* @__PURE__ */ jsx6(
|
|
970
2129
|
"text",
|
|
971
2130
|
{
|
|
972
2131
|
x: "9",
|
|
@@ -984,34 +2143,34 @@ var RulersOverlay = memo2(function RulersOverlay2({
|
|
|
984
2143
|
)
|
|
985
2144
|
}
|
|
986
2145
|
),
|
|
987
|
-
/* @__PURE__ */
|
|
2146
|
+
/* @__PURE__ */ jsx6("div", { className: "msr:absolute msr:left-0 msr:top-0 msr:size-[18px] msr:bg-white" })
|
|
988
2147
|
]
|
|
989
2148
|
}
|
|
990
2149
|
);
|
|
991
2150
|
});
|
|
992
2151
|
|
|
993
2152
|
// hooks/use-drag-state.ts
|
|
994
|
-
import { useState as
|
|
2153
|
+
import { useState as useState6 } from "react";
|
|
995
2154
|
var useDragState = () => {
|
|
996
|
-
const [start, setStart] =
|
|
997
|
-
const [end, setEnd] =
|
|
998
|
-
const [isDragging, setIsDragging] =
|
|
2155
|
+
const [start, setStart] = useState6(null);
|
|
2156
|
+
const [end, setEnd] = useState6(null);
|
|
2157
|
+
const [isDragging, setIsDragging] = useState6(false);
|
|
999
2158
|
return { start, setStart, end, setEnd, isDragging, setIsDragging };
|
|
1000
2159
|
};
|
|
1001
2160
|
|
|
1002
2161
|
// hooks/use-guide-drag-hold.ts
|
|
1003
|
-
import { useCallback as
|
|
2162
|
+
import { useCallback as useCallback4, useRef as useRef5 } from "react";
|
|
1004
2163
|
var useGuideDragHold = (eventTarget) => {
|
|
1005
|
-
const guideDragHoldTimerRef =
|
|
1006
|
-
const guideDragHoldGuideIdRef =
|
|
1007
|
-
const clearGuideDragHold =
|
|
2164
|
+
const guideDragHoldTimerRef = useRef5(null);
|
|
2165
|
+
const guideDragHoldGuideIdRef = useRef5(null);
|
|
2166
|
+
const clearGuideDragHold = useCallback4(() => {
|
|
1008
2167
|
if (guideDragHoldTimerRef.current !== null) {
|
|
1009
2168
|
eventTarget.clearTimeout(guideDragHoldTimerRef.current);
|
|
1010
2169
|
guideDragHoldTimerRef.current = null;
|
|
1011
2170
|
}
|
|
1012
2171
|
guideDragHoldGuideIdRef.current = null;
|
|
1013
2172
|
}, []);
|
|
1014
|
-
const scheduleGuideDragHold =
|
|
2173
|
+
const scheduleGuideDragHold = useCallback4(
|
|
1015
2174
|
(id, onHold) => {
|
|
1016
2175
|
clearGuideDragHold();
|
|
1017
2176
|
guideDragHoldGuideIdRef.current = id;
|
|
@@ -1030,11 +2189,11 @@ var useGuideDragHold = (eventTarget) => {
|
|
|
1030
2189
|
};
|
|
1031
2190
|
|
|
1032
2191
|
// hooks/use-guide-state.ts
|
|
1033
|
-
import { useState as
|
|
2192
|
+
import { useState as useState7 } from "react";
|
|
1034
2193
|
var useGuideState = (options = {}) => {
|
|
1035
|
-
const [guides, setGuides] =
|
|
1036
|
-
const [draggingGuideId, setDraggingGuideId] =
|
|
1037
|
-
const [selectedGuideIds, setSelectedGuideIds] =
|
|
2194
|
+
const [guides, setGuides] = useState7(options.initialGuides ?? []);
|
|
2195
|
+
const [draggingGuideId, setDraggingGuideId] = useState7(null);
|
|
2196
|
+
const [selectedGuideIds, setSelectedGuideIds] = useState7(
|
|
1038
2197
|
options.initialSelectedGuideIds ?? []
|
|
1039
2198
|
);
|
|
1040
2199
|
return {
|
|
@@ -1048,67 +2207,91 @@ var useGuideState = (options = {}) => {
|
|
|
1048
2207
|
};
|
|
1049
2208
|
|
|
1050
2209
|
// hooks/use-hotkeys.ts
|
|
1051
|
-
import { useEffect } from "react";
|
|
2210
|
+
import { useEffect as useEffect3, useRef as useRef6 } from "react";
|
|
1052
2211
|
var useHotkeys = (options) => {
|
|
1053
|
-
|
|
2212
|
+
const optionsRef = useRef6(options);
|
|
2213
|
+
optionsRef.current = options;
|
|
2214
|
+
useEffect3(() => {
|
|
1054
2215
|
const target = options.eventTarget;
|
|
1055
2216
|
const handleKeyDown = (event) => {
|
|
2217
|
+
const current = optionsRef.current;
|
|
1056
2218
|
if (event.key === "Escape") {
|
|
1057
|
-
|
|
2219
|
+
if (current.isSettingsOpen()) {
|
|
2220
|
+
current.onToggleSettings();
|
|
2221
|
+
return;
|
|
2222
|
+
}
|
|
2223
|
+
if (current.isColorPickerActive()) {
|
|
2224
|
+
current.onCloseColorPicker();
|
|
2225
|
+
return;
|
|
2226
|
+
}
|
|
2227
|
+
current.clearAll();
|
|
1058
2228
|
return;
|
|
1059
2229
|
}
|
|
1060
2230
|
if (event.metaKey || event.ctrlKey) {
|
|
2231
|
+
if (event.key === ",") {
|
|
2232
|
+
event.preventDefault();
|
|
2233
|
+
current.onToggleSettings();
|
|
2234
|
+
current.onInteract();
|
|
2235
|
+
return;
|
|
2236
|
+
}
|
|
1061
2237
|
if (event.key.toLowerCase() !== "z") return;
|
|
1062
2238
|
if (event.shiftKey) {
|
|
1063
2239
|
event.preventDefault();
|
|
1064
|
-
|
|
2240
|
+
current.redo();
|
|
1065
2241
|
return;
|
|
1066
2242
|
}
|
|
1067
2243
|
event.preventDefault();
|
|
1068
|
-
|
|
2244
|
+
current.undo();
|
|
1069
2245
|
return;
|
|
1070
2246
|
}
|
|
1071
2247
|
if (event.key.toLowerCase() === "m") {
|
|
1072
|
-
|
|
2248
|
+
current.setEnabled((prev) => !prev);
|
|
1073
2249
|
}
|
|
1074
2250
|
const key = event.key.toLowerCase();
|
|
1075
|
-
if (
|
|
2251
|
+
if (key === "p") {
|
|
2252
|
+
event.preventDefault();
|
|
2253
|
+
current.onColorPicker();
|
|
2254
|
+
current.onInteract();
|
|
2255
|
+
return;
|
|
2256
|
+
}
|
|
2257
|
+
if (key === "x") {
|
|
2258
|
+
current.onToggleXray();
|
|
2259
|
+
current.onInteract();
|
|
2260
|
+
return;
|
|
2261
|
+
}
|
|
2262
|
+
if (current.isOverlayActive()) {
|
|
1076
2263
|
if (key === "a") {
|
|
1077
|
-
|
|
2264
|
+
current.setToolMode(
|
|
1078
2265
|
(prev) => prev === "text-inspector" ? "none" : "text-inspector"
|
|
1079
2266
|
);
|
|
1080
|
-
|
|
2267
|
+
current.onInteract();
|
|
1081
2268
|
}
|
|
1082
2269
|
if (key === "s") {
|
|
1083
|
-
|
|
1084
|
-
|
|
2270
|
+
current.setToolMode((prev) => prev === "select" ? "none" : "select");
|
|
2271
|
+
current.onInteract();
|
|
1085
2272
|
}
|
|
1086
2273
|
if (key === "g") {
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
}
|
|
1090
|
-
if (key === "x") {
|
|
1091
|
-
options.setToolMode((prev) => prev === "xray" ? "none" : "xray");
|
|
1092
|
-
options.onInteract();
|
|
2274
|
+
current.setToolMode((prev) => prev === "guides" ? "none" : "guides");
|
|
2275
|
+
current.onInteract();
|
|
1093
2276
|
}
|
|
1094
2277
|
if (key === "r") {
|
|
1095
|
-
|
|
1096
|
-
|
|
2278
|
+
current.setRulersVisible((prev) => !prev);
|
|
2279
|
+
current.onInteract();
|
|
1097
2280
|
}
|
|
1098
2281
|
if (key === "h") {
|
|
1099
|
-
|
|
1100
|
-
|
|
2282
|
+
current.setGuideOrientation("horizontal");
|
|
2283
|
+
current.onInteract();
|
|
1101
2284
|
}
|
|
1102
2285
|
if (key === "v") {
|
|
1103
|
-
|
|
1104
|
-
|
|
2286
|
+
current.setGuideOrientation("vertical");
|
|
2287
|
+
current.onInteract();
|
|
1105
2288
|
}
|
|
1106
2289
|
}
|
|
1107
2290
|
if (event.key === "Alt") {
|
|
1108
|
-
|
|
2291
|
+
current.setAltPressed(true);
|
|
1109
2292
|
}
|
|
1110
2293
|
if (event.key === "Backspace" || event.key === "Delete") {
|
|
1111
|
-
const removed =
|
|
2294
|
+
const removed = current.removeSelectedGuides();
|
|
1112
2295
|
if (removed) {
|
|
1113
2296
|
event.preventDefault();
|
|
1114
2297
|
}
|
|
@@ -1116,7 +2299,7 @@ var useHotkeys = (options) => {
|
|
|
1116
2299
|
};
|
|
1117
2300
|
const handleKeyUp = (event) => {
|
|
1118
2301
|
if (event.key === "Alt") {
|
|
1119
|
-
|
|
2302
|
+
optionsRef.current.setAltPressed(false);
|
|
1120
2303
|
}
|
|
1121
2304
|
};
|
|
1122
2305
|
target.addEventListener("keydown", handleKeyDown);
|
|
@@ -1125,11 +2308,11 @@ var useHotkeys = (options) => {
|
|
|
1125
2308
|
target.removeEventListener("keydown", handleKeyDown);
|
|
1126
2309
|
target.removeEventListener("keyup", handleKeyUp);
|
|
1127
2310
|
};
|
|
1128
|
-
}, [options]);
|
|
2311
|
+
}, [options.eventTarget]);
|
|
1129
2312
|
};
|
|
1130
2313
|
|
|
1131
2314
|
// hooks/use-live-element-tracking.ts
|
|
1132
|
-
import { useEffect as
|
|
2315
|
+
import { useEffect as useEffect4, useRef as useRef7 } from "react";
|
|
1133
2316
|
|
|
1134
2317
|
// core/geometry.ts
|
|
1135
2318
|
var getViewportSize = (ownerWindow) => ({
|
|
@@ -1155,7 +2338,7 @@ var getRectFromPoints = (start, end) => {
|
|
|
1155
2338
|
const height = Math.abs(start.y - end.y);
|
|
1156
2339
|
return { left, top, width, height };
|
|
1157
2340
|
};
|
|
1158
|
-
var
|
|
2341
|
+
var clamp2 = (value, min, max) => Math.max(min, Math.min(max, value));
|
|
1159
2342
|
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;
|
|
1160
2343
|
var rectArea = (rect) => rect.width * rect.height;
|
|
1161
2344
|
var intersectionArea = (rectA, rectB) => {
|
|
@@ -1219,10 +2402,10 @@ var getDistanceOverlay = (rectA, rectB, elementRefA, elementRefB, ownerWindow =
|
|
|
1219
2402
|
}
|
|
1220
2403
|
}
|
|
1221
2404
|
const normalizedConnectors = connectors.map((segment) => ({
|
|
1222
|
-
x1:
|
|
1223
|
-
y1:
|
|
1224
|
-
x2:
|
|
1225
|
-
y2:
|
|
2405
|
+
x1: clamp2(segment.x1, 0, ownerWindow.innerWidth),
|
|
2406
|
+
y1: clamp2(segment.y1, 0, ownerWindow.innerHeight),
|
|
2407
|
+
x2: clamp2(segment.x2, 0, ownerWindow.innerWidth),
|
|
2408
|
+
y2: clamp2(segment.y2, 0, ownerWindow.innerHeight)
|
|
1226
2409
|
})).filter(
|
|
1227
2410
|
(segment) => Math.abs(segment.x1 - segment.x2) > 0.5 || Math.abs(segment.y1 - segment.y2) > 0.5
|
|
1228
2411
|
);
|
|
@@ -1389,19 +2572,23 @@ var updateMeasurementForResize = (measurement, viewport = getViewportSize(), own
|
|
|
1389
2572
|
|
|
1390
2573
|
// hooks/use-live-element-tracking.ts
|
|
1391
2574
|
var useLiveElementTracking = (params) => {
|
|
1392
|
-
const
|
|
1393
|
-
|
|
2575
|
+
const paramsRef = useRef7(params);
|
|
2576
|
+
paramsRef.current = params;
|
|
2577
|
+
const frameRef = useRef7(null);
|
|
2578
|
+
useEffect4(() => {
|
|
2579
|
+
const ownerWindow = params.window;
|
|
1394
2580
|
if (!params.enabled) {
|
|
1395
2581
|
if (frameRef.current) {
|
|
1396
|
-
|
|
2582
|
+
ownerWindow.cancelAnimationFrame(frameRef.current);
|
|
1397
2583
|
}
|
|
1398
2584
|
frameRef.current = null;
|
|
1399
2585
|
return;
|
|
1400
2586
|
}
|
|
1401
2587
|
const tick = () => {
|
|
1402
|
-
|
|
2588
|
+
const current = paramsRef.current;
|
|
2589
|
+
current.setMeasurements(
|
|
1403
2590
|
(prev) => prev.map((measurement) => {
|
|
1404
|
-
if (!measurement.elementRef || !
|
|
2591
|
+
if (!measurement.elementRef || !current.document.contains(measurement.elementRef)) {
|
|
1405
2592
|
return measurement;
|
|
1406
2593
|
}
|
|
1407
2594
|
const rect = getRectFromDom(measurement.elementRef);
|
|
@@ -1414,8 +2601,8 @@ var useLiveElementTracking = (params) => {
|
|
|
1414
2601
|
};
|
|
1415
2602
|
})
|
|
1416
2603
|
);
|
|
1417
|
-
|
|
1418
|
-
if (!prev?.elementRef || !
|
|
2604
|
+
current.setActiveMeasurement((prev) => {
|
|
2605
|
+
if (!prev?.elementRef || !current.document.contains(prev.elementRef))
|
|
1419
2606
|
return prev;
|
|
1420
2607
|
const rect = getRectFromDom(prev.elementRef);
|
|
1421
2608
|
if (rectAlmostEqual(rect, prev.rect)) return prev;
|
|
@@ -1426,10 +2613,10 @@ var useLiveElementTracking = (params) => {
|
|
|
1426
2613
|
originRect: void 0
|
|
1427
2614
|
};
|
|
1428
2615
|
});
|
|
1429
|
-
|
|
2616
|
+
current.setHeldDistances(
|
|
1430
2617
|
(prev) => prev.map((distance) => {
|
|
1431
|
-
const canTrackA = distance.elementRefA &&
|
|
1432
|
-
const canTrackB = distance.elementRefB &&
|
|
2618
|
+
const canTrackA = distance.elementRefA && current.document.contains(distance.elementRefA);
|
|
2619
|
+
const canTrackB = distance.elementRefB && current.document.contains(distance.elementRefB);
|
|
1433
2620
|
if (!canTrackA && !canTrackB) return distance;
|
|
1434
2621
|
const rectA = canTrackA ? getRectFromDom(distance.elementRefA) : distance.rectA;
|
|
1435
2622
|
const rectB = canTrackB ? getRectFromDom(distance.elementRefB) : distance.rectB;
|
|
@@ -1441,7 +2628,7 @@ var useLiveElementTracking = (params) => {
|
|
|
1441
2628
|
rectB,
|
|
1442
2629
|
distance.elementRefA,
|
|
1443
2630
|
distance.elementRefB,
|
|
1444
|
-
|
|
2631
|
+
ownerWindow
|
|
1445
2632
|
);
|
|
1446
2633
|
return {
|
|
1447
2634
|
...updated,
|
|
@@ -1449,62 +2636,71 @@ var useLiveElementTracking = (params) => {
|
|
|
1449
2636
|
};
|
|
1450
2637
|
})
|
|
1451
2638
|
);
|
|
1452
|
-
const selected =
|
|
1453
|
-
if (selected &&
|
|
1454
|
-
|
|
1455
|
-
const next = getInspectMeasurement(selected,
|
|
2639
|
+
const selected = current.selectedElementRef.current;
|
|
2640
|
+
if (current.selectionEnabled && selected && current.document.contains(selected)) {
|
|
2641
|
+
current.setSelectedMeasurement((prev) => {
|
|
2642
|
+
const next = getInspectMeasurement(selected, ownerWindow);
|
|
1456
2643
|
if (prev && rectAlmostEqual(prev.rect, next.rect)) return prev;
|
|
1457
2644
|
return next;
|
|
1458
2645
|
});
|
|
1459
2646
|
}
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
2647
|
+
if (current.selectionEnabled) {
|
|
2648
|
+
current.setSelectedMeasurements(
|
|
2649
|
+
(prev) => prev.map((measurement) => {
|
|
2650
|
+
if (!measurement.elementRef || !current.document.contains(measurement.elementRef)) {
|
|
2651
|
+
return measurement;
|
|
2652
|
+
}
|
|
2653
|
+
const next = getInspectMeasurement(measurement.elementRef, ownerWindow);
|
|
2654
|
+
if (rectAlmostEqual(next.rect, measurement.rect)) return measurement;
|
|
2655
|
+
return {
|
|
2656
|
+
...next,
|
|
2657
|
+
id: measurement.id
|
|
2658
|
+
};
|
|
2659
|
+
})
|
|
2660
|
+
);
|
|
2661
|
+
}
|
|
2662
|
+
const hover = current.hoverElementRef.current;
|
|
2663
|
+
if (current.selectionEnabled && hover && current.document.contains(hover)) {
|
|
1475
2664
|
const rect = getRectFromDom(hover);
|
|
1476
|
-
|
|
2665
|
+
current.setHoverRect(
|
|
1477
2666
|
(prev) => prev && rectAlmostEqual(prev, rect) ? prev : rect
|
|
1478
2667
|
);
|
|
1479
2668
|
}
|
|
1480
|
-
frameRef.current =
|
|
2669
|
+
frameRef.current = ownerWindow.requestAnimationFrame(tick);
|
|
1481
2670
|
};
|
|
1482
|
-
frameRef.current =
|
|
2671
|
+
frameRef.current = ownerWindow.requestAnimationFrame(tick);
|
|
1483
2672
|
return () => {
|
|
1484
2673
|
if (frameRef.current) {
|
|
1485
|
-
|
|
2674
|
+
ownerWindow.cancelAnimationFrame(frameRef.current);
|
|
1486
2675
|
}
|
|
1487
2676
|
frameRef.current = null;
|
|
1488
2677
|
};
|
|
1489
|
-
}, [params]);
|
|
2678
|
+
}, [params.enabled, params.window]);
|
|
1490
2679
|
};
|
|
1491
2680
|
|
|
1492
2681
|
// hooks/use-measure-toggles.ts
|
|
1493
|
-
import { useState as
|
|
2682
|
+
import { useState as useState8 } from "react";
|
|
1494
2683
|
var useMeasureToggles = (options = {}) => {
|
|
1495
|
-
const [enabled, setEnabled] =
|
|
1496
|
-
const [altPressed, setAltPressed] =
|
|
1497
|
-
const [toolMode, setToolMode] =
|
|
2684
|
+
const [enabled, setEnabled] = useState8(options.initialEnabled ?? true);
|
|
2685
|
+
const [altPressed, setAltPressed] = useState8(false);
|
|
2686
|
+
const [toolMode, setToolMode] = useState8(
|
|
1498
2687
|
options.initialToolMode ?? "none"
|
|
1499
2688
|
);
|
|
1500
|
-
const [rulersVisible, setRulersVisible] =
|
|
2689
|
+
const [rulersVisible, setRulersVisible] = useState8(
|
|
1501
2690
|
options.initialRulersVisible ?? false
|
|
1502
2691
|
);
|
|
1503
2692
|
const holdEnabled = false;
|
|
1504
|
-
const multiMeasureEnabled =
|
|
1505
|
-
|
|
2693
|
+
const [multiMeasureEnabled, setMultiMeasureEnabled] = useState8(
|
|
2694
|
+
options.initialMultiMeasureEnabled ?? false
|
|
2695
|
+
);
|
|
2696
|
+
const [snapGuidesEnabled, setSnapGuidesEnabled] = useState8(
|
|
2697
|
+
options.initialSnapGuidesEnabled ?? true
|
|
2698
|
+
);
|
|
2699
|
+
const [selectNewGuideEnabled, setSelectNewGuideEnabled] = useState8(
|
|
2700
|
+
options.initialSelectNewGuideEnabled ?? true
|
|
2701
|
+
);
|
|
1506
2702
|
const guidesEnabled = toolMode === "guides";
|
|
1507
|
-
const snapEnabled = true;
|
|
2703
|
+
const [snapEnabled, setSnapEnabled] = useState8(options.initialSnapEnabled ?? true);
|
|
1508
2704
|
return {
|
|
1509
2705
|
enabled,
|
|
1510
2706
|
setEnabled,
|
|
@@ -1518,21 +2714,26 @@ var useMeasureToggles = (options = {}) => {
|
|
|
1518
2714
|
guidesEnabled,
|
|
1519
2715
|
multiMeasureEnabled,
|
|
1520
2716
|
snapGuidesEnabled,
|
|
1521
|
-
|
|
2717
|
+
setSnapGuidesEnabled,
|
|
2718
|
+
selectNewGuideEnabled,
|
|
2719
|
+
setSelectNewGuideEnabled,
|
|
2720
|
+
snapEnabled,
|
|
2721
|
+
setSnapEnabled,
|
|
2722
|
+
setMultiMeasureEnabled
|
|
1522
2723
|
};
|
|
1523
2724
|
};
|
|
1524
2725
|
|
|
1525
2726
|
// hooks/use-measurement-state.ts
|
|
1526
|
-
import { useState as
|
|
2727
|
+
import { useState as useState9 } from "react";
|
|
1527
2728
|
var useMeasurementState = (options = {}) => {
|
|
1528
|
-
const [activeMeasurement, setActiveMeasurement] =
|
|
1529
|
-
const [measurements, setMeasurements] =
|
|
2729
|
+
const [activeMeasurement, setActiveMeasurement] = useState9(options.initialActiveMeasurement ?? null);
|
|
2730
|
+
const [measurements, setMeasurements] = useState9(
|
|
1530
2731
|
options.initialMeasurements ?? []
|
|
1531
2732
|
);
|
|
1532
|
-
const [selectedMeasurement, setSelectedMeasurement] =
|
|
1533
|
-
const [selectedMeasurements, setSelectedMeasurements] =
|
|
1534
|
-
const [hoverRect, setHoverRect] =
|
|
1535
|
-
const [heldDistances, setHeldDistances] =
|
|
2733
|
+
const [selectedMeasurement, setSelectedMeasurement] = useState9(null);
|
|
2734
|
+
const [selectedMeasurements, setSelectedMeasurements] = useState9([]);
|
|
2735
|
+
const [hoverRect, setHoverRect] = useState9(null);
|
|
2736
|
+
const [heldDistances, setHeldDistances] = useState9(
|
|
1536
2737
|
options.initialHeldDistances ?? []
|
|
1537
2738
|
);
|
|
1538
2739
|
return {
|
|
@@ -2022,7 +3223,7 @@ var useMeasurerDerived = ({
|
|
|
2022
3223
|
};
|
|
2023
3224
|
|
|
2024
3225
|
// hooks/use-measurer-history.ts
|
|
2025
|
-
import { useCallback as
|
|
3226
|
+
import { useCallback as useCallback5, useRef as useRef8 } from "react";
|
|
2026
3227
|
var HISTORY_LIMIT = 50;
|
|
2027
3228
|
var useMeasurerHistory = ({
|
|
2028
3229
|
toggles,
|
|
@@ -2068,10 +3269,10 @@ var useMeasurerHistory = ({
|
|
|
2068
3269
|
setSelectedElement,
|
|
2069
3270
|
clearSelectionRect
|
|
2070
3271
|
} = transient;
|
|
2071
|
-
const historyRef =
|
|
2072
|
-
const futureRef =
|
|
2073
|
-
const historySignatureRef =
|
|
2074
|
-
const captureSnapshot =
|
|
3272
|
+
const historyRef = useRef8([]);
|
|
3273
|
+
const futureRef = useRef8([]);
|
|
3274
|
+
const historySignatureRef = useRef8(null);
|
|
3275
|
+
const captureSnapshot = useCallback5(() => {
|
|
2075
3276
|
return {
|
|
2076
3277
|
enabled,
|
|
2077
3278
|
toolMode,
|
|
@@ -2098,7 +3299,7 @@ var useMeasurerHistory = ({
|
|
|
2098
3299
|
selectedMeasurements,
|
|
2099
3300
|
toolMode
|
|
2100
3301
|
]);
|
|
2101
|
-
const getSnapshotSignature =
|
|
3302
|
+
const getSnapshotSignature = useCallback5((snapshot) => {
|
|
2102
3303
|
const serializeRect = (rect) => `${Math.round(rect.left)}:${Math.round(rect.top)}:${Math.round(rect.width)}:${Math.round(rect.height)}`;
|
|
2103
3304
|
return [
|
|
2104
3305
|
snapshot.enabled ? "1" : "0",
|
|
@@ -2114,7 +3315,7 @@ var useMeasurerHistory = ({
|
|
|
2114
3315
|
snapshot.draggingGuideId ?? ""
|
|
2115
3316
|
].join("|");
|
|
2116
3317
|
}, []);
|
|
2117
|
-
const recordSnapshot =
|
|
3318
|
+
const recordSnapshot = useCallback5(() => {
|
|
2118
3319
|
const snapshot = captureSnapshot();
|
|
2119
3320
|
const signature = getSnapshotSignature(snapshot);
|
|
2120
3321
|
if (historySignatureRef.current === signature) return;
|
|
@@ -2125,7 +3326,7 @@ var useMeasurerHistory = ({
|
|
|
2125
3326
|
historyRef.current.shift();
|
|
2126
3327
|
}
|
|
2127
3328
|
}, [captureSnapshot, getSnapshotSignature]);
|
|
2128
|
-
const restoreSnapshot =
|
|
3329
|
+
const restoreSnapshot = useCallback5(
|
|
2129
3330
|
(snapshot) => {
|
|
2130
3331
|
setEnabled(snapshot.enabled);
|
|
2131
3332
|
setToolMode(snapshot.toolMode);
|
|
@@ -2170,7 +3371,7 @@ var useMeasurerHistory = ({
|
|
|
2170
3371
|
setHoverElement
|
|
2171
3372
|
]
|
|
2172
3373
|
);
|
|
2173
|
-
const undo =
|
|
3374
|
+
const undo = useCallback5(() => {
|
|
2174
3375
|
const previousSnapshot = historyRef.current.pop();
|
|
2175
3376
|
if (!previousSnapshot) return;
|
|
2176
3377
|
const currentSnapshot = captureSnapshot();
|
|
@@ -2181,7 +3382,7 @@ var useMeasurerHistory = ({
|
|
|
2181
3382
|
historySignatureRef.current = null;
|
|
2182
3383
|
restoreSnapshot(previousSnapshot);
|
|
2183
3384
|
}, [captureSnapshot, restoreSnapshot]);
|
|
2184
|
-
const redo =
|
|
3385
|
+
const redo = useCallback5(() => {
|
|
2185
3386
|
const nextSnapshot = futureRef.current.pop();
|
|
2186
3387
|
if (!nextSnapshot) return;
|
|
2187
3388
|
historyRef.current.push(captureSnapshot());
|
|
@@ -2191,7 +3392,7 @@ var useMeasurerHistory = ({
|
|
|
2191
3392
|
historySignatureRef.current = null;
|
|
2192
3393
|
restoreSnapshot(nextSnapshot);
|
|
2193
3394
|
}, [captureSnapshot, restoreSnapshot]);
|
|
2194
|
-
const setToolModeWithHistory =
|
|
3395
|
+
const setToolModeWithHistory = useCallback5(
|
|
2195
3396
|
(value) => {
|
|
2196
3397
|
setToolMode((prev) => {
|
|
2197
3398
|
const next = typeof value === "function" ? value(prev) : value;
|
|
@@ -2202,7 +3403,7 @@ var useMeasurerHistory = ({
|
|
|
2202
3403
|
},
|
|
2203
3404
|
[recordSnapshot, setToolMode]
|
|
2204
3405
|
);
|
|
2205
|
-
const setGuideOrientationWithHistory =
|
|
3406
|
+
const setGuideOrientationWithHistory = useCallback5(
|
|
2206
3407
|
(value) => {
|
|
2207
3408
|
setGuideOrientation((prev) => {
|
|
2208
3409
|
const next = typeof value === "function" ? value(prev) : value;
|
|
@@ -2213,7 +3414,7 @@ var useMeasurerHistory = ({
|
|
|
2213
3414
|
},
|
|
2214
3415
|
[recordSnapshot, setGuideOrientation]
|
|
2215
3416
|
);
|
|
2216
|
-
const setEnabledWithHistory =
|
|
3417
|
+
const setEnabledWithHistory = useCallback5(
|
|
2217
3418
|
(value) => {
|
|
2218
3419
|
setEnabled((prev) => {
|
|
2219
3420
|
const next = typeof value === "function" ? value(prev) : value;
|
|
@@ -2224,7 +3425,7 @@ var useMeasurerHistory = ({
|
|
|
2224
3425
|
},
|
|
2225
3426
|
[recordSnapshot, setEnabled]
|
|
2226
3427
|
);
|
|
2227
|
-
const createActionCommit =
|
|
3428
|
+
const createActionCommit = useCallback5(() => {
|
|
2228
3429
|
let committed = false;
|
|
2229
3430
|
return () => {
|
|
2230
3431
|
if (committed) return;
|
|
@@ -2244,35 +3445,35 @@ var useMeasurerHistory = ({
|
|
|
2244
3445
|
};
|
|
2245
3446
|
|
|
2246
3447
|
// hooks/use-measurer-local-state.ts
|
|
2247
|
-
import { useCallback as
|
|
3448
|
+
import { useCallback as useCallback6, useState as useState10 } from "react";
|
|
2248
3449
|
var useMeasurerLocalState = ({
|
|
2249
3450
|
selectedElementRef,
|
|
2250
3451
|
hoverElementRef,
|
|
2251
3452
|
selectionRectRef
|
|
2252
3453
|
}) => {
|
|
2253
|
-
const [selectionOriginRect, setSelectionOriginRect] =
|
|
3454
|
+
const [selectionOriginRect, setSelectionOriginRect] = useState10(
|
|
2254
3455
|
null
|
|
2255
3456
|
);
|
|
2256
|
-
const [hoverPointer, setHoverPointer] =
|
|
2257
|
-
const [hoverElement, setHoverElementState] =
|
|
3457
|
+
const [hoverPointer, setHoverPointer] = useState10(null);
|
|
3458
|
+
const [hoverElement, setHoverElementState] = useState10(
|
|
2258
3459
|
null
|
|
2259
3460
|
);
|
|
2260
|
-
const [selectedElement, setSelectedElementState] =
|
|
2261
|
-
const setSelectedElement =
|
|
3461
|
+
const [selectedElement, setSelectedElementState] = useState10(null);
|
|
3462
|
+
const setSelectedElement = useCallback6(
|
|
2262
3463
|
(element) => {
|
|
2263
3464
|
selectedElementRef.current = element;
|
|
2264
3465
|
setSelectedElementState(element);
|
|
2265
3466
|
},
|
|
2266
3467
|
[selectedElementRef]
|
|
2267
3468
|
);
|
|
2268
|
-
const setHoverElement =
|
|
3469
|
+
const setHoverElement = useCallback6(
|
|
2269
3470
|
(element) => {
|
|
2270
3471
|
hoverElementRef.current = element;
|
|
2271
3472
|
setHoverElementState(element);
|
|
2272
3473
|
},
|
|
2273
3474
|
[hoverElementRef]
|
|
2274
3475
|
);
|
|
2275
|
-
const clearSelectionRect =
|
|
3476
|
+
const clearSelectionRect = useCallback6(() => {
|
|
2276
3477
|
selectionRectRef.current = null;
|
|
2277
3478
|
setSelectionOriginRect(null);
|
|
2278
3479
|
}, [selectionRectRef]);
|
|
@@ -2290,7 +3491,7 @@ var useMeasurerLocalState = ({
|
|
|
2290
3491
|
};
|
|
2291
3492
|
|
|
2292
3493
|
// hooks/use-measurer-pointer.ts
|
|
2293
|
-
import { useCallback as
|
|
3494
|
+
import { useCallback as useCallback7, useEffect as useEffect5, useRef as useRef9 } from "react";
|
|
2294
3495
|
|
|
2295
3496
|
// core/targets.ts
|
|
2296
3497
|
var pickMultiTargets = (selectionRect, items) => {
|
|
@@ -2493,10 +3694,12 @@ var useMeasurerPointer = ({
|
|
|
2493
3694
|
clearGuideDragHold,
|
|
2494
3695
|
scheduleGuideDragHold,
|
|
2495
3696
|
enabled,
|
|
3697
|
+
settingsOpen,
|
|
2496
3698
|
toolMode,
|
|
2497
3699
|
guidesEnabled,
|
|
2498
3700
|
snapEnabled,
|
|
2499
3701
|
snapGuidesEnabled,
|
|
3702
|
+
selectNewGuideEnabled,
|
|
2500
3703
|
altPressed,
|
|
2501
3704
|
guideOrientation,
|
|
2502
3705
|
hoverHighlightEnabled,
|
|
@@ -2529,24 +3732,24 @@ var useMeasurerPointer = ({
|
|
|
2529
3732
|
setHoverPointer,
|
|
2530
3733
|
clearSelectionRect
|
|
2531
3734
|
}) => {
|
|
2532
|
-
const hoverFrameRef =
|
|
2533
|
-
const hoverPointRef =
|
|
2534
|
-
const selectionCacheRef =
|
|
3735
|
+
const hoverFrameRef = useRef9(null);
|
|
3736
|
+
const hoverPointRef = useRef9(null);
|
|
3737
|
+
const selectionCacheRef = useRef9({
|
|
2535
3738
|
key: "",
|
|
2536
3739
|
entries: [],
|
|
2537
3740
|
overlayNode: null,
|
|
2538
3741
|
frame: -1
|
|
2539
3742
|
});
|
|
2540
|
-
const shiftDragRef =
|
|
2541
|
-
const shiftToggleElementRef =
|
|
2542
|
-
|
|
3743
|
+
const shiftDragRef = useRef9(false);
|
|
3744
|
+
const shiftToggleElementRef = useRef9(null);
|
|
3745
|
+
useEffect5(() => {
|
|
2543
3746
|
return () => {
|
|
2544
3747
|
if (hoverFrameRef.current) {
|
|
2545
3748
|
window2.cancelAnimationFrame(hoverFrameRef.current);
|
|
2546
3749
|
}
|
|
2547
3750
|
};
|
|
2548
3751
|
}, []);
|
|
2549
|
-
const updateHoverTarget =
|
|
3752
|
+
const updateHoverTarget = useCallback7(
|
|
2550
3753
|
(point) => {
|
|
2551
3754
|
const target = getTargetElement(point, overlayRef.current, document2);
|
|
2552
3755
|
if (target) {
|
|
@@ -2565,18 +3768,19 @@ var useMeasurerPointer = ({
|
|
|
2565
3768
|
},
|
|
2566
3769
|
[document2, overlayRef, setHoverElement, setHoverRect]
|
|
2567
3770
|
);
|
|
2568
|
-
const updateHoverElement =
|
|
3771
|
+
const updateHoverElement = useCallback7(
|
|
2569
3772
|
(point) => {
|
|
2570
3773
|
const target = getTargetElement(point, overlayRef.current, document2);
|
|
2571
3774
|
setHoverElement(target);
|
|
2572
3775
|
},
|
|
2573
3776
|
[document2, overlayRef, setHoverElement]
|
|
2574
3777
|
);
|
|
2575
|
-
const handlePointerDown =
|
|
3778
|
+
const handlePointerDown = useCallback7(
|
|
2576
3779
|
(event) => {
|
|
2577
3780
|
const commit = createActionCommit();
|
|
2578
3781
|
const toolbarNode = toolbarRef.current;
|
|
2579
3782
|
if (toolbarNode && toolbarNode.contains(event.target)) return;
|
|
3783
|
+
if (settingsOpen) return;
|
|
2580
3784
|
if (!enabled || event.button !== 0) return;
|
|
2581
3785
|
if (toolMode === "none") return;
|
|
2582
3786
|
clearSelectionRect();
|
|
@@ -2601,7 +3805,11 @@ var useMeasurerPointer = ({
|
|
|
2601
3805
|
return;
|
|
2602
3806
|
}
|
|
2603
3807
|
if (guidesEnabled) {
|
|
3808
|
+
event.preventDefault();
|
|
2604
3809
|
commit();
|
|
3810
|
+
setStart(null);
|
|
3811
|
+
setEnd(null);
|
|
3812
|
+
setIsDragging(false);
|
|
2605
3813
|
const position = getSnapGuidePosition({
|
|
2606
3814
|
orientation: guideOrientation,
|
|
2607
3815
|
point,
|
|
@@ -2612,7 +3820,7 @@ var useMeasurerPointer = ({
|
|
|
2612
3820
|
document: document2
|
|
2613
3821
|
});
|
|
2614
3822
|
const id = createId();
|
|
2615
|
-
setSelectedGuideIds([id]);
|
|
3823
|
+
setSelectedGuideIds(selectNewGuideEnabled ? [id] : []);
|
|
2616
3824
|
setGuides((prev) => [
|
|
2617
3825
|
...prev,
|
|
2618
3826
|
{ id, orientation: guideOrientation, position }
|
|
@@ -2637,12 +3845,14 @@ var useMeasurerPointer = ({
|
|
|
2637
3845
|
draggingGuideId,
|
|
2638
3846
|
document2,
|
|
2639
3847
|
enabled,
|
|
3848
|
+
settingsOpen,
|
|
2640
3849
|
guideOrientation,
|
|
2641
3850
|
guides,
|
|
2642
3851
|
guidesEnabled,
|
|
2643
3852
|
optionPairOverlay,
|
|
2644
3853
|
overlayRef,
|
|
2645
3854
|
scheduleGuideDragHold,
|
|
3855
|
+
selectNewGuideEnabled,
|
|
2646
3856
|
selectedGuideIds.length,
|
|
2647
3857
|
selectedMeasurements,
|
|
2648
3858
|
setDraggingGuideId,
|
|
@@ -2657,10 +3867,11 @@ var useMeasurerPointer = ({
|
|
|
2657
3867
|
toolbarRef
|
|
2658
3868
|
]
|
|
2659
3869
|
);
|
|
2660
|
-
const handlePointerMove =
|
|
3870
|
+
const handlePointerMove = useCallback7(
|
|
2661
3871
|
(event) => {
|
|
2662
3872
|
const toolbarNode = toolbarRef.current;
|
|
2663
3873
|
if (toolbarNode && toolbarNode.contains(event.target)) return;
|
|
3874
|
+
if (settingsOpen) return;
|
|
2664
3875
|
if (!enabled) return;
|
|
2665
3876
|
if (toolMode === "none") {
|
|
2666
3877
|
if (hoverHighlightEnabled) {
|
|
@@ -2679,7 +3890,7 @@ var useMeasurerPointer = ({
|
|
|
2679
3890
|
if (!hoverFrameRef.current) {
|
|
2680
3891
|
hoverFrameRef.current = window2.requestAnimationFrame(() => {
|
|
2681
3892
|
const latest = hoverPointRef.current;
|
|
2682
|
-
if (latest && !draggingGuideId) {
|
|
3893
|
+
if (latest && !draggingGuideId && !guidesEnabled) {
|
|
2683
3894
|
if (hoverHighlightEnabled) {
|
|
2684
3895
|
updateHoverTarget(latest);
|
|
2685
3896
|
} else {
|
|
@@ -2729,6 +3940,7 @@ var useMeasurerPointer = ({
|
|
|
2729
3940
|
)
|
|
2730
3941
|
);
|
|
2731
3942
|
}
|
|
3943
|
+
if (guidesEnabled) return;
|
|
2732
3944
|
if (!start) return;
|
|
2733
3945
|
setEnd(point);
|
|
2734
3946
|
if (!isDragging) {
|
|
@@ -2744,6 +3956,7 @@ var useMeasurerPointer = ({
|
|
|
2744
3956
|
altPressed,
|
|
2745
3957
|
draggingGuideId,
|
|
2746
3958
|
enabled,
|
|
3959
|
+
settingsOpen,
|
|
2747
3960
|
hoverHighlightEnabled,
|
|
2748
3961
|
guides,
|
|
2749
3962
|
guidesEnabled,
|
|
@@ -2766,13 +3979,20 @@ var useMeasurerPointer = ({
|
|
|
2766
3979
|
updateHoverTarget
|
|
2767
3980
|
]
|
|
2768
3981
|
);
|
|
2769
|
-
const handlePointerUp =
|
|
3982
|
+
const handlePointerUp = useCallback7(
|
|
2770
3983
|
(event) => {
|
|
2771
3984
|
const commit = createActionCommit();
|
|
2772
3985
|
const toolbarNode = toolbarRef.current;
|
|
2773
3986
|
if (toolbarNode && toolbarNode.contains(event.target)) return;
|
|
3987
|
+
if (settingsOpen) return;
|
|
2774
3988
|
if (!enabled) return;
|
|
2775
3989
|
clearGuideDragHold();
|
|
3990
|
+
if (guidesEnabled) {
|
|
3991
|
+
setStart(null);
|
|
3992
|
+
setEnd(null);
|
|
3993
|
+
setIsDragging(false);
|
|
3994
|
+
return;
|
|
3995
|
+
}
|
|
2776
3996
|
if (toolMode === "none") {
|
|
2777
3997
|
setStart(null);
|
|
2778
3998
|
setEnd(null);
|
|
@@ -2943,7 +4163,9 @@ var useMeasurerPointer = ({
|
|
|
2943
4163
|
createActionCommit,
|
|
2944
4164
|
draggingGuideId,
|
|
2945
4165
|
enabled,
|
|
4166
|
+
settingsOpen,
|
|
2946
4167
|
end,
|
|
4168
|
+
guidesEnabled,
|
|
2947
4169
|
hoverHighlightEnabled,
|
|
2948
4170
|
isDragging,
|
|
2949
4171
|
overlayRef,
|
|
@@ -2966,7 +4188,7 @@ var useMeasurerPointer = ({
|
|
|
2966
4188
|
toolbarRef
|
|
2967
4189
|
]
|
|
2968
4190
|
);
|
|
2969
|
-
const handlePointerLeave =
|
|
4191
|
+
const handlePointerLeave = useCallback7(() => {
|
|
2970
4192
|
clearGuideDragHold();
|
|
2971
4193
|
setStart(null);
|
|
2972
4194
|
setEnd(null);
|
|
@@ -2990,54 +4212,58 @@ var useMeasurerPointer = ({
|
|
|
2990
4212
|
};
|
|
2991
4213
|
|
|
2992
4214
|
// hooks/use-overlay-refs.ts
|
|
2993
|
-
import { useRef as
|
|
4215
|
+
import { useRef as useRef10 } from "react";
|
|
2994
4216
|
var useOverlayRefs = () => {
|
|
2995
|
-
const overlayRef =
|
|
2996
|
-
const selectedElementRef =
|
|
2997
|
-
const hoverElementRef =
|
|
4217
|
+
const overlayRef = useRef10(null);
|
|
4218
|
+
const selectedElementRef = useRef10(null);
|
|
4219
|
+
const hoverElementRef = useRef10(null);
|
|
2998
4220
|
return { overlayRef, selectedElementRef, hoverElementRef };
|
|
2999
4221
|
};
|
|
3000
4222
|
|
|
3001
4223
|
// hooks/use-resize-sync.ts
|
|
3002
|
-
import { useEffect as
|
|
4224
|
+
import { useEffect as useEffect6, useRef as useRef11 } from "react";
|
|
3003
4225
|
var useResizeSync = (params) => {
|
|
3004
|
-
const
|
|
3005
|
-
|
|
3006
|
-
|
|
4226
|
+
const paramsRef = useRef11(params);
|
|
4227
|
+
paramsRef.current = params;
|
|
4228
|
+
const resizeFrameRef = useRef11(null);
|
|
4229
|
+
const viewportRef = useRef11(getViewportSize(params.window));
|
|
4230
|
+
useEffect6(() => {
|
|
4231
|
+
const ownerWindow = params.window;
|
|
3007
4232
|
const handleResize = () => {
|
|
4233
|
+
const current = paramsRef.current;
|
|
3008
4234
|
if (resizeFrameRef.current) {
|
|
3009
|
-
|
|
4235
|
+
ownerWindow.cancelAnimationFrame(resizeFrameRef.current);
|
|
3010
4236
|
}
|
|
3011
|
-
resizeFrameRef.current =
|
|
3012
|
-
const viewport = getViewportSize(
|
|
4237
|
+
resizeFrameRef.current = ownerWindow.requestAnimationFrame(() => {
|
|
4238
|
+
const viewport = getViewportSize(ownerWindow);
|
|
3013
4239
|
const previousViewport = viewportRef.current;
|
|
3014
|
-
|
|
4240
|
+
current.setMeasurements(
|
|
3015
4241
|
(prev) => prev.map(
|
|
3016
|
-
(measurement) => updateMeasurementForResize(measurement, viewport,
|
|
4242
|
+
(measurement) => updateMeasurementForResize(measurement, viewport, current.document)
|
|
3017
4243
|
)
|
|
3018
4244
|
);
|
|
3019
|
-
|
|
3020
|
-
(prev) => prev ? updateMeasurementForResize(prev, viewport,
|
|
4245
|
+
current.setActiveMeasurement(
|
|
4246
|
+
(prev) => prev ? updateMeasurementForResize(prev, viewport, current.document) : prev
|
|
3021
4247
|
);
|
|
3022
|
-
|
|
4248
|
+
current.setHeldDistances(
|
|
3023
4249
|
(prev) => prev.map(
|
|
3024
4250
|
(distance) => updateDistanceForResize(
|
|
3025
4251
|
distance,
|
|
3026
4252
|
viewport,
|
|
3027
|
-
|
|
3028
|
-
|
|
4253
|
+
current.document,
|
|
4254
|
+
ownerWindow
|
|
3029
4255
|
)
|
|
3030
4256
|
)
|
|
3031
4257
|
);
|
|
3032
|
-
if (
|
|
3033
|
-
|
|
3034
|
-
getInspectMeasurement(
|
|
4258
|
+
if (current.selectedElementRef.current && current.document.contains(current.selectedElementRef.current)) {
|
|
4259
|
+
current.setSelectedMeasurement(
|
|
4260
|
+
getInspectMeasurement(current.selectedElementRef.current, ownerWindow)
|
|
3035
4261
|
);
|
|
3036
4262
|
}
|
|
3037
4263
|
if (previousViewport.width > 0 && previousViewport.height > 0) {
|
|
3038
4264
|
const scaleX = viewport.width / previousViewport.width;
|
|
3039
4265
|
const scaleY = viewport.height / previousViewport.height;
|
|
3040
|
-
|
|
4266
|
+
current.setGuides(
|
|
3041
4267
|
(prev) => prev.map(
|
|
3042
4268
|
(guide) => guide.orientation === "vertical" ? { ...guide, position: guide.position * scaleX } : { ...guide, position: guide.position * scaleY }
|
|
3043
4269
|
)
|
|
@@ -3046,27 +4272,27 @@ var useResizeSync = (params) => {
|
|
|
3046
4272
|
viewportRef.current = viewport;
|
|
3047
4273
|
});
|
|
3048
4274
|
};
|
|
3049
|
-
|
|
4275
|
+
ownerWindow.addEventListener("resize", handleResize);
|
|
3050
4276
|
return () => {
|
|
3051
4277
|
if (resizeFrameRef.current) {
|
|
3052
|
-
|
|
4278
|
+
ownerWindow.cancelAnimationFrame(resizeFrameRef.current);
|
|
3053
4279
|
}
|
|
3054
|
-
|
|
4280
|
+
ownerWindow.removeEventListener("resize", handleResize);
|
|
3055
4281
|
};
|
|
3056
|
-
}, [params]);
|
|
4282
|
+
}, [params.window]);
|
|
3057
4283
|
};
|
|
3058
4284
|
|
|
3059
4285
|
// render/measurer-overlay.tsx
|
|
3060
4286
|
import { memo as memo6 } from "react";
|
|
3061
4287
|
|
|
3062
4288
|
// components/measure-tag.tsx
|
|
3063
|
-
import { jsx as
|
|
4289
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
3064
4290
|
function MeasureTag({
|
|
3065
4291
|
children,
|
|
3066
4292
|
className = "",
|
|
3067
4293
|
style
|
|
3068
4294
|
}) {
|
|
3069
|
-
return /* @__PURE__ */
|
|
4295
|
+
return /* @__PURE__ */ jsx7(
|
|
3070
4296
|
"div",
|
|
3071
4297
|
{
|
|
3072
4298
|
className: cn(
|
|
@@ -3081,20 +4307,20 @@ function MeasureTag({
|
|
|
3081
4307
|
|
|
3082
4308
|
// components/measurement-box.tsx
|
|
3083
4309
|
import { memo as memo3 } from "react";
|
|
3084
|
-
import { jsx as
|
|
4310
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
3085
4311
|
var formatValue2 = (value) => Math.round(value);
|
|
3086
4312
|
var MeasurementBox = memo3(function MeasurementBox2({
|
|
3087
4313
|
measurement,
|
|
3088
4314
|
transitionMs,
|
|
3089
4315
|
labelOffset,
|
|
3090
|
-
edgeVisibility
|
|
4316
|
+
edgeVisibility,
|
|
4317
|
+
outlineColor,
|
|
4318
|
+
fillColor
|
|
3091
4319
|
}) {
|
|
3092
4320
|
const edges = edgeVisibility ?? { top: true, right: true, bottom: true, left: true };
|
|
3093
4321
|
const displayRect = measurement.rect;
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
return /* @__PURE__ */ jsxs3("div", { className: "msr:pointer-events-none", children: [
|
|
3097
|
-
/* @__PURE__ */ jsxs3(
|
|
4322
|
+
return /* @__PURE__ */ jsxs7("div", { className: "msr:pointer-events-none", children: [
|
|
4323
|
+
/* @__PURE__ */ jsxs7(
|
|
3098
4324
|
"div",
|
|
3099
4325
|
{
|
|
3100
4326
|
className: "msr:absolute",
|
|
@@ -3107,28 +4333,28 @@ var MeasurementBox = memo3(function MeasurementBox2({
|
|
|
3107
4333
|
transition: `left ${transitionMs}ms ease, top ${transitionMs}ms ease, width ${transitionMs}ms ease, height ${transitionMs}ms ease`
|
|
3108
4334
|
},
|
|
3109
4335
|
children: [
|
|
3110
|
-
edges.top ? /* @__PURE__ */
|
|
4336
|
+
edges.top ? /* @__PURE__ */ jsx8(
|
|
3111
4337
|
"div",
|
|
3112
4338
|
{
|
|
3113
4339
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-px msr:w-full",
|
|
3114
4340
|
style: { backgroundColor: outlineColor }
|
|
3115
4341
|
}
|
|
3116
4342
|
) : null,
|
|
3117
|
-
edges.right ? /* @__PURE__ */
|
|
4343
|
+
edges.right ? /* @__PURE__ */ jsx8(
|
|
3118
4344
|
"div",
|
|
3119
4345
|
{
|
|
3120
4346
|
className: "msr:absolute msr:right-0 msr:top-0 msr:h-full msr:w-px",
|
|
3121
4347
|
style: { backgroundColor: outlineColor }
|
|
3122
4348
|
}
|
|
3123
4349
|
) : null,
|
|
3124
|
-
edges.bottom ? /* @__PURE__ */
|
|
4350
|
+
edges.bottom ? /* @__PURE__ */ jsx8(
|
|
3125
4351
|
"div",
|
|
3126
4352
|
{
|
|
3127
4353
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:h-px msr:w-full",
|
|
3128
4354
|
style: { backgroundColor: outlineColor }
|
|
3129
4355
|
}
|
|
3130
4356
|
) : null,
|
|
3131
|
-
edges.left ? /* @__PURE__ */
|
|
4357
|
+
edges.left ? /* @__PURE__ */ jsx8(
|
|
3132
4358
|
"div",
|
|
3133
4359
|
{
|
|
3134
4360
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-full msr:w-px",
|
|
@@ -3138,7 +4364,7 @@ var MeasurementBox = memo3(function MeasurementBox2({
|
|
|
3138
4364
|
]
|
|
3139
4365
|
}
|
|
3140
4366
|
),
|
|
3141
|
-
/* @__PURE__ */
|
|
4367
|
+
/* @__PURE__ */ jsxs7(
|
|
3142
4368
|
MeasureTag,
|
|
3143
4369
|
{
|
|
3144
4370
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3159,20 +4385,20 @@ var MeasurementBox = memo3(function MeasurementBox2({
|
|
|
3159
4385
|
|
|
3160
4386
|
// components/selected-measurement-box.tsx
|
|
3161
4387
|
import { memo as memo4 } from "react";
|
|
3162
|
-
import { jsx as
|
|
4388
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
3163
4389
|
var formatValue3 = (value) => Math.round(value);
|
|
3164
4390
|
var SelectedMeasurementBox = memo4(function SelectedMeasurementBox2({
|
|
3165
4391
|
measurement,
|
|
3166
4392
|
transitionMs,
|
|
3167
4393
|
labelOffset,
|
|
3168
|
-
edgeVisibility
|
|
4394
|
+
edgeVisibility,
|
|
4395
|
+
outlineColor,
|
|
4396
|
+
fillColor
|
|
3169
4397
|
}) {
|
|
3170
4398
|
const edges = edgeVisibility ?? { top: true, right: true, bottom: true, left: true };
|
|
3171
4399
|
const displayRect = measurement.rect;
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
return /* @__PURE__ */ jsxs4("div", { className: "msr:pointer-events-none", children: [
|
|
3175
|
-
/* @__PURE__ */ jsxs4(
|
|
4400
|
+
return /* @__PURE__ */ jsxs8("div", { className: "msr:pointer-events-none", "data-mesurer-selected-measurement": "true", children: [
|
|
4401
|
+
/* @__PURE__ */ jsxs8(
|
|
3176
4402
|
"div",
|
|
3177
4403
|
{
|
|
3178
4404
|
className: "msr:absolute",
|
|
@@ -3185,28 +4411,28 @@ var SelectedMeasurementBox = memo4(function SelectedMeasurementBox2({
|
|
|
3185
4411
|
transition: `left ${transitionMs}ms ease, top ${transitionMs}ms ease, width ${transitionMs}ms ease, height ${transitionMs}ms ease`
|
|
3186
4412
|
},
|
|
3187
4413
|
children: [
|
|
3188
|
-
edges.top ? /* @__PURE__ */
|
|
4414
|
+
edges.top ? /* @__PURE__ */ jsx9(
|
|
3189
4415
|
"div",
|
|
3190
4416
|
{
|
|
3191
4417
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-px msr:w-full",
|
|
3192
4418
|
style: { backgroundColor: outlineColor }
|
|
3193
4419
|
}
|
|
3194
4420
|
) : null,
|
|
3195
|
-
edges.right ? /* @__PURE__ */
|
|
4421
|
+
edges.right ? /* @__PURE__ */ jsx9(
|
|
3196
4422
|
"div",
|
|
3197
4423
|
{
|
|
3198
4424
|
className: "msr:absolute msr:right-0 msr:top-0 msr:h-full msr:w-px",
|
|
3199
4425
|
style: { backgroundColor: outlineColor }
|
|
3200
4426
|
}
|
|
3201
4427
|
) : null,
|
|
3202
|
-
edges.bottom ? /* @__PURE__ */
|
|
4428
|
+
edges.bottom ? /* @__PURE__ */ jsx9(
|
|
3203
4429
|
"div",
|
|
3204
4430
|
{
|
|
3205
4431
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:h-px msr:w-full",
|
|
3206
4432
|
style: { backgroundColor: outlineColor }
|
|
3207
4433
|
}
|
|
3208
4434
|
) : null,
|
|
3209
|
-
edges.left ? /* @__PURE__ */
|
|
4435
|
+
edges.left ? /* @__PURE__ */ jsx9(
|
|
3210
4436
|
"div",
|
|
3211
4437
|
{
|
|
3212
4438
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-full msr:w-px",
|
|
@@ -3216,7 +4442,7 @@ var SelectedMeasurementBox = memo4(function SelectedMeasurementBox2({
|
|
|
3216
4442
|
]
|
|
3217
4443
|
}
|
|
3218
4444
|
),
|
|
3219
|
-
/* @__PURE__ */
|
|
4445
|
+
/* @__PURE__ */ jsxs8(
|
|
3220
4446
|
MeasureTag,
|
|
3221
4447
|
{
|
|
3222
4448
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3237,13 +4463,13 @@ var SelectedMeasurementBox = memo4(function SelectedMeasurementBox2({
|
|
|
3237
4463
|
|
|
3238
4464
|
// render/distance-overlay-item.tsx
|
|
3239
4465
|
import { memo as memo5 } from "react";
|
|
3240
|
-
import { Fragment, jsx as
|
|
4466
|
+
import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3241
4467
|
var DistanceOverlayItem = memo5(function DistanceOverlayItem2({
|
|
3242
4468
|
distance,
|
|
3243
4469
|
labelOffset,
|
|
3244
4470
|
onRemove
|
|
3245
4471
|
}) {
|
|
3246
|
-
return /* @__PURE__ */
|
|
4472
|
+
return /* @__PURE__ */ jsxs9(
|
|
3247
4473
|
"div",
|
|
3248
4474
|
{
|
|
3249
4475
|
className: onRemove ? "msr:pointer-events-auto" : "msr:pointer-events-none",
|
|
@@ -3252,7 +4478,7 @@ var DistanceOverlayItem = memo5(function DistanceOverlayItem2({
|
|
|
3252
4478
|
onRemove(distance.id);
|
|
3253
4479
|
} : void 0,
|
|
3254
4480
|
children: [
|
|
3255
|
-
/* @__PURE__ */
|
|
4481
|
+
/* @__PURE__ */ jsx10(
|
|
3256
4482
|
"div",
|
|
3257
4483
|
{
|
|
3258
4484
|
className: "msr:absolute msr:rounded msr:border msr:border-[#2563eb]/70",
|
|
@@ -3264,7 +4490,7 @@ var DistanceOverlayItem = memo5(function DistanceOverlayItem2({
|
|
|
3264
4490
|
}
|
|
3265
4491
|
}
|
|
3266
4492
|
),
|
|
3267
|
-
/* @__PURE__ */
|
|
4493
|
+
/* @__PURE__ */ jsx10(
|
|
3268
4494
|
"div",
|
|
3269
4495
|
{
|
|
3270
4496
|
className: "msr:absolute msr:rounded msr:border msr:border-[#2563eb]/70",
|
|
@@ -3277,7 +4503,7 @@ var DistanceOverlayItem = memo5(function DistanceOverlayItem2({
|
|
|
3277
4503
|
}
|
|
3278
4504
|
),
|
|
3279
4505
|
distance.connectors.map(
|
|
3280
|
-
(connector, index) => Math.abs(connector.x1 - connector.x2) < 1 ? /* @__PURE__ */
|
|
4506
|
+
(connector, index) => Math.abs(connector.x1 - connector.x2) < 1 ? /* @__PURE__ */ jsx10(
|
|
3281
4507
|
"div",
|
|
3282
4508
|
{
|
|
3283
4509
|
className: "msr:absolute msr:border-l msr:border-dashed msr:border-[#2563eb]/70",
|
|
@@ -3288,7 +4514,7 @@ var DistanceOverlayItem = memo5(function DistanceOverlayItem2({
|
|
|
3288
4514
|
}
|
|
3289
4515
|
},
|
|
3290
4516
|
`${distance.id}-connector-${index}`
|
|
3291
|
-
) : /* @__PURE__ */
|
|
4517
|
+
) : /* @__PURE__ */ jsx10(
|
|
3292
4518
|
"div",
|
|
3293
4519
|
{
|
|
3294
4520
|
className: "msr:absolute msr:border-t msr:border-dashed msr:border-[#2563eb]/70",
|
|
@@ -3301,8 +4527,8 @@ var DistanceOverlayItem = memo5(function DistanceOverlayItem2({
|
|
|
3301
4527
|
`${distance.id}-connector-${index}`
|
|
3302
4528
|
)
|
|
3303
4529
|
),
|
|
3304
|
-
distance.horizontal && distance.horizontal.value > 0 ? /* @__PURE__ */
|
|
3305
|
-
/* @__PURE__ */
|
|
4530
|
+
distance.horizontal && distance.horizontal.value > 0 ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
4531
|
+
/* @__PURE__ */ jsx10(
|
|
3306
4532
|
"div",
|
|
3307
4533
|
{
|
|
3308
4534
|
className: "msr:absolute msr:h-px msr:bg-[#2563eb]",
|
|
@@ -3313,7 +4539,7 @@ var DistanceOverlayItem = memo5(function DistanceOverlayItem2({
|
|
|
3313
4539
|
}
|
|
3314
4540
|
}
|
|
3315
4541
|
),
|
|
3316
|
-
/* @__PURE__ */
|
|
4542
|
+
/* @__PURE__ */ jsx10(
|
|
3317
4543
|
MeasureTag,
|
|
3318
4544
|
{
|
|
3319
4545
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3325,8 +4551,8 @@ var DistanceOverlayItem = memo5(function DistanceOverlayItem2({
|
|
|
3325
4551
|
}
|
|
3326
4552
|
)
|
|
3327
4553
|
] }) : null,
|
|
3328
|
-
distance.vertical && distance.vertical.value > 0 ? /* @__PURE__ */
|
|
3329
|
-
/* @__PURE__ */
|
|
4554
|
+
distance.vertical && distance.vertical.value > 0 ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
4555
|
+
/* @__PURE__ */ jsx10(
|
|
3330
4556
|
"div",
|
|
3331
4557
|
{
|
|
3332
4558
|
className: "msr:absolute msr:w-px msr:bg-[#2563eb]",
|
|
@@ -3337,7 +4563,7 @@ var DistanceOverlayItem = memo5(function DistanceOverlayItem2({
|
|
|
3337
4563
|
}
|
|
3338
4564
|
}
|
|
3339
4565
|
),
|
|
3340
|
-
/* @__PURE__ */
|
|
4566
|
+
/* @__PURE__ */ jsx10(
|
|
3341
4567
|
MeasureTag,
|
|
3342
4568
|
{
|
|
3343
4569
|
className: "msr:-translate-y-1/2 msr:bg-ink-900/90",
|
|
@@ -3355,9 +4581,10 @@ var DistanceOverlayItem = memo5(function DistanceOverlayItem2({
|
|
|
3355
4581
|
});
|
|
3356
4582
|
|
|
3357
4583
|
// render/measurer-overlay.tsx
|
|
3358
|
-
import { Fragment as
|
|
4584
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3359
4585
|
var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
3360
4586
|
enabled,
|
|
4587
|
+
interactive = true,
|
|
3361
4588
|
toolMode,
|
|
3362
4589
|
guidePointerEvents,
|
|
3363
4590
|
guidesEnabled,
|
|
@@ -3387,6 +4614,7 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3387
4614
|
guideColorActive,
|
|
3388
4615
|
guideColorHover,
|
|
3389
4616
|
guideColorDefault,
|
|
4617
|
+
guideStyle,
|
|
3390
4618
|
onPointerDown,
|
|
3391
4619
|
onPointerMove,
|
|
3392
4620
|
onPointerUp,
|
|
@@ -3397,30 +4625,32 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3397
4625
|
onGuidePointerCancel
|
|
3398
4626
|
}) {
|
|
3399
4627
|
const overlayVisible = enabled;
|
|
3400
|
-
const overlayInteractive = overlayVisible && toolMode !== "none" && toolMode !== "text-inspector" && toolMode !== "xray" && toolMode !== "rulers";
|
|
3401
|
-
const selectionVisible = toolMode === "select";
|
|
3402
|
-
return /* @__PURE__ */
|
|
4628
|
+
const overlayInteractive = interactive && overlayVisible && toolMode !== "none" && toolMode !== "text-inspector" && toolMode !== "xray" && toolMode !== "rulers";
|
|
4629
|
+
const selectionVisible = interactive && toolMode === "select";
|
|
4630
|
+
return /* @__PURE__ */ jsxs10(
|
|
3403
4631
|
"div",
|
|
3404
4632
|
{
|
|
3405
|
-
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"}`,
|
|
4633
|
+
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"}`,
|
|
3406
4634
|
style: { pointerEvents: overlayInteractive ? "auto" : "none" },
|
|
3407
4635
|
onPointerDown,
|
|
3408
4636
|
onPointerMove,
|
|
3409
4637
|
onPointerUp,
|
|
3410
4638
|
onPointerLeave,
|
|
3411
4639
|
children: [
|
|
3412
|
-
selectionVisible ? displayedMeasurements.map((measurement, index) => /* @__PURE__ */
|
|
4640
|
+
selectionVisible ? displayedMeasurements.map((measurement, index) => /* @__PURE__ */ jsx11(
|
|
3413
4641
|
MeasurementBox,
|
|
3414
4642
|
{
|
|
3415
4643
|
measurement,
|
|
3416
4644
|
transitionMs: MEASURE_TRANSITION_MS,
|
|
3417
4645
|
labelOffset: MEASURE_LABEL_OFFSET,
|
|
3418
|
-
edgeVisibility: measurementEdgeVisibility[index]
|
|
4646
|
+
edgeVisibility: measurementEdgeVisibility[index],
|
|
4647
|
+
outlineColor,
|
|
4648
|
+
fillColor
|
|
3419
4649
|
},
|
|
3420
4650
|
measurement.id
|
|
3421
4651
|
)) : null,
|
|
3422
|
-
selectionVisible && activeRect && isDragging ? /* @__PURE__ */
|
|
3423
|
-
/* @__PURE__ */
|
|
4652
|
+
selectionVisible && activeRect && isDragging ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
4653
|
+
/* @__PURE__ */ jsxs10(
|
|
3424
4654
|
"div",
|
|
3425
4655
|
{
|
|
3426
4656
|
className: "msr:pointer-events-none msr:absolute",
|
|
@@ -3432,28 +4662,28 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3432
4662
|
backgroundColor: fillColor
|
|
3433
4663
|
},
|
|
3434
4664
|
children: [
|
|
3435
|
-
/* @__PURE__ */
|
|
4665
|
+
/* @__PURE__ */ jsx11(
|
|
3436
4666
|
"div",
|
|
3437
4667
|
{
|
|
3438
4668
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-px msr:w-full",
|
|
3439
4669
|
style: { backgroundColor: outlineColor }
|
|
3440
4670
|
}
|
|
3441
4671
|
),
|
|
3442
|
-
/* @__PURE__ */
|
|
4672
|
+
/* @__PURE__ */ jsx11(
|
|
3443
4673
|
"div",
|
|
3444
4674
|
{
|
|
3445
4675
|
className: "msr:absolute msr:right-0 msr:top-0 msr:h-full msr:w-px",
|
|
3446
4676
|
style: { backgroundColor: outlineColor }
|
|
3447
4677
|
}
|
|
3448
4678
|
),
|
|
3449
|
-
/* @__PURE__ */
|
|
4679
|
+
/* @__PURE__ */ jsx11(
|
|
3450
4680
|
"div",
|
|
3451
4681
|
{
|
|
3452
4682
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:h-px msr:w-full",
|
|
3453
4683
|
style: { backgroundColor: outlineColor }
|
|
3454
4684
|
}
|
|
3455
4685
|
),
|
|
3456
|
-
/* @__PURE__ */
|
|
4686
|
+
/* @__PURE__ */ jsx11(
|
|
3457
4687
|
"div",
|
|
3458
4688
|
{
|
|
3459
4689
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-full msr:w-px",
|
|
@@ -3463,7 +4693,7 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3463
4693
|
]
|
|
3464
4694
|
}
|
|
3465
4695
|
),
|
|
3466
|
-
/* @__PURE__ */
|
|
4696
|
+
/* @__PURE__ */ jsxs10(
|
|
3467
4697
|
MeasureTag,
|
|
3468
4698
|
{
|
|
3469
4699
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3479,7 +4709,7 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3479
4709
|
}
|
|
3480
4710
|
)
|
|
3481
4711
|
] }) : null,
|
|
3482
|
-
selectionVisible && hoverRectToShow ? /* @__PURE__ */
|
|
4712
|
+
selectionVisible && hoverRectToShow ? /* @__PURE__ */ jsxs10(
|
|
3483
4713
|
"div",
|
|
3484
4714
|
{
|
|
3485
4715
|
className: "msr:pointer-events-none msr:absolute",
|
|
@@ -3491,28 +4721,28 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3491
4721
|
backgroundColor: fillColor
|
|
3492
4722
|
},
|
|
3493
4723
|
children: [
|
|
3494
|
-
hoverEdgeVisibility?.top ? /* @__PURE__ */
|
|
4724
|
+
hoverEdgeVisibility?.top ? /* @__PURE__ */ jsx11(
|
|
3495
4725
|
"div",
|
|
3496
4726
|
{
|
|
3497
4727
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-px msr:w-full",
|
|
3498
4728
|
style: { backgroundColor: outlineColor }
|
|
3499
4729
|
}
|
|
3500
4730
|
) : null,
|
|
3501
|
-
hoverEdgeVisibility?.right ? /* @__PURE__ */
|
|
4731
|
+
hoverEdgeVisibility?.right ? /* @__PURE__ */ jsx11(
|
|
3502
4732
|
"div",
|
|
3503
4733
|
{
|
|
3504
4734
|
className: "msr:absolute msr:right-0 msr:top-0 msr:h-full msr:w-px",
|
|
3505
4735
|
style: { backgroundColor: outlineColor }
|
|
3506
4736
|
}
|
|
3507
4737
|
) : null,
|
|
3508
|
-
hoverEdgeVisibility?.bottom ? /* @__PURE__ */
|
|
4738
|
+
hoverEdgeVisibility?.bottom ? /* @__PURE__ */ jsx11(
|
|
3509
4739
|
"div",
|
|
3510
4740
|
{
|
|
3511
4741
|
className: "msr:absolute msr:bottom-0 msr:left-0 msr:h-px msr:w-full",
|
|
3512
4742
|
style: { backgroundColor: outlineColor }
|
|
3513
4743
|
}
|
|
3514
4744
|
) : null,
|
|
3515
|
-
hoverEdgeVisibility?.left ? /* @__PURE__ */
|
|
4745
|
+
hoverEdgeVisibility?.left ? /* @__PURE__ */ jsx11(
|
|
3516
4746
|
"div",
|
|
3517
4747
|
{
|
|
3518
4748
|
className: "msr:absolute msr:left-0 msr:top-0 msr:h-full msr:w-px",
|
|
@@ -3522,7 +4752,7 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3522
4752
|
]
|
|
3523
4753
|
}
|
|
3524
4754
|
) : null,
|
|
3525
|
-
guidesEnabled && guidePreview ? /* @__PURE__ */
|
|
4755
|
+
interactive && guidesEnabled && guidePreview ? /* @__PURE__ */ jsx11(
|
|
3526
4756
|
"div",
|
|
3527
4757
|
{
|
|
3528
4758
|
className: "msr:pointer-events-none msr:absolute",
|
|
@@ -3537,7 +4767,7 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3537
4767
|
height: GUIDE_HITBOX_SIZE,
|
|
3538
4768
|
width: "100%"
|
|
3539
4769
|
},
|
|
3540
|
-
children: /* @__PURE__ */
|
|
4770
|
+
children: /* @__PURE__ */ jsx11(
|
|
3541
4771
|
"div",
|
|
3542
4772
|
{
|
|
3543
4773
|
className: "msr:absolute",
|
|
@@ -3558,17 +4788,19 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3558
4788
|
)
|
|
3559
4789
|
}
|
|
3560
4790
|
) : null,
|
|
3561
|
-
selectionVisible ? displayedSelectedMeasurements.map((measurement, index) => /* @__PURE__ */
|
|
4791
|
+
selectionVisible ? displayedSelectedMeasurements.map((measurement, index) => /* @__PURE__ */ jsx11(
|
|
3562
4792
|
SelectedMeasurementBox,
|
|
3563
4793
|
{
|
|
3564
4794
|
measurement,
|
|
3565
4795
|
transitionMs: MEASURE_TRANSITION_MS,
|
|
3566
4796
|
labelOffset: MEASURE_LABEL_OFFSET,
|
|
3567
|
-
edgeVisibility: selectedEdgeVisibility[index]
|
|
4797
|
+
edgeVisibility: selectedEdgeVisibility[index],
|
|
4798
|
+
outlineColor,
|
|
4799
|
+
fillColor
|
|
3568
4800
|
},
|
|
3569
4801
|
measurement.id
|
|
3570
4802
|
)) : null,
|
|
3571
|
-
heldDistances.map((distance) => /* @__PURE__ */
|
|
4803
|
+
interactive ? heldDistances.map((distance) => /* @__PURE__ */ jsx11(
|
|
3572
4804
|
DistanceOverlayItem,
|
|
3573
4805
|
{
|
|
3574
4806
|
distance,
|
|
@@ -3576,8 +4808,8 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3576
4808
|
onRemove: onRemoveHeldDistance
|
|
3577
4809
|
},
|
|
3578
4810
|
`held-${distance.id}`
|
|
3579
|
-
)),
|
|
3580
|
-
selectionVisible && altPressed && optionPairOverlay ? /* @__PURE__ */
|
|
4811
|
+
)) : null,
|
|
4812
|
+
selectionVisible && altPressed && optionPairOverlay ? /* @__PURE__ */ jsx11(
|
|
3581
4813
|
DistanceOverlayItem,
|
|
3582
4814
|
{
|
|
3583
4815
|
distance: optionPairOverlay,
|
|
@@ -3585,7 +4817,7 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3585
4817
|
},
|
|
3586
4818
|
`option-${optionPairOverlay.id}`
|
|
3587
4819
|
) : null,
|
|
3588
|
-
guidesEnabled && altPressed && guideDistanceOverlay ? /* @__PURE__ */
|
|
4820
|
+
interactive && guidesEnabled && altPressed && guideDistanceOverlay ? /* @__PURE__ */ jsx11(
|
|
3589
4821
|
DistanceOverlayItem,
|
|
3590
4822
|
{
|
|
3591
4823
|
distance: guideDistanceOverlay,
|
|
@@ -3593,9 +4825,9 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3593
4825
|
},
|
|
3594
4826
|
`guide-preview-${guideDistanceOverlay.id}`
|
|
3595
4827
|
) : null,
|
|
3596
|
-
selectionVisible && altPressed && optionContainerLines ? /* @__PURE__ */
|
|
3597
|
-
optionContainerLines.top.value > 0 ? /* @__PURE__ */
|
|
3598
|
-
/* @__PURE__ */
|
|
4828
|
+
selectionVisible && altPressed && optionContainerLines ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
4829
|
+
optionContainerLines.top.value > 0 ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
4830
|
+
/* @__PURE__ */ jsx11(
|
|
3599
4831
|
"div",
|
|
3600
4832
|
{
|
|
3601
4833
|
className: "msr:absolute msr:w-px msr:bg-[#2563eb]",
|
|
@@ -3606,7 +4838,7 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3606
4838
|
}
|
|
3607
4839
|
}
|
|
3608
4840
|
),
|
|
3609
|
-
/* @__PURE__ */
|
|
4841
|
+
/* @__PURE__ */ jsx11(
|
|
3610
4842
|
MeasureTag,
|
|
3611
4843
|
{
|
|
3612
4844
|
className: "msr:-translate-y-1/2 msr:bg-ink-900/90",
|
|
@@ -3618,8 +4850,8 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3618
4850
|
}
|
|
3619
4851
|
)
|
|
3620
4852
|
] }) : null,
|
|
3621
|
-
optionContainerLines.bottom.value > 0 ? /* @__PURE__ */
|
|
3622
|
-
/* @__PURE__ */
|
|
4853
|
+
optionContainerLines.bottom.value > 0 ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
4854
|
+
/* @__PURE__ */ jsx11(
|
|
3623
4855
|
"div",
|
|
3624
4856
|
{
|
|
3625
4857
|
className: "msr:absolute msr:w-px msr:bg-[#2563eb]",
|
|
@@ -3630,7 +4862,7 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3630
4862
|
}
|
|
3631
4863
|
}
|
|
3632
4864
|
),
|
|
3633
|
-
/* @__PURE__ */
|
|
4865
|
+
/* @__PURE__ */ jsx11(
|
|
3634
4866
|
MeasureTag,
|
|
3635
4867
|
{
|
|
3636
4868
|
className: "msr:-translate-y-1/2 msr:bg-ink-900/90",
|
|
@@ -3642,8 +4874,8 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3642
4874
|
}
|
|
3643
4875
|
)
|
|
3644
4876
|
] }) : null,
|
|
3645
|
-
optionContainerLines.left.value > 0 ? /* @__PURE__ */
|
|
3646
|
-
/* @__PURE__ */
|
|
4877
|
+
optionContainerLines.left.value > 0 ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
4878
|
+
/* @__PURE__ */ jsx11(
|
|
3647
4879
|
"div",
|
|
3648
4880
|
{
|
|
3649
4881
|
className: "msr:absolute msr:h-px msr:bg-[#2563eb]",
|
|
@@ -3654,7 +4886,7 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3654
4886
|
}
|
|
3655
4887
|
}
|
|
3656
4888
|
),
|
|
3657
|
-
/* @__PURE__ */
|
|
4889
|
+
/* @__PURE__ */ jsx11(
|
|
3658
4890
|
MeasureTag,
|
|
3659
4891
|
{
|
|
3660
4892
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3666,8 +4898,8 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3666
4898
|
}
|
|
3667
4899
|
)
|
|
3668
4900
|
] }) : null,
|
|
3669
|
-
optionContainerLines.right.value > 0 ? /* @__PURE__ */
|
|
3670
|
-
/* @__PURE__ */
|
|
4901
|
+
optionContainerLines.right.value > 0 ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
4902
|
+
/* @__PURE__ */ jsx11(
|
|
3671
4903
|
"div",
|
|
3672
4904
|
{
|
|
3673
4905
|
className: "msr:absolute msr:h-px msr:bg-[#2563eb]",
|
|
@@ -3678,7 +4910,7 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3678
4910
|
}
|
|
3679
4911
|
}
|
|
3680
4912
|
),
|
|
3681
|
-
/* @__PURE__ */
|
|
4913
|
+
/* @__PURE__ */ jsx11(
|
|
3682
4914
|
MeasureTag,
|
|
3683
4915
|
{
|
|
3684
4916
|
className: "msr:-translate-x-1/2 msr:bg-ink-900/90",
|
|
@@ -3694,9 +4926,12 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3694
4926
|
guides.map((guide) => {
|
|
3695
4927
|
const isSelected = selectedGuideIds.includes(guide.id);
|
|
3696
4928
|
const isHovered = hoverGuide?.id === guide.id;
|
|
3697
|
-
const strokeWidth = isSelected || isHovered ? 2 : 1;
|
|
3698
4929
|
const strokeColor = isSelected ? guideColorActive : isHovered ? guideColorHover : guideColorDefault;
|
|
3699
|
-
|
|
4930
|
+
const strokeWidth = Math.max(guideStyle.width, isSelected || isHovered ? 2 : guideStyle.width);
|
|
4931
|
+
const isSolid = guideStyle.pattern === "solid";
|
|
4932
|
+
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)`;
|
|
4933
|
+
const backgroundSize = guideStyle.pattern === "dotted" ? guide.orientation === "vertical" ? `${strokeWidth}px ${guideStyle.dashLength + guideStyle.gap}px` : `${guideStyle.dashLength + guideStyle.gap}px ${strokeWidth}px` : void 0;
|
|
4934
|
+
return /* @__PURE__ */ jsx11(
|
|
3700
4935
|
"div",
|
|
3701
4936
|
{
|
|
3702
4937
|
className: "msr:absolute",
|
|
@@ -3717,7 +4952,7 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3717
4952
|
onPointerDown: (event) => onGuidePointerDown(guide, event),
|
|
3718
4953
|
onPointerUp: (event) => onGuidePointerUp(guide, event),
|
|
3719
4954
|
onPointerCancel: (event) => onGuidePointerCancel(guide, event),
|
|
3720
|
-
children: /* @__PURE__ */
|
|
4955
|
+
children: /* @__PURE__ */ jsx11(
|
|
3721
4956
|
"div",
|
|
3722
4957
|
{
|
|
3723
4958
|
className: "msr:absolute",
|
|
@@ -3726,13 +4961,19 @@ var MeasurerOverlay = memo6(function MeasurerOverlay2({
|
|
|
3726
4961
|
top: 0,
|
|
3727
4962
|
width: strokeWidth,
|
|
3728
4963
|
height: "100%",
|
|
3729
|
-
backgroundColor: strokeColor
|
|
4964
|
+
backgroundColor: isSolid ? strokeColor : "transparent",
|
|
4965
|
+
backgroundImage,
|
|
4966
|
+
backgroundSize,
|
|
4967
|
+
opacity: guideStyle.opacity
|
|
3730
4968
|
} : {
|
|
3731
4969
|
top: GUIDE_HITBOX_SIZE / 2 - 1,
|
|
3732
4970
|
left: 0,
|
|
3733
4971
|
height: strokeWidth,
|
|
3734
4972
|
width: "100%",
|
|
3735
|
-
backgroundColor: strokeColor
|
|
4973
|
+
backgroundColor: isSolid ? strokeColor : "transparent",
|
|
4974
|
+
backgroundImage,
|
|
4975
|
+
backgroundSize,
|
|
4976
|
+
opacity: guideStyle.opacity
|
|
3736
4977
|
}
|
|
3737
4978
|
}
|
|
3738
4979
|
)
|
|
@@ -4253,6 +5494,7 @@ var createTextInspector = (options = {}, legacy = false) => {
|
|
|
4253
5494
|
if (!element) return false;
|
|
4254
5495
|
for (let node = element; node; node = node.parentElement) {
|
|
4255
5496
|
if (node.classList.contains("mesurer-toolbar-surface")) return true;
|
|
5497
|
+
if (node.hasAttribute("data-mesurer-inspector-ui")) return true;
|
|
4256
5498
|
}
|
|
4257
5499
|
return false;
|
|
4258
5500
|
};
|
|
@@ -4550,7 +5792,7 @@ var createTextInspector = (options = {}, legacy = false) => {
|
|
|
4550
5792
|
const isInspectorUIEvent = (event) => event.composedPath().some(
|
|
4551
5793
|
(node) => node instanceof HTMLElementConstructor && (() => {
|
|
4552
5794
|
const element = node;
|
|
4553
|
-
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");
|
|
5795
|
+
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");
|
|
4554
5796
|
})()
|
|
4555
5797
|
);
|
|
4556
5798
|
const onClick = (event) => {
|
|
@@ -4633,8 +5875,223 @@ var createTextInspector = (options = {}, legacy = false) => {
|
|
|
4633
5875
|
};
|
|
4634
5876
|
var TextInspector = createTextInspector({}, true);
|
|
4635
5877
|
|
|
5878
|
+
// core/persistence.ts
|
|
5879
|
+
var MESURER_STORAGE_VERSION = 2;
|
|
5880
|
+
var DEFAULT_GUIDE_STYLE = {
|
|
5881
|
+
opacity: 1,
|
|
5882
|
+
width: 1,
|
|
5883
|
+
pattern: "solid",
|
|
5884
|
+
dashLength: 6,
|
|
5885
|
+
gap: 4
|
|
5886
|
+
};
|
|
5887
|
+
var DEFAULT_RULER_SETTINGS = {
|
|
5888
|
+
opacity: 1,
|
|
5889
|
+
edgeReveal: false
|
|
5890
|
+
};
|
|
5891
|
+
var isFormat = (value) => value === "hex" || value === "rgb" || value === "hsl" || value === "oklch";
|
|
5892
|
+
var normalizeGuideStyle = (value) => {
|
|
5893
|
+
if (!value || typeof value !== "object") return void 0;
|
|
5894
|
+
const input = value;
|
|
5895
|
+
return {
|
|
5896
|
+
opacity: typeof input.opacity === "number" ? Math.min(1, Math.max(0, input.opacity)) : DEFAULT_GUIDE_STYLE.opacity,
|
|
5897
|
+
width: typeof input.width === "number" ? Math.min(4, Math.max(1, input.width)) : DEFAULT_GUIDE_STYLE.width,
|
|
5898
|
+
pattern: input.pattern === "dashed" || input.pattern === "dotted" ? input.pattern : DEFAULT_GUIDE_STYLE.pattern,
|
|
5899
|
+
dashLength: typeof input.dashLength === "number" ? Math.min(24, Math.max(2, input.dashLength)) : DEFAULT_GUIDE_STYLE.dashLength,
|
|
5900
|
+
gap: typeof input.gap === "number" ? Math.min(24, Math.max(0, input.gap)) : DEFAULT_GUIDE_STYLE.gap
|
|
5901
|
+
};
|
|
5902
|
+
};
|
|
5903
|
+
var normalizeRulerSettings = (value) => {
|
|
5904
|
+
if (!value || typeof value !== "object") return void 0;
|
|
5905
|
+
const input = value;
|
|
5906
|
+
return {
|
|
5907
|
+
opacity: typeof input.opacity === "number" ? Math.min(1, Math.max(0.2, input.opacity)) : DEFAULT_RULER_SETTINGS.opacity,
|
|
5908
|
+
edgeReveal: typeof input.edgeReveal === "boolean" ? input.edgeReveal : DEFAULT_RULER_SETTINGS.edgeReveal
|
|
5909
|
+
};
|
|
5910
|
+
};
|
|
5911
|
+
var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
5912
|
+
var isRect = (value) => {
|
|
5913
|
+
if (!value || typeof value !== "object") return false;
|
|
5914
|
+
const rect = value;
|
|
5915
|
+
return isFiniteNumber(rect.left) && isFiniteNumber(rect.top) && isFiniteNumber(rect.width) && rect.width >= 0 && isFiniteNumber(rect.height) && rect.height >= 0;
|
|
5916
|
+
};
|
|
5917
|
+
var isNormalizedRect = (value) => isRect(value);
|
|
5918
|
+
var isMeasurement = (value) => {
|
|
5919
|
+
if (!value || typeof value !== "object") return false;
|
|
5920
|
+
const measurement = value;
|
|
5921
|
+
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");
|
|
5922
|
+
};
|
|
5923
|
+
var isGuide = (value) => {
|
|
5924
|
+
if (!value || typeof value !== "object") return false;
|
|
5925
|
+
const guide = value;
|
|
5926
|
+
return typeof guide.id === "string" && (guide.orientation === "vertical" || guide.orientation === "horizontal") && isFiniteNumber(guide.position);
|
|
5927
|
+
};
|
|
5928
|
+
var isDistanceOverlay = (value) => {
|
|
5929
|
+
if (!value || typeof value !== "object") return false;
|
|
5930
|
+
const distance = value;
|
|
5931
|
+
const isDistanceLine = (line) => {
|
|
5932
|
+
if (line === null) return true;
|
|
5933
|
+
if (!line || typeof line !== "object") return false;
|
|
5934
|
+
const item = line;
|
|
5935
|
+
return isFiniteNumber(item.x1) && isFiniteNumber(item.x2) && isFiniteNumber(item.y) && isFiniteNumber(item.value);
|
|
5936
|
+
};
|
|
5937
|
+
const isVerticalLine = (line) => {
|
|
5938
|
+
if (line === null) return true;
|
|
5939
|
+
if (!line || typeof line !== "object") return false;
|
|
5940
|
+
const item = line;
|
|
5941
|
+
return isFiniteNumber(item.y1) && isFiniteNumber(item.y2) && isFiniteNumber(item.x) && isFiniteNumber(item.value);
|
|
5942
|
+
};
|
|
5943
|
+
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) => {
|
|
5944
|
+
if (!connector || typeof connector !== "object") return false;
|
|
5945
|
+
const item = connector;
|
|
5946
|
+
return isFiniteNumber(item.x1) && isFiniteNumber(item.y1) && isFiniteNumber(item.x2) && isFiniteNumber(item.y2);
|
|
5947
|
+
});
|
|
5948
|
+
};
|
|
5949
|
+
var normalizeStoredSettings = (value) => {
|
|
5950
|
+
if (!value || typeof value !== "object") return {};
|
|
5951
|
+
const input = value;
|
|
5952
|
+
return {
|
|
5953
|
+
...typeof input.highlightColor === "string" ? { highlightColor: input.highlightColor } : {},
|
|
5954
|
+
...typeof input.guideColor === "string" ? { guideColor: input.guideColor } : {},
|
|
5955
|
+
...typeof input.hoverHighlightEnabled === "boolean" ? { hoverHighlightEnabled: input.hoverHighlightEnabled } : {},
|
|
5956
|
+
...Array.isArray(input.colorPickerFormats) && input.colorPickerFormats.some(isFormat) ? { colorPickerFormats: input.colorPickerFormats.filter(isFormat) } : {},
|
|
5957
|
+
...isFormat(input.colorPickerClickFormat) ? { colorPickerClickFormat: input.colorPickerClickFormat } : {},
|
|
5958
|
+
...typeof input.snapEnabled === "boolean" ? { snapEnabled: input.snapEnabled } : {},
|
|
5959
|
+
...typeof input.snapGuidesEnabled === "boolean" ? { snapGuidesEnabled: input.snapGuidesEnabled } : {},
|
|
5960
|
+
...typeof input.selectNewGuideEnabled === "boolean" ? { selectNewGuideEnabled: input.selectNewGuideEnabled } : {},
|
|
5961
|
+
...typeof input.multiMeasureEnabled === "boolean" ? { multiMeasureEnabled: input.multiMeasureEnabled } : {},
|
|
5962
|
+
...typeof input.persistOnReload === "boolean" ? { persistOnReload: input.persistOnReload } : {},
|
|
5963
|
+
...normalizeGuideStyle(input.guideStyle) ? { guideStyle: normalizeGuideStyle(input.guideStyle) } : {},
|
|
5964
|
+
...normalizeRulerSettings(input.rulerSettings) ? { rulerSettings: normalizeRulerSettings(input.rulerSettings) } : {}
|
|
5965
|
+
};
|
|
5966
|
+
};
|
|
5967
|
+
var normalizeStoredWorkspace = (value) => {
|
|
5968
|
+
if (!value || typeof value !== "object") return null;
|
|
5969
|
+
const input = value;
|
|
5970
|
+
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;
|
|
5971
|
+
return {
|
|
5972
|
+
enabled: input.enabled,
|
|
5973
|
+
xrayVisible: typeof input.xrayVisible === "boolean" ? input.xrayVisible : input.toolMode === "xray",
|
|
5974
|
+
toolMode: input.toolMode,
|
|
5975
|
+
rulersVisible: input.rulersVisible,
|
|
5976
|
+
guideOrientation: input.guideOrientation,
|
|
5977
|
+
guides: input.guides.filter(isGuide),
|
|
5978
|
+
selectedGuideIds: input.selectedGuideIds.filter((id) => typeof id === "string"),
|
|
5979
|
+
measurements: input.measurements.filter(isMeasurement),
|
|
5980
|
+
activeMeasurement: isMeasurement(input.activeMeasurement) ? input.activeMeasurement : null,
|
|
5981
|
+
heldDistances: input.heldDistances.filter(isDistanceOverlay)
|
|
5982
|
+
};
|
|
5983
|
+
};
|
|
5984
|
+
var normalizePersistenceSnapshot = (value) => {
|
|
5985
|
+
if (!value || typeof value !== "object") return null;
|
|
5986
|
+
const record = value;
|
|
5987
|
+
if (record.version !== MESURER_STORAGE_VERSION) return null;
|
|
5988
|
+
return {
|
|
5989
|
+
settings: normalizeStoredSettings(record.settings),
|
|
5990
|
+
workspace: normalizeStoredWorkspace(record.workspace)
|
|
5991
|
+
};
|
|
5992
|
+
};
|
|
5993
|
+
var migrate = (record) => {
|
|
5994
|
+
if (record.version === MESURER_STORAGE_VERSION) {
|
|
5995
|
+
return normalizePersistenceSnapshot(record);
|
|
5996
|
+
}
|
|
5997
|
+
if (record.version !== 1) return null;
|
|
5998
|
+
return {
|
|
5999
|
+
settings: {},
|
|
6000
|
+
workspace: record.enabled === void 0 || !record.toolMode || !record.guideOrientation || !record.guides || !record.selectedGuideIds || !record.measurements || record.activeMeasurement === void 0 || !record.heldDistances ? null : normalizeStoredWorkspace({
|
|
6001
|
+
enabled: record.enabled,
|
|
6002
|
+
xrayVisible: record.toolMode === "xray",
|
|
6003
|
+
toolMode: record.toolMode,
|
|
6004
|
+
rulersVisible: record.rulersVisible ?? record.toolMode === "rulers",
|
|
6005
|
+
guideOrientation: record.guideOrientation,
|
|
6006
|
+
guides: record.guides,
|
|
6007
|
+
selectedGuideIds: record.selectedGuideIds,
|
|
6008
|
+
measurements: record.measurements,
|
|
6009
|
+
activeMeasurement: record.activeMeasurement,
|
|
6010
|
+
heldDistances: record.heldDistances
|
|
6011
|
+
})
|
|
6012
|
+
};
|
|
6013
|
+
};
|
|
6014
|
+
var createLocalStoragePersistence = (ownerWindow, workspaceKey, settingsKey = workspaceKey, legacyKey) => {
|
|
6015
|
+
let errorHandler;
|
|
6016
|
+
const readRecord = (key) => {
|
|
6017
|
+
try {
|
|
6018
|
+
const raw = ownerWindow.localStorage.getItem(key);
|
|
6019
|
+
if (!raw) return null;
|
|
6020
|
+
return migrate(JSON.parse(raw));
|
|
6021
|
+
} catch (error) {
|
|
6022
|
+
errorHandler?.(error);
|
|
6023
|
+
return null;
|
|
6024
|
+
}
|
|
6025
|
+
};
|
|
6026
|
+
const read = () => {
|
|
6027
|
+
const legacy = legacyKey ? readRecord(legacyKey) : null;
|
|
6028
|
+
const settingsRecord = readRecord(settingsKey);
|
|
6029
|
+
const workspaceRecord = readRecord(workspaceKey);
|
|
6030
|
+
if (!settingsRecord && !workspaceRecord && !legacy) return null;
|
|
6031
|
+
return {
|
|
6032
|
+
settings: settingsRecord?.settings ?? legacy?.settings ?? {},
|
|
6033
|
+
workspace: workspaceRecord?.workspace ?? legacy?.workspace ?? null
|
|
6034
|
+
};
|
|
6035
|
+
};
|
|
6036
|
+
const writeRecord = (key, snapshot) => {
|
|
6037
|
+
try {
|
|
6038
|
+
ownerWindow.localStorage.setItem(
|
|
6039
|
+
key,
|
|
6040
|
+
JSON.stringify({ version: MESURER_STORAGE_VERSION, ...snapshot })
|
|
6041
|
+
);
|
|
6042
|
+
} catch (error) {
|
|
6043
|
+
errorHandler?.(error);
|
|
6044
|
+
}
|
|
6045
|
+
};
|
|
6046
|
+
return {
|
|
6047
|
+
load: read,
|
|
6048
|
+
saveSettings: (settings) => {
|
|
6049
|
+
if (settingsKey === workspaceKey) {
|
|
6050
|
+
writeRecord(workspaceKey, { settings, workspace: read()?.workspace ?? null });
|
|
6051
|
+
return;
|
|
6052
|
+
}
|
|
6053
|
+
writeRecord(settingsKey, { settings, workspace: null });
|
|
6054
|
+
},
|
|
6055
|
+
saveWorkspace: (workspace) => {
|
|
6056
|
+
if (settingsKey === workspaceKey) {
|
|
6057
|
+
writeRecord(workspaceKey, { settings: read()?.settings ?? {}, workspace });
|
|
6058
|
+
return;
|
|
6059
|
+
}
|
|
6060
|
+
writeRecord(workspaceKey, { settings: {}, workspace });
|
|
6061
|
+
},
|
|
6062
|
+
clearWorkspace: () => {
|
|
6063
|
+
if (settingsKey === workspaceKey) {
|
|
6064
|
+
const current = read();
|
|
6065
|
+
if (current) writeRecord(workspaceKey, { settings: current.settings, workspace: null });
|
|
6066
|
+
return;
|
|
6067
|
+
}
|
|
6068
|
+
writeRecord(workspaceKey, { settings: {}, workspace: null });
|
|
6069
|
+
},
|
|
6070
|
+
clearSettings: () => {
|
|
6071
|
+
if (settingsKey === workspaceKey) {
|
|
6072
|
+
writeRecord(workspaceKey, { settings: {}, workspace: read()?.workspace ?? null });
|
|
6073
|
+
return;
|
|
6074
|
+
}
|
|
6075
|
+
writeRecord(settingsKey, { settings: {}, workspace: null });
|
|
6076
|
+
},
|
|
6077
|
+
setErrorHandler: (handler) => {
|
|
6078
|
+
errorHandler = handler;
|
|
6079
|
+
},
|
|
6080
|
+
subscribe: (listener) => {
|
|
6081
|
+
const handleStorage = (event) => {
|
|
6082
|
+
if (event.key !== settingsKey && event.key !== workspaceKey && event.key !== legacyKey) return;
|
|
6083
|
+
listener(read());
|
|
6084
|
+
};
|
|
6085
|
+
ownerWindow.addEventListener("storage", handleStorage);
|
|
6086
|
+
return () => {
|
|
6087
|
+
ownerWindow.removeEventListener("storage", handleStorage);
|
|
6088
|
+
};
|
|
6089
|
+
}
|
|
6090
|
+
};
|
|
6091
|
+
};
|
|
6092
|
+
|
|
4636
6093
|
// measurer.tsx
|
|
4637
|
-
import { jsx as
|
|
6094
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
4638
6095
|
var measurerInstanceCount = 0;
|
|
4639
6096
|
var XRAY_STYLE_ID = "mesurer-xray-styles";
|
|
4640
6097
|
var XRAY_STYLES = `
|
|
@@ -4646,7 +6103,11 @@ var XRAY_STYLES = `
|
|
|
4646
6103
|
.xray-mode .mesurer-root,
|
|
4647
6104
|
.xray-mode .mesurer-root *,
|
|
4648
6105
|
.xray-mode .mesurer-toolbar-surface,
|
|
4649
|
-
.xray-mode .mesurer-toolbar-surface
|
|
6106
|
+
.xray-mode .mesurer-toolbar-surface *,
|
|
6107
|
+
.xray-mode .mesurer-ti-box,
|
|
6108
|
+
.xray-mode .mesurer-ti-card,
|
|
6109
|
+
.xray-mode .mesurer-ti-card *,
|
|
6110
|
+
.xray-mode .mesurer-ti-close {
|
|
4650
6111
|
outline: none !important;
|
|
4651
6112
|
}
|
|
4652
6113
|
`;
|
|
@@ -4666,70 +6127,112 @@ var stripDistance = (distance) => ({
|
|
|
4666
6127
|
elementRefA: void 0,
|
|
4667
6128
|
elementRefB: void 0
|
|
4668
6129
|
});
|
|
6130
|
+
var TAB_ID_KEY = "mesurer:tab-id";
|
|
6131
|
+
var SETTINGS_STORAGE_KEY = "mesurer-settings";
|
|
6132
|
+
var LEGACY_STORAGE_KEY = "mesurer-state";
|
|
6133
|
+
var getTabId = (ownerWindow) => {
|
|
6134
|
+
try {
|
|
6135
|
+
const existing = ownerWindow.sessionStorage.getItem(TAB_ID_KEY);
|
|
6136
|
+
if (existing) return existing;
|
|
6137
|
+
const id = ownerWindow.crypto.randomUUID();
|
|
6138
|
+
ownerWindow.sessionStorage.setItem(TAB_ID_KEY, id);
|
|
6139
|
+
return id;
|
|
6140
|
+
} catch {
|
|
6141
|
+
return "session";
|
|
6142
|
+
}
|
|
6143
|
+
};
|
|
6144
|
+
var sanitizeStoredSettings = (ownerWindow, settings) => {
|
|
6145
|
+
const supportsColor = (value) => value !== void 0 && ownerWindow.CSS?.supports("color", value) === true;
|
|
6146
|
+
return {
|
|
6147
|
+
...settings,
|
|
6148
|
+
...supportsColor(settings.highlightColor) ? {} : { highlightColor: void 0 },
|
|
6149
|
+
...supportsColor(settings.guideColor) ? {} : { guideColor: void 0 }
|
|
6150
|
+
};
|
|
6151
|
+
};
|
|
4669
6152
|
function MeasurerClient({
|
|
4670
6153
|
highlightColor,
|
|
4671
6154
|
guideColor,
|
|
4672
6155
|
hoverHighlightEnabled,
|
|
4673
6156
|
persistOnReload,
|
|
4674
6157
|
portalTarget,
|
|
4675
|
-
persistKey
|
|
6158
|
+
persistKey,
|
|
6159
|
+
colorPickerFormats,
|
|
6160
|
+
colorPickerClickFormat,
|
|
6161
|
+
snapEnabled: snapEnabledDefault,
|
|
6162
|
+
snapGuidesEnabled: snapGuidesEnabledDefault,
|
|
6163
|
+
selectNewGuideEnabled: selectNewGuideEnabledDefault,
|
|
6164
|
+
multiMeasureEnabled: multiMeasureEnabledDefault,
|
|
6165
|
+
guideStyle: guideStyleDefault,
|
|
6166
|
+
rulerSettings: rulerSettingsDefault,
|
|
6167
|
+
persistence,
|
|
6168
|
+
onPersistenceError
|
|
4676
6169
|
}) {
|
|
4677
|
-
const instanceIdRef =
|
|
6170
|
+
const instanceIdRef = useRef12(null);
|
|
4678
6171
|
if (instanceIdRef.current === null) {
|
|
4679
6172
|
instanceIdRef.current = ++measurerInstanceCount;
|
|
4680
6173
|
}
|
|
4681
|
-
const storageKey = persistKey ?? (instanceIdRef.current === 1 ? "mesurer-state" : `mesurer-state-${instanceIdRef.current}`);
|
|
4682
6174
|
const ownerDocument = portalTarget.ownerDocument ?? document;
|
|
4683
6175
|
const ownerWindow = ownerDocument.defaultView ?? window;
|
|
4684
|
-
const
|
|
6176
|
+
const tabIdRef = useRef12(null);
|
|
6177
|
+
if (tabIdRef.current === null) tabIdRef.current = getTabId(ownerWindow);
|
|
6178
|
+
const storageKey = persistKey ?? (instanceIdRef.current === 1 ? `mesurer-state:${tabIdRef.current}` : `mesurer-state:${tabIdRef.current}:${instanceIdRef.current}`);
|
|
6179
|
+
const legacyStorageKey = persistKey ? void 0 : LEGACY_STORAGE_KEY;
|
|
6180
|
+
const guideScrollRef = useRef12({
|
|
4685
6181
|
x: ownerWindow.scrollX,
|
|
4686
6182
|
y: ownerWindow.scrollY
|
|
4687
6183
|
});
|
|
4688
|
-
const textInspectorRef =
|
|
6184
|
+
const textInspectorRef = useRef12(null);
|
|
4689
6185
|
if (!textInspectorRef.current) {
|
|
4690
6186
|
textInspectorRef.current = createTextInspector({ portalTarget });
|
|
4691
6187
|
}
|
|
4692
6188
|
const textInspector = textInspectorRef.current;
|
|
4693
|
-
const selectionRectRef =
|
|
4694
|
-
const toolbarRef =
|
|
4695
|
-
const selectionAnimationCleanupTimeoutRef =
|
|
4696
|
-
const guideDragRef =
|
|
4697
|
-
const guideUserSelectRef =
|
|
4698
|
-
const
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
const
|
|
4711
|
-
|
|
6189
|
+
const selectionRectRef = useRef12(null);
|
|
6190
|
+
const toolbarRef = useRef12(null);
|
|
6191
|
+
const selectionAnimationCleanupTimeoutRef = useRef12(null);
|
|
6192
|
+
const guideDragRef = useRef12(null);
|
|
6193
|
+
const guideUserSelectRef = useRef12(null);
|
|
6194
|
+
const persistenceErrorHandlerRef = useRef12(onPersistenceError);
|
|
6195
|
+
persistenceErrorHandlerRef.current = onPersistenceError;
|
|
6196
|
+
const activePersistence = useMemo2(() => {
|
|
6197
|
+
const next = persistence ?? createLocalStoragePersistence(ownerWindow, storageKey, SETTINGS_STORAGE_KEY, legacyStorageKey);
|
|
6198
|
+
next.setErrorHandler?.((error) => persistenceErrorHandlerRef.current?.(error));
|
|
6199
|
+
return next;
|
|
6200
|
+
}, [legacyStorageKey, ownerWindow, persistence, storageKey]);
|
|
6201
|
+
const storedState = useMemo2(
|
|
6202
|
+
() => activePersistence.load(),
|
|
6203
|
+
[activePersistence]
|
|
6204
|
+
);
|
|
6205
|
+
const persistedState = persistOnReload || storedState?.settings.persistOnReload ? storedState?.workspace ?? null : null;
|
|
6206
|
+
const persistedSettings = sanitizeStoredSettings(ownerWindow, storedState?.settings ?? {});
|
|
6207
|
+
useEffect7(() => {
|
|
6208
|
+
return () => activePersistence.setErrorHandler?.(void 0);
|
|
6209
|
+
}, [activePersistence]);
|
|
6210
|
+
const enabledRef = useRef12(false);
|
|
6211
|
+
const toolModeRef = useRef12(
|
|
4712
6212
|
persistedState?.toolMode === "rulers" ? "none" : persistedState?.toolMode ?? "none"
|
|
4713
6213
|
);
|
|
4714
|
-
const rulersVisibleRef =
|
|
6214
|
+
const rulersVisibleRef = useRef12(
|
|
4715
6215
|
persistedState?.rulersVisible ?? persistedState?.toolMode === "rulers"
|
|
4716
6216
|
);
|
|
4717
|
-
const
|
|
6217
|
+
const xrayVisibleRef = useRef12(persistedState?.xrayVisible ?? persistedState?.toolMode === "xray");
|
|
6218
|
+
const guideOrientationRef = useRef12(
|
|
4718
6219
|
persistedState?.guideOrientation ?? "vertical"
|
|
4719
6220
|
);
|
|
4720
|
-
const measurementsRef =
|
|
6221
|
+
const measurementsRef = useRef12(
|
|
4721
6222
|
persistedState?.measurements ?? []
|
|
4722
6223
|
);
|
|
4723
|
-
const activeMeasurementRef =
|
|
6224
|
+
const activeMeasurementRef = useRef12(
|
|
4724
6225
|
persistedState?.activeMeasurement ?? null
|
|
4725
6226
|
);
|
|
4726
|
-
const heldDistancesRef =
|
|
6227
|
+
const heldDistancesRef = useRef12(
|
|
4727
6228
|
persistedState?.heldDistances ?? []
|
|
4728
6229
|
);
|
|
4729
|
-
const guidesRef =
|
|
4730
|
-
const selectedGuideIdsRef =
|
|
6230
|
+
const guidesRef = useRef12(persistedState?.guides ?? []);
|
|
6231
|
+
const selectedGuideIdsRef = useRef12(
|
|
4731
6232
|
persistedState?.selectedGuideIds ?? []
|
|
4732
6233
|
);
|
|
6234
|
+
const workspacePersistTimeoutRef = useRef12(null);
|
|
6235
|
+
const applyingExternalPersistenceRef = useRef12(false);
|
|
4733
6236
|
const { overlayRef, selectedElementRef, hoverElementRef } = useOverlayRefs();
|
|
4734
6237
|
const {
|
|
4735
6238
|
selectionOriginRect,
|
|
@@ -4759,11 +6262,20 @@ function MeasurerClient({
|
|
|
4759
6262
|
setRulersVisible,
|
|
4760
6263
|
guidesEnabled,
|
|
4761
6264
|
multiMeasureEnabled,
|
|
4762
|
-
snapGuidesEnabled
|
|
6265
|
+
snapGuidesEnabled,
|
|
6266
|
+
setSnapGuidesEnabled,
|
|
6267
|
+
selectNewGuideEnabled,
|
|
6268
|
+
setSelectNewGuideEnabled,
|
|
6269
|
+
setSnapEnabled,
|
|
6270
|
+
setMultiMeasureEnabled
|
|
4763
6271
|
} = useMeasureToggles({
|
|
4764
6272
|
initialEnabled: persistedState?.enabled,
|
|
4765
6273
|
initialToolMode: persistedState?.toolMode === "rulers" ? "none" : persistedState?.toolMode,
|
|
4766
|
-
initialRulersVisible: persistedState?.rulersVisible ?? persistedState?.toolMode === "rulers"
|
|
6274
|
+
initialRulersVisible: persistedState?.rulersVisible ?? persistedState?.toolMode === "rulers",
|
|
6275
|
+
initialSnapEnabled: persistedSettings.snapEnabled ?? snapEnabledDefault,
|
|
6276
|
+
initialSnapGuidesEnabled: persistedSettings.snapGuidesEnabled ?? snapGuidesEnabledDefault,
|
|
6277
|
+
initialSelectNewGuideEnabled: persistedSettings.selectNewGuideEnabled ?? selectNewGuideEnabledDefault,
|
|
6278
|
+
initialMultiMeasureEnabled: persistedSettings.multiMeasureEnabled ?? multiMeasureEnabledDefault
|
|
4767
6279
|
});
|
|
4768
6280
|
const { start, setStart, end, setEnd, isDragging, setIsDragging } = useDragState();
|
|
4769
6281
|
const {
|
|
@@ -4795,11 +6307,58 @@ function MeasurerClient({
|
|
|
4795
6307
|
initialGuides: persistedState?.guides ?? [],
|
|
4796
6308
|
initialSelectedGuideIds: persistedState?.selectedGuideIds ?? []
|
|
4797
6309
|
});
|
|
4798
|
-
const [toolbarActive, setToolbarActive] =
|
|
6310
|
+
const [toolbarActive, setToolbarActive] = useState11(true);
|
|
6311
|
+
const [colorPickerActive, setColorPickerActive] = useState11(false);
|
|
6312
|
+
const [colorPickerSample, setColorPickerSample] = useState11(null);
|
|
6313
|
+
const [colorPickerUnsupported, setColorPickerUnsupported] = useState11(false);
|
|
6314
|
+
const [settingsOpen, setSettingsOpen] = useState11(false);
|
|
6315
|
+
const [settingsHighlightColor, setSettingsHighlightColor] = useState11(
|
|
6316
|
+
persistedSettings.highlightColor ?? highlightColor
|
|
6317
|
+
);
|
|
6318
|
+
const [settingsGuideColor, setSettingsGuideColor] = useState11(
|
|
6319
|
+
persistedSettings.guideColor ?? guideColor
|
|
6320
|
+
);
|
|
6321
|
+
const [settingsHoverHighlight, setSettingsHoverHighlight] = useState11(
|
|
6322
|
+
persistedSettings.hoverHighlightEnabled ?? hoverHighlightEnabled
|
|
6323
|
+
);
|
|
6324
|
+
const [settingsPersistOnReload, setSettingsPersistOnReload] = useState11(
|
|
6325
|
+
persistedSettings.persistOnReload ?? persistOnReload
|
|
6326
|
+
);
|
|
6327
|
+
const [settingsColorFormats, setSettingsColorFormats] = useState11(
|
|
6328
|
+
persistedSettings.colorPickerFormats ?? colorPickerFormats
|
|
6329
|
+
);
|
|
6330
|
+
const [settingsColorClickFormat, setSettingsColorClickFormat] = useState11(
|
|
6331
|
+
persistedSettings.colorPickerClickFormat ?? colorPickerClickFormat
|
|
6332
|
+
);
|
|
6333
|
+
const [settingsGuideStyle, setSettingsGuideStyle] = useState11({
|
|
6334
|
+
...guideStyleDefault,
|
|
6335
|
+
...persistedSettings.guideStyle
|
|
6336
|
+
});
|
|
6337
|
+
const [settingsRulerSettings, setSettingsRulerSettings] = useState11({
|
|
6338
|
+
...rulerSettingsDefault,
|
|
6339
|
+
...persistedSettings.rulerSettings
|
|
6340
|
+
});
|
|
6341
|
+
const [xrayVisible, setXrayVisible] = useState11(xrayVisibleRef.current);
|
|
4799
6342
|
const { clearGuideDragHold, scheduleGuideDragHold } = useGuideDragHold(ownerWindow);
|
|
4800
|
-
const [guidePreview, setGuidePreview] =
|
|
4801
|
-
const
|
|
6343
|
+
const [guidePreview, setGuidePreview] = useState11(null);
|
|
6344
|
+
const resetSettings = () => {
|
|
6345
|
+
setSettingsHighlightColor(highlightColor);
|
|
6346
|
+
setSettingsGuideColor(guideColor);
|
|
6347
|
+
setSettingsHoverHighlight(hoverHighlightEnabled);
|
|
6348
|
+
setSettingsPersistOnReload(persistOnReload);
|
|
6349
|
+
setSettingsColorFormats([...colorPickerFormats]);
|
|
6350
|
+
setSettingsColorClickFormat(colorPickerClickFormat);
|
|
6351
|
+
setSnapEnabled(snapEnabledDefault);
|
|
6352
|
+
setSnapGuidesEnabled(snapGuidesEnabledDefault);
|
|
6353
|
+
setSelectNewGuideEnabled(selectNewGuideEnabledDefault);
|
|
6354
|
+
setMultiMeasureEnabled(multiMeasureEnabledDefault);
|
|
6355
|
+
setSettingsGuideStyle({ ...guideStyleDefault });
|
|
6356
|
+
setSettingsRulerSettings({ ...rulerSettingsDefault });
|
|
6357
|
+
};
|
|
6358
|
+
const initialSettingsTab = colorPickerActive ? "color-picker" : rulersVisible ? "rulers" : toolMode === "guides" ? "guides" : toolMode === "select" || toolMode === "text-inspector" ? "select" : "general";
|
|
6359
|
+
const [guideOrientation, setGuideOrientation] = useState11(persistedState?.guideOrientation ?? "vertical");
|
|
4802
6360
|
enabledRef.current = enabled;
|
|
6361
|
+
xrayVisibleRef.current = xrayVisible;
|
|
4803
6362
|
toolModeRef.current = toolMode;
|
|
4804
6363
|
rulersVisibleRef.current = rulersVisible;
|
|
4805
6364
|
guideOrientationRef.current = guideOrientation;
|
|
@@ -4808,29 +6367,173 @@ function MeasurerClient({
|
|
|
4808
6367
|
heldDistancesRef.current = heldDistances;
|
|
4809
6368
|
guidesRef.current = guides;
|
|
4810
6369
|
selectedGuideIdsRef.current = selectedGuideIds;
|
|
4811
|
-
const
|
|
4812
|
-
if (!
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
6370
|
+
const saveWorkspace = useCallback8(() => {
|
|
6371
|
+
if (!settingsPersistOnReload) return;
|
|
6372
|
+
const workspace = {
|
|
6373
|
+
enabled: enabledRef.current,
|
|
6374
|
+
xrayVisible: xrayVisibleRef.current,
|
|
6375
|
+
toolMode: toolModeRef.current,
|
|
6376
|
+
rulersVisible: rulersVisibleRef.current,
|
|
6377
|
+
guideOrientation: guideOrientationRef.current,
|
|
6378
|
+
guides: guidesRef.current,
|
|
6379
|
+
selectedGuideIds: selectedGuideIdsRef.current,
|
|
6380
|
+
measurements: measurementsRef.current.map(stripMeasurement),
|
|
6381
|
+
activeMeasurement: activeMeasurementRef.current ? stripMeasurement(activeMeasurementRef.current) : null,
|
|
6382
|
+
heldDistances: heldDistancesRef.current.map(stripDistance)
|
|
6383
|
+
};
|
|
6384
|
+
activePersistence.saveWorkspace(workspace);
|
|
6385
|
+
}, [activePersistence, settingsPersistOnReload]);
|
|
6386
|
+
const persistState = useCallback8(() => {
|
|
6387
|
+
if (!settingsPersistOnReload) return;
|
|
6388
|
+
if (workspacePersistTimeoutRef.current !== null) {
|
|
6389
|
+
ownerWindow.clearTimeout(workspacePersistTimeoutRef.current);
|
|
6390
|
+
}
|
|
6391
|
+
workspacePersistTimeoutRef.current = ownerWindow.setTimeout(() => {
|
|
6392
|
+
workspacePersistTimeoutRef.current = null;
|
|
6393
|
+
saveWorkspace();
|
|
6394
|
+
}, 250);
|
|
6395
|
+
}, [ownerWindow, saveWorkspace, settingsPersistOnReload]);
|
|
6396
|
+
const persistSettings = useCallback8(() => {
|
|
6397
|
+
activePersistence.saveSettings({
|
|
6398
|
+
highlightColor: settingsHighlightColor,
|
|
6399
|
+
guideColor: settingsGuideColor,
|
|
6400
|
+
hoverHighlightEnabled: settingsHoverHighlight,
|
|
6401
|
+
colorPickerFormats: settingsColorFormats,
|
|
6402
|
+
colorPickerClickFormat: settingsColorClickFormat,
|
|
6403
|
+
snapEnabled,
|
|
6404
|
+
snapGuidesEnabled,
|
|
6405
|
+
selectNewGuideEnabled,
|
|
6406
|
+
multiMeasureEnabled,
|
|
6407
|
+
persistOnReload: settingsPersistOnReload,
|
|
6408
|
+
guideStyle: settingsGuideStyle,
|
|
6409
|
+
rulerSettings: settingsRulerSettings
|
|
6410
|
+
});
|
|
6411
|
+
}, [
|
|
6412
|
+
multiMeasureEnabled,
|
|
6413
|
+
selectNewGuideEnabled,
|
|
6414
|
+
settingsColorClickFormat,
|
|
6415
|
+
settingsColorFormats,
|
|
6416
|
+
settingsGuideColor,
|
|
6417
|
+
settingsHighlightColor,
|
|
6418
|
+
settingsHoverHighlight,
|
|
6419
|
+
settingsPersistOnReload,
|
|
6420
|
+
snapEnabled,
|
|
6421
|
+
snapGuidesEnabled,
|
|
6422
|
+
activePersistence,
|
|
6423
|
+
settingsGuideStyle,
|
|
6424
|
+
settingsRulerSettings
|
|
6425
|
+
]);
|
|
6426
|
+
useEffect7(() => {
|
|
6427
|
+
if (applyingExternalPersistenceRef.current) {
|
|
6428
|
+
applyingExternalPersistenceRef.current = false;
|
|
6429
|
+
return;
|
|
6430
|
+
}
|
|
6431
|
+
persistSettings();
|
|
6432
|
+
if (settingsPersistOnReload) persistState();
|
|
6433
|
+
}, [persistSettings, persistState, settingsPersistOnReload]);
|
|
6434
|
+
useEffect7(() => {
|
|
6435
|
+
if (!settingsPersistOnReload) return;
|
|
6436
|
+
const handleBeforeUnload = () => saveWorkspace();
|
|
6437
|
+
ownerWindow.addEventListener("beforeunload", handleBeforeUnload);
|
|
6438
|
+
return () => {
|
|
6439
|
+
ownerWindow.removeEventListener("beforeunload", handleBeforeUnload);
|
|
6440
|
+
if (workspacePersistTimeoutRef.current !== null) {
|
|
6441
|
+
ownerWindow.clearTimeout(workspacePersistTimeoutRef.current);
|
|
6442
|
+
workspacePersistTimeoutRef.current = null;
|
|
6443
|
+
saveWorkspace();
|
|
6444
|
+
}
|
|
6445
|
+
};
|
|
6446
|
+
}, [ownerWindow, saveWorkspace, settingsPersistOnReload]);
|
|
6447
|
+
const clearPersistedWorkspace = useCallback8(() => {
|
|
6448
|
+
enabledRef.current = false;
|
|
6449
|
+
toolModeRef.current = "none";
|
|
6450
|
+
rulersVisibleRef.current = false;
|
|
6451
|
+
xrayVisibleRef.current = false;
|
|
6452
|
+
guideOrientationRef.current = "vertical";
|
|
6453
|
+
measurementsRef.current = [];
|
|
6454
|
+
activeMeasurementRef.current = null;
|
|
6455
|
+
heldDistancesRef.current = [];
|
|
6456
|
+
guidesRef.current = [];
|
|
6457
|
+
selectedGuideIdsRef.current = [];
|
|
6458
|
+
setEnabled(false);
|
|
6459
|
+
setToolMode("none");
|
|
6460
|
+
setRulersVisible(false);
|
|
6461
|
+
setXrayVisible(false);
|
|
6462
|
+
setGuideOrientation("vertical");
|
|
6463
|
+
setMeasurements([]);
|
|
6464
|
+
setActiveMeasurement(null);
|
|
6465
|
+
setSelectedMeasurement(null);
|
|
6466
|
+
setSelectedMeasurements([]);
|
|
6467
|
+
setHeldDistances([]);
|
|
6468
|
+
setGuides([]);
|
|
6469
|
+
setSelectedGuideIds([]);
|
|
6470
|
+
}, [setActiveMeasurement, setEnabled, setGuideOrientation, setGuides, setHeldDistances, setMeasurements, setRulersVisible, setSelectedGuideIds, setSelectedMeasurement, setSelectedMeasurements, setToolMode]);
|
|
6471
|
+
const clearWorkspace = useCallback8(() => {
|
|
6472
|
+
clearPersistedWorkspace();
|
|
6473
|
+
activePersistence.clearWorkspace();
|
|
6474
|
+
}, [activePersistence, clearPersistedWorkspace]);
|
|
6475
|
+
const applyPersistedWorkspace = useCallback8((workspace) => {
|
|
6476
|
+
enabledRef.current = workspace.enabled;
|
|
6477
|
+
toolModeRef.current = workspace.toolMode;
|
|
6478
|
+
rulersVisibleRef.current = workspace.rulersVisible;
|
|
6479
|
+
xrayVisibleRef.current = workspace.xrayVisible;
|
|
6480
|
+
guideOrientationRef.current = workspace.guideOrientation;
|
|
6481
|
+
measurementsRef.current = workspace.measurements;
|
|
6482
|
+
activeMeasurementRef.current = workspace.activeMeasurement;
|
|
6483
|
+
heldDistancesRef.current = workspace.heldDistances;
|
|
6484
|
+
guidesRef.current = workspace.guides;
|
|
6485
|
+
selectedGuideIdsRef.current = workspace.selectedGuideIds;
|
|
6486
|
+
setEnabled(workspace.enabled);
|
|
6487
|
+
setToolMode(workspace.toolMode);
|
|
6488
|
+
setRulersVisible(workspace.rulersVisible);
|
|
6489
|
+
setXrayVisible(workspace.xrayVisible);
|
|
6490
|
+
setGuideOrientation(workspace.guideOrientation);
|
|
6491
|
+
setMeasurements(workspace.measurements);
|
|
6492
|
+
setActiveMeasurement(workspace.activeMeasurement);
|
|
6493
|
+
setGuides(workspace.guides);
|
|
6494
|
+
setSelectedGuideIds(workspace.selectedGuideIds);
|
|
6495
|
+
setHeldDistances(workspace.heldDistances);
|
|
6496
|
+
}, [setActiveMeasurement, setEnabled, setGuideOrientation, setGuides, setHeldDistances, setMeasurements, setRulersVisible, setSelectedGuideIds, setToolMode]);
|
|
6497
|
+
const applyPersistenceSnapshot = useCallback8((snapshot) => {
|
|
6498
|
+
if (!snapshot) {
|
|
6499
|
+
clearPersistedWorkspace();
|
|
6500
|
+
return;
|
|
4831
6501
|
}
|
|
4832
|
-
|
|
4833
|
-
|
|
6502
|
+
applyingExternalPersistenceRef.current = true;
|
|
6503
|
+
const settings = sanitizeStoredSettings(ownerWindow, snapshot.settings);
|
|
6504
|
+
if (settings.highlightColor !== void 0) setSettingsHighlightColor(settings.highlightColor);
|
|
6505
|
+
if (settings.guideColor !== void 0) setSettingsGuideColor(settings.guideColor);
|
|
6506
|
+
if (settings.hoverHighlightEnabled !== void 0) setSettingsHoverHighlight(settings.hoverHighlightEnabled);
|
|
6507
|
+
if (settings.colorPickerFormats !== void 0) setSettingsColorFormats(settings.colorPickerFormats);
|
|
6508
|
+
if (settings.colorPickerClickFormat !== void 0) setSettingsColorClickFormat(settings.colorPickerClickFormat);
|
|
6509
|
+
if (settings.persistOnReload !== void 0) setSettingsPersistOnReload(settings.persistOnReload);
|
|
6510
|
+
if (settings.snapEnabled !== void 0) setSnapEnabled(settings.snapEnabled);
|
|
6511
|
+
if (settings.snapGuidesEnabled !== void 0) setSnapGuidesEnabled(settings.snapGuidesEnabled);
|
|
6512
|
+
if (settings.selectNewGuideEnabled !== void 0) setSelectNewGuideEnabled(settings.selectNewGuideEnabled);
|
|
6513
|
+
if (settings.multiMeasureEnabled !== void 0) setMultiMeasureEnabled(settings.multiMeasureEnabled);
|
|
6514
|
+
if (settings.guideStyle !== void 0) setSettingsGuideStyle({ ...guideStyleDefault, ...settings.guideStyle });
|
|
6515
|
+
if (settings.rulerSettings !== void 0) setSettingsRulerSettings({ ...rulerSettingsDefault, ...settings.rulerSettings });
|
|
6516
|
+
const workspace = snapshot.workspace;
|
|
6517
|
+
if (!workspace) {
|
|
6518
|
+
clearPersistedWorkspace();
|
|
6519
|
+
} else if (settings.persistOnReload ?? settingsPersistOnReload) {
|
|
6520
|
+
applyPersistedWorkspace(workspace);
|
|
6521
|
+
}
|
|
6522
|
+
ownerWindow.setTimeout(() => {
|
|
6523
|
+
applyingExternalPersistenceRef.current = false;
|
|
6524
|
+
}, 0);
|
|
6525
|
+
}, [applyPersistedWorkspace, clearPersistedWorkspace, guideStyleDefault, ownerWindow, rulerSettingsDefault, setMultiMeasureEnabled, setSelectNewGuideEnabled, setSettingsColorClickFormat, setSettingsColorFormats, setSettingsGuideColor, setSettingsHighlightColor, setSettingsHoverHighlight, setSettingsPersistOnReload, setSnapEnabled, setSnapGuidesEnabled, settingsPersistOnReload]);
|
|
6526
|
+
const previousPersistenceRef = useRef12(activePersistence);
|
|
6527
|
+
useEffect7(() => {
|
|
6528
|
+
if (previousPersistenceRef.current === activePersistence) return;
|
|
6529
|
+
previousPersistenceRef.current = activePersistence;
|
|
6530
|
+
applyPersistenceSnapshot(storedState);
|
|
6531
|
+
}, [activePersistence, applyPersistenceSnapshot, storedState]);
|
|
6532
|
+
useEffect7(() => {
|
|
6533
|
+
const unsubscribe = activePersistence.subscribe?.(applyPersistenceSnapshot);
|
|
6534
|
+
return unsubscribe;
|
|
6535
|
+
}, [activePersistence, applyPersistenceSnapshot]);
|
|
6536
|
+
const setEnabledPersisted = useCallback8(
|
|
4834
6537
|
(value) => {
|
|
4835
6538
|
const next = typeof value === "function" ? value(enabledRef.current) : value;
|
|
4836
6539
|
if (Object.is(next, enabledRef.current)) return;
|
|
@@ -4840,7 +6543,7 @@ function MeasurerClient({
|
|
|
4840
6543
|
},
|
|
4841
6544
|
[persistState, setEnabled]
|
|
4842
6545
|
);
|
|
4843
|
-
const setRulersVisiblePersisted =
|
|
6546
|
+
const setRulersVisiblePersisted = useCallback8(
|
|
4844
6547
|
(value) => {
|
|
4845
6548
|
const next = typeof value === "function" ? value(rulersVisibleRef.current) : value;
|
|
4846
6549
|
if (Object.is(next, rulersVisibleRef.current)) return;
|
|
@@ -4850,7 +6553,7 @@ function MeasurerClient({
|
|
|
4850
6553
|
},
|
|
4851
6554
|
[persistState, setRulersVisible]
|
|
4852
6555
|
);
|
|
4853
|
-
const setToolModePersisted =
|
|
6556
|
+
const setToolModePersisted = useCallback8(
|
|
4854
6557
|
(value) => {
|
|
4855
6558
|
const next = typeof value === "function" ? value(toolModeRef.current) : value;
|
|
4856
6559
|
if (Object.is(next, toolModeRef.current)) return;
|
|
@@ -4865,7 +6568,7 @@ function MeasurerClient({
|
|
|
4865
6568
|
},
|
|
4866
6569
|
[persistState, setToolMode, textInspector]
|
|
4867
6570
|
);
|
|
4868
|
-
const setGuideOrientationPersisted =
|
|
6571
|
+
const setGuideOrientationPersisted = useCallback8(
|
|
4869
6572
|
(value) => {
|
|
4870
6573
|
const next = typeof value === "function" ? value(guideOrientationRef.current) : value;
|
|
4871
6574
|
if (Object.is(next, guideOrientationRef.current)) return;
|
|
@@ -4875,7 +6578,7 @@ function MeasurerClient({
|
|
|
4875
6578
|
},
|
|
4876
6579
|
[persistState, setGuideOrientation]
|
|
4877
6580
|
);
|
|
4878
|
-
const setMeasurementsPersisted =
|
|
6581
|
+
const setMeasurementsPersisted = useCallback8(
|
|
4879
6582
|
(value) => {
|
|
4880
6583
|
const next = typeof value === "function" ? value(measurementsRef.current) : value;
|
|
4881
6584
|
if (Object.is(next, measurementsRef.current)) return;
|
|
@@ -4885,7 +6588,7 @@ function MeasurerClient({
|
|
|
4885
6588
|
},
|
|
4886
6589
|
[persistState, setMeasurements]
|
|
4887
6590
|
);
|
|
4888
|
-
const setActiveMeasurementPersisted =
|
|
6591
|
+
const setActiveMeasurementPersisted = useCallback8(
|
|
4889
6592
|
(value) => {
|
|
4890
6593
|
const next = typeof value === "function" ? value(activeMeasurementRef.current) : value;
|
|
4891
6594
|
if (Object.is(next, activeMeasurementRef.current)) return;
|
|
@@ -4895,7 +6598,7 @@ function MeasurerClient({
|
|
|
4895
6598
|
},
|
|
4896
6599
|
[persistState, setActiveMeasurement]
|
|
4897
6600
|
);
|
|
4898
|
-
const setHeldDistancesPersisted =
|
|
6601
|
+
const setHeldDistancesPersisted = useCallback8(
|
|
4899
6602
|
(value) => {
|
|
4900
6603
|
const next = typeof value === "function" ? value(heldDistancesRef.current) : value;
|
|
4901
6604
|
if (Object.is(next, heldDistancesRef.current)) return;
|
|
@@ -4905,7 +6608,7 @@ function MeasurerClient({
|
|
|
4905
6608
|
},
|
|
4906
6609
|
[persistState, setHeldDistances]
|
|
4907
6610
|
);
|
|
4908
|
-
const setGuidesPersisted =
|
|
6611
|
+
const setGuidesPersisted = useCallback8(
|
|
4909
6612
|
(value) => {
|
|
4910
6613
|
const next = typeof value === "function" ? value(guidesRef.current) : value;
|
|
4911
6614
|
if (Object.is(next, guidesRef.current)) return;
|
|
@@ -4915,7 +6618,7 @@ function MeasurerClient({
|
|
|
4915
6618
|
},
|
|
4916
6619
|
[persistState, setGuides]
|
|
4917
6620
|
);
|
|
4918
|
-
const setSelectedGuideIdsPersisted =
|
|
6621
|
+
const setSelectedGuideIdsPersisted = useCallback8(
|
|
4919
6622
|
(value) => {
|
|
4920
6623
|
const next = typeof value === "function" ? value(selectedGuideIdsRef.current) : value;
|
|
4921
6624
|
if (Object.is(next, selectedGuideIdsRef.current)) return;
|
|
@@ -4973,15 +6676,15 @@ function MeasurerClient({
|
|
|
4973
6676
|
clearSelectionRect
|
|
4974
6677
|
}
|
|
4975
6678
|
});
|
|
4976
|
-
const undo =
|
|
6679
|
+
const undo = useCallback8(() => {
|
|
4977
6680
|
if (toolMode === "text-inspector" && textInspector.undo()) return;
|
|
4978
6681
|
undoHistory();
|
|
4979
6682
|
}, [textInspector, toolMode, undoHistory]);
|
|
4980
|
-
const redo =
|
|
6683
|
+
const redo = useCallback8(() => {
|
|
4981
6684
|
if (toolMode === "text-inspector" && textInspector.redo()) return;
|
|
4982
6685
|
redoHistory();
|
|
4983
6686
|
}, [redoHistory, textInspector, toolMode]);
|
|
4984
|
-
const clearAll =
|
|
6687
|
+
const clearAll = useCallback8(() => {
|
|
4985
6688
|
if (toolMode === "text-inspector") {
|
|
4986
6689
|
textInspector.clear();
|
|
4987
6690
|
}
|
|
@@ -5021,7 +6724,7 @@ function MeasurerClient({
|
|
|
5021
6724
|
textInspector,
|
|
5022
6725
|
toolMode
|
|
5023
6726
|
]);
|
|
5024
|
-
const removeSelectedGuides =
|
|
6727
|
+
const removeSelectedGuides = useCallback8(() => {
|
|
5025
6728
|
if (selectedGuideIds.length === 0) return false;
|
|
5026
6729
|
recordSnapshot();
|
|
5027
6730
|
setGuidesPersisted(
|
|
@@ -5035,6 +6738,29 @@ function MeasurerClient({
|
|
|
5035
6738
|
setGuidesPersisted,
|
|
5036
6739
|
setSelectedGuideIdsPersisted
|
|
5037
6740
|
]);
|
|
6741
|
+
const openColorPicker = useCallback8(async () => {
|
|
6742
|
+
const EyeDropper = ownerWindow.EyeDropper;
|
|
6743
|
+
setEnabledWithHistory(true);
|
|
6744
|
+
setToolModeWithHistory("none");
|
|
6745
|
+
setColorPickerActive(true);
|
|
6746
|
+
setColorPickerSample(null);
|
|
6747
|
+
setColorPickerUnsupported(!EyeDropper);
|
|
6748
|
+
if (!EyeDropper) return;
|
|
6749
|
+
try {
|
|
6750
|
+
const result = await new EyeDropper().open();
|
|
6751
|
+
const nextSample = parseCssColor(result.sRGBHex);
|
|
6752
|
+
if (!nextSample) return;
|
|
6753
|
+
setColorPickerSample(nextSample);
|
|
6754
|
+
const clipboardWrite = ownerWindow.navigator.clipboard?.writeText(
|
|
6755
|
+
formatColor(nextSample, settingsColorClickFormat)
|
|
6756
|
+
);
|
|
6757
|
+
void clipboardWrite?.catch(() => void 0);
|
|
6758
|
+
} catch (error) {
|
|
6759
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
6760
|
+
setColorPickerActive(false);
|
|
6761
|
+
}
|
|
6762
|
+
}
|
|
6763
|
+
}, [ownerWindow, setEnabledWithHistory, setToolModeWithHistory, settingsColorClickFormat]);
|
|
5038
6764
|
useHotkeys({
|
|
5039
6765
|
eventTarget: ownerWindow,
|
|
5040
6766
|
clearAll,
|
|
@@ -5047,7 +6773,13 @@ function MeasurerClient({
|
|
|
5047
6773
|
setAltPressed,
|
|
5048
6774
|
isOverlayActive: () => enabled && (toolMode !== "none" || toolbarActive),
|
|
5049
6775
|
setGuideOrientation: setGuideOrientationWithHistory,
|
|
5050
|
-
onInteract: () => setToolbarActive(true)
|
|
6776
|
+
onInteract: () => setToolbarActive(true),
|
|
6777
|
+
onColorPicker: openColorPicker,
|
|
6778
|
+
onToggleXray: () => setXrayVisible((previous) => !previous),
|
|
6779
|
+
onToggleSettings: () => setSettingsOpen((previous) => !previous),
|
|
6780
|
+
isSettingsOpen: () => settingsOpen,
|
|
6781
|
+
onCloseColorPicker: () => setColorPickerActive(false),
|
|
6782
|
+
isColorPickerActive: () => colorPickerActive
|
|
5051
6783
|
});
|
|
5052
6784
|
useResizeSync({
|
|
5053
6785
|
document: ownerDocument,
|
|
@@ -5059,7 +6791,7 @@ function MeasurerClient({
|
|
|
5059
6791
|
setGuides: setGuidesPersisted,
|
|
5060
6792
|
selectedElementRef
|
|
5061
6793
|
});
|
|
5062
|
-
|
|
6794
|
+
useEffect7(() => {
|
|
5063
6795
|
const handleScroll = () => {
|
|
5064
6796
|
const next = {
|
|
5065
6797
|
x: ownerWindow.scrollX,
|
|
@@ -5083,6 +6815,7 @@ function MeasurerClient({
|
|
|
5083
6815
|
document: ownerDocument,
|
|
5084
6816
|
window: ownerWindow,
|
|
5085
6817
|
enabled,
|
|
6818
|
+
selectionEnabled: toolMode === "select" && !settingsOpen,
|
|
5086
6819
|
selectedElementRef,
|
|
5087
6820
|
hoverElementRef,
|
|
5088
6821
|
setSelectedMeasurement,
|
|
@@ -5092,7 +6825,7 @@ function MeasurerClient({
|
|
|
5092
6825
|
setActiveMeasurement: setActiveMeasurementPersisted,
|
|
5093
6826
|
setHeldDistances: setHeldDistancesPersisted
|
|
5094
6827
|
});
|
|
5095
|
-
|
|
6828
|
+
useEffect7(() => {
|
|
5096
6829
|
if (!toolbarActive || toolMode !== "none") return;
|
|
5097
6830
|
const handlePointerDown2 = (event) => {
|
|
5098
6831
|
const toolbarNode = toolbarRef.current;
|
|
@@ -5104,9 +6837,10 @@ function MeasurerClient({
|
|
|
5104
6837
|
ownerWindow.removeEventListener("pointerdown", handlePointerDown2);
|
|
5105
6838
|
};
|
|
5106
6839
|
}, [ownerWindow, toolbarActive, toolMode]);
|
|
5107
|
-
|
|
6840
|
+
useEffect7(() => {
|
|
5108
6841
|
if (!enabled) return;
|
|
5109
6842
|
const handleGuidePointerDown2 = (event) => {
|
|
6843
|
+
if (settingsOpen) return;
|
|
5110
6844
|
if (toolbarRef.current?.contains(event.target)) return;
|
|
5111
6845
|
const guideTarget = event.composedPath().some(
|
|
5112
6846
|
(target) => target instanceof ownerWindow.Element && target.hasAttribute("data-mesurer-guide")
|
|
@@ -5189,16 +6923,30 @@ function MeasurerClient({
|
|
|
5189
6923
|
ownerWindow,
|
|
5190
6924
|
setGuidesPersisted,
|
|
5191
6925
|
setSelectedGuideIdsPersisted,
|
|
6926
|
+
settingsOpen,
|
|
5192
6927
|
toolMode
|
|
5193
6928
|
]);
|
|
5194
|
-
|
|
5195
|
-
if (toolMode === "text-inspector") {
|
|
6929
|
+
useEffect7(() => {
|
|
6930
|
+
if (toolMode === "text-inspector" && !settingsOpen) {
|
|
5196
6931
|
textInspector.enable();
|
|
5197
6932
|
} else {
|
|
5198
6933
|
textInspector.disable();
|
|
5199
6934
|
}
|
|
5200
|
-
}, [textInspector, toolMode]);
|
|
5201
|
-
|
|
6935
|
+
}, [settingsOpen, textInspector, toolMode]);
|
|
6936
|
+
const selectionContextRef = useRef12({ toolMode, settingsOpen });
|
|
6937
|
+
if (selectionContextRef.current.toolMode !== toolMode || selectionContextRef.current.settingsOpen !== settingsOpen) {
|
|
6938
|
+
selectionContextRef.current = { toolMode, settingsOpen };
|
|
6939
|
+
if (!(toolMode === "select" && !settingsOpen)) {
|
|
6940
|
+
setSelectedElement(null);
|
|
6941
|
+
setHoverElement(null);
|
|
6942
|
+
setHoverRect(null);
|
|
6943
|
+
setHoverPointer(null);
|
|
6944
|
+
setSelectedMeasurement(null);
|
|
6945
|
+
setSelectedMeasurements([]);
|
|
6946
|
+
clearSelectionRect();
|
|
6947
|
+
}
|
|
6948
|
+
}
|
|
6949
|
+
useEffect7(() => {
|
|
5202
6950
|
let style = ownerDocument.getElementById(XRAY_STYLE_ID);
|
|
5203
6951
|
if (!style) {
|
|
5204
6952
|
style = ownerDocument.createElement("style");
|
|
@@ -5206,7 +6954,7 @@ function MeasurerClient({
|
|
|
5206
6954
|
style.textContent = XRAY_STYLES;
|
|
5207
6955
|
ownerDocument.head.appendChild(style);
|
|
5208
6956
|
}
|
|
5209
|
-
if (
|
|
6957
|
+
if (xrayVisible) {
|
|
5210
6958
|
ownerDocument.body.classList.add("xray-mode");
|
|
5211
6959
|
} else {
|
|
5212
6960
|
ownerDocument.body.classList.remove("xray-mode");
|
|
@@ -5214,13 +6962,13 @@ function MeasurerClient({
|
|
|
5214
6962
|
return () => {
|
|
5215
6963
|
ownerDocument.body.classList.remove("xray-mode");
|
|
5216
6964
|
};
|
|
5217
|
-
}, [ownerDocument,
|
|
5218
|
-
|
|
6965
|
+
}, [ownerDocument, xrayVisible]);
|
|
6966
|
+
useEffect7(() => {
|
|
5219
6967
|
return () => {
|
|
5220
6968
|
textInspector.destroy();
|
|
5221
6969
|
};
|
|
5222
6970
|
}, [textInspector]);
|
|
5223
|
-
|
|
6971
|
+
useEffect7(() => {
|
|
5224
6972
|
const hasSelectionAnimationState = !!selectionOriginRect || !!selectedMeasurement?.originRect || selectedMeasurements.some((measurement) => !!measurement.originRect);
|
|
5225
6973
|
if (!hasSelectionAnimationState) {
|
|
5226
6974
|
if (selectionAnimationCleanupTimeoutRef.current !== null) {
|
|
@@ -5301,9 +7049,9 @@ function MeasurerClient({
|
|
|
5301
7049
|
guidesEnabled,
|
|
5302
7050
|
guidePreview,
|
|
5303
7051
|
displayedMeasurements,
|
|
5304
|
-
hoverHighlightEnabled,
|
|
5305
|
-
highlightColor,
|
|
5306
|
-
guideColor
|
|
7052
|
+
hoverHighlightEnabled: settingsHoverHighlight,
|
|
7053
|
+
highlightColor: settingsHighlightColor,
|
|
7054
|
+
guideColor: settingsGuideColor
|
|
5307
7055
|
});
|
|
5308
7056
|
const {
|
|
5309
7057
|
handlePointerDown,
|
|
@@ -5320,10 +7068,12 @@ function MeasurerClient({
|
|
|
5320
7068
|
clearGuideDragHold,
|
|
5321
7069
|
scheduleGuideDragHold,
|
|
5322
7070
|
enabled,
|
|
7071
|
+
settingsOpen,
|
|
5323
7072
|
toolMode,
|
|
5324
7073
|
guidesEnabled,
|
|
5325
7074
|
snapEnabled,
|
|
5326
7075
|
snapGuidesEnabled,
|
|
7076
|
+
selectNewGuideEnabled,
|
|
5327
7077
|
altPressed,
|
|
5328
7078
|
guideOrientation,
|
|
5329
7079
|
hoverHighlightEnabled,
|
|
@@ -5356,7 +7106,7 @@ function MeasurerClient({
|
|
|
5356
7106
|
setHoverPointer,
|
|
5357
7107
|
clearSelectionRect
|
|
5358
7108
|
});
|
|
5359
|
-
const removeHeldDistance =
|
|
7109
|
+
const removeHeldDistance = useCallback8(
|
|
5360
7110
|
(id) => {
|
|
5361
7111
|
recordSnapshot();
|
|
5362
7112
|
setHeldDistancesPersisted(
|
|
@@ -5365,42 +7115,62 @@ function MeasurerClient({
|
|
|
5365
7115
|
},
|
|
5366
7116
|
[recordSnapshot, setHeldDistancesPersisted]
|
|
5367
7117
|
);
|
|
5368
|
-
const
|
|
7118
|
+
const snapGuidePosition = useCallback8(
|
|
7119
|
+
(orientation, position, draggingGuideId2 = null) => getSnapGuidePosition({
|
|
7120
|
+
orientation,
|
|
7121
|
+
point: orientation === "vertical" ? { x: position, y: 0 } : { x: 0, y: position },
|
|
7122
|
+
snapGuidesEnabled,
|
|
7123
|
+
overlayNode: overlayRef.current,
|
|
7124
|
+
guides,
|
|
7125
|
+
draggingGuideId: draggingGuideId2,
|
|
7126
|
+
document: ownerDocument
|
|
7127
|
+
}),
|
|
7128
|
+
[guides, ownerDocument, overlayRef, snapGuidesEnabled]
|
|
7129
|
+
);
|
|
7130
|
+
const startGuideFromRuler = useCallback8(
|
|
5369
7131
|
(orientation, position) => {
|
|
5370
7132
|
const id = createId();
|
|
5371
7133
|
const commit = createActionCommit();
|
|
5372
7134
|
commit();
|
|
5373
7135
|
setSelectedGuideIdsPersisted([]);
|
|
5374
|
-
setGuidesPersisted((prev) => [
|
|
7136
|
+
setGuidesPersisted((prev) => [
|
|
7137
|
+
...prev,
|
|
7138
|
+
{ id, orientation, position: snapGuidePosition(orientation, position) }
|
|
7139
|
+
]);
|
|
5375
7140
|
return id;
|
|
5376
7141
|
},
|
|
5377
7142
|
[
|
|
5378
7143
|
createActionCommit,
|
|
5379
7144
|
setGuidesPersisted,
|
|
5380
|
-
setSelectedGuideIdsPersisted
|
|
7145
|
+
setSelectedGuideIdsPersisted,
|
|
7146
|
+
snapGuidePosition
|
|
5381
7147
|
]
|
|
5382
7148
|
);
|
|
5383
|
-
const moveGuideFromRuler =
|
|
7149
|
+
const moveGuideFromRuler = useCallback8(
|
|
5384
7150
|
(id, position) => {
|
|
5385
7151
|
setGuidesPersisted(
|
|
5386
|
-
(prev) => prev.map(
|
|
7152
|
+
(prev) => prev.map(
|
|
7153
|
+
(guide) => guide.id === id ? { ...guide, position: snapGuidePosition(guide.orientation, position, id) } : guide
|
|
7154
|
+
)
|
|
5387
7155
|
);
|
|
5388
7156
|
},
|
|
5389
|
-
[setGuidesPersisted]
|
|
7157
|
+
[setGuidesPersisted, snapGuidePosition]
|
|
5390
7158
|
);
|
|
5391
|
-
const finishGuideFromRuler =
|
|
7159
|
+
const finishGuideFromRuler = useCallback8(
|
|
5392
7160
|
(id) => {
|
|
5393
|
-
|
|
7161
|
+
if (selectNewGuideEnabled) {
|
|
7162
|
+
setSelectedGuideIdsPersisted([id]);
|
|
7163
|
+
}
|
|
5394
7164
|
},
|
|
5395
|
-
[setSelectedGuideIdsPersisted]
|
|
7165
|
+
[selectNewGuideEnabled, setSelectedGuideIdsPersisted]
|
|
5396
7166
|
);
|
|
5397
|
-
const cancelGuideFromRuler =
|
|
7167
|
+
const cancelGuideFromRuler = useCallback8(
|
|
5398
7168
|
(id) => {
|
|
5399
7169
|
setGuidesPersisted((prev) => prev.filter((guide) => guide.id !== id));
|
|
5400
7170
|
},
|
|
5401
7171
|
[setGuidesPersisted]
|
|
5402
7172
|
);
|
|
5403
|
-
const handleGuidePointerDown =
|
|
7173
|
+
const handleGuidePointerDown = useCallback8(
|
|
5404
7174
|
(guide, event) => {
|
|
5405
7175
|
const commit = createActionCommit();
|
|
5406
7176
|
if (!enabled) return;
|
|
@@ -5426,7 +7196,7 @@ function MeasurerClient({
|
|
|
5426
7196
|
setSelectedGuideIdsPersisted
|
|
5427
7197
|
]
|
|
5428
7198
|
);
|
|
5429
|
-
const handleGuidePointerUp =
|
|
7199
|
+
const handleGuidePointerUp = useCallback8(
|
|
5430
7200
|
(guide, event) => {
|
|
5431
7201
|
event.stopPropagation();
|
|
5432
7202
|
clearGuideDragHold();
|
|
@@ -5437,16 +7207,19 @@ function MeasurerClient({
|
|
|
5437
7207
|
},
|
|
5438
7208
|
[clearGuideDragHold, setDraggingGuideId]
|
|
5439
7209
|
);
|
|
7210
|
+
const overlayInteractive = enabled && !settingsOpen;
|
|
5440
7211
|
return createPortal(
|
|
5441
|
-
/* @__PURE__ */
|
|
7212
|
+
/* @__PURE__ */ jsxs11(
|
|
5442
7213
|
"div",
|
|
5443
7214
|
{
|
|
5444
7215
|
ref: overlayRef,
|
|
5445
7216
|
className: "mesurer-root msr:pointer-events-none msr:fixed msr:inset-0 msr:z-50",
|
|
5446
7217
|
children: [
|
|
5447
|
-
enabled && rulersVisible ? /* @__PURE__ */
|
|
7218
|
+
enabled && rulersVisible && !settingsOpen ? /* @__PURE__ */ jsx12(
|
|
5448
7219
|
RulersOverlay,
|
|
5449
7220
|
{
|
|
7221
|
+
ownerWindow,
|
|
7222
|
+
settings: settingsRulerSettings,
|
|
5450
7223
|
onStartGuide: startGuideFromRuler,
|
|
5451
7224
|
onMoveGuide: moveGuideFromRuler,
|
|
5452
7225
|
onFinishGuide: finishGuideFromRuler,
|
|
@@ -5455,12 +7228,13 @@ function MeasurerClient({
|
|
|
5455
7228
|
selectedGuideIds
|
|
5456
7229
|
}
|
|
5457
7230
|
) : null,
|
|
5458
|
-
/* @__PURE__ */
|
|
7231
|
+
/* @__PURE__ */ jsx12(
|
|
5459
7232
|
MeasurerOverlay,
|
|
5460
7233
|
{
|
|
5461
|
-
enabled,
|
|
7234
|
+
enabled: enabled && (!settingsOpen || guides.length > 0),
|
|
7235
|
+
interactive: overlayInteractive,
|
|
5462
7236
|
toolMode,
|
|
5463
|
-
guidePointerEvents:
|
|
7237
|
+
guidePointerEvents: overlayInteractive && (toolMode !== "none" || rulersVisible),
|
|
5464
7238
|
guidesEnabled,
|
|
5465
7239
|
altPressed,
|
|
5466
7240
|
isDragging,
|
|
@@ -5488,6 +7262,7 @@ function MeasurerClient({
|
|
|
5488
7262
|
guideColorActive,
|
|
5489
7263
|
guideColorHover,
|
|
5490
7264
|
guideColorDefault,
|
|
7265
|
+
guideStyle: settingsGuideStyle,
|
|
5491
7266
|
onPointerDown: handlePointerDown,
|
|
5492
7267
|
onPointerMove: handlePointerMove,
|
|
5493
7268
|
onPointerUp: handlePointerUp,
|
|
@@ -5498,7 +7273,20 @@ function MeasurerClient({
|
|
|
5498
7273
|
onGuidePointerCancel: handleGuidePointerUp
|
|
5499
7274
|
}
|
|
5500
7275
|
),
|
|
5501
|
-
/* @__PURE__ */
|
|
7276
|
+
/* @__PURE__ */ jsx12(
|
|
7277
|
+
ColorPicker,
|
|
7278
|
+
{
|
|
7279
|
+
active: colorPickerActive,
|
|
7280
|
+
sample: colorPickerSample,
|
|
7281
|
+
unsupported: colorPickerUnsupported,
|
|
7282
|
+
ownerWindow,
|
|
7283
|
+
toolbarRef,
|
|
7284
|
+
formats: settingsColorFormats,
|
|
7285
|
+
favoriteFormat: settingsColorClickFormat,
|
|
7286
|
+
onClose: () => setColorPickerActive(false)
|
|
7287
|
+
}
|
|
7288
|
+
),
|
|
7289
|
+
/* @__PURE__ */ jsx12(
|
|
5502
7290
|
Toolbar,
|
|
5503
7291
|
{
|
|
5504
7292
|
ref: toolbarRef,
|
|
@@ -5506,11 +7294,45 @@ function MeasurerClient({
|
|
|
5506
7294
|
toolMode,
|
|
5507
7295
|
setEnabled: setEnabledWithHistory,
|
|
5508
7296
|
setToolMode: setToolModeWithHistory,
|
|
7297
|
+
xrayVisible,
|
|
7298
|
+
setXrayVisible,
|
|
5509
7299
|
rulersVisible,
|
|
5510
7300
|
setRulersVisible: setRulersVisiblePersisted,
|
|
5511
7301
|
guideOrientation,
|
|
5512
7302
|
setGuideOrientation: setGuideOrientationWithHistory,
|
|
5513
|
-
onInteract: () => setToolbarActive(true)
|
|
7303
|
+
onInteract: () => setToolbarActive(true),
|
|
7304
|
+
colorPickerActive,
|
|
7305
|
+
setColorPickerActive,
|
|
7306
|
+
onColorPickerClick: openColorPicker,
|
|
7307
|
+
settingsOpen,
|
|
7308
|
+
setSettingsOpen,
|
|
7309
|
+
highlightColor: settingsHighlightColor,
|
|
7310
|
+
setHighlightColor: setSettingsHighlightColor,
|
|
7311
|
+
guideColor: settingsGuideColor,
|
|
7312
|
+
setGuideColor: setSettingsGuideColor,
|
|
7313
|
+
hoverHighlight: settingsHoverHighlight,
|
|
7314
|
+
setHoverHighlight: setSettingsHoverHighlight,
|
|
7315
|
+
persistOnReload: settingsPersistOnReload,
|
|
7316
|
+
setPersistOnReload: setSettingsPersistOnReload,
|
|
7317
|
+
colorPickerFormats: settingsColorFormats,
|
|
7318
|
+
setColorPickerFormats: setSettingsColorFormats,
|
|
7319
|
+
colorPickerClickFormat: settingsColorClickFormat,
|
|
7320
|
+
setColorPickerClickFormat: setSettingsColorClickFormat,
|
|
7321
|
+
snapEnabled,
|
|
7322
|
+
setSnapEnabled,
|
|
7323
|
+
snapGuidesEnabled,
|
|
7324
|
+
setSnapGuidesEnabled,
|
|
7325
|
+
selectNewGuideEnabled,
|
|
7326
|
+
setSelectNewGuideEnabled,
|
|
7327
|
+
multiMeasureEnabled,
|
|
7328
|
+
setMultiMeasureEnabled,
|
|
7329
|
+
guideStyle: settingsGuideStyle,
|
|
7330
|
+
setGuideStyle: setSettingsGuideStyle,
|
|
7331
|
+
rulerSettings: settingsRulerSettings,
|
|
7332
|
+
setRulerSettings: setSettingsRulerSettings,
|
|
7333
|
+
initialSettingsTab,
|
|
7334
|
+
onResetSettings: resetSettings,
|
|
7335
|
+
onClearWorkspace: clearWorkspace
|
|
5514
7336
|
}
|
|
5515
7337
|
)
|
|
5516
7338
|
]
|
|
@@ -5525,14 +7347,24 @@ function Measurer({
|
|
|
5525
7347
|
hoverHighlightEnabled = true,
|
|
5526
7348
|
persistOnReload = false,
|
|
5527
7349
|
portalTarget,
|
|
5528
|
-
persistKey
|
|
7350
|
+
persistKey,
|
|
7351
|
+
colorPickerFormats = ["hex", "rgb", "oklch"],
|
|
7352
|
+
colorPickerClickFormat = "hex",
|
|
7353
|
+
snapEnabled = true,
|
|
7354
|
+
snapGuidesEnabled = true,
|
|
7355
|
+
selectNewGuideEnabled = true,
|
|
7356
|
+
multiMeasureEnabled = false,
|
|
7357
|
+
guideStyle,
|
|
7358
|
+
rulerSettings,
|
|
7359
|
+
persistence,
|
|
7360
|
+
onPersistenceError
|
|
5529
7361
|
}) {
|
|
5530
7362
|
if (typeof document !== "undefined") {
|
|
5531
7363
|
ensureMeasurerStyles(MESURER_STYLES, portalTarget);
|
|
5532
7364
|
}
|
|
5533
7365
|
const hydrated = useHydrated();
|
|
5534
7366
|
if (!hydrated) return null;
|
|
5535
|
-
return /* @__PURE__ */
|
|
7367
|
+
return /* @__PURE__ */ jsx12(
|
|
5536
7368
|
MeasurerClient,
|
|
5537
7369
|
{
|
|
5538
7370
|
highlightColor,
|
|
@@ -5540,12 +7372,26 @@ function Measurer({
|
|
|
5540
7372
|
hoverHighlightEnabled,
|
|
5541
7373
|
persistOnReload,
|
|
5542
7374
|
persistKey,
|
|
7375
|
+
colorPickerFormats,
|
|
7376
|
+
colorPickerClickFormat,
|
|
7377
|
+
snapEnabled,
|
|
7378
|
+
snapGuidesEnabled,
|
|
7379
|
+
selectNewGuideEnabled,
|
|
7380
|
+
multiMeasureEnabled,
|
|
7381
|
+
guideStyle: { ...DEFAULT_GUIDE_STYLE, ...guideStyle },
|
|
7382
|
+
rulerSettings: { ...DEFAULT_RULER_SETTINGS, ...rulerSettings },
|
|
7383
|
+
persistence,
|
|
7384
|
+
onPersistenceError,
|
|
5543
7385
|
portalTarget: portalTarget ?? document.body
|
|
5544
7386
|
}
|
|
5545
7387
|
);
|
|
5546
7388
|
}
|
|
5547
7389
|
export {
|
|
7390
|
+
MESURER_STORAGE_VERSION,
|
|
5548
7391
|
Measurer,
|
|
5549
7392
|
TextInspector,
|
|
5550
|
-
|
|
7393
|
+
createLocalStoragePersistence,
|
|
7394
|
+
createTextInspector,
|
|
7395
|
+
normalizeStoredSettings,
|
|
7396
|
+
normalizeStoredWorkspace
|
|
5551
7397
|
};
|