@rogieking/figui3 10.0.2 → 10.0.3
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/.cursor/skills/figui3/components.md +4 -2
- package/CHANGELOG.md +17 -0
- package/README.md +4 -1
- package/components.css +26 -35
- package/dist/components.css +1 -1
- package/dist/fig.css +1 -1
- package/dist/fig.js +5 -5
- package/fig.js +53 -30
- package/package.json +1 -1
package/fig.js
CHANGED
|
@@ -13126,6 +13126,7 @@ const FIG_MEDIA_FORWARDED_EVENTS = [
|
|
|
13126
13126
|
* @attr {string} src - Media source URL
|
|
13127
13127
|
* @attr {string} type - "image" (default) or "video" (for fig-media)
|
|
13128
13128
|
* @attr {string} alt - Alt text for the generated image (default "")
|
|
13129
|
+
* @attr {boolean} loaded - Read-only reflected state when an image has loaded successfully
|
|
13129
13130
|
* @attr {boolean} upload - Show upload overlay (generates fig-input-file)
|
|
13130
13131
|
* @attr {boolean} loading-indicator - Set to `false` to disable the generated image loading spinner
|
|
13131
13132
|
* @attr {string} label - Upload button label (default "Upload")
|
|
@@ -13344,6 +13345,7 @@ class FigMedia extends HTMLElement {
|
|
|
13344
13345
|
}
|
|
13345
13346
|
|
|
13346
13347
|
#syncImageLoadingState() {
|
|
13348
|
+
this.#syncImageLoadedState();
|
|
13347
13349
|
const src = this.#currentMediaSrc();
|
|
13348
13350
|
if (!src || !this.#usesDefaultImageLoadingIndicator()) {
|
|
13349
13351
|
this.#finishImageLoading();
|
|
@@ -13383,6 +13385,18 @@ class FigMedia extends HTMLElement {
|
|
|
13383
13385
|
}, 150);
|
|
13384
13386
|
}
|
|
13385
13387
|
|
|
13388
|
+
#syncImageLoadedState() {
|
|
13389
|
+
const image = this.#mediaEl?.tagName === "IMG" ? this.#mediaEl : null;
|
|
13390
|
+
const src =
|
|
13391
|
+
image?.currentSrc ||
|
|
13392
|
+
image?.getAttribute("src") ||
|
|
13393
|
+
this.#currentMediaSrc();
|
|
13394
|
+
this.toggleAttribute(
|
|
13395
|
+
"loaded",
|
|
13396
|
+
Boolean(src && image?.complete && image.naturalWidth > 0),
|
|
13397
|
+
);
|
|
13398
|
+
}
|
|
13399
|
+
|
|
13386
13400
|
#finishImageLoading() {
|
|
13387
13401
|
if (this.#loadingTimer !== null) {
|
|
13388
13402
|
clearTimeout(this.#loadingTimer);
|
|
@@ -13553,6 +13567,7 @@ class FigMedia extends HTMLElement {
|
|
|
13553
13567
|
if (!this.#mediaEl.hasAttribute("data-generated")) return;
|
|
13554
13568
|
const src = this.#currentMediaSrc();
|
|
13555
13569
|
if (this.#mediaEl.getAttribute("src") !== src) {
|
|
13570
|
+
this.removeAttribute("loaded");
|
|
13556
13571
|
if (src) {
|
|
13557
13572
|
this.#mediaEl.setAttribute("src", src);
|
|
13558
13573
|
} else {
|
|
@@ -13880,6 +13895,7 @@ class FigMedia extends HTMLElement {
|
|
|
13880
13895
|
media.tagName === "IMG" &&
|
|
13881
13896
|
(event.type === "load" || event.type === "error")
|
|
13882
13897
|
) {
|
|
13898
|
+
this.toggleAttribute("loaded", event.type === "load");
|
|
13883
13899
|
this.#finishImageLoading();
|
|
13884
13900
|
}
|
|
13885
13901
|
const detail = {
|
|
@@ -19788,6 +19804,8 @@ figDefineElement("fig-color-tip", FigColorTip);
|
|
|
19788
19804
|
* @attr {boolean} disabled - Whether this choice is disabled
|
|
19789
19805
|
*/
|
|
19790
19806
|
class FigChoice extends HTMLElement {
|
|
19807
|
+
#childObserver = null;
|
|
19808
|
+
|
|
19791
19809
|
static get observedAttributes() {
|
|
19792
19810
|
return ["selected", "disabled"];
|
|
19793
19811
|
}
|
|
@@ -19797,21 +19815,34 @@ class FigChoice extends HTMLElement {
|
|
|
19797
19815
|
if (!this.hasAttribute("tabindex")) {
|
|
19798
19816
|
this.setAttribute("tabindex", "0");
|
|
19799
19817
|
}
|
|
19800
|
-
this
|
|
19801
|
-
"aria-selected",
|
|
19802
|
-
figBooleanAttribute(this, "selected") ? "true" : "false",
|
|
19803
|
-
);
|
|
19818
|
+
this.#syncSelectedState();
|
|
19804
19819
|
if (figBooleanAttribute(this, "disabled")) {
|
|
19805
19820
|
this.setAttribute("aria-disabled", "true");
|
|
19806
19821
|
}
|
|
19807
19822
|
}
|
|
19808
19823
|
|
|
19824
|
+
disconnectedCallback() {
|
|
19825
|
+
this.#childObserver?.disconnect();
|
|
19826
|
+
}
|
|
19827
|
+
|
|
19828
|
+
#syncSelectedState() {
|
|
19829
|
+
const selected = figBooleanAttribute(this, "selected");
|
|
19830
|
+
this.setAttribute("aria-selected", selected ? "true" : "false");
|
|
19831
|
+
for (const child of this.children) {
|
|
19832
|
+
child.toggleAttribute("selected", selected);
|
|
19833
|
+
}
|
|
19834
|
+
this.#childObserver?.disconnect();
|
|
19835
|
+
if (selected && this.isConnected) {
|
|
19836
|
+
this.#childObserver ??= new MutationObserver(() =>
|
|
19837
|
+
this.#syncSelectedState(),
|
|
19838
|
+
);
|
|
19839
|
+
this.#childObserver.observe(this, { childList: true });
|
|
19840
|
+
}
|
|
19841
|
+
}
|
|
19842
|
+
|
|
19809
19843
|
attributeChangedCallback(name) {
|
|
19810
19844
|
if (name === "selected") {
|
|
19811
|
-
this
|
|
19812
|
-
"aria-selected",
|
|
19813
|
-
figBooleanAttribute(this, "selected") ? "true" : "false",
|
|
19814
|
-
);
|
|
19845
|
+
this.#syncSelectedState();
|
|
19815
19846
|
}
|
|
19816
19847
|
if (name === "disabled") {
|
|
19817
19848
|
const isDisabled =
|
|
@@ -19914,19 +19945,11 @@ class FigChooser extends HTMLElement {
|
|
|
19914
19945
|
const raw = this.getAttribute("columns");
|
|
19915
19946
|
const columns = raw === null ? NaN : Number(raw);
|
|
19916
19947
|
const validColumns = Number.isInteger(columns) && columns > 0;
|
|
19917
|
-
const effectiveColumns = validColumns ? columns : 2;
|
|
19918
19948
|
if (validColumns) {
|
|
19919
|
-
this.style.setProperty("--fig-chooser-grid-columns", String(
|
|
19949
|
+
this.style.setProperty("--fig-chooser-grid-columns", String(columns));
|
|
19920
19950
|
} else {
|
|
19921
19951
|
this.style.removeProperty("--fig-chooser-grid-columns");
|
|
19922
19952
|
}
|
|
19923
|
-
const isGrid = this.getAttribute("layout") === "grid";
|
|
19924
|
-
this.choices.forEach((choice, index) => {
|
|
19925
|
-
choice.toggleAttribute(
|
|
19926
|
-
"data-fig-chooser-first-row",
|
|
19927
|
-
isGrid && index < effectiveColumns,
|
|
19928
|
-
);
|
|
19929
|
-
});
|
|
19930
19953
|
}
|
|
19931
19954
|
|
|
19932
19955
|
get choices() {
|
|
@@ -20176,7 +20199,8 @@ class FigChooser extends HTMLElement {
|
|
|
20176
20199
|
!c.hasAttribute("disabled") || c.getAttribute("disabled") === "false",
|
|
20177
20200
|
);
|
|
20178
20201
|
if (!choices.length) return;
|
|
20179
|
-
const
|
|
20202
|
+
const focusedChoice = this.#findChoiceFromTarget(event.target);
|
|
20203
|
+
const currentIndex = choices.indexOf(focusedChoice);
|
|
20180
20204
|
let nextIndex = currentIndex;
|
|
20181
20205
|
|
|
20182
20206
|
const loop = this.hasAttribute("loop");
|
|
@@ -20211,12 +20235,9 @@ class FigChooser extends HTMLElement {
|
|
|
20211
20235
|
case "Enter":
|
|
20212
20236
|
case " ":
|
|
20213
20237
|
event.preventDefault();
|
|
20214
|
-
if (
|
|
20215
|
-
|
|
20216
|
-
|
|
20217
|
-
this.selectedChoice = focused;
|
|
20218
|
-
this.#emitEvents();
|
|
20219
|
-
}
|
|
20238
|
+
if (focusedChoice && focusedChoice !== this.#selectedChoice) {
|
|
20239
|
+
this.selectedChoice = focusedChoice;
|
|
20240
|
+
this.#emitEvents();
|
|
20220
20241
|
}
|
|
20221
20242
|
return;
|
|
20222
20243
|
default:
|
|
@@ -20224,9 +20245,9 @@ class FigChooser extends HTMLElement {
|
|
|
20224
20245
|
}
|
|
20225
20246
|
|
|
20226
20247
|
if (nextIndex !== currentIndex && choices[nextIndex]) {
|
|
20227
|
-
|
|
20228
|
-
|
|
20229
|
-
this.#
|
|
20248
|
+
const nextChoice = choices[nextIndex];
|
|
20249
|
+
nextChoice.focus({ preventScroll: true });
|
|
20250
|
+
if (this.autoScroll) this.#scrollToChoice(nextChoice);
|
|
20230
20251
|
}
|
|
20231
20252
|
}
|
|
20232
20253
|
|
|
@@ -20397,12 +20418,14 @@ class FigChooser extends HTMLElement {
|
|
|
20397
20418
|
}
|
|
20398
20419
|
|
|
20399
20420
|
#applyOverflowMode() {
|
|
20400
|
-
|
|
20421
|
+
const usesScrollbar = this.#overflowMode === "scrollbar";
|
|
20422
|
+
const isGrid = this.getAttribute("layout") === "grid";
|
|
20423
|
+
if (usesScrollbar || isGrid) {
|
|
20401
20424
|
this.#removeNavButtons();
|
|
20402
|
-
this.classList.
|
|
20425
|
+
this.classList.toggle("fig-overflow-fade", usesScrollbar);
|
|
20403
20426
|
this.classList.toggle(
|
|
20404
20427
|
"fig-overflow-fade-horizontal",
|
|
20405
|
-
this.getAttribute("layout") === "horizontal",
|
|
20428
|
+
usesScrollbar && this.getAttribute("layout") === "horizontal",
|
|
20406
20429
|
);
|
|
20407
20430
|
} else {
|
|
20408
20431
|
this.#createNavButtons();
|
package/package.json
CHANGED