@rogieking/figui3 6.18.2 → 6.18.4
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/components.css +1 -1
- package/dist/components.css +1 -1
- package/dist/fig-editor.css +1 -1
- package/dist/fig-lab.css +1 -1
- package/dist/fig-lab.js +14 -14
- package/dist/fig.css +1 -1
- package/fig-lab.css +18 -7
- package/fig-lab.js +168 -24
- package/package.json +1 -1
package/fig-lab.css
CHANGED
|
@@ -273,15 +273,20 @@ propskit-select {
|
|
|
273
273
|
|
|
274
274
|
fig-select {
|
|
275
275
|
position: relative;
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
display: flex;
|
|
277
|
+
flex: 1 1 auto;
|
|
278
|
+
width: 100%;
|
|
278
279
|
min-width: 0;
|
|
279
|
-
|
|
280
|
+
height: 100%;
|
|
280
281
|
border-radius: var(--radius-medium);
|
|
281
282
|
background: transparent;
|
|
282
283
|
box-shadow: none;
|
|
283
284
|
|
|
284
|
-
--fig-select-trigger-width:
|
|
285
|
+
--fig-select-trigger-width: 100%;
|
|
286
|
+
|
|
287
|
+
&::part(label) {
|
|
288
|
+
text-align: right;
|
|
289
|
+
}
|
|
285
290
|
}
|
|
286
291
|
}
|
|
287
292
|
}
|
|
@@ -848,6 +853,11 @@ body.fig-lab-move-active * {
|
|
|
848
853
|
cursor: var(--fig-lab-cursor-move) !important;
|
|
849
854
|
}
|
|
850
855
|
|
|
856
|
+
body.fig-lab-rotate-active,
|
|
857
|
+
body.fig-lab-rotate-active * {
|
|
858
|
+
cursor: var(--fig-lab-cursor-rotate) !important;
|
|
859
|
+
}
|
|
860
|
+
|
|
851
861
|
fig-canvas-control {
|
|
852
862
|
display: contents;
|
|
853
863
|
--fig-canvas-control-line-stroke: light-dark(
|
|
@@ -888,13 +898,14 @@ fig-canvas-control {
|
|
|
888
898
|
--fig-handle-padding: 2px !important;
|
|
889
899
|
}
|
|
890
900
|
&[selected]:not([selected="false"]){
|
|
891
|
-
--fig-handle-padding:
|
|
901
|
+
--fig-handle-padding: 2px;
|
|
892
902
|
}
|
|
893
903
|
}
|
|
894
904
|
}
|
|
895
905
|
|
|
906
|
+
/* Point handle hover — resize/rotate hit-areas set cursor via JS !important. */
|
|
896
907
|
fig-handle:hover,
|
|
897
|
-
fig-handle:hover .fig-handle-hit-area {
|
|
908
|
+
fig-handle:hover .fig-handle-hit-area:not([data-cursor]) {
|
|
898
909
|
cursor: var(--fig-lab-cursor) !important;
|
|
899
910
|
}
|
|
900
911
|
|
|
@@ -904,7 +915,7 @@ fig-canvas-control {
|
|
|
904
915
|
}
|
|
905
916
|
|
|
906
917
|
fig-handle:is(:active, .active, .dragging),
|
|
907
|
-
fig-handle:is(:active, .active, .dragging) .fig-handle-hit-area {
|
|
918
|
+
fig-handle:is(:active, .active, .dragging) .fig-handle-hit-area:not([data-cursor]) {
|
|
908
919
|
cursor: var(--fig-lab-cursor-move) !important;
|
|
909
920
|
}
|
|
910
921
|
|
package/fig-lab.js
CHANGED
|
@@ -453,6 +453,9 @@ class PropskitSelect extends HTMLElement {
|
|
|
453
453
|
#boundHandleInput = null;
|
|
454
454
|
#boundHandleChange = null;
|
|
455
455
|
#boundHandleClick = this.#handleClick.bind(this);
|
|
456
|
+
#boundHandlePointerDown = this.#handlePointerDown.bind(this);
|
|
457
|
+
/** True when pointerdown saw the menu open — skip click-to-open after light-dismiss. */
|
|
458
|
+
#closeGesture = false;
|
|
456
459
|
|
|
457
460
|
static get observedAttributes() {
|
|
458
461
|
return ["label", "direction", "aria-label", "options", "value"];
|
|
@@ -465,6 +468,8 @@ class PropskitSelect extends HTMLElement {
|
|
|
465
468
|
this.#bindSelectEvents();
|
|
466
469
|
this.removeEventListener("click", this.#boundHandleClick);
|
|
467
470
|
this.addEventListener("click", this.#boundHandleClick);
|
|
471
|
+
this.removeEventListener("pointerdown", this.#boundHandlePointerDown, true);
|
|
472
|
+
this.addEventListener("pointerdown", this.#boundHandlePointerDown, true);
|
|
468
473
|
|
|
469
474
|
if (!this.#observer) {
|
|
470
475
|
this.#observer = new MutationObserver((mutations) => {
|
|
@@ -497,6 +502,7 @@ class PropskitSelect extends HTMLElement {
|
|
|
497
502
|
this.#observer?.disconnect();
|
|
498
503
|
this.#unbindSelectEvents();
|
|
499
504
|
this.removeEventListener("click", this.#boundHandleClick);
|
|
505
|
+
this.removeEventListener("pointerdown", this.#boundHandlePointerDown, true);
|
|
500
506
|
}
|
|
501
507
|
|
|
502
508
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
@@ -628,14 +634,44 @@ class PropskitSelect extends HTMLElement {
|
|
|
628
634
|
);
|
|
629
635
|
}
|
|
630
636
|
|
|
637
|
+
#isSelectMenuOpen() {
|
|
638
|
+
if (!this.#select) return false;
|
|
639
|
+
if (this.#select.open) return true;
|
|
640
|
+
const popup = this.#select.shadowRoot?.querySelector(
|
|
641
|
+
'dialog[is="fig-popup"]',
|
|
642
|
+
);
|
|
643
|
+
return Boolean(popup?.open || popup?.matches?.(":open"));
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
#handlePointerDown(event) {
|
|
647
|
+
if (!(event.target instanceof Element)) return;
|
|
648
|
+
// fig-select owns its trigger/option clicks.
|
|
649
|
+
if (event.target.closest("fig-select")) {
|
|
650
|
+
this.#closeGesture = false;
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
// Light-dismiss closes on pointerdown; remember so click doesn't reopen.
|
|
654
|
+
this.#closeGesture = this.#isSelectMenuOpen();
|
|
655
|
+
}
|
|
656
|
+
|
|
631
657
|
#handleClick(event) {
|
|
632
658
|
if (event.target instanceof Element && event.target.closest("fig-select")) {
|
|
659
|
+
this.#closeGesture = false;
|
|
633
660
|
return;
|
|
634
661
|
}
|
|
635
|
-
this.#select
|
|
636
|
-
|
|
637
|
-
|
|
662
|
+
if (!this.#select || figLabBooleanAttribute(this.#select, "disabled")) {
|
|
663
|
+
this.#closeGesture = false;
|
|
664
|
+
return;
|
|
638
665
|
}
|
|
666
|
+
this.#select.focus();
|
|
667
|
+
|
|
668
|
+
if (this.#closeGesture || this.#isSelectMenuOpen()) {
|
|
669
|
+
this.#closeGesture = false;
|
|
670
|
+
this.#select.open = false;
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
this.#select.open = true;
|
|
639
675
|
}
|
|
640
676
|
|
|
641
677
|
get value() {
|
|
@@ -1722,6 +1758,11 @@ class FigCanvasControl extends HTMLElement {
|
|
|
1722
1758
|
#moveCursorPrevBodyCursor = "";
|
|
1723
1759
|
#moveCursorPrevBodyCursorPriority = "";
|
|
1724
1760
|
#boundMoveCursorEnd = null;
|
|
1761
|
+
#rotateCursorPointerId = null;
|
|
1762
|
+
#rotateCursorHandle = null;
|
|
1763
|
+
#rotateCursorPrevBodyCursor = "";
|
|
1764
|
+
#rotateCursorPrevBodyCursorPriority = "";
|
|
1765
|
+
#boundRotateCursorEnd = null;
|
|
1725
1766
|
|
|
1726
1767
|
get #type() {
|
|
1727
1768
|
return this.getAttribute("type") || "point";
|
|
@@ -1822,7 +1863,9 @@ class FigCanvasControl extends HTMLElement {
|
|
|
1822
1863
|
disconnectedCallback() {
|
|
1823
1864
|
this.#teardownRadiusDrag();
|
|
1824
1865
|
this.#deactivateMoveCursor();
|
|
1866
|
+
this.#deactivateRotateCursor();
|
|
1825
1867
|
document.body.classList.remove("fig-lab-move-active");
|
|
1868
|
+
document.body.classList.remove("fig-lab-rotate-active");
|
|
1826
1869
|
}
|
|
1827
1870
|
|
|
1828
1871
|
attributeChangedCallback(name, oldVal, newVal) {
|
|
@@ -1984,19 +2027,27 @@ class FigCanvasControl extends HTMLElement {
|
|
|
1984
2027
|
this.#createSecondHandle(disabled, tooltips, handleSurface);
|
|
1985
2028
|
}
|
|
1986
2029
|
|
|
1987
|
-
this.#
|
|
1988
|
-
this.#
|
|
1989
|
-
this.#
|
|
2030
|
+
this.#setupHandleDragCursor(this.#pointHandle);
|
|
2031
|
+
this.#setupHandleDragCursor(this.#angleHandle);
|
|
2032
|
+
this.#setupHandleDragCursor(this.#secondHandle);
|
|
1990
2033
|
this.#setupEventListeners();
|
|
1991
2034
|
this.#wireHoverTooltips();
|
|
1992
2035
|
requestAnimationFrame(() => this.#syncPositions());
|
|
1993
2036
|
}
|
|
1994
2037
|
|
|
1995
|
-
#
|
|
2038
|
+
#setupHandleDragCursor(handle) {
|
|
1996
2039
|
if (!handle) return;
|
|
1997
2040
|
handle.addEventListener(
|
|
1998
2041
|
"pointerdown",
|
|
1999
|
-
(e) =>
|
|
2042
|
+
(e) => {
|
|
2043
|
+
// Hit-area (outside ring) = rotate; handle body = move/resize.
|
|
2044
|
+
const onHitArea = e.target?.classList?.contains("fig-handle-hit-area");
|
|
2045
|
+
if (onHitArea && handle.querySelector(".fig-handle-hit-area")) {
|
|
2046
|
+
this.#activateRotateCursor(e, handle);
|
|
2047
|
+
} else {
|
|
2048
|
+
this.#activateMoveCursor(e);
|
|
2049
|
+
}
|
|
2050
|
+
},
|
|
2000
2051
|
{ capture: true },
|
|
2001
2052
|
);
|
|
2002
2053
|
}
|
|
@@ -2065,6 +2116,86 @@ class FigCanvasControl extends HTMLElement {
|
|
|
2065
2116
|
}
|
|
2066
2117
|
}
|
|
2067
2118
|
|
|
2119
|
+
#rotateDegForHandle(handle) {
|
|
2120
|
+
if (!handle) return 0;
|
|
2121
|
+
if (handle === this.#angleHandle) return this.#angle;
|
|
2122
|
+
if (!this.#hasSecondPoint) return 0;
|
|
2123
|
+
const lineDeg = this.#pointPointLineDeg();
|
|
2124
|
+
return handle === this.#pointHandle ? lineDeg + 180 : lineDeg;
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2127
|
+
#refreshBodyRotateCursor() {
|
|
2128
|
+
if (this.#rotateCursorPointerId === null) return;
|
|
2129
|
+
const cursor = this.#rotateCursorSvg(
|
|
2130
|
+
this.#rotateDegForHandle(this.#rotateCursorHandle),
|
|
2131
|
+
);
|
|
2132
|
+
document.body.style.setProperty("--fig-lab-cursor-rotate", cursor);
|
|
2133
|
+
document.body.style.setProperty("cursor", cursor, "important");
|
|
2134
|
+
}
|
|
2135
|
+
|
|
2136
|
+
#activateRotateCursor(e, handle) {
|
|
2137
|
+
if (figLabBooleanAttribute(this, "disabled")) return;
|
|
2138
|
+
if (e?.button !== undefined && e.button !== 0) return;
|
|
2139
|
+
if (e?.isPrimary === false) return;
|
|
2140
|
+
|
|
2141
|
+
if (this.#rotateCursorPointerId === null) {
|
|
2142
|
+
this.#rotateCursorPrevBodyCursor =
|
|
2143
|
+
document.body.style.getPropertyValue("cursor");
|
|
2144
|
+
this.#rotateCursorPrevBodyCursorPriority =
|
|
2145
|
+
document.body.style.getPropertyPriority("cursor");
|
|
2146
|
+
}
|
|
2147
|
+
|
|
2148
|
+
this.#rotateCursorPointerId = e?.pointerId ?? -1;
|
|
2149
|
+
this.#rotateCursorHandle = handle;
|
|
2150
|
+
document.body.classList.add("fig-lab-rotate-active");
|
|
2151
|
+
this.#refreshBodyRotateCursor();
|
|
2152
|
+
|
|
2153
|
+
if (!this.#boundRotateCursorEnd) {
|
|
2154
|
+
this.#boundRotateCursorEnd = (event) => {
|
|
2155
|
+
if (
|
|
2156
|
+
event?.pointerId !== undefined &&
|
|
2157
|
+
this.#rotateCursorPointerId !== null &&
|
|
2158
|
+
event.pointerId !== this.#rotateCursorPointerId
|
|
2159
|
+
) {
|
|
2160
|
+
return;
|
|
2161
|
+
}
|
|
2162
|
+
if (event?.type === "blur") {
|
|
2163
|
+
this.#deactivateRotateCursor();
|
|
2164
|
+
} else {
|
|
2165
|
+
requestAnimationFrame(() => this.#deactivateRotateCursor());
|
|
2166
|
+
}
|
|
2167
|
+
};
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
window.addEventListener("pointerup", this.#boundRotateCursorEnd);
|
|
2171
|
+
window.addEventListener("pointercancel", this.#boundRotateCursorEnd);
|
|
2172
|
+
window.addEventListener("blur", this.#boundRotateCursorEnd);
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2175
|
+
#deactivateRotateCursor() {
|
|
2176
|
+
if (this.#rotateCursorPointerId === null) return;
|
|
2177
|
+
document.body.classList.remove("fig-lab-rotate-active");
|
|
2178
|
+
document.body.style.removeProperty("--fig-lab-cursor-rotate");
|
|
2179
|
+
if (this.#rotateCursorPrevBodyCursor) {
|
|
2180
|
+
document.body.style.setProperty(
|
|
2181
|
+
"cursor",
|
|
2182
|
+
this.#rotateCursorPrevBodyCursor,
|
|
2183
|
+
this.#rotateCursorPrevBodyCursorPriority,
|
|
2184
|
+
);
|
|
2185
|
+
} else {
|
|
2186
|
+
document.body.style.removeProperty("cursor");
|
|
2187
|
+
}
|
|
2188
|
+
this.#rotateCursorPointerId = null;
|
|
2189
|
+
this.#rotateCursorHandle = null;
|
|
2190
|
+
this.#rotateCursorPrevBodyCursor = "";
|
|
2191
|
+
this.#rotateCursorPrevBodyCursorPriority = "";
|
|
2192
|
+
if (this.#boundRotateCursorEnd) {
|
|
2193
|
+
window.removeEventListener("pointerup", this.#boundRotateCursorEnd);
|
|
2194
|
+
window.removeEventListener("pointercancel", this.#boundRotateCursorEnd);
|
|
2195
|
+
window.removeEventListener("blur", this.#boundRotateCursorEnd);
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2068
2199
|
#wireHoverTooltip(target, getTooltip, getText, isDraggingRef) {
|
|
2069
2200
|
if (!target) return;
|
|
2070
2201
|
const shouldSuppress = () => !!isDraggingRef?.();
|
|
@@ -2365,11 +2496,27 @@ class FigCanvasControl extends HTMLElement {
|
|
|
2365
2496
|
return `url("data:image/svg+xml,%3Csvg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform='rotate(${r} 16 16)'%3E%3Cg filter='url(%23f)'%3E%3Cpath d='M12.5607 22.4393L12.0216 21.9002C17.1558 21.2216 21.2216 17.1558 21.9002 12.0216L22.4393 12.5607C23.0251 13.1464 23.9749 13.1464 24.5607 12.5607C25.1464 11.9749 25.1464 11.0251 24.5607 10.4393L21.5607 7.43934C20.9749 6.85355 20.0251 6.85355 19.4393 7.43934L16.4393 10.4393C15.8536 11.0251 15.8536 11.9749 16.4393 12.5607C17.0251 13.1464 17.9749 13.1464 18.5607 12.5607L18.8056 12.3157C18.1013 15.5527 15.5527 18.1013 12.3157 18.8056L12.5607 18.5607C13.1464 17.9749 13.1464 17.0251 12.5607 16.4393C11.9749 15.8536 11.0251 15.8536 10.4393 16.4393L7.43934 19.4393C6.85356 20.0251 6.85356 20.9749 7.43934 21.5607L10.4393 24.5607C11.0251 25.1464 11.9749 25.1464 12.5607 24.5607C13.1464 23.9749 13.1464 23.0251 12.5607 22.4393Z' fill='white'/%3E%3C/g%3E%3Cpath d='M23.8536 11.8536C23.6583 12.0488 23.3417 12.0488 23.1464 11.8536L21 9.70711V10.5C21 16.299 16.299 21 10.5 21H9.70711L11.8536 23.1464C12.0488 23.3417 12.0488 23.6583 11.8536 23.8536C11.6583 24.0488 11.3417 24.0488 11.1464 23.8536L8.14645 20.8536C7.95119 20.6583 7.95119 20.3417 8.14645 20.1464L11.1464 17.1464C11.3417 16.9512 11.6583 16.9512 11.8536 17.1464C12.0488 17.3417 12.0488 17.6583 11.8536 17.8536L9.70711 20H10.5C15.7467 20 20 15.7467 20 10.5V9.70711L17.8536 11.8536C17.6583 12.0488 17.3417 12.0488 17.1464 11.8536C16.9512 11.6583 16.9512 11.3417 17.1464 11.1464L20.1464 8.14645C20.3417 7.95119 20.6583 7.95119 20.8536 8.14645L23.8536 11.1464C24.0488 11.3417 24.0488 11.6583 23.8536 11.8536Z' fill='black'/%3E%3C/g%3E%3Cdefs%3E%3Cfilter id='f' x='4' y='5' width='24' height='24' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='a'/%3E%3CfeColorMatrix in='SourceAlpha' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0' result='b'/%3E%3CfeOffset dy='1'/%3E%3CfeGaussianBlur stdDeviation='1.5'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.35 0'/%3E%3CfeBlend in2='a' result='c'/%3E%3CfeBlend in='SourceGraphic' in2='c'/%3E%3C/filter%3E%3C/defs%3E%3C/svg%3E") 16 16, pointer`;
|
|
2366
2497
|
}
|
|
2367
2498
|
|
|
2499
|
+
#setHitCursor(el, cursor) {
|
|
2500
|
+
if (!el) return;
|
|
2501
|
+
// !important — fig-canvas-control hover rules override plain inline cursor.
|
|
2502
|
+
el.style.setProperty("cursor", cursor, "important");
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
#applyRotateCursor(handle, deg) {
|
|
2506
|
+
if (!handle) return;
|
|
2507
|
+
// Rotate only on the outside hit-area ring — handle body uses normal point cursor.
|
|
2508
|
+
const hitArea = handle.querySelector(".fig-handle-hit-area");
|
|
2509
|
+
if (!hitArea) return;
|
|
2510
|
+
hitArea.setAttribute("data-cursor", "rotate");
|
|
2511
|
+
this.#setHitCursor(hitArea, this.#rotateCursorSvg(deg));
|
|
2512
|
+
if (this.#rotateCursorHandle === handle) {
|
|
2513
|
+
this.#refreshBodyRotateCursor();
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2368
2517
|
#syncAngleCursor() {
|
|
2369
2518
|
if (!this.#angleHandle || !this.#hasAngle) return;
|
|
2370
|
-
|
|
2371
|
-
if (!hitArea) return;
|
|
2372
|
-
hitArea.style.cursor = this.#rotateCursorSvg(this.#angle);
|
|
2519
|
+
this.#applyRotateCursor(this.#angleHandle, this.#angle);
|
|
2373
2520
|
}
|
|
2374
2521
|
|
|
2375
2522
|
#pointPointLineDeg() {
|
|
@@ -2379,13 +2526,11 @@ class FigCanvasControl extends HTMLElement {
|
|
|
2379
2526
|
#syncPointPointCursors() {
|
|
2380
2527
|
if (!this.#hasSecondPoint) return;
|
|
2381
2528
|
const deg = this.#pointPointLineDeg();
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
setHitCursor(this.#pointHandle, deg + 180);
|
|
2388
|
-
setHitCursor(this.#secondHandle, deg);
|
|
2529
|
+
// Handle body: leave cursor to CSS (same as default point handle).
|
|
2530
|
+
this.#pointHandle?.style.removeProperty("cursor");
|
|
2531
|
+
this.#secondHandle?.style.removeProperty("cursor");
|
|
2532
|
+
this.#applyRotateCursor(this.#pointHandle, deg + 180);
|
|
2533
|
+
this.#applyRotateCursor(this.#secondHandle, deg);
|
|
2389
2534
|
}
|
|
2390
2535
|
|
|
2391
2536
|
#positionHandle(handle, xPct, yPct, rect) {
|
|
@@ -2759,7 +2904,7 @@ class FigCanvasControl extends HTMLElement {
|
|
|
2759
2904
|
(Math.atan2(e.clientY - rect.top - cy, e.clientX - rect.left - cx) *
|
|
2760
2905
|
180) /
|
|
2761
2906
|
Math.PI;
|
|
2762
|
-
circle
|
|
2907
|
+
this.#setHitCursor(circle, this.#resizeCursorSvg(deg));
|
|
2763
2908
|
});
|
|
2764
2909
|
const onDown = (e) => {
|
|
2765
2910
|
if (figLabBooleanAttribute(this, "disabled")) return;
|
|
@@ -5606,12 +5751,11 @@ class FigSelect extends HTMLElement {
|
|
|
5606
5751
|
if (figLabBooleanAttribute(this, "disabled")) return;
|
|
5607
5752
|
e.preventDefault();
|
|
5608
5753
|
e.stopPropagation();
|
|
5609
|
-
const
|
|
5610
|
-
if (this
|
|
5611
|
-
|
|
5612
|
-
if (this.#popup && this.#button) this.#popup.anchor = this.#button;
|
|
5613
|
-
this.open = true;
|
|
5754
|
+
const nextOpen = !this.open;
|
|
5755
|
+
if (nextOpen && this.#popup && this.#button) {
|
|
5756
|
+
this.#popup.anchor = this.#button;
|
|
5614
5757
|
}
|
|
5758
|
+
this.open = nextOpen;
|
|
5615
5759
|
}
|
|
5616
5760
|
|
|
5617
5761
|
#handleOptionClick(e) {
|
package/package.json
CHANGED