@rogieking/figui3 9.4.4 → 9.4.6
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/fig-lab/components.md +1 -0
- package/.cursor/skills/fig-lab/reference.md +2 -0
- package/.cursor/skills/figui3/components.md +7 -0
- package/.cursor/skills/figui3/reference.md +1 -0
- package/CHANGELOG.md +21 -0
- package/README.md +4 -1
- package/components.css +318 -241
- package/dist/components.css +1 -1
- package/dist/fig-lab.js +1 -1
- package/dist/fig.css +1 -1
- package/dist/fig.js +4 -4
- package/fig-lab.js +5 -4
- package/fig.js +80 -8
- package/package.json +1 -1
package/fig-lab.js
CHANGED
|
@@ -3065,8 +3065,10 @@ class FigReorder extends HTMLElement {
|
|
|
3065
3065
|
this.#clearHandleMarks(allChildren);
|
|
3066
3066
|
this.#clearReorderItemMarks(allChildren);
|
|
3067
3067
|
this.#markNonItems(allChildren.filter((child) => !childSet.has(child)));
|
|
3068
|
+
const reorderable = !this.#disabled && children.length >= 2;
|
|
3069
|
+
this.#markReorderItems(children, reorderable);
|
|
3068
3070
|
|
|
3069
|
-
if (
|
|
3071
|
+
if (!reorderable) {
|
|
3070
3072
|
this.#unbindAll();
|
|
3071
3073
|
return;
|
|
3072
3074
|
}
|
|
@@ -3088,7 +3090,6 @@ class FigReorder extends HTMLElement {
|
|
|
3088
3090
|
}
|
|
3089
3091
|
|
|
3090
3092
|
this.#markHandles(children);
|
|
3091
|
-
this.#markReorderItems(children);
|
|
3092
3093
|
}
|
|
3093
3094
|
|
|
3094
3095
|
#clearReorderItemMarks(children) {
|
|
@@ -3101,9 +3102,9 @@ class FigReorder extends HTMLElement {
|
|
|
3101
3102
|
}
|
|
3102
3103
|
}
|
|
3103
3104
|
|
|
3104
|
-
#markReorderItems(children) {
|
|
3105
|
+
#markReorderItems(children, reorderable = true) {
|
|
3105
3106
|
for (const child of children) {
|
|
3106
|
-
child.setAttribute("data-reorder-item", "");
|
|
3107
|
+
if (reorderable) child.setAttribute("data-reorder-item", "");
|
|
3107
3108
|
if (!child.hasAttribute("role")) {
|
|
3108
3109
|
child.setAttribute("role", "listitem");
|
|
3109
3110
|
child.setAttribute("data-reorder-generated-role", "");
|
package/fig.js
CHANGED
|
@@ -4912,14 +4912,20 @@ figDefineElement("fig-toolbelt-item", FigToolbeltItem);
|
|
|
4912
4912
|
* @attr {boolean} disabled - Disables all items
|
|
4913
4913
|
* @attr {"horizontal"|"vertical"} layout - Item direction (default: horizontal)
|
|
4914
4914
|
* @attr {"buttons"|"scrollbar"} overflow - Overflow controls (default: scrollbar)
|
|
4915
|
+
* @slot prepend - Fixed content before the scrolling viewport
|
|
4916
|
+
* @slot append - Fixed content after the scrolling viewport
|
|
4915
4917
|
* @fires input - Selected value
|
|
4916
4918
|
* @fires change - Selected value
|
|
4917
4919
|
*/
|
|
4918
4920
|
class FigToolbelt extends HTMLElement {
|
|
4919
4921
|
#boundHandleClick = this.#handleClick.bind(this);
|
|
4920
4922
|
#boundHandleKeyDown = this.#handleKeyDown.bind(this);
|
|
4923
|
+
#boundHandleSlotChange = this.#handleSlotChange.bind(this);
|
|
4921
4924
|
#boundSyncOverflow = this.#syncOverflow.bind(this);
|
|
4922
4925
|
#viewport = null;
|
|
4926
|
+
#itemSlot = null;
|
|
4927
|
+
#prependSlot = null;
|
|
4928
|
+
#appendSlot = null;
|
|
4923
4929
|
#mutationObserver = null;
|
|
4924
4930
|
#resizeObserver = null;
|
|
4925
4931
|
#navStart = null;
|
|
@@ -4933,6 +4939,15 @@ class FigToolbelt extends HTMLElement {
|
|
|
4933
4939
|
const frame = document.createElement("div");
|
|
4934
4940
|
frame.setAttribute("part", "frame");
|
|
4935
4941
|
|
|
4942
|
+
this.#prependSlot = document.createElement("slot");
|
|
4943
|
+
this.#prependSlot.name = "prepend";
|
|
4944
|
+
this.#prependSlot.setAttribute("part", "prepend");
|
|
4945
|
+
this.#prependSlot.hidden = true;
|
|
4946
|
+
this.#prependSlot.style.display = "none";
|
|
4947
|
+
|
|
4948
|
+
const scrollRegion = document.createElement("div");
|
|
4949
|
+
scrollRegion.setAttribute("part", "scroll-region");
|
|
4950
|
+
|
|
4936
4951
|
const startSlot = document.createElement("slot");
|
|
4937
4952
|
startSlot.name = "start";
|
|
4938
4953
|
startSlot.style.display = "contents";
|
|
@@ -4940,16 +4955,31 @@ class FigToolbelt extends HTMLElement {
|
|
|
4940
4955
|
this.#viewport = document.createElement("div");
|
|
4941
4956
|
this.#viewport.className = "fig-overflow-fade";
|
|
4942
4957
|
this.#viewport.setAttribute("part", "viewport");
|
|
4943
|
-
|
|
4944
|
-
itemSlot.style.display = "contents";
|
|
4945
|
-
this.#viewport.append(itemSlot);
|
|
4958
|
+
this.#itemSlot = document.createElement("slot");
|
|
4959
|
+
this.#itemSlot.style.display = "contents";
|
|
4960
|
+
this.#viewport.append(this.#itemSlot);
|
|
4946
4961
|
|
|
4947
4962
|
const endSlot = document.createElement("slot");
|
|
4948
4963
|
endSlot.name = "end";
|
|
4949
4964
|
endSlot.style.display = "contents";
|
|
4950
4965
|
|
|
4951
|
-
|
|
4966
|
+
this.#appendSlot = document.createElement("slot");
|
|
4967
|
+
this.#appendSlot.name = "append";
|
|
4968
|
+
this.#appendSlot.setAttribute("part", "append");
|
|
4969
|
+
this.#appendSlot.hidden = true;
|
|
4970
|
+
this.#appendSlot.style.display = "none";
|
|
4971
|
+
|
|
4972
|
+
scrollRegion.append(startSlot, this.#viewport, endSlot);
|
|
4973
|
+
frame.append(this.#prependSlot, scrollRegion, this.#appendSlot);
|
|
4952
4974
|
shadow.append(frame);
|
|
4975
|
+
|
|
4976
|
+
for (const slot of [
|
|
4977
|
+
this.#prependSlot,
|
|
4978
|
+
this.#itemSlot,
|
|
4979
|
+
this.#appendSlot,
|
|
4980
|
+
]) {
|
|
4981
|
+
slot.addEventListener("slotchange", this.#boundHandleSlotChange);
|
|
4982
|
+
}
|
|
4953
4983
|
}
|
|
4954
4984
|
|
|
4955
4985
|
static get observedAttributes() {
|
|
@@ -4968,6 +4998,7 @@ class FigToolbelt extends HTMLElement {
|
|
|
4968
4998
|
|
|
4969
4999
|
connectedCallback() {
|
|
4970
5000
|
if (!this.hasAttribute("role")) this.setAttribute("role", "toolbar");
|
|
5001
|
+
this.#syncFixedSlots();
|
|
4971
5002
|
this.#syncOrientation();
|
|
4972
5003
|
this.addEventListener("click", this.#boundHandleClick);
|
|
4973
5004
|
this.addEventListener("keydown", this.#boundHandleKeyDown);
|
|
@@ -5036,9 +5067,32 @@ class FigToolbelt extends HTMLElement {
|
|
|
5036
5067
|
}
|
|
5037
5068
|
|
|
5038
5069
|
#items() {
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5070
|
+
const itemsByRegion = {
|
|
5071
|
+
prepend: [],
|
|
5072
|
+
viewport: [],
|
|
5073
|
+
append: [],
|
|
5074
|
+
};
|
|
5075
|
+
for (const item of this.querySelectorAll("fig-toolbelt-item")) {
|
|
5076
|
+
if (item.closest("fig-toolbelt") !== this) continue;
|
|
5077
|
+
const region = this.#itemRegion(item);
|
|
5078
|
+
if (region) itemsByRegion[region].push(item);
|
|
5079
|
+
}
|
|
5080
|
+
return [
|
|
5081
|
+
...itemsByRegion.prepend,
|
|
5082
|
+
...itemsByRegion.viewport,
|
|
5083
|
+
...itemsByRegion.append,
|
|
5084
|
+
];
|
|
5085
|
+
}
|
|
5086
|
+
|
|
5087
|
+
#itemRegion(item) {
|
|
5088
|
+
let topLevelChild = item;
|
|
5089
|
+
while (topLevelChild.parentElement && topLevelChild.parentElement !== this) {
|
|
5090
|
+
topLevelChild = topLevelChild.parentElement;
|
|
5091
|
+
}
|
|
5092
|
+
if (topLevelChild.parentElement !== this) return null;
|
|
5093
|
+
const slot = topLevelChild.getAttribute("slot") || "";
|
|
5094
|
+
if (slot === "prepend" || slot === "append") return slot;
|
|
5095
|
+
return slot ? null : "viewport";
|
|
5042
5096
|
}
|
|
5043
5097
|
|
|
5044
5098
|
#availableItems() {
|
|
@@ -5188,6 +5242,24 @@ class FigToolbelt extends HTMLElement {
|
|
|
5188
5242
|
this.dispatchEvent(new CustomEvent("change", { detail, bubbles: true }));
|
|
5189
5243
|
}
|
|
5190
5244
|
|
|
5245
|
+
#handleSlotChange() {
|
|
5246
|
+
this.#syncFixedSlots();
|
|
5247
|
+
this.#syncSelection();
|
|
5248
|
+
this.#syncTabIndexes();
|
|
5249
|
+
requestAnimationFrame(() => {
|
|
5250
|
+
this.#syncOverflow();
|
|
5251
|
+
this.#scrollSelectedItemIntoView();
|
|
5252
|
+
});
|
|
5253
|
+
}
|
|
5254
|
+
|
|
5255
|
+
#syncFixedSlots() {
|
|
5256
|
+
for (const slot of [this.#prependSlot, this.#appendSlot]) {
|
|
5257
|
+
const hidden = slot.assignedElements({ flatten: true }).length === 0;
|
|
5258
|
+
slot.hidden = hidden;
|
|
5259
|
+
slot.style.display = hidden ? "none" : "";
|
|
5260
|
+
}
|
|
5261
|
+
}
|
|
5262
|
+
|
|
5191
5263
|
#startObserver() {
|
|
5192
5264
|
this.#mutationObserver?.disconnect();
|
|
5193
5265
|
this.#mutationObserver = new MutationObserver((records) => {
|
|
@@ -5305,7 +5377,7 @@ class FigToolbelt extends HTMLElement {
|
|
|
5305
5377
|
}
|
|
5306
5378
|
|
|
5307
5379
|
#scrollItemIntoView(item, behavior = "smooth") {
|
|
5308
|
-
if (!item) return;
|
|
5380
|
+
if (!item || this.#itemRegion(item) !== "viewport") return;
|
|
5309
5381
|
requestAnimationFrame(() => {
|
|
5310
5382
|
if (!this.isConnected || !item.isConnected) return;
|
|
5311
5383
|
const isVertical = this.#isVertical;
|
package/package.json
CHANGED