@rogieking/figui3 1.9.6 → 2.0.0
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/base.css +13 -0
- package/components.css +344 -411
- package/example.html +1906 -1051
- package/fig.js +380 -27
- package/package.json +1 -1
package/fig.js
CHANGED
|
@@ -26,7 +26,7 @@ class FigButton extends HTMLElement {
|
|
|
26
26
|
#selected;
|
|
27
27
|
constructor() {
|
|
28
28
|
super();
|
|
29
|
-
this.attachShadow({ mode: "open" });
|
|
29
|
+
this.attachShadow({ mode: "open", delegatesFocus: true });
|
|
30
30
|
}
|
|
31
31
|
connectedCallback() {
|
|
32
32
|
this.type = this.getAttribute("type") || "button";
|
|
@@ -48,6 +48,11 @@ class FigButton extends HTMLElement {
|
|
|
48
48
|
background: transparent;
|
|
49
49
|
margin: calc(var(--spacer-2)*-1);
|
|
50
50
|
height: var(--spacer-4);
|
|
51
|
+
white-space: nowrap;
|
|
52
|
+
overflow: hidden;
|
|
53
|
+
text-overflow: ellipsis;
|
|
54
|
+
width: 100%;
|
|
55
|
+
min-width: 0;
|
|
51
56
|
}
|
|
52
57
|
</style>
|
|
53
58
|
<button type="${this.type}">
|
|
@@ -62,6 +67,16 @@ class FigButton extends HTMLElement {
|
|
|
62
67
|
requestAnimationFrame(() => {
|
|
63
68
|
this.button = this.shadowRoot.querySelector("button");
|
|
64
69
|
this.button.addEventListener("click", this.#handleClick.bind(this));
|
|
70
|
+
|
|
71
|
+
// Forward focus-visible state to host element
|
|
72
|
+
this.button.addEventListener("focus", () => {
|
|
73
|
+
if (this.button.matches(":focus-visible")) {
|
|
74
|
+
this.setAttribute("data-focus-visible", "");
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
this.button.addEventListener("blur", () => {
|
|
78
|
+
this.removeAttribute("data-focus-visible");
|
|
79
|
+
});
|
|
65
80
|
});
|
|
66
81
|
}
|
|
67
82
|
|
|
@@ -592,20 +607,232 @@ customElements.define("fig-popover", FigPopover);
|
|
|
592
607
|
* @attr {boolean} modal - Whether the dialog should be modal
|
|
593
608
|
*/
|
|
594
609
|
class FigDialog extends HTMLDialogElement {
|
|
610
|
+
#isDragging = false;
|
|
611
|
+
#dragOffset = { x: 0, y: 0 };
|
|
612
|
+
#boundPointerDown;
|
|
613
|
+
#boundPointerMove;
|
|
614
|
+
#boundPointerUp;
|
|
615
|
+
#offset = 16; // 1rem in pixels
|
|
616
|
+
#positionInitialized = false;
|
|
617
|
+
|
|
618
|
+
constructor() {
|
|
619
|
+
super();
|
|
620
|
+
this.#boundPointerDown = this.#handlePointerDown.bind(this);
|
|
621
|
+
this.#boundPointerMove = this.#handlePointerMove.bind(this);
|
|
622
|
+
this.#boundPointerUp = this.#handlePointerUp.bind(this);
|
|
623
|
+
}
|
|
624
|
+
|
|
595
625
|
connectedCallback() {
|
|
596
626
|
this.modal =
|
|
597
627
|
this.hasAttribute("modal") && this.getAttribute("modal") !== "false";
|
|
628
|
+
|
|
629
|
+
// Set up drag functionality
|
|
630
|
+
this.drag =
|
|
631
|
+
this.hasAttribute("drag") && this.getAttribute("drag") !== "false";
|
|
632
|
+
|
|
598
633
|
requestAnimationFrame(() => {
|
|
599
634
|
this.#addCloseListeners();
|
|
635
|
+
this.#setupDragListeners();
|
|
636
|
+
this.#applyPosition();
|
|
600
637
|
});
|
|
601
638
|
}
|
|
602
639
|
|
|
640
|
+
disconnectedCallback() {
|
|
641
|
+
this.#removeDragListeners();
|
|
642
|
+
}
|
|
643
|
+
|
|
603
644
|
#addCloseListeners() {
|
|
604
645
|
this.querySelectorAll("fig-button[close-dialog]").forEach((button) => {
|
|
605
646
|
button.removeEventListener("click", this.close);
|
|
606
647
|
button.addEventListener("click", this.close.bind(this));
|
|
607
648
|
});
|
|
608
649
|
}
|
|
650
|
+
|
|
651
|
+
#applyPosition() {
|
|
652
|
+
const position = this.getAttribute("position") || "";
|
|
653
|
+
|
|
654
|
+
// Apply common styles
|
|
655
|
+
this.style.position = "fixed";
|
|
656
|
+
this.style.margin = "0";
|
|
657
|
+
|
|
658
|
+
// Reset position properties
|
|
659
|
+
this.style.top = "auto";
|
|
660
|
+
this.style.bottom = "auto";
|
|
661
|
+
this.style.left = "auto";
|
|
662
|
+
this.style.right = "auto";
|
|
663
|
+
this.style.transform = "none";
|
|
664
|
+
|
|
665
|
+
// Parse position attribute
|
|
666
|
+
const hasTop = position.includes("top");
|
|
667
|
+
const hasBottom = position.includes("bottom");
|
|
668
|
+
const hasLeft = position.includes("left");
|
|
669
|
+
const hasRight = position.includes("right");
|
|
670
|
+
const hasVCenter = position.includes("center") && !hasTop && !hasBottom;
|
|
671
|
+
const hasHCenter = position.includes("center") && !hasLeft && !hasRight;
|
|
672
|
+
|
|
673
|
+
// Vertical positioning
|
|
674
|
+
if (hasTop) {
|
|
675
|
+
this.style.top = `${this.#offset}px`;
|
|
676
|
+
} else if (hasBottom) {
|
|
677
|
+
this.style.bottom = `${this.#offset}px`;
|
|
678
|
+
} else if (hasVCenter) {
|
|
679
|
+
this.style.top = "50%";
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// Horizontal positioning
|
|
683
|
+
if (hasLeft) {
|
|
684
|
+
this.style.left = `${this.#offset}px`;
|
|
685
|
+
} else if (hasRight) {
|
|
686
|
+
this.style.right = `${this.#offset}px`;
|
|
687
|
+
} else if (hasHCenter) {
|
|
688
|
+
this.style.left = "50%";
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// Apply transform for centering
|
|
692
|
+
if (hasVCenter && hasHCenter) {
|
|
693
|
+
this.style.transform = "translate(-50%, -50%)";
|
|
694
|
+
} else if (hasVCenter) {
|
|
695
|
+
this.style.transform = "translateY(-50%)";
|
|
696
|
+
} else if (hasHCenter) {
|
|
697
|
+
this.style.transform = "translateX(-50%)";
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
this.#positionInitialized = true;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
#setupDragListeners() {
|
|
704
|
+
if (this.drag) {
|
|
705
|
+
this.addEventListener("pointerdown", this.#boundPointerDown);
|
|
706
|
+
// Set move cursor only on fig-header elements
|
|
707
|
+
const header = this.querySelector("fig-header, header");
|
|
708
|
+
if (header) {
|
|
709
|
+
header.style.cursor = "move";
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
#removeDragListeners() {
|
|
715
|
+
this.removeEventListener("pointerdown", this.#boundPointerDown);
|
|
716
|
+
document.removeEventListener("pointermove", this.#boundPointerMove);
|
|
717
|
+
document.removeEventListener("pointerup", this.#boundPointerUp);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
#isInteractiveElement(element) {
|
|
721
|
+
// List of interactive element types and attributes to avoid dragging on
|
|
722
|
+
const interactiveSelectors = [
|
|
723
|
+
"input",
|
|
724
|
+
"button",
|
|
725
|
+
"select",
|
|
726
|
+
"textarea",
|
|
727
|
+
"a",
|
|
728
|
+
"label",
|
|
729
|
+
'[contenteditable="true"]',
|
|
730
|
+
"[tabindex]",
|
|
731
|
+
"fig-button",
|
|
732
|
+
"fig-input-text",
|
|
733
|
+
"fig-input-number",
|
|
734
|
+
"fig-slider",
|
|
735
|
+
"fig-checkbox",
|
|
736
|
+
"fig-radio",
|
|
737
|
+
"fig-tab",
|
|
738
|
+
"fig-dropdown",
|
|
739
|
+
"fig-chit",
|
|
740
|
+
];
|
|
741
|
+
|
|
742
|
+
// Check if the element itself is interactive
|
|
743
|
+
if (interactiveSelectors.some((selector) => element.matches?.(selector))) {
|
|
744
|
+
return true;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// Check if any parent element up to the dialog is interactive
|
|
748
|
+
let parent = element.parentElement;
|
|
749
|
+
while (parent && parent !== this) {
|
|
750
|
+
if (interactiveSelectors.some((selector) => parent.matches?.(selector))) {
|
|
751
|
+
return true;
|
|
752
|
+
}
|
|
753
|
+
parent = parent.parentElement;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
return false;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
#handlePointerDown(e) {
|
|
760
|
+
if (!this.drag || this.#isInteractiveElement(e.target)) {
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
this.#isDragging = true;
|
|
765
|
+
this.setPointerCapture(e.pointerId);
|
|
766
|
+
|
|
767
|
+
// Get current position from computed style
|
|
768
|
+
const rect = this.getBoundingClientRect();
|
|
769
|
+
|
|
770
|
+
// Ensure we are using top/left for dragging by converting current position
|
|
771
|
+
this.style.top = `${rect.top}px`;
|
|
772
|
+
this.style.left = `${rect.left}px`;
|
|
773
|
+
this.style.bottom = "auto";
|
|
774
|
+
this.style.right = "auto";
|
|
775
|
+
|
|
776
|
+
// Store offset from pointer to dialog top-left corner
|
|
777
|
+
this.#dragOffset.x = e.clientX - rect.left;
|
|
778
|
+
this.#dragOffset.y = e.clientY - rect.top;
|
|
779
|
+
|
|
780
|
+
document.addEventListener("pointermove", this.#boundPointerMove);
|
|
781
|
+
document.addEventListener("pointerup", this.#boundPointerUp);
|
|
782
|
+
|
|
783
|
+
e.preventDefault();
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
#handlePointerMove(e) {
|
|
787
|
+
if (!this.#isDragging) return;
|
|
788
|
+
|
|
789
|
+
// Calculate new position based on pointer position minus offset
|
|
790
|
+
const newLeft = e.clientX - this.#dragOffset.x;
|
|
791
|
+
const newTop = e.clientY - this.#dragOffset.y;
|
|
792
|
+
|
|
793
|
+
// Apply position directly with pixels
|
|
794
|
+
this.style.left = `${newLeft}px`;
|
|
795
|
+
this.style.top = `${newTop}px`;
|
|
796
|
+
|
|
797
|
+
e.preventDefault();
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
#handlePointerUp(e) {
|
|
801
|
+
if (!this.#isDragging) return;
|
|
802
|
+
|
|
803
|
+
this.#isDragging = false;
|
|
804
|
+
this.releasePointerCapture(e.pointerId);
|
|
805
|
+
|
|
806
|
+
document.removeEventListener("pointermove", this.#boundPointerMove);
|
|
807
|
+
document.removeEventListener("pointerup", this.#boundPointerUp);
|
|
808
|
+
|
|
809
|
+
e.preventDefault();
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
static get observedAttributes() {
|
|
813
|
+
return ["modal", "drag", "position"];
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
817
|
+
if (name === "drag") {
|
|
818
|
+
this.drag = newValue !== null && newValue !== "false";
|
|
819
|
+
|
|
820
|
+
if (this.drag) {
|
|
821
|
+
this.#setupDragListeners();
|
|
822
|
+
} else {
|
|
823
|
+
this.#removeDragListeners();
|
|
824
|
+
// Remove move cursor from header
|
|
825
|
+
const header = this.querySelector("fig-header, header");
|
|
826
|
+
if (header) {
|
|
827
|
+
header.style.cursor = "";
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
if (name === "position" && this.#positionInitialized) {
|
|
833
|
+
this.#applyPosition();
|
|
834
|
+
}
|
|
835
|
+
}
|
|
609
836
|
}
|
|
610
837
|
customElements.define("fig-dialog", FigDialog, { extends: "dialog" });
|
|
611
838
|
|
|
@@ -2078,8 +2305,7 @@ class FigCheckbox extends HTMLElement {
|
|
|
2078
2305
|
this.input.setAttribute("id", figUniqueId());
|
|
2079
2306
|
this.input.setAttribute("name", this.name);
|
|
2080
2307
|
this.input.setAttribute("type", "checkbox");
|
|
2081
|
-
this.labelElement =
|
|
2082
|
-
this.labelElement.setAttribute("for", this.input.id);
|
|
2308
|
+
this.labelElement = null;
|
|
2083
2309
|
}
|
|
2084
2310
|
connectedCallback() {
|
|
2085
2311
|
this.checked = this.input.checked =
|
|
@@ -2095,7 +2321,12 @@ class FigCheckbox extends HTMLElement {
|
|
|
2095
2321
|
}
|
|
2096
2322
|
|
|
2097
2323
|
this.append(this.input);
|
|
2098
|
-
|
|
2324
|
+
|
|
2325
|
+
// Only create label if label attribute is present
|
|
2326
|
+
if (this.hasAttribute("label")) {
|
|
2327
|
+
this.#createLabel();
|
|
2328
|
+
this.labelElement.innerText = this.getAttribute("label");
|
|
2329
|
+
}
|
|
2099
2330
|
|
|
2100
2331
|
this.render();
|
|
2101
2332
|
}
|
|
@@ -2103,6 +2334,14 @@ class FigCheckbox extends HTMLElement {
|
|
|
2103
2334
|
return ["disabled", "label", "checked", "name", "value"];
|
|
2104
2335
|
}
|
|
2105
2336
|
|
|
2337
|
+
#createLabel() {
|
|
2338
|
+
if (!this.labelElement) {
|
|
2339
|
+
this.labelElement = document.createElement("label");
|
|
2340
|
+
this.labelElement.setAttribute("for", this.input.id);
|
|
2341
|
+
this.append(this.labelElement);
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
|
|
2106
2345
|
render() {}
|
|
2107
2346
|
|
|
2108
2347
|
focus() {
|
|
@@ -2116,7 +2355,13 @@ class FigCheckbox extends HTMLElement {
|
|
|
2116
2355
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
2117
2356
|
switch (name) {
|
|
2118
2357
|
case "label":
|
|
2119
|
-
|
|
2358
|
+
if (newValue) {
|
|
2359
|
+
this.#createLabel();
|
|
2360
|
+
this.labelElement.innerText = newValue;
|
|
2361
|
+
} else if (this.labelElement) {
|
|
2362
|
+
this.labelElement.remove();
|
|
2363
|
+
this.labelElement = null;
|
|
2364
|
+
}
|
|
2120
2365
|
break;
|
|
2121
2366
|
case "checked":
|
|
2122
2367
|
this.checked = this.input.checked =
|
|
@@ -2174,29 +2419,139 @@ class FigSwitch extends FigCheckbox {
|
|
|
2174
2419
|
}
|
|
2175
2420
|
window.customElements.define("fig-switch", FigSwitch);
|
|
2176
2421
|
|
|
2177
|
-
/*
|
|
2178
|
-
|
|
2422
|
+
/* Toast */
|
|
2423
|
+
/**
|
|
2424
|
+
* A toast notification element for non-modal, time-based messages.
|
|
2425
|
+
* Always positioned at bottom center of the screen.
|
|
2426
|
+
* @attr {number} duration - Auto-dismiss duration in ms (0 = no auto-dismiss, default: 5000)
|
|
2427
|
+
* @attr {number} offset - Distance from bottom edge in pixels (default: 16)
|
|
2428
|
+
* @attr {string} theme - Visual theme: "dark" (default), "light", "danger", "brand"
|
|
2429
|
+
* @attr {boolean} open - Whether the toast is visible
|
|
2430
|
+
*/
|
|
2431
|
+
class FigToast extends HTMLDialogElement {
|
|
2432
|
+
#defaultOffset = 16; // 1rem in pixels
|
|
2433
|
+
#autoCloseTimer = null;
|
|
2434
|
+
|
|
2179
2435
|
constructor() {
|
|
2180
2436
|
super();
|
|
2181
2437
|
}
|
|
2182
|
-
}
|
|
2183
|
-
window.customElements.define("fig-bell", FigBell);
|
|
2184
2438
|
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
constructor() {
|
|
2188
|
-
super();
|
|
2439
|
+
get #offset() {
|
|
2440
|
+
return parseInt(this.getAttribute("offset") ?? this.#defaultOffset);
|
|
2189
2441
|
}
|
|
2190
|
-
}
|
|
2191
|
-
window.customElements.define("fig-badge", FigBadge);
|
|
2192
2442
|
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2443
|
+
connectedCallback() {
|
|
2444
|
+
// Set default theme if not specified
|
|
2445
|
+
if (!this.hasAttribute("theme")) {
|
|
2446
|
+
this.setAttribute("theme", "dark");
|
|
2447
|
+
}
|
|
2448
|
+
|
|
2449
|
+
// Ensure toast is closed by default
|
|
2450
|
+
// Remove native open attribute if present and not explicitly "true"
|
|
2451
|
+
const shouldOpen =
|
|
2452
|
+
this.getAttribute("open") === "true" || this.getAttribute("open") === "";
|
|
2453
|
+
if (this.hasAttribute("open") && !shouldOpen) {
|
|
2454
|
+
this.removeAttribute("open");
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2457
|
+
// Close the dialog initially (override native behavior)
|
|
2458
|
+
if (!shouldOpen) {
|
|
2459
|
+
this.close();
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
requestAnimationFrame(() => {
|
|
2463
|
+
this.#addCloseListeners();
|
|
2464
|
+
this.#applyPosition();
|
|
2465
|
+
|
|
2466
|
+
// Auto-show if open attribute is explicitly true
|
|
2467
|
+
if (shouldOpen) {
|
|
2468
|
+
this.showToast();
|
|
2469
|
+
}
|
|
2470
|
+
});
|
|
2471
|
+
}
|
|
2472
|
+
|
|
2473
|
+
disconnectedCallback() {
|
|
2474
|
+
this.#clearAutoClose();
|
|
2475
|
+
}
|
|
2476
|
+
|
|
2477
|
+
#addCloseListeners() {
|
|
2478
|
+
this.querySelectorAll("[close-toast]").forEach((button) => {
|
|
2479
|
+
button.removeEventListener("click", this.#handleClose);
|
|
2480
|
+
button.addEventListener("click", this.#handleClose.bind(this));
|
|
2481
|
+
});
|
|
2482
|
+
}
|
|
2483
|
+
|
|
2484
|
+
#handleClose() {
|
|
2485
|
+
this.hideToast();
|
|
2486
|
+
}
|
|
2487
|
+
|
|
2488
|
+
#applyPosition() {
|
|
2489
|
+
// Always bottom center
|
|
2490
|
+
this.style.position = "fixed";
|
|
2491
|
+
this.style.margin = "0";
|
|
2492
|
+
this.style.top = "auto";
|
|
2493
|
+
this.style.bottom = `${this.#offset}px`;
|
|
2494
|
+
this.style.left = "50%";
|
|
2495
|
+
this.style.right = "auto";
|
|
2496
|
+
this.style.transform = "translateX(-50%)";
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
#startAutoClose() {
|
|
2500
|
+
this.#clearAutoClose();
|
|
2501
|
+
|
|
2502
|
+
const duration = parseInt(this.getAttribute("duration") ?? "5000");
|
|
2503
|
+
if (duration > 0) {
|
|
2504
|
+
this.#autoCloseTimer = setTimeout(() => {
|
|
2505
|
+
this.hideToast();
|
|
2506
|
+
}, duration);
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2509
|
+
|
|
2510
|
+
#clearAutoClose() {
|
|
2511
|
+
if (this.#autoCloseTimer) {
|
|
2512
|
+
clearTimeout(this.#autoCloseTimer);
|
|
2513
|
+
this.#autoCloseTimer = null;
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
/**
|
|
2518
|
+
* Show the toast notification (non-modal)
|
|
2519
|
+
*/
|
|
2520
|
+
showToast() {
|
|
2521
|
+
this.show(); // Non-modal show
|
|
2522
|
+
this.#applyPosition();
|
|
2523
|
+
this.#startAutoClose();
|
|
2524
|
+
this.dispatchEvent(new CustomEvent("toast-show", { bubbles: true }));
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
/**
|
|
2528
|
+
* Hide the toast notification
|
|
2529
|
+
*/
|
|
2530
|
+
hideToast() {
|
|
2531
|
+
this.#clearAutoClose();
|
|
2532
|
+
this.close();
|
|
2533
|
+
this.dispatchEvent(new CustomEvent("toast-hide", { bubbles: true }));
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
static get observedAttributes() {
|
|
2537
|
+
return ["duration", "offset", "open", "theme"];
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2540
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
2541
|
+
if (name === "offset") {
|
|
2542
|
+
this.#applyPosition();
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2545
|
+
if (name === "open") {
|
|
2546
|
+
if (newValue !== null && newValue !== "false") {
|
|
2547
|
+
this.showToast();
|
|
2548
|
+
} else {
|
|
2549
|
+
this.hideToast();
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2197
2552
|
}
|
|
2198
2553
|
}
|
|
2199
|
-
|
|
2554
|
+
customElements.define("fig-toast", FigToast, { extends: "dialog" });
|
|
2200
2555
|
|
|
2201
2556
|
/* Combo Input */
|
|
2202
2557
|
/**
|
|
@@ -2871,15 +3226,14 @@ class FigInputAngle extends HTMLElement {
|
|
|
2871
3226
|
</div>
|
|
2872
3227
|
${
|
|
2873
3228
|
this.text
|
|
2874
|
-
? `<fig-input-
|
|
2875
|
-
type="number"
|
|
3229
|
+
? `<fig-input-number
|
|
2876
3230
|
name="angle"
|
|
2877
3231
|
step="0.1"
|
|
2878
3232
|
value="${this.angle}"
|
|
2879
3233
|
min="0"
|
|
2880
|
-
max="360"
|
|
2881
|
-
|
|
2882
|
-
</fig-input-
|
|
3234
|
+
max="360"
|
|
3235
|
+
units="°">
|
|
3236
|
+
</fig-input-number>`
|
|
2883
3237
|
: ""
|
|
2884
3238
|
}
|
|
2885
3239
|
`;
|
|
@@ -2888,7 +3242,7 @@ class FigInputAngle extends HTMLElement {
|
|
|
2888
3242
|
#setupListeners() {
|
|
2889
3243
|
this.handle = this.querySelector(".fig-input-angle-handle");
|
|
2890
3244
|
this.plane = this.querySelector(".fig-input-angle-plane");
|
|
2891
|
-
this.angleInput = this.querySelector("fig-input-
|
|
3245
|
+
this.angleInput = this.querySelector("fig-input-number[name='angle']");
|
|
2892
3246
|
this.plane.addEventListener("mousedown", this.#handleMouseDown.bind(this));
|
|
2893
3247
|
this.plane.addEventListener(
|
|
2894
3248
|
"touchstart",
|
|
@@ -2897,7 +3251,6 @@ class FigInputAngle extends HTMLElement {
|
|
|
2897
3251
|
window.addEventListener("keydown", this.#handleKeyDown.bind(this));
|
|
2898
3252
|
window.addEventListener("keyup", this.#handleKeyUp.bind(this));
|
|
2899
3253
|
if (this.text && this.angleInput) {
|
|
2900
|
-
this.angleInput = this.querySelector("fig-input-text");
|
|
2901
3254
|
this.angleInput.addEventListener(
|
|
2902
3255
|
"input",
|
|
2903
3256
|
this.#handleAngleInput.bind(this)
|