@rogieking/figui3 6.19.1 → 6.20.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/README.md +34 -0
- package/components.css +131 -0
- package/dist/components.css +1 -1
- package/dist/fig.css +1 -1
- package/dist/fig.js +26 -26
- package/fig.js +273 -0
- package/package.json +1 -1
package/fig.js
CHANGED
|
@@ -11906,6 +11906,279 @@ class FigVideo extends FigMedia {
|
|
|
11906
11906
|
}
|
|
11907
11907
|
customElements.define("fig-video", FigVideo);
|
|
11908
11908
|
|
|
11909
|
+
/**
|
|
11910
|
+
* <fig-card> — Media card with optional link, selection chrome, and truncated label.
|
|
11911
|
+
*
|
|
11912
|
+
* Composes a generated `fig-image` (or authored fig-image/fig-media/fig-preview).
|
|
11913
|
+
* Selection is attribute-only (`selected`); apps own toggle/group logic.
|
|
11914
|
+
* When `href` is set (and not disabled), content wraps in a real `<a>`.
|
|
11915
|
+
*
|
|
11916
|
+
* @attr {string} src - Image URL forwarded to generated fig-image
|
|
11917
|
+
* @attr {string} alt - Alt text forwarded to generated fig-image
|
|
11918
|
+
* @attr {string} label - Card title text (preferred over `text`)
|
|
11919
|
+
* @attr {string} text - Alias for `label`
|
|
11920
|
+
* @attr {string} sublabel - Secondary one-line text under the label
|
|
11921
|
+
* @attr {string} href - Makes the card a link
|
|
11922
|
+
* @attr {string} target - Forwarded to the `<a>`
|
|
11923
|
+
* @attr {boolean} selected - Selected chrome (CSS only)
|
|
11924
|
+
* @attr {boolean} disabled - Dim + non-interactive; no `<a>` when disabled
|
|
11925
|
+
* @attr {boolean} full - Stretch to available width (CSS; default width is already 100%)
|
|
11926
|
+
* @attr {string} aspect-ratio - Forwarded to fig-image (default `1/1`)
|
|
11927
|
+
* @attr {string} fit - Forwarded to fig-image (default `contain`)
|
|
11928
|
+
* @attr {string} label-line-clamp - `1` (default) or `2`
|
|
11929
|
+
*/
|
|
11930
|
+
class FigCard extends HTMLElement {
|
|
11931
|
+
static get observedAttributes() {
|
|
11932
|
+
return [
|
|
11933
|
+
"src",
|
|
11934
|
+
"alt",
|
|
11935
|
+
"label",
|
|
11936
|
+
"text",
|
|
11937
|
+
"sublabel",
|
|
11938
|
+
"href",
|
|
11939
|
+
"target",
|
|
11940
|
+
"selected",
|
|
11941
|
+
"disabled",
|
|
11942
|
+
"full",
|
|
11943
|
+
"aspect-ratio",
|
|
11944
|
+
"fit",
|
|
11945
|
+
"label-line-clamp",
|
|
11946
|
+
];
|
|
11947
|
+
}
|
|
11948
|
+
|
|
11949
|
+
#linkEl = null;
|
|
11950
|
+
#mediaWrap = null;
|
|
11951
|
+
#textWrap = null;
|
|
11952
|
+
#imageEl = null;
|
|
11953
|
+
#labelEl = null;
|
|
11954
|
+
#sublabelEl = null;
|
|
11955
|
+
#usesAuthoredMedia = false;
|
|
11956
|
+
|
|
11957
|
+
connectedCallback() {
|
|
11958
|
+
this.#ensureStructure();
|
|
11959
|
+
this.#sync();
|
|
11960
|
+
}
|
|
11961
|
+
|
|
11962
|
+
attributeChangedCallback() {
|
|
11963
|
+
if (!this.isConnected) return;
|
|
11964
|
+
this.#ensureStructure();
|
|
11965
|
+
this.#sync();
|
|
11966
|
+
}
|
|
11967
|
+
|
|
11968
|
+
#labelText() {
|
|
11969
|
+
return this.getAttribute("label") ?? this.getAttribute("text") ?? "";
|
|
11970
|
+
}
|
|
11971
|
+
|
|
11972
|
+
#sublabelText() {
|
|
11973
|
+
return this.getAttribute("sublabel") ?? "";
|
|
11974
|
+
}
|
|
11975
|
+
|
|
11976
|
+
#wantsLink() {
|
|
11977
|
+
const href = this.getAttribute("href");
|
|
11978
|
+
return Boolean(href) && !figBooleanAttribute(this, "disabled");
|
|
11979
|
+
}
|
|
11980
|
+
|
|
11981
|
+
#lineClamp() {
|
|
11982
|
+
const raw = this.getAttribute("label-line-clamp");
|
|
11983
|
+
return raw === "2" ? "2" : "1";
|
|
11984
|
+
}
|
|
11985
|
+
|
|
11986
|
+
#findAuthoredMedia() {
|
|
11987
|
+
return this.querySelector(
|
|
11988
|
+
":scope > fig-image:not([data-generated]), :scope > fig-media:not([data-generated]), :scope > fig-preview:not([data-generated]), :scope > .fig-card-link > .fig-card-media > fig-image:not([data-generated]), :scope > .fig-card-link > .fig-card-media > fig-media:not([data-generated]), :scope > .fig-card-link > .fig-card-media > fig-preview:not([data-generated])",
|
|
11989
|
+
);
|
|
11990
|
+
}
|
|
11991
|
+
|
|
11992
|
+
#ensureStructure() {
|
|
11993
|
+
const authored = this.#findAuthoredMedia();
|
|
11994
|
+
this.#usesAuthoredMedia = Boolean(authored);
|
|
11995
|
+
|
|
11996
|
+
const wantAnchor = this.#wantsLink();
|
|
11997
|
+
const tag = wantAnchor ? "a" : "div";
|
|
11998
|
+
|
|
11999
|
+
if (!this.#linkEl || this.#linkEl.tagName.toLowerCase() !== tag) {
|
|
12000
|
+
const next = document.createElement(tag);
|
|
12001
|
+
next.className = "fig-card-link";
|
|
12002
|
+
if (this.#linkEl) {
|
|
12003
|
+
while (this.#linkEl.firstChild) {
|
|
12004
|
+
next.appendChild(this.#linkEl.firstChild);
|
|
12005
|
+
}
|
|
12006
|
+
this.#linkEl.replaceWith(next);
|
|
12007
|
+
} else {
|
|
12008
|
+
this.appendChild(next);
|
|
12009
|
+
}
|
|
12010
|
+
this.#linkEl = next;
|
|
12011
|
+
}
|
|
12012
|
+
|
|
12013
|
+
if (!this.#mediaWrap || !this.#mediaWrap.isConnected) {
|
|
12014
|
+
this.#mediaWrap = this.#linkEl.querySelector(":scope > .fig-card-media");
|
|
12015
|
+
if (!this.#mediaWrap) {
|
|
12016
|
+
this.#mediaWrap = document.createElement("div");
|
|
12017
|
+
this.#mediaWrap.className = "fig-card-media";
|
|
12018
|
+
this.#linkEl.prepend(this.#mediaWrap);
|
|
12019
|
+
}
|
|
12020
|
+
}
|
|
12021
|
+
|
|
12022
|
+
if (authored && authored.parentElement !== this.#mediaWrap) {
|
|
12023
|
+
this.#mediaWrap
|
|
12024
|
+
.querySelectorAll("[data-generated]")
|
|
12025
|
+
.forEach((el) => el.remove());
|
|
12026
|
+
this.#mediaWrap.appendChild(authored);
|
|
12027
|
+
this.#imageEl = null;
|
|
12028
|
+
}
|
|
12029
|
+
|
|
12030
|
+
if (!this.#usesAuthoredMedia) {
|
|
12031
|
+
this.#imageEl =
|
|
12032
|
+
this.#mediaWrap.querySelector(":scope > fig-image[data-generated]") ||
|
|
12033
|
+
null;
|
|
12034
|
+
if (!this.#imageEl) {
|
|
12035
|
+
this.#mediaWrap
|
|
12036
|
+
.querySelectorAll(
|
|
12037
|
+
":scope > fig-image, :scope > fig-media, :scope > fig-preview",
|
|
12038
|
+
)
|
|
12039
|
+
.forEach((el) => {
|
|
12040
|
+
if (el.hasAttribute("data-generated")) el.remove();
|
|
12041
|
+
});
|
|
12042
|
+
this.#imageEl = document.createElement("fig-image");
|
|
12043
|
+
this.#imageEl.setAttribute("data-generated", "");
|
|
12044
|
+
this.#imageEl.setAttribute("full", "");
|
|
12045
|
+
this.#imageEl.setAttribute("size", "auto");
|
|
12046
|
+
this.#mediaWrap.appendChild(this.#imageEl);
|
|
12047
|
+
}
|
|
12048
|
+
}
|
|
12049
|
+
|
|
12050
|
+
if (!this.#textWrap || !this.#textWrap.isConnected) {
|
|
12051
|
+
this.#textWrap = this.#linkEl.querySelector(":scope > .fig-card-text");
|
|
12052
|
+
if (!this.#textWrap) {
|
|
12053
|
+
this.#textWrap = document.createElement("div");
|
|
12054
|
+
this.#textWrap.className = "fig-card-text";
|
|
12055
|
+
this.#textWrap.setAttribute("data-generated", "");
|
|
12056
|
+
this.#linkEl.appendChild(this.#textWrap);
|
|
12057
|
+
}
|
|
12058
|
+
}
|
|
12059
|
+
|
|
12060
|
+
if (!this.#labelEl || !this.#labelEl.isConnected) {
|
|
12061
|
+
this.#labelEl = this.#textWrap.querySelector(
|
|
12062
|
+
":scope > .fig-card-label[data-generated]",
|
|
12063
|
+
);
|
|
12064
|
+
if (!this.#labelEl) {
|
|
12065
|
+
this.#labelEl =
|
|
12066
|
+
this.#linkEl.querySelector(":scope > .fig-card-label[data-generated]") ||
|
|
12067
|
+
null;
|
|
12068
|
+
if (!this.#labelEl) {
|
|
12069
|
+
this.#labelEl = document.createElement("label");
|
|
12070
|
+
this.#labelEl.className = "fig-card-label";
|
|
12071
|
+
this.#labelEl.setAttribute("data-generated", "");
|
|
12072
|
+
}
|
|
12073
|
+
this.#textWrap.appendChild(this.#labelEl);
|
|
12074
|
+
}
|
|
12075
|
+
}
|
|
12076
|
+
|
|
12077
|
+
if (!this.#sublabelEl || !this.#sublabelEl.isConnected) {
|
|
12078
|
+
this.#sublabelEl = this.#textWrap.querySelector(
|
|
12079
|
+
":scope > .fig-card-sublabel[data-generated]",
|
|
12080
|
+
);
|
|
12081
|
+
if (!this.#sublabelEl) {
|
|
12082
|
+
this.#sublabelEl =
|
|
12083
|
+
this.#linkEl.querySelector(
|
|
12084
|
+
":scope > .fig-card-sublabel[data-generated]",
|
|
12085
|
+
) || null;
|
|
12086
|
+
if (!this.#sublabelEl) {
|
|
12087
|
+
this.#sublabelEl = document.createElement("span");
|
|
12088
|
+
this.#sublabelEl.className = "fig-card-sublabel";
|
|
12089
|
+
this.#sublabelEl.setAttribute("data-generated", "");
|
|
12090
|
+
}
|
|
12091
|
+
this.#labelEl.after(this.#sublabelEl);
|
|
12092
|
+
}
|
|
12093
|
+
}
|
|
12094
|
+
}
|
|
12095
|
+
|
|
12096
|
+
#sync() {
|
|
12097
|
+
if (!this.#linkEl) return;
|
|
12098
|
+
|
|
12099
|
+
const disabled = figBooleanAttribute(this, "disabled");
|
|
12100
|
+
const selected = figBooleanAttribute(this, "selected");
|
|
12101
|
+
const label = this.#labelText();
|
|
12102
|
+
const sublabel = this.#sublabelText();
|
|
12103
|
+
const clamp = this.#lineClamp();
|
|
12104
|
+
|
|
12105
|
+
this.style.setProperty("--fig-card-label-line-clamp", clamp);
|
|
12106
|
+
|
|
12107
|
+
if (this.#wantsLink()) {
|
|
12108
|
+
const href = this.getAttribute("href") || "";
|
|
12109
|
+
const target = this.getAttribute("target");
|
|
12110
|
+
this.#linkEl.setAttribute("href", href);
|
|
12111
|
+
if (target) {
|
|
12112
|
+
this.#linkEl.setAttribute("target", target);
|
|
12113
|
+
if (target === "_blank") {
|
|
12114
|
+
this.#linkEl.setAttribute("rel", "noopener noreferrer");
|
|
12115
|
+
} else {
|
|
12116
|
+
this.#linkEl.removeAttribute("rel");
|
|
12117
|
+
}
|
|
12118
|
+
} else {
|
|
12119
|
+
this.#linkEl.removeAttribute("target");
|
|
12120
|
+
this.#linkEl.removeAttribute("rel");
|
|
12121
|
+
}
|
|
12122
|
+
if (selected) {
|
|
12123
|
+
this.#linkEl.setAttribute("aria-current", "true");
|
|
12124
|
+
} else {
|
|
12125
|
+
this.#linkEl.removeAttribute("aria-current");
|
|
12126
|
+
}
|
|
12127
|
+
this.removeAttribute("role");
|
|
12128
|
+
this.removeAttribute("aria-label");
|
|
12129
|
+
} else {
|
|
12130
|
+
this.#linkEl.removeAttribute("href");
|
|
12131
|
+
this.#linkEl.removeAttribute("target");
|
|
12132
|
+
this.#linkEl.removeAttribute("rel");
|
|
12133
|
+
this.#linkEl.removeAttribute("aria-current");
|
|
12134
|
+
this.setAttribute("role", "group");
|
|
12135
|
+
const ariaLabel = [label, sublabel].filter(Boolean).join(", ");
|
|
12136
|
+
if (ariaLabel) {
|
|
12137
|
+
this.setAttribute("aria-label", ariaLabel);
|
|
12138
|
+
} else {
|
|
12139
|
+
this.removeAttribute("aria-label");
|
|
12140
|
+
}
|
|
12141
|
+
}
|
|
12142
|
+
|
|
12143
|
+
if (disabled) {
|
|
12144
|
+
this.setAttribute("aria-disabled", "true");
|
|
12145
|
+
} else {
|
|
12146
|
+
this.removeAttribute("aria-disabled");
|
|
12147
|
+
}
|
|
12148
|
+
|
|
12149
|
+
if (this.#imageEl && !this.#usesAuthoredMedia) {
|
|
12150
|
+
const src = this.getAttribute("src");
|
|
12151
|
+
const altAttr = this.getAttribute("alt");
|
|
12152
|
+
const aspect = this.getAttribute("aspect-ratio") || "1/1";
|
|
12153
|
+
const fit = this.getAttribute("fit") || "contain";
|
|
12154
|
+
const alt = altAttr != null ? altAttr : "";
|
|
12155
|
+
|
|
12156
|
+
if (src) this.#imageEl.setAttribute("src", src);
|
|
12157
|
+
else this.#imageEl.removeAttribute("src");
|
|
12158
|
+
this.#imageEl.setAttribute("alt", alt);
|
|
12159
|
+
this.#imageEl.setAttribute("aspect-ratio", aspect);
|
|
12160
|
+
this.#imageEl.setAttribute("fit", fit);
|
|
12161
|
+
this.#imageEl.setAttribute("full", "");
|
|
12162
|
+
this.#imageEl.setAttribute("size", "auto");
|
|
12163
|
+
}
|
|
12164
|
+
|
|
12165
|
+
if (this.#labelEl) {
|
|
12166
|
+
this.#labelEl.textContent = label;
|
|
12167
|
+
this.#labelEl.hidden = !label;
|
|
12168
|
+
}
|
|
12169
|
+
|
|
12170
|
+
if (this.#sublabelEl) {
|
|
12171
|
+
this.#sublabelEl.textContent = sublabel;
|
|
12172
|
+
this.#sublabelEl.hidden = !sublabel;
|
|
12173
|
+
}
|
|
12174
|
+
|
|
12175
|
+
if (this.#textWrap) {
|
|
12176
|
+
this.#textWrap.hidden = !label && !sublabel;
|
|
12177
|
+
}
|
|
12178
|
+
}
|
|
12179
|
+
}
|
|
12180
|
+
customElements.define("fig-card", FigCard);
|
|
12181
|
+
|
|
11909
12182
|
/**
|
|
11910
12183
|
* <fig-media-controls> — Standalone playback controls UI.
|
|
11911
12184
|
*
|
package/package.json
CHANGED