@rogieking/figui3 8.9.29 → 8.9.31
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 +6 -0
- package/components.css +15 -0
- package/dist/components.css +1 -1
- package/dist/fig-lab.js +1 -1
- package/dist/fig.css +1 -1
- package/dist/fig.js +5 -5
- package/fig-lab.js +19 -10
- package/fig.js +166 -38
- package/package.json +1 -1
package/fig-lab.js
CHANGED
|
@@ -4639,6 +4639,7 @@ class PropskitSlider extends HTMLElement {
|
|
|
4639
4639
|
"data-wave-index",
|
|
4640
4640
|
"data-active",
|
|
4641
4641
|
"data-elastic-dragging",
|
|
4642
|
+
"default",
|
|
4642
4643
|
"style",
|
|
4643
4644
|
]);
|
|
4644
4645
|
|
|
@@ -4761,8 +4762,11 @@ class PropskitSlider extends HTMLElement {
|
|
|
4761
4762
|
}
|
|
4762
4763
|
|
|
4763
4764
|
#initialize() {
|
|
4765
|
+
const sliderType = (this.getAttribute("type") || "range").toLowerCase();
|
|
4764
4766
|
this.#initialValue =
|
|
4765
|
-
this.getAttribute("value") ??
|
|
4767
|
+
this.getAttribute("value") ??
|
|
4768
|
+
this.getAttribute("default") ??
|
|
4769
|
+
(sliderType === "delta" ? "0" : this.getAttribute("min") ?? "0");
|
|
4766
4770
|
const initialChildren = Array.from(this.childNodes).filter((node) => {
|
|
4767
4771
|
return (
|
|
4768
4772
|
node.nodeType !== Node.TEXT_NODE || Boolean(node.textContent?.trim())
|
|
@@ -4866,12 +4870,15 @@ class PropskitSlider extends HTMLElement {
|
|
|
4866
4870
|
this.#slider.setAttribute("text", "true");
|
|
4867
4871
|
|
|
4868
4872
|
const sliderType = (this.getAttribute("type") || "range").toLowerCase();
|
|
4869
|
-
if (sliderType === "delta"
|
|
4870
|
-
this.#slider.
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4873
|
+
if (sliderType === "delta") {
|
|
4874
|
+
const min = Number(this.#slider.min);
|
|
4875
|
+
const max = Number(this.#slider.max);
|
|
4876
|
+
const midpoint =
|
|
4877
|
+
Number.isFinite(min) && Number.isFinite(max)
|
|
4878
|
+
? min + (max - min) / 2
|
|
4879
|
+
: 0;
|
|
4880
|
+
this.#slider.setAttribute("default", String(midpoint));
|
|
4881
|
+
} else {
|
|
4875
4882
|
this.#slider.removeAttribute("default");
|
|
4876
4883
|
}
|
|
4877
4884
|
if (sliderType === "stepper") {
|
|
@@ -4910,8 +4917,10 @@ class PropskitSlider extends HTMLElement {
|
|
|
4910
4917
|
}
|
|
4911
4918
|
|
|
4912
4919
|
#pushExternalValueToSlider() {
|
|
4913
|
-
if (!this.#slider
|
|
4914
|
-
const next = this.
|
|
4920
|
+
if (!this.#slider) return;
|
|
4921
|
+
const next = this.hasAttribute("value")
|
|
4922
|
+
? this.getAttribute("value") ?? ""
|
|
4923
|
+
: this.#initialValue ?? "";
|
|
4915
4924
|
if (String(this.#slider.value) !== next) {
|
|
4916
4925
|
this.#slider.value = next;
|
|
4917
4926
|
}
|
|
@@ -5313,7 +5322,6 @@ class PropskitSlider extends HTMLElement {
|
|
|
5313
5322
|
#defaultValue() {
|
|
5314
5323
|
return (
|
|
5315
5324
|
this.getAttribute("default") ??
|
|
5316
|
-
this.#slider?.getAttribute("default") ??
|
|
5317
5325
|
this.#initialValue ??
|
|
5318
5326
|
this.#rangeInput?.min ??
|
|
5319
5327
|
"0"
|
|
@@ -7163,6 +7171,7 @@ class PropskitOscillator extends HTMLElement {
|
|
|
7163
7171
|
{ text: label },
|
|
7164
7172
|
figLabCreateElement("fig-handle", {
|
|
7165
7173
|
size: "small",
|
|
7174
|
+
type: "minimal",
|
|
7166
7175
|
"aria-label": `Oscillator ${type} handle`,
|
|
7167
7176
|
}),
|
|
7168
7177
|
),
|
package/fig.js
CHANGED
|
@@ -407,14 +407,19 @@ function figSyncOverflowState(host, scrollEl, axis = "x", threshold = 2) {
|
|
|
407
407
|
return scrollable;
|
|
408
408
|
}
|
|
409
409
|
|
|
410
|
-
function figScrollOverflowPage(
|
|
410
|
+
function figScrollOverflowPage(
|
|
411
|
+
scrollEl,
|
|
412
|
+
axis = "x",
|
|
413
|
+
direction = 1,
|
|
414
|
+
behavior = "smooth",
|
|
415
|
+
) {
|
|
411
416
|
if (!scrollEl) return;
|
|
412
417
|
const isHorizontal = axis === "x";
|
|
413
418
|
const pageSize = isHorizontal ? scrollEl.clientWidth : scrollEl.clientHeight;
|
|
414
419
|
const scrollAmount = pageSize * 0.8 * direction;
|
|
415
420
|
scrollEl.scrollBy({
|
|
416
421
|
[isHorizontal ? "left" : "top"]: scrollAmount,
|
|
417
|
-
behavior
|
|
422
|
+
behavior,
|
|
418
423
|
});
|
|
419
424
|
}
|
|
420
425
|
|
|
@@ -5700,11 +5705,7 @@ class FigSlider extends HTMLElement {
|
|
|
5700
5705
|
this.step = readNumber("step", defaults.step);
|
|
5701
5706
|
if (!(this.step > 0)) this.step = defaults.step > 0 ? defaults.step : 1;
|
|
5702
5707
|
this.color = this.getAttribute("color") || defaults?.color;
|
|
5703
|
-
this.default = this
|
|
5704
|
-
? this.getAttribute("default")
|
|
5705
|
-
: this.type === "delta"
|
|
5706
|
-
? 0
|
|
5707
|
-
: this.min;
|
|
5708
|
+
this.default = this.#resolveDefaultValue();
|
|
5708
5709
|
this.value = this.#normalizeSliderValue(rawValue);
|
|
5709
5710
|
}
|
|
5710
5711
|
|
|
@@ -5772,12 +5773,7 @@ class FigSlider extends HTMLElement {
|
|
|
5772
5773
|
this.input.removeEventListener("pointercancel", this.#boundRangePointerUp);
|
|
5773
5774
|
this.input.addEventListener("pointercancel", this.#boundRangePointerUp);
|
|
5774
5775
|
|
|
5775
|
-
|
|
5776
|
-
this.style.setProperty(
|
|
5777
|
-
"--default",
|
|
5778
|
-
this.#calculateNormal(this.default),
|
|
5779
|
-
);
|
|
5780
|
-
}
|
|
5776
|
+
this.style.setProperty("--default", this.#calculateNormal(this.default));
|
|
5781
5777
|
|
|
5782
5778
|
if (this.figInputNumber) {
|
|
5783
5779
|
this.#syncTextInputA11yAttributes();
|
|
@@ -5864,6 +5860,7 @@ class FigSlider extends HTMLElement {
|
|
|
5864
5860
|
this.input.setAttribute("list", this.datalist.getAttribute("id"));
|
|
5865
5861
|
} else if (this.type === "stepper") {
|
|
5866
5862
|
this.datalist = document.createElement("datalist");
|
|
5863
|
+
this.datalist.setAttribute("data-generated", "slider-stepper");
|
|
5867
5864
|
this.datalist.setAttribute("id", figUniqueId());
|
|
5868
5865
|
const steps = Math.min(
|
|
5869
5866
|
1001,
|
|
@@ -5878,6 +5875,7 @@ class FigSlider extends HTMLElement {
|
|
|
5878
5875
|
this.input.setAttribute("list", this.datalist.getAttribute("id"));
|
|
5879
5876
|
} else if (this.type === "delta") {
|
|
5880
5877
|
this.datalist = document.createElement("datalist");
|
|
5878
|
+
this.datalist.setAttribute("data-generated", "slider-delta");
|
|
5881
5879
|
this.datalist.setAttribute("id", figUniqueId());
|
|
5882
5880
|
let option = document.createElement("option");
|
|
5883
5881
|
option.setAttribute("value", this.default);
|
|
@@ -5885,14 +5883,7 @@ class FigSlider extends HTMLElement {
|
|
|
5885
5883
|
this.inputContainer.append(this.datalist);
|
|
5886
5884
|
this.input.setAttribute("list", this.datalist.getAttribute("id"));
|
|
5887
5885
|
}
|
|
5888
|
-
|
|
5889
|
-
const defaultOption = [...this.datalist.querySelectorAll("option")].find(
|
|
5890
|
-
(option) => option.value === String(this.default),
|
|
5891
|
-
);
|
|
5892
|
-
if (defaultOption) {
|
|
5893
|
-
defaultOption.setAttribute("default", "true");
|
|
5894
|
-
}
|
|
5895
|
-
}
|
|
5886
|
+
this.#syncDefaultDatalist();
|
|
5896
5887
|
this.#syncValue();
|
|
5897
5888
|
}
|
|
5898
5889
|
|
|
@@ -5938,6 +5929,10 @@ class FigSlider extends HTMLElement {
|
|
|
5938
5929
|
if (this.input) this.#syncProperties();
|
|
5939
5930
|
}
|
|
5940
5931
|
|
|
5932
|
+
get defaultValue() {
|
|
5933
|
+
return this.#resolveDefaultValue();
|
|
5934
|
+
}
|
|
5935
|
+
|
|
5941
5936
|
disconnectedCallback() {
|
|
5942
5937
|
this.#pendingRegeneration = false;
|
|
5943
5938
|
if (this.input) {
|
|
@@ -5998,6 +5993,28 @@ class FigSlider extends HTMLElement {
|
|
|
5998
5993
|
const { min, max } = this.#getBounds();
|
|
5999
5994
|
return Math.min(max, Math.max(min, value));
|
|
6000
5995
|
}
|
|
5996
|
+
#isStepAligned(value) {
|
|
5997
|
+
const { min } = this.#getBounds();
|
|
5998
|
+
const step = this.#toFiniteNumber(this.step);
|
|
5999
|
+
if (!(step > 0)) return true;
|
|
6000
|
+
const steps = (value - min) / step;
|
|
6001
|
+
const nearest = Math.round(steps);
|
|
6002
|
+
const tolerance = Number.EPSILON * Math.max(1, Math.abs(steps)) * 16;
|
|
6003
|
+
return Math.abs(steps - nearest) <= tolerance;
|
|
6004
|
+
}
|
|
6005
|
+
#resolveDefaultValue(rawDefault = this.getAttribute("default")) {
|
|
6006
|
+
const { min, max } = this.#getBounds();
|
|
6007
|
+
const parsed = this.#toFiniteNumber(rawDefault);
|
|
6008
|
+
const isValid =
|
|
6009
|
+
parsed !== null &&
|
|
6010
|
+
parsed >= min &&
|
|
6011
|
+
parsed <= max &&
|
|
6012
|
+
(this.type !== "stepper" || this.#isStepAligned(parsed));
|
|
6013
|
+
if (isValid) return parsed;
|
|
6014
|
+
return this.type === "delta"
|
|
6015
|
+
? Math.min(max, Math.max(min, 0))
|
|
6016
|
+
: min;
|
|
6017
|
+
}
|
|
6001
6018
|
#getFallbackValue() {
|
|
6002
6019
|
if (this.type === "delta") {
|
|
6003
6020
|
const deltaDefault = this.#toFiniteNumber(this.default);
|
|
@@ -6163,10 +6180,13 @@ class FigSlider extends HTMLElement {
|
|
|
6163
6180
|
}
|
|
6164
6181
|
if (!this.hasAttribute("default") && this.type !== "delta") {
|
|
6165
6182
|
this.default = this.min;
|
|
6183
|
+
} else {
|
|
6184
|
+
this.default = this.#resolveDefaultValue();
|
|
6166
6185
|
}
|
|
6167
6186
|
this.value = this.#normalizeSliderValue(this.value);
|
|
6168
6187
|
this.#syncProperties();
|
|
6169
6188
|
this.#syncStepperDatalist();
|
|
6189
|
+
this.#syncDefaultDatalist();
|
|
6170
6190
|
}
|
|
6171
6191
|
|
|
6172
6192
|
#syncStepperDatalist() {
|
|
@@ -6183,6 +6203,25 @@ class FigSlider extends HTMLElement {
|
|
|
6183
6203
|
}
|
|
6184
6204
|
this.datalist.replaceChildren(fragment);
|
|
6185
6205
|
this.input.setAttribute("list", this.datalist.id);
|
|
6206
|
+
this.#syncDefaultDatalist();
|
|
6207
|
+
}
|
|
6208
|
+
|
|
6209
|
+
#syncDefaultDatalist() {
|
|
6210
|
+
if (!this.datalist) return;
|
|
6211
|
+
const defaultValue = String(this.default);
|
|
6212
|
+
const options = [...this.datalist.querySelectorAll("option")];
|
|
6213
|
+
options.forEach((option) => option.removeAttribute("default"));
|
|
6214
|
+
let defaultOption = options.find((option) => option.value === defaultValue);
|
|
6215
|
+
if (
|
|
6216
|
+
!defaultOption &&
|
|
6217
|
+
this.type === "delta" &&
|
|
6218
|
+
this.datalist.getAttribute("data-generated") === "slider-delta"
|
|
6219
|
+
) {
|
|
6220
|
+
defaultOption = document.createElement("option");
|
|
6221
|
+
defaultOption.value = defaultValue;
|
|
6222
|
+
this.datalist.replaceChildren(defaultOption);
|
|
6223
|
+
}
|
|
6224
|
+
defaultOption?.setAttribute("default", "true");
|
|
6186
6225
|
}
|
|
6187
6226
|
|
|
6188
6227
|
#regenerateWhenIdle() {
|
|
@@ -6272,9 +6311,9 @@ class FigSlider extends HTMLElement {
|
|
|
6272
6311
|
}
|
|
6273
6312
|
break;
|
|
6274
6313
|
case "default":
|
|
6275
|
-
this.default =
|
|
6276
|
-
newValue !== null ? newValue : this.type === "delta" ? 0 : this.min;
|
|
6314
|
+
this.default = this.#resolveDefaultValue(newValue);
|
|
6277
6315
|
this.#syncProperties();
|
|
6316
|
+
this.#syncDefaultDatalist();
|
|
6278
6317
|
break;
|
|
6279
6318
|
case "min":
|
|
6280
6319
|
case "max":
|
|
@@ -16850,6 +16889,7 @@ class FigGroup extends HTMLElement {
|
|
|
16850
16889
|
|
|
16851
16890
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
16852
16891
|
if (oldValue === newValue) return;
|
|
16892
|
+
if (!this.isConnected) return;
|
|
16853
16893
|
if (name === "open") {
|
|
16854
16894
|
this.#header?.setAttribute("aria-expanded", String(this.open));
|
|
16855
16895
|
return;
|
|
@@ -16898,7 +16938,9 @@ class FigGroup extends HTMLElement {
|
|
|
16898
16938
|
const label = nameAttr || (isCollapsible ? "Group" : null);
|
|
16899
16939
|
|
|
16900
16940
|
// Check if user supplied their own fig-header
|
|
16901
|
-
const userHeader = this.querySelector(
|
|
16941
|
+
const userHeader = this.querySelector(
|
|
16942
|
+
":scope > fig-header:not([data-generated])",
|
|
16943
|
+
);
|
|
16902
16944
|
|
|
16903
16945
|
if (!label && !isCollapsible && !userHeader) {
|
|
16904
16946
|
if (this.#header && this.#header.dataset.generated) {
|
|
@@ -16910,6 +16952,9 @@ class FigGroup extends HTMLElement {
|
|
|
16910
16952
|
}
|
|
16911
16953
|
|
|
16912
16954
|
if (userHeader) {
|
|
16955
|
+
this.querySelectorAll(":scope > fig-header[data-generated]").forEach(
|
|
16956
|
+
(header) => header.remove(),
|
|
16957
|
+
);
|
|
16913
16958
|
this.#header = userHeader;
|
|
16914
16959
|
} else if (!this.#header || !this.#header.dataset.generated) {
|
|
16915
16960
|
this.#header = document.createElement("fig-header");
|
|
@@ -17647,6 +17692,8 @@ figDefineElement("fig-choice", FigChoice);
|
|
|
17647
17692
|
* @attr {number} columns - Number of columns when layout="grid" (default: 2)
|
|
17648
17693
|
* @attr {string} value - Selected choice value. Omit to select the first choice; `value=""` means none.
|
|
17649
17694
|
* @attr {boolean} disabled - Whether the chooser is disabled
|
|
17695
|
+
* @attr {boolean} auto-scroll - Whether selection changes automatically scroll into view (default: true)
|
|
17696
|
+
* @attr {"auto"|"smooth"} scroll-behavior - Scrolling animation behavior (default: "smooth")
|
|
17650
17697
|
*/
|
|
17651
17698
|
class FigChooser extends HTMLElement {
|
|
17652
17699
|
#selectedChoice = null;
|
|
@@ -17674,6 +17721,7 @@ class FigChooser extends HTMLElement {
|
|
|
17674
17721
|
"layout",
|
|
17675
17722
|
"overflow",
|
|
17676
17723
|
"loop",
|
|
17724
|
+
"auto-scroll",
|
|
17677
17725
|
];
|
|
17678
17726
|
}
|
|
17679
17727
|
|
|
@@ -17688,6 +17736,31 @@ class FigChooser extends HTMLElement {
|
|
|
17688
17736
|
return attr === null || attr !== "false";
|
|
17689
17737
|
}
|
|
17690
17738
|
|
|
17739
|
+
get autoScroll() {
|
|
17740
|
+
const attr = this.getAttribute("auto-scroll");
|
|
17741
|
+
return attr === null || attr !== "false";
|
|
17742
|
+
}
|
|
17743
|
+
|
|
17744
|
+
set autoScroll(value) {
|
|
17745
|
+
if (value === false || value === "false" || value === null) {
|
|
17746
|
+
this.setAttribute("auto-scroll", "false");
|
|
17747
|
+
} else {
|
|
17748
|
+
this.removeAttribute("auto-scroll");
|
|
17749
|
+
}
|
|
17750
|
+
}
|
|
17751
|
+
|
|
17752
|
+
get scrollBehavior() {
|
|
17753
|
+
return this.getAttribute("scroll-behavior") === "auto" ? "auto" : "smooth";
|
|
17754
|
+
}
|
|
17755
|
+
|
|
17756
|
+
set scrollBehavior(value) {
|
|
17757
|
+
if (value === "auto" || value === "smooth") {
|
|
17758
|
+
this.setAttribute("scroll-behavior", value);
|
|
17759
|
+
} else {
|
|
17760
|
+
this.removeAttribute("scroll-behavior");
|
|
17761
|
+
}
|
|
17762
|
+
}
|
|
17763
|
+
|
|
17691
17764
|
get #choiceSelector() {
|
|
17692
17765
|
return this.getAttribute("choice-element") || "fig-choice";
|
|
17693
17766
|
}
|
|
@@ -17727,7 +17800,7 @@ class FigChooser extends HTMLElement {
|
|
|
17727
17800
|
if (this.getAttribute("value") !== val) {
|
|
17728
17801
|
this.setAttribute("value", val);
|
|
17729
17802
|
}
|
|
17730
|
-
this.#scrollToChoice(element);
|
|
17803
|
+
if (this.autoScroll) this.#scrollToChoice(element);
|
|
17731
17804
|
}
|
|
17732
17805
|
|
|
17733
17806
|
get value() {
|
|
@@ -17742,6 +17815,11 @@ class FigChooser extends HTMLElement {
|
|
|
17742
17815
|
this.setAttribute("value", String(val));
|
|
17743
17816
|
}
|
|
17744
17817
|
|
|
17818
|
+
scrollSelectionIntoView(options = {}) {
|
|
17819
|
+
if (!this.#selectedChoice) return;
|
|
17820
|
+
this.#scrollToChoice(this.#selectedChoice, options);
|
|
17821
|
+
}
|
|
17822
|
+
|
|
17745
17823
|
connectedCallback() {
|
|
17746
17824
|
this.setAttribute("role", "listbox");
|
|
17747
17825
|
if (this.shadowRoot) this.shadowRoot.replaceChildren();
|
|
@@ -17765,9 +17843,9 @@ class FigChooser extends HTMLElement {
|
|
|
17765
17843
|
|
|
17766
17844
|
#scheduleInitialScrollSettle() {
|
|
17767
17845
|
const resettle = () => {
|
|
17768
|
-
if (!this.isConnected) return;
|
|
17846
|
+
if (!this.isConnected || !this.autoScroll) return;
|
|
17769
17847
|
if (this.#selectedChoice) {
|
|
17770
|
-
this.#scrollToChoice(this.#selectedChoice
|
|
17848
|
+
this.#scrollToChoice(this.#selectedChoice);
|
|
17771
17849
|
}
|
|
17772
17850
|
};
|
|
17773
17851
|
const wireImages = () => {
|
|
@@ -17843,6 +17921,9 @@ class FigChooser extends HTMLElement {
|
|
|
17843
17921
|
}
|
|
17844
17922
|
this.#resettleSelectedChoice();
|
|
17845
17923
|
}
|
|
17924
|
+
if (name === "auto-scroll" && this.autoScroll) {
|
|
17925
|
+
this.#resettleSelectedChoice();
|
|
17926
|
+
}
|
|
17846
17927
|
}
|
|
17847
17928
|
|
|
17848
17929
|
#syncSelection() {
|
|
@@ -17986,7 +18067,7 @@ class FigChooser extends HTMLElement {
|
|
|
17986
18067
|
|
|
17987
18068
|
if (nextIndex !== currentIndex && choices[nextIndex]) {
|
|
17988
18069
|
this.selectedChoice = choices[nextIndex];
|
|
17989
|
-
choices[nextIndex].focus();
|
|
18070
|
+
choices[nextIndex].focus({ preventScroll: !this.autoScroll });
|
|
17990
18071
|
this.#emitEvents();
|
|
17991
18072
|
}
|
|
17992
18073
|
}
|
|
@@ -18196,16 +18277,25 @@ class FigChooser extends HTMLElement {
|
|
|
18196
18277
|
|
|
18197
18278
|
#scrollByPage(direction) {
|
|
18198
18279
|
const isHorizontal = this.getAttribute("layout") === "horizontal";
|
|
18199
|
-
figScrollOverflowPage(this, isHorizontal ? "x" : "y", direction);
|
|
18280
|
+
figScrollOverflowPage(this, isHorizontal ? "x" : "y", direction, "auto");
|
|
18200
18281
|
}
|
|
18201
18282
|
|
|
18202
18283
|
#resettleSelectedChoice() {
|
|
18203
|
-
if (!this.#selectedChoice) return;
|
|
18204
|
-
this.#scrollToChoice(this.#selectedChoice
|
|
18284
|
+
if (!this.autoScroll || !this.#selectedChoice) return;
|
|
18285
|
+
this.#scrollToChoice(this.#selectedChoice);
|
|
18205
18286
|
}
|
|
18206
18287
|
|
|
18207
|
-
#scrollToChoice(el,
|
|
18288
|
+
#scrollToChoice(el, options = {}) {
|
|
18208
18289
|
if (!el) return;
|
|
18290
|
+
const scrollOptions =
|
|
18291
|
+
typeof options === "object" && options !== null ? options : {};
|
|
18292
|
+
const behavior =
|
|
18293
|
+
scrollOptions.behavior === "smooth" ||
|
|
18294
|
+
scrollOptions.behavior === "instant"
|
|
18295
|
+
? scrollOptions.behavior
|
|
18296
|
+
: "auto";
|
|
18297
|
+
const block = scrollOptions.block || "center";
|
|
18298
|
+
const inline = scrollOptions.inline || "center";
|
|
18209
18299
|
requestAnimationFrame(() => {
|
|
18210
18300
|
if (!el.isConnected) return;
|
|
18211
18301
|
const overflowY = this.scrollHeight > this.clientHeight;
|
|
@@ -18220,9 +18310,13 @@ class FigChooser extends HTMLElement {
|
|
|
18220
18310
|
if (overflowY) {
|
|
18221
18311
|
const choiceTop = choiceRect.top - hostRect.top + this.scrollTop;
|
|
18222
18312
|
const maxScroll = this.scrollHeight - this.clientHeight;
|
|
18223
|
-
options.top =
|
|
18224
|
-
|
|
18225
|
-
|
|
18313
|
+
options.top = this.#alignedScrollPosition(
|
|
18314
|
+
choiceTop,
|
|
18315
|
+
choiceRect.height,
|
|
18316
|
+
this.clientHeight,
|
|
18317
|
+
this.scrollTop,
|
|
18318
|
+
maxScroll,
|
|
18319
|
+
block,
|
|
18226
18320
|
);
|
|
18227
18321
|
shouldScroll = true;
|
|
18228
18322
|
}
|
|
@@ -18230,9 +18324,13 @@ class FigChooser extends HTMLElement {
|
|
|
18230
18324
|
if (overflowX) {
|
|
18231
18325
|
const choiceLeft = choiceRect.left - hostRect.left + this.scrollLeft;
|
|
18232
18326
|
const maxScroll = this.scrollWidth - this.clientWidth;
|
|
18233
|
-
options.left =
|
|
18234
|
-
|
|
18235
|
-
|
|
18327
|
+
options.left = this.#alignedScrollPosition(
|
|
18328
|
+
choiceLeft,
|
|
18329
|
+
choiceRect.width,
|
|
18330
|
+
this.clientWidth,
|
|
18331
|
+
this.scrollLeft,
|
|
18332
|
+
maxScroll,
|
|
18333
|
+
inline,
|
|
18236
18334
|
);
|
|
18237
18335
|
shouldScroll = true;
|
|
18238
18336
|
}
|
|
@@ -18244,6 +18342,36 @@ class FigChooser extends HTMLElement {
|
|
|
18244
18342
|
});
|
|
18245
18343
|
}
|
|
18246
18344
|
|
|
18345
|
+
#alignedScrollPosition(
|
|
18346
|
+
elementStart,
|
|
18347
|
+
elementSize,
|
|
18348
|
+
viewportSize,
|
|
18349
|
+
currentScroll,
|
|
18350
|
+
maxScroll,
|
|
18351
|
+
alignment,
|
|
18352
|
+
) {
|
|
18353
|
+
let nextScroll;
|
|
18354
|
+
if (alignment === "start") {
|
|
18355
|
+
nextScroll = elementStart;
|
|
18356
|
+
} else if (alignment === "end") {
|
|
18357
|
+
nextScroll = elementStart + elementSize - viewportSize;
|
|
18358
|
+
} else if (alignment === "nearest") {
|
|
18359
|
+
const viewportStart = currentScroll;
|
|
18360
|
+
const viewportEnd = currentScroll + viewportSize;
|
|
18361
|
+
const elementEnd = elementStart + elementSize;
|
|
18362
|
+
if (elementStart >= viewportStart && elementEnd <= viewportEnd) {
|
|
18363
|
+
nextScroll = currentScroll;
|
|
18364
|
+
} else if (elementStart < viewportStart) {
|
|
18365
|
+
nextScroll = elementStart;
|
|
18366
|
+
} else {
|
|
18367
|
+
nextScroll = elementEnd - viewportSize;
|
|
18368
|
+
}
|
|
18369
|
+
} else {
|
|
18370
|
+
nextScroll = elementStart + elementSize / 2 - viewportSize / 2;
|
|
18371
|
+
}
|
|
18372
|
+
return Math.max(0, Math.min(nextScroll, maxScroll));
|
|
18373
|
+
}
|
|
18374
|
+
|
|
18247
18375
|
#startObserver() {
|
|
18248
18376
|
this.#mutationObserver?.disconnect();
|
|
18249
18377
|
this.#mutationObserver = new MutationObserver(() => {
|
package/package.json
CHANGED