@rogieking/figui3 6.9.5 → 6.9.7

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/fig.js CHANGED
@@ -10740,6 +10740,7 @@ customElements.define("fig-swatch", FigSwatch);
10740
10740
  * @attr {string} aspect-ratio - CSS aspect-ratio value
10741
10741
  * @attr {string} fit - CSS object-fit value
10742
10742
  * @attr {boolean} checkerboard - Show checkerboard behind transparent media
10743
+ * @attr {string} caption - Caption text rendered below the media preview
10743
10744
  * @attr {boolean} controls - Video controls visibility (default false)
10744
10745
  * @attr {boolean} autoplay - Video autoplay
10745
10746
  * @attr {boolean} loop - Video loop
@@ -10783,6 +10784,7 @@ class FigMedia extends HTMLElement {
10783
10784
  "aspect-ratio",
10784
10785
  "fit",
10785
10786
  "checkerboard",
10787
+ "caption",
10786
10788
  "controls",
10787
10789
  "autoplay",
10788
10790
  "loop",
@@ -10869,6 +10871,7 @@ class FigMedia extends HTMLElement {
10869
10871
  this.#ensureMediaElement();
10870
10872
  this.#syncGeneratedMediaElement();
10871
10873
  this.#syncMediaAccessibility();
10874
+ this.#syncCaption();
10872
10875
 
10873
10876
  const isUpload = this.hasAttribute("upload") && this.getAttribute("upload") !== "false";
10874
10877
  if (isUpload && !this.querySelector("fig-input-file[data-generated]")) {
@@ -10995,6 +10998,50 @@ class FigMedia extends HTMLElement {
10995
10998
  });
10996
10999
  }
10997
11000
 
11001
+ #userProvidedCaptionEl() {
11002
+ return this.querySelector(":scope > caption:not([data-generated])");
11003
+ }
11004
+
11005
+ #generatedCaptionEls() {
11006
+ return Array.from(
11007
+ this.querySelectorAll(":scope > caption[data-generated]"),
11008
+ );
11009
+ }
11010
+
11011
+ #syncCaption() {
11012
+ const userCaption = this.#userProvidedCaptionEl();
11013
+ const generatedCaptions = this.#generatedCaptionEls();
11014
+
11015
+ if (userCaption) {
11016
+ generatedCaptions.forEach((caption) => caption.remove());
11017
+ return;
11018
+ }
11019
+
11020
+ const captionText = this.getAttribute("caption") || "";
11021
+ if (!captionText) {
11022
+ generatedCaptions.forEach((caption) => caption.remove());
11023
+ return;
11024
+ }
11025
+
11026
+ const caption = generatedCaptions[0] || document.createElement("caption");
11027
+ generatedCaptions.slice(1).forEach((duplicate) => duplicate.remove());
11028
+ if (!caption.hasAttribute("data-generated")) {
11029
+ caption.setAttribute("data-generated", "");
11030
+ }
11031
+ if (caption.textContent !== captionText) {
11032
+ caption.textContent = captionText;
11033
+ }
11034
+
11035
+ const controls = this.querySelector(":scope > fig-media-controls");
11036
+ if (controls) {
11037
+ controls.before(caption);
11038
+ } else if (this.#previewEl?.isConnected) {
11039
+ this.#previewEl.after(caption);
11040
+ } else if (!caption.isConnected) {
11041
+ this.append(caption);
11042
+ }
11043
+ }
11044
+
10998
11045
  #isEnabledAttr(name, defaultEnabled = false) {
10999
11046
  if (!this.hasAttribute(name)) return defaultEnabled;
11000
11047
  return this.getAttribute(name) !== "false";
@@ -11060,7 +11107,14 @@ class FigMedia extends HTMLElement {
11060
11107
  }
11061
11108
 
11062
11109
  #ensureControls() {
11063
- if (this.#controlsEl && this.#controlsEl.isConnected) {
11110
+ const generatedControls = Array.from(
11111
+ this.querySelectorAll(":scope > fig-media-controls[data-generated]"),
11112
+ );
11113
+ const existingControls = generatedControls[0];
11114
+ generatedControls.slice(1).forEach((controls) => controls.remove());
11115
+
11116
+ if (existingControls) {
11117
+ this.#controlsEl = existingControls;
11064
11118
  this.#wireControlsToMedia();
11065
11119
  return;
11066
11120
  }
@@ -11157,10 +11211,9 @@ class FigMedia extends HTMLElement {
11157
11211
 
11158
11212
  #removeControls() {
11159
11213
  this.#unwireControls();
11160
- if (!this.#controlsEl) return;
11161
- if (this.#controlsEl.hasAttribute("data-generated")) {
11162
- this.#controlsEl.remove();
11163
- }
11214
+ this.querySelectorAll(":scope > fig-media-controls[data-generated]").forEach((controls) => {
11215
+ controls.remove();
11216
+ });
11164
11217
  this.#controlsEl = null;
11165
11218
  }
11166
11219
 
@@ -11373,6 +11426,10 @@ class FigMedia extends HTMLElement {
11373
11426
  if (["controls", "autoplay", "loop", "muted", "poster"].includes(name)) {
11374
11427
  this.#syncGeneratedMediaElement();
11375
11428
  }
11429
+
11430
+ if (name === "caption") {
11431
+ this.#syncCaption();
11432
+ }
11376
11433
  }
11377
11434
  }
11378
11435
 
@@ -12944,6 +13001,7 @@ class FigEasingCurve extends HTMLElement {
12944
13001
  #startSpringDrag(e, handleType) {
12945
13002
  e.preventDefault();
12946
13003
  this.#isDragging = handleType;
13004
+ this.classList.toggle("spring-bounce-dragging", handleType === "bounce");
12947
13005
 
12948
13006
  const startDamping = this.#spring.damping;
12949
13007
  const startStiffness = this.#spring.stiffness;
@@ -12981,6 +13039,7 @@ class FigEasingCurve extends HTMLElement {
12981
13039
 
12982
13040
  const onUp = () => {
12983
13041
  this.#isDragging = null;
13042
+ this.classList.remove("spring-bounce-dragging");
12984
13043
  document.removeEventListener("pointermove", onMove);
12985
13044
  document.removeEventListener("pointerup", onUp);
12986
13045
  this.#emit("change");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "6.9.5",
3
+ "version": "6.9.7",
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",