@nanahoshi/mona-ui 0.18.0 → 0.18.1
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.
|
@@ -132,6 +132,7 @@ class SegmentedComponent {
|
|
|
132
132
|
#lastAnimatedIndex;
|
|
133
133
|
#lastOptions;
|
|
134
134
|
#lastSize;
|
|
135
|
+
#observedOptionElements;
|
|
135
136
|
#resizeObserver;
|
|
136
137
|
constructor() {
|
|
137
138
|
this.#destroyRef = inject(DestroyRef);
|
|
@@ -139,6 +140,7 @@ class SegmentedComponent {
|
|
|
139
140
|
this.#lastAnimatedIndex = null;
|
|
140
141
|
this.#lastOptions = null;
|
|
141
142
|
this.#lastSize = null;
|
|
143
|
+
this.#observedOptionElements = [];
|
|
142
144
|
this.#resizeObserver = null;
|
|
143
145
|
this.containerClasses = computed(() => {
|
|
144
146
|
const classes = segmentedContainerThemeVariants({ alignment: this.alignment(), rounded: this.rounded() });
|
|
@@ -265,7 +267,7 @@ class SegmentedComponent {
|
|
|
265
267
|
afterRenderEffect({
|
|
266
268
|
read: () => {
|
|
267
269
|
this.selectedIndex();
|
|
268
|
-
this.optionElements();
|
|
270
|
+
const optionElements = this.optionElements();
|
|
269
271
|
this.alignment();
|
|
270
272
|
this.rounded();
|
|
271
273
|
this.animate();
|
|
@@ -276,12 +278,14 @@ class SegmentedComponent {
|
|
|
276
278
|
const suppressTransition = isSizeChange || isOptionsChange;
|
|
277
279
|
this.#lastSize = size;
|
|
278
280
|
this.#lastOptions = options;
|
|
281
|
+
this.observeOptionElements(optionElements);
|
|
279
282
|
this.updateIndicatorGeometry({ suppressTransition });
|
|
280
283
|
}
|
|
281
284
|
});
|
|
282
285
|
afterNextRender({
|
|
283
286
|
read: () => {
|
|
284
287
|
this.setupResizeObserver();
|
|
288
|
+
this.scheduleSettledGeometryUpdate();
|
|
285
289
|
}
|
|
286
290
|
});
|
|
287
291
|
this.#destroyRef.onDestroy(() => {
|
|
@@ -307,6 +311,39 @@ class SegmentedComponent {
|
|
|
307
311
|
this.value.set(option.value);
|
|
308
312
|
this.touch.emit();
|
|
309
313
|
}
|
|
314
|
+
observeOptionElements(optionElements) {
|
|
315
|
+
if (!this.#resizeObserver) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const elements = optionElements.map(optionElement => optionElement.nativeElement);
|
|
319
|
+
for (const element of this.#observedOptionElements) {
|
|
320
|
+
if (!elements.includes(element)) {
|
|
321
|
+
this.#resizeObserver.unobserve(element);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
for (const element of elements) {
|
|
325
|
+
if (!this.#observedOptionElements.includes(element)) {
|
|
326
|
+
this.#resizeObserver.observe(element);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
this.#observedOptionElements = elements;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Guards against a stale indicator snapshot when the control mounts inside a container that is
|
|
333
|
+
* still transitioning in (e.g. a popup's enter animation): the host's own box may not change once
|
|
334
|
+
* that settles, so the ResizeObserver on it alone would never re-fire to correct the geometry.
|
|
335
|
+
*/
|
|
336
|
+
scheduleSettledGeometryUpdate() {
|
|
337
|
+
const win = this.#hostElementRef.nativeElement.ownerDocument.defaultView;
|
|
338
|
+
if (!win) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
win.requestAnimationFrame(() => {
|
|
342
|
+
win.requestAnimationFrame(() => {
|
|
343
|
+
this.updateIndicatorGeometry({ suppressTransition: true });
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
}
|
|
310
347
|
setupResizeObserver() {
|
|
311
348
|
if (typeof ResizeObserver === "undefined") {
|
|
312
349
|
return;
|
|
@@ -315,6 +352,7 @@ class SegmentedComponent {
|
|
|
315
352
|
this.updateIndicatorGeometry({ suppressTransition: true });
|
|
316
353
|
});
|
|
317
354
|
this.#resizeObserver.observe(this.#hostElementRef.nativeElement);
|
|
355
|
+
this.observeOptionElements(this.optionElements());
|
|
318
356
|
}
|
|
319
357
|
updateIndicatorGeometry(options) {
|
|
320
358
|
const selectedIndex = this.selectedIndex();
|
package/package.json
CHANGED
|
@@ -148,6 +148,13 @@ declare class SegmentedComponent<T extends SegmentedValue = SegmentedValue> impl
|
|
|
148
148
|
protected createOptionContext(option: SegmentedOption<T>, index: number): SegmentedItemTemplateContext<T>;
|
|
149
149
|
protected onOptionBlur(): void;
|
|
150
150
|
protected onOptionChange(option: SegmentedOption<T>): void;
|
|
151
|
+
private observeOptionElements;
|
|
152
|
+
/**
|
|
153
|
+
* Guards against a stale indicator snapshot when the control mounts inside a container that is
|
|
154
|
+
* still transitioning in (e.g. a popup's enter animation): the host's own box may not change once
|
|
155
|
+
* that settles, so the ResizeObserver on it alone would never re-fire to correct the geometry.
|
|
156
|
+
*/
|
|
157
|
+
private scheduleSettledGeometryUpdate;
|
|
151
158
|
private setupResizeObserver;
|
|
152
159
|
private updateIndicatorGeometry;
|
|
153
160
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SegmentedComponent<any>, never>;
|