@rogieking/figui3 2.12.1 → 2.13.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/components.css CHANGED
@@ -1523,7 +1523,7 @@ details {
1523
1523
  display: flex;
1524
1524
  align-items: center;
1525
1525
  padding: 0 1rem 0 0;
1526
- height: var(--spacer-6);
1526
+ height: var(--spacer-5);
1527
1527
  user-select: none;
1528
1528
  color: var(--figma-color-text-secondary);
1529
1529
 
package/fig.js CHANGED
@@ -719,12 +719,15 @@ customElements.define("fig-popover", FigPopover);
719
719
  */
720
720
  class FigDialog extends HTMLDialogElement {
721
721
  #isDragging = false;
722
+ #dragPending = false;
723
+ #dragStartPos = { x: 0, y: 0 };
722
724
  #dragOffset = { x: 0, y: 0 };
723
725
  #boundPointerDown;
724
726
  #boundPointerMove;
725
727
  #boundPointerUp;
726
728
  #offset = 16; // 1rem in pixels
727
729
  #positionInitialized = false;
730
+ #dragThreshold = 3; // pixels before drag starts
728
731
 
729
732
  constructor() {
730
733
  super();
@@ -844,6 +847,8 @@ class FigDialog extends HTMLDialogElement {
844
847
  "textarea",
845
848
  "a",
846
849
  "label",
850
+ "details",
851
+ "summary",
847
852
  '[contenteditable="true"]',
848
853
  "[tabindex]",
849
854
  ];
@@ -886,7 +891,12 @@ class FigDialog extends HTMLDialogElement {
886
891
  }
887
892
 
888
893
  #handlePointerDown(e) {
889
- if (!this.drag || this.#isInteractiveElement(e.target)) {
894
+ if (!this.drag) {
895
+ return;
896
+ }
897
+
898
+ // Don't interfere with interactive elements (inputs, sliders, buttons, etc.)
899
+ if (this.#isInteractiveElement(e.target)) {
890
900
  return;
891
901
  }
892
902
 
@@ -901,31 +911,48 @@ class FigDialog extends HTMLDialogElement {
901
911
  }
902
912
  // No handle specified = drag from anywhere (original behavior)
903
913
 
904
- this.#isDragging = true;
905
- this.setPointerCapture(e.pointerId);
914
+ // Don't prevent default yet - just set up pending drag
915
+ // This allows clicks on non-interactive elements like <details> to work
916
+ this.#dragPending = true;
917
+ this.#dragStartPos.x = e.clientX;
918
+ this.#dragStartPos.y = e.clientY;
906
919
 
907
920
  // Get current position from computed style
908
921
  const rect = this.getBoundingClientRect();
909
922
 
910
- // Convert to pixel-based top/left positioning for dragging
911
- // (clears margin: auto centering)
912
- this.style.top = `${rect.top}px`;
913
- this.style.left = `${rect.left}px`;
914
- this.style.bottom = "auto";
915
- this.style.right = "auto";
916
- this.style.margin = "0";
917
-
918
923
  // Store offset from pointer to dialog top-left corner
919
924
  this.#dragOffset.x = e.clientX - rect.left;
920
925
  this.#dragOffset.y = e.clientY - rect.top;
921
926
 
922
927
  document.addEventListener("pointermove", this.#boundPointerMove);
923
928
  document.addEventListener("pointerup", this.#boundPointerUp);
924
-
925
- e.preventDefault();
926
929
  }
927
930
 
928
931
  #handlePointerMove(e) {
932
+ // Check if we should start dragging (threshold exceeded)
933
+ if (this.#dragPending && !this.#isDragging) {
934
+ const dx = Math.abs(e.clientX - this.#dragStartPos.x);
935
+ const dy = Math.abs(e.clientY - this.#dragStartPos.y);
936
+
937
+ if (dx > this.#dragThreshold || dy > this.#dragThreshold) {
938
+ // Start actual drag
939
+ this.#isDragging = true;
940
+ this.#dragPending = false;
941
+ this.setPointerCapture(e.pointerId);
942
+
943
+ // Get current position from computed style
944
+ const rect = this.getBoundingClientRect();
945
+
946
+ // Convert to pixel-based top/left positioning for dragging
947
+ // (clears margin: auto centering)
948
+ this.style.top = `${rect.top}px`;
949
+ this.style.left = `${rect.left}px`;
950
+ this.style.bottom = "auto";
951
+ this.style.right = "auto";
952
+ this.style.margin = "0";
953
+ }
954
+ }
955
+
929
956
  if (!this.#isDragging) return;
930
957
 
931
958
  // Calculate new position based on pointer position minus offset
@@ -940,10 +967,13 @@ class FigDialog extends HTMLDialogElement {
940
967
  }
941
968
 
942
969
  #handlePointerUp(e) {
943
- if (!this.#isDragging) return;
970
+ // Clean up pending or active drag
971
+ if (this.#isDragging) {
972
+ this.releasePointerCapture(e.pointerId);
973
+ }
944
974
 
945
975
  this.#isDragging = false;
946
- this.releasePointerCapture(e.pointerId);
976
+ this.#dragPending = false;
947
977
 
948
978
  document.removeEventListener("pointermove", this.#boundPointerMove);
949
979
  document.removeEventListener("pointerup", this.#boundPointerUp);
package/index.html CHANGED
@@ -683,9 +683,28 @@
683
683
  <fig-content>
684
684
  <p>This is a draggable dialog. You can drag it by the header.</p>
685
685
  <fig-field direction="horizontal">
686
- <label>Example Field</label>
686
+ <label>Text</label>
687
687
  <fig-input-text placeholder="Enter text"></fig-input-text>
688
688
  </fig-field>
689
+ <fig-field direction="horizontal">
690
+ <label>Number</label>
691
+ <fig-input-number value="50" min="0" max="100" units="px"></fig-input-number>
692
+ </fig-field>
693
+ <fig-field direction="horizontal">
694
+ <label>Slider</label>
695
+ <fig-slider value="50" min="0" max="100"></fig-slider>
696
+ </fig-field>
697
+ <fig-field direction="horizontal">
698
+ <label>Checkbox</label>
699
+ <fig-checkbox checked="true">Enable feature</fig-checkbox>
700
+ </fig-field>
701
+ <details>
702
+ <summary>More options</summary>
703
+ <fig-field direction="horizontal">
704
+ <label>Advanced</label>
705
+ <fig-input-text placeholder="Advanced setting"></fig-input-text>
706
+ </fig-field>
707
+ </details>
689
708
  </fig-content>
690
709
  <footer>
691
710
  <fig-button variant="secondary"
@@ -728,6 +747,14 @@
728
747
  </fig-header>
729
748
  <fig-content>
730
749
  <p>This dialog is positioned at a specific corner.</p>
750
+ <fig-field direction="horizontal">
751
+ <label>Number</label>
752
+ <fig-input-number value="100" units="%"></fig-input-number>
753
+ </fig-field>
754
+ <fig-field direction="horizontal">
755
+ <label>Slider</label>
756
+ <fig-slider value="50" min="0" max="100"></fig-slider>
757
+ </fig-field>
731
758
  </fig-content>
732
759
  <footer>
733
760
  <fig-button close-dialog>Close</fig-button>
@@ -771,6 +798,21 @@
771
798
  <li>✗ This content area (won't drag)</li>
772
799
  <li>✗ The footer below (won't drag)</li>
773
800
  </ul>
801
+ <fig-field direction="horizontal">
802
+ <label>Number</label>
803
+ <fig-input-number value="45" units="°" min="0" max="360"></fig-input-number>
804
+ </fig-field>
805
+ <fig-field direction="horizontal">
806
+ <label>Slider</label>
807
+ <fig-slider value="50" min="0" max="100"></fig-slider>
808
+ </fig-field>
809
+ <details>
810
+ <summary>More options</summary>
811
+ <fig-field direction="horizontal">
812
+ <label>Advanced</label>
813
+ <fig-input-text placeholder="Advanced setting"></fig-input-text>
814
+ </fig-field>
815
+ </details>
774
816
  </fig-content>
775
817
  <footer>
776
818
  <fig-button close-dialog>Close</fig-button>
@@ -3351,48 +3393,45 @@ button.addEventListener('click', () => {
3351
3393
  <p class="description">A disclosure widget for expandable/collapsible content.</p>
3352
3394
 
3353
3395
  <h3>Default (Closed)</h3>
3354
- <details style="font-size: 13px; color: var(--figma-color-text);">
3355
- <summary style="cursor: pointer; padding: 8px 0;">Click to expand</summary>
3356
- <p style="padding: 8px 0 8px 16px; margin: 0; color: var(--figma-color-text-secondary);">
3396
+ <details>
3397
+ <summary>Click to expand</summary>
3398
+ <p>
3357
3399
  This is the hidden content that appears when the details element is expanded.
3358
3400
  </p>
3359
3401
  </details>
3360
3402
 
3361
3403
  <h3>Default Open</h3>
3362
- <details open
3363
- style="font-size: 13px; color: var(--figma-color-text);">
3404
+ <details open>
3364
3405
  <summary style="cursor: pointer; padding: 8px 0;">Already expanded</summary>
3365
- <p style="padding: 8px 0 8px 16px; margin: 0; color: var(--figma-color-text-secondary);">
3406
+ <p>
3366
3407
  This content is visible by default because of the <code>open</code> attribute.
3367
3408
  </p>
3368
3409
  </details>
3369
3410
 
3370
3411
  <h3>Multiple Sections</h3>
3371
3412
  <vstack style="gap: 0;">
3372
- <details
3373
- style="font-size: 13px; color: var(--figma-color-text); border-bottom: 1px solid var(--figma-color-border);">
3413
+ <details>
3374
3414
  <summary style="cursor: pointer; padding: 8px 0;">Section One</summary>
3375
- <p style="padding: 8px 0 8px 16px; margin: 0; color: var(--figma-color-text-secondary);">
3415
+ <p>
3376
3416
  Content for section one.
3377
3417
  </p>
3378
3418
  </details>
3379
- <details
3380
- style="font-size: 13px; color: var(--figma-color-text); border-bottom: 1px solid var(--figma-color-border);">
3419
+ <details>
3381
3420
  <summary style="cursor: pointer; padding: 8px 0;">Section Two</summary>
3382
- <p style="padding: 8px 0 8px 16px; margin: 0; color: var(--figma-color-text-secondary);">
3421
+ <p>
3383
3422
  Content for section two.
3384
3423
  </p>
3385
3424
  </details>
3386
- <details style="font-size: 13px; color: var(--figma-color-text);">
3425
+ <details>
3387
3426
  <summary style="cursor: pointer; padding: 8px 0;">Section Three</summary>
3388
- <p style="padding: 8px 0 8px 16px; margin: 0; color: var(--figma-color-text-secondary);">
3427
+ <p>
3389
3428
  Content for section three.
3390
3429
  </p>
3391
3430
  </details>
3392
3431
  </vstack>
3393
3432
 
3394
3433
  <h3>With Rich Content</h3>
3395
- <details style="font-size: 13px; color: var(--figma-color-text);">
3434
+ <details>
3396
3435
  <summary style="cursor: pointer; padding: 8px 0;">Advanced Settings</summary>
3397
3436
  <vstack style="padding: 8px 0 8px 16px;">
3398
3437
  <fig-field direction="horizontal"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "2.12.1",
3
+ "version": "2.13.0",
4
4
  "description": "A lightweight web components library for building Figma plugin and widget UIs with native look and feel",
5
5
  "author": "Rogie King",
6
6
  "license": "MIT",