From b7b8306657e621c5e7dff3288da77fa8171c374a Mon Sep 17 00:00:00 2001 From: VeinDevTtv Date: Wed, 11 Mar 2026 00:30:05 -0700 Subject: [PATCH 1/6] fix(core): LiquidGlass layout breaking FlexboxLayout (#11099) --- .../liquid-glass-container/index.ios.ts | 42 ++++++++++++++++- .../core/ui/layouts/liquid-glass/index.ios.ts | 45 +++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/packages/core/ui/layouts/liquid-glass-container/index.ios.ts b/packages/core/ui/layouts/liquid-glass-container/index.ios.ts index a9bc485687..c2450437e5 100644 --- a/packages/core/ui/layouts/liquid-glass-container/index.ios.ts +++ b/packages/core/ui/layouts/liquid-glass-container/index.ios.ts @@ -53,12 +53,52 @@ export class LiquidGlassContainer extends LiquidGlassContainerCommon { return false; } + // When LiquidGlassContainer is a child of FlexboxLayout (or any layout that passes + // a measure spec already reduced by the child's padding), AbsoluteLayout.onMeasure + // would subtract our padding a second time. To prevent this double-deduction we + // temporarily zero the effective padding/border values before delegating to the + // AbsoluteLayout measurement, then restore them immediately after. + public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void { + const pl = this.effectivePaddingLeft; + const pr = this.effectivePaddingRight; + const pt = this.effectivePaddingTop; + const pb = this.effectivePaddingBottom; + const bl = this.effectiveBorderLeftWidth; + const br = this.effectiveBorderRightWidth; + const bt = this.effectiveBorderTopWidth; + const bb = this.effectiveBorderBottomWidth; + + this.effectivePaddingLeft = 0; + this.effectivePaddingRight = 0; + this.effectivePaddingTop = 0; + this.effectivePaddingBottom = 0; + this.effectiveBorderLeftWidth = 0; + this.effectiveBorderRightWidth = 0; + this.effectiveBorderTopWidth = 0; + this.effectiveBorderBottomWidth = 0; + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + this.effectivePaddingLeft = pl; + this.effectivePaddingRight = pr; + this.effectivePaddingTop = pt; + this.effectivePaddingBottom = pb; + this.effectiveBorderLeftWidth = bl; + this.effectiveBorderRightWidth = br; + this.effectiveBorderTopWidth = bt; + this.effectiveBorderBottomWidth = bb; + } + // When children animate with translate (layer transform), UIVisualEffectView-based // container effects may recompute based on the underlying frames (not transforms), // which can cause jumps. Normalize any residual translation into the // child's frame so the effect uses the final visual positions. public onLayout(left: number, top: number, right: number, bottom: number): void { - super.onLayout(left, top, right, bottom); + // AbsoluteLayout.onLayout positions children using our padding as an offset. + // Since the FlexboxLayout (or parent) already placed our UIVisualEffectView at + // (left, top), we normalise to local coordinates so that AbsoluteLayout places + // children in (0, 0, width, height) space — the coordinate space of _contentHost. + super.onLayout(0, 0, right - left, bottom - top); // Try to fold any pending translates into frames on each layout pass this._normalizeChildrenTransforms(); diff --git a/packages/core/ui/layouts/liquid-glass/index.ios.ts b/packages/core/ui/layouts/liquid-glass/index.ios.ts index 2bf63e39d7..12cab6cdbd 100644 --- a/packages/core/ui/layouts/liquid-glass/index.ios.ts +++ b/packages/core/ui/layouts/liquid-glass/index.ios.ts @@ -49,6 +49,51 @@ export class LiquidGlass extends LiquidGlassCommon { return false; } + public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void { + // When LiquidGlass is a child of FlexboxLayout (or any layout that passes a child + // measure spec already reduced by the child's padding), GridLayout.onMeasure would + // subtract our padding a second time. To prevent this double-deduction we temporarily + // zero the effective padding/border values before delegating to the GridLayout + // measurement, then restore them immediately after. + const pl = this.effectivePaddingLeft; + const pr = this.effectivePaddingRight; + const pt = this.effectivePaddingTop; + const pb = this.effectivePaddingBottom; + const bl = this.effectiveBorderLeftWidth; + const br = this.effectiveBorderRightWidth; + const bt = this.effectiveBorderTopWidth; + const bb = this.effectiveBorderBottomWidth; + + this.effectivePaddingLeft = 0; + this.effectivePaddingRight = 0; + this.effectivePaddingTop = 0; + this.effectivePaddingBottom = 0; + this.effectiveBorderLeftWidth = 0; + this.effectiveBorderRightWidth = 0; + this.effectiveBorderTopWidth = 0; + this.effectiveBorderBottomWidth = 0; + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + this.effectivePaddingLeft = pl; + this.effectivePaddingRight = pr; + this.effectivePaddingTop = pt; + this.effectivePaddingBottom = pb; + this.effectiveBorderLeftWidth = bl; + this.effectiveBorderRightWidth = br; + this.effectiveBorderTopWidth = bt; + this.effectiveBorderBottomWidth = bb; + } + + public onLayout(left: number, top: number, right: number, bottom: number): void { + // GridLayout.onLayout computes column/row offsets relative to (left, top), then + // adds its own padding on top. Since the FlexboxLayout (or parent) already placed + // our UIVisualEffectView at (left, top), we normalise to local coordinates so that + // GridLayout lays children out in (0, 0, width, height) space — which is exactly + // the coordinate space of our _contentHost UIView that hosts the children. + super.onLayout(0, 0, right - left, bottom - top); + } + [iosGlassEffectProperty.setNative](value: GlassEffectType) { this._applyGlassEffect(value, { effectType: 'glass', From 042afeb742609ca0bf595ca33e49ae48a8b5a3ce Mon Sep 17 00:00:00 2001 From: VeinDevTtv Date: Wed, 11 Mar 2026 00:39:30 -0700 Subject: [PATCH 2/6] test(core): add LiquidGlass FlexboxLayout tests --- .../src/ui/layouts/flexbox-layout-tests.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/apps/automated/src/ui/layouts/flexbox-layout-tests.ts b/apps/automated/src/ui/layouts/flexbox-layout-tests.ts index 3bbe457cdc..e1f68c0bc9 100644 --- a/apps/automated/src/ui/layouts/flexbox-layout-tests.ts +++ b/apps/automated/src/ui/layouts/flexbox-layout-tests.ts @@ -1746,3 +1746,24 @@ export const testFlexboxLayout_does_not_crash_with_proxy_view_container = test(a // Omit testDivider_directionRow_verticalBeginning // Omit divider test family, we don't draw dividers + +let activity_liquidglass_flexbox_layout = () => + getViews( + ` + + + `, + ); + +export const testLiquidGlassFlexboxLayout = test(activity_liquidglass_flexbox_layout, noop, ({ flexbox, text1, text2, text3 }) => { + isTopAlignedWith(text1, flexbox); + isLeftAlignedWith(text1, flexbox); + isRightOf(text2, text1); + isTopAlignedWith(text2, flexbox); + isRightOf(text3, text2); + isTopAlignedWith(text3, flexbox); + + equal(width(flexbox), width(text1) + width(text2) + width(text3)); + equal(height(flexbox), 300); +}); From b9e72c5e2dc5e483d998e6e516b5bc750b7a391f Mon Sep 17 00:00:00 2001 From: VeinDevTtv Date: Wed, 11 Mar 2026 01:13:56 -0700 Subject: [PATCH 3/6] fix(ios): harden liquid glass fallback and label layout invalidation - fall back to plain UIVisualEffectView when glass APIs are unavailable - guard glass effect runtime access behind capability checks - request layout for iOS 18+ label text changes even for fixed-size labels - add automated regression coverage for liquid glass effect updates --- .../src/ui/layouts/flexbox-layout-tests.ts | 16 ++++++++++++++++ packages/core/ui/core/view/index.ios.ts | 13 ++++++------- packages/core/ui/label/index.ios.ts | 15 +++++++++------ .../layouts/liquid-glass-container/index.ios.ts | 12 +++++++++--- .../core/ui/layouts/liquid-glass/index.ios.ts | 12 ++++++++---- packages/core/utils/constants.ios.ts | 7 ++++++- 6 files changed, 54 insertions(+), 21 deletions(-) diff --git a/apps/automated/src/ui/layouts/flexbox-layout-tests.ts b/apps/automated/src/ui/layouts/flexbox-layout-tests.ts index e1f68c0bc9..3d4d75d200 100644 --- a/apps/automated/src/ui/layouts/flexbox-layout-tests.ts +++ b/apps/automated/src/ui/layouts/flexbox-layout-tests.ts @@ -1767,3 +1767,19 @@ export const testLiquidGlassFlexboxLayout = test(activity_liquidglass_flexbox_la equal(width(flexbox), width(text1) + width(text2) + width(text3)); equal(height(flexbox), 300); }); + +export const testLiquidGlassViews_do_not_crash_when_updating_iosGlassEffect = test(activity_liquidglass_flexbox_layout, noop, ({ root, text1, text2 }) => { + const liquidGlass = text1 as unknown as View; + const liquidGlassContainer = text2 as unknown as View; + + TKUnit.assertTrue(liquidGlass.nativeViewProtected instanceof UIVisualEffectView, 'LiquidGlass should create a UIVisualEffectView host.'); + TKUnit.assertTrue(liquidGlassContainer.nativeViewProtected instanceof UIVisualEffectView, 'LiquidGlassContainer should create a UIVisualEffectView host.'); + + liquidGlass.iosGlassEffect = 'regular'; + liquidGlassContainer.iosGlassEffect = { variant: 'clear', spacing: 12 }; + liquidGlass.iosGlassEffect = 'none'; + liquidGlassContainer.iosGlassEffect = 'none'; + + waitUntilTestElementLayoutIsValid(root); + TKUnit.assertTrue(root.isLoaded, 'Liquid glass view tree should remain loaded after glass effect updates.'); +}); diff --git a/packages/core/ui/core/view/index.ios.ts b/packages/core/ui/core/view/index.ios.ts index a88ccaf8dc..f63c0f995d 100644 --- a/packages/core/ui/core/view/index.ios.ts +++ b/packages/core/ui/core/view/index.ios.ts @@ -927,13 +927,11 @@ export class View extends ViewCommon { const variant = config ? config.variant : (value as GlassEffectVariant); const defaultDuration = 0.3; const duration = config ? (config.animateChangeDuration ?? defaultDuration) : defaultDuration; - - let effect: UIGlassEffect | UIGlassContainerEffect | UIVisualEffect; + const glassSupported = supportsGlass(); + let effect: UIVisualEffect = UIVisualEffect.new(); // Create the appropriate effect based on type and variant - if (!value || ['identity', 'none'].includes(variant)) { - effect = UIVisualEffect.new(); - } else { + if (value && !['identity', 'none'].includes(variant) && glassSupported) { if (options.effectType === 'glass') { const styleFn = options.toGlassStyleFn || this.toUIGlassStyle.bind(this); effect = UIGlassEffect.effectWithStyle(styleFn(variant)); @@ -1084,11 +1082,12 @@ export class View extends ViewCommon { public toUIGlassStyle(value?: GlassEffectVariant) { if (supportsGlass()) { + const glassEffectStyle = (globalThis as any)?.UIGlassEffectStyle; switch (value) { case 'regular': - return UIGlassEffectStyle?.Regular ?? 0; + return glassEffectStyle?.Regular ?? 0; case 'clear': - return UIGlassEffectStyle?.Clear ?? 1; + return glassEffectStyle?.Clear ?? 1; } } return 1; diff --git a/packages/core/ui/label/index.ios.ts b/packages/core/ui/label/index.ios.ts index bad9acefd3..42e7cb5bb7 100644 --- a/packages/core/ui/label/index.ios.ts +++ b/packages/core/ui/label/index.ios.ts @@ -5,6 +5,7 @@ import { booleanConverter } from '../core/view-base'; import { View, CSSType } from '../core/view'; import { CoreTypes } from '../../core-types'; import { TextBase, whiteSpaceProperty, textOverflowProperty } from '../text-base'; +import { SDK_VERSION } from '../../utils/constants'; import { layout } from '../../utils'; import { ios } from '../styling/background'; @@ -52,12 +53,14 @@ export class Label extends TextBase implements LabelDefinition { } _requestLayoutOnTextChanged(): void { - if (this._fixedSize === FixedSize.BOTH) { - return; - } - if (this._fixedSize === FixedSize.WIDTH && !this.textWrap && this.getMeasuredHeight() > 0) { - // Single line label with fixed width will skip request layout on text change. - return; + if (SDK_VERSION < 18) { + if (this._fixedSize === FixedSize.BOTH) { + return; + } + if (this._fixedSize === FixedSize.WIDTH && !this.textWrap && this.getMeasuredHeight() > 0) { + // Single line label with fixed width will skip request layout on text change. + return; + } } super._requestLayoutOnTextChanged(); } diff --git a/packages/core/ui/layouts/liquid-glass-container/index.ios.ts b/packages/core/ui/layouts/liquid-glass-container/index.ios.ts index c2450437e5..a17eb2b8d7 100644 --- a/packages/core/ui/layouts/liquid-glass-container/index.ios.ts +++ b/packages/core/ui/layouts/liquid-glass-container/index.ios.ts @@ -1,4 +1,5 @@ import type { NativeScriptUIView } from '../../utils'; +import { supportsGlass } from '../../../utils/constants'; import { GlassEffectType, iosGlassEffectProperty, View } from '../../core/view'; import { LiquidGlassContainerCommon } from './liquid-glass-container-common'; import { toUIGlassStyle } from '../liquid-glass'; @@ -9,11 +10,16 @@ export class LiquidGlassContainer extends LiquidGlassContainerCommon { private _normalizing = false; createNativeView() { + const glassSupported = supportsGlass(); // Keep UIVisualEffectView as the root to preserve interactive container effect - const effect = UIGlassContainerEffect.alloc().init(); - effect.spacing = 8; + const effect = glassSupported ? UIGlassContainerEffect.alloc().init() : UIVisualEffect.new(); + if (glassSupported) { + (effect as UIGlassContainerEffect).spacing = 8; + } const effectView = UIVisualEffectView.alloc().initWithEffect(effect); - effectView.overrideUserInterfaceStyle = UIUserInterfaceStyle.Dark; + if (glassSupported) { + effectView.overrideUserInterfaceStyle = UIUserInterfaceStyle.Dark; + } effectView.clipsToBounds = true; effectView.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight; diff --git a/packages/core/ui/layouts/liquid-glass/index.ios.ts b/packages/core/ui/layouts/liquid-glass/index.ios.ts index 12cab6cdbd..ef82617b53 100644 --- a/packages/core/ui/layouts/liquid-glass/index.ios.ts +++ b/packages/core/ui/layouts/liquid-glass/index.ios.ts @@ -8,9 +8,12 @@ export class LiquidGlass extends LiquidGlassCommon { private _contentHost: UIView; createNativeView() { + const glassSupported = supportsGlass(); // Use UIVisualEffectView as the root so interactive effects can track touches - const effect = UIGlassEffect.effectWithStyle(UIGlassEffectStyle.Clear); - effect.interactive = true; + const effect = glassSupported ? UIGlassEffect.effectWithStyle(toUIGlassStyle('clear')) : UIVisualEffect.new(); + if (glassSupported) { + (effect as UIGlassEffect).interactive = true; + } const effectView = UIVisualEffectView.alloc().initWithEffect(effect); effectView.frame = CGRectMake(0, 0, 0, 0); effectView.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight; @@ -105,11 +108,12 @@ export class LiquidGlass extends LiquidGlassCommon { export function toUIGlassStyle(value?: GlassEffectVariant) { if (supportsGlass()) { + const glassEffectStyle = (globalThis as any)?.UIGlassEffectStyle; switch (value) { case 'regular': - return UIGlassEffectStyle?.Regular ?? 0; + return glassEffectStyle?.Regular ?? 0; case 'clear': - return UIGlassEffectStyle?.Clear ?? 1; + return glassEffectStyle?.Clear ?? 1; } } return 1; diff --git a/packages/core/utils/constants.ios.ts b/packages/core/utils/constants.ios.ts index 735e204362..ef2769b93f 100644 --- a/packages/core/utils/constants.ios.ts +++ b/packages/core/utils/constants.ios.ts @@ -1,4 +1,9 @@ export const SDK_VERSION = parseFloat(UIDevice.currentDevice.systemVersion); + +function hasRuntimeGlobal(name: 'UIGlassEffect' | 'UIGlassContainerEffect' | 'UIGlassEffectStyle'): boolean { + return typeof (globalThis as any)?.[name] !== 'undefined'; +} + export function supportsGlass(): boolean { - return __APPLE__ && SDK_VERSION >= 26; + return __APPLE__ && SDK_VERSION >= 26 && hasRuntimeGlobal('UIGlassEffect') && hasRuntimeGlobal('UIGlassContainerEffect') && hasRuntimeGlobal('UIGlassEffectStyle'); } From 78199ce2ef0ea795d8f43c2922867b70f1cdc332 Mon Sep 17 00:00:00 2001 From: VeinDevTtv Date: Wed, 11 Mar 2026 01:34:49 -0700 Subject: [PATCH 4/6] fix(test): compare LiquidGlass flexbox height in device pixels Update the iOS LiquidGlass FlexboxLayout test to compare the fixed 300 DIP container height using device pixels. The layout helper reports pixel sizes, so 300 DIP correctly renders as 900 px on a 3x simulator; this fixes an outdated test expectation rather than a flexbox regression. --- apps/automated/src/ui/layouts/flexbox-layout-tests.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/automated/src/ui/layouts/flexbox-layout-tests.ts b/apps/automated/src/ui/layouts/flexbox-layout-tests.ts index 3d4d75d200..2f562cf4db 100644 --- a/apps/automated/src/ui/layouts/flexbox-layout-tests.ts +++ b/apps/automated/src/ui/layouts/flexbox-layout-tests.ts @@ -1765,7 +1765,8 @@ export const testLiquidGlassFlexboxLayout = test(activity_liquidglass_flexbox_la isTopAlignedWith(text3, flexbox); equal(width(flexbox), width(text1) + width(text2) + width(text3)); - equal(height(flexbox), 300); + // Layout helpers report device pixels, so fixed XML DIP sizes must be converted too. + closeEnough(height(flexbox), dipToDp(300)); }); export const testLiquidGlassViews_do_not_crash_when_updating_iosGlassEffect = test(activity_liquidglass_flexbox_layout, noop, ({ root, text1, text2 }) => { From c5e60962786991ac76ea88b6690beee7a2125fb7 Mon Sep 17 00:00:00 2001 From: VeinDevTtv Date: Thu, 12 Mar 2026 13:25:13 -0700 Subject: [PATCH 5/6] fix(ios): address liquid glass flexbox review feedback Remove the unrelated Label layout invalidation change and simplify glass support back to the SDK gate requested in PR review. Also drop runtime glass style global lookups and restore temporary measure-state overrides in finally blocks so the flexbox fix remains scoped and safe. --- packages/core/ui/core/view/index.ios.ts | 5 ++-- packages/core/ui/label/index.ios.ts | 15 +++++------ .../liquid-glass-container/index.ios.ts | 22 ++++++++------- .../core/ui/layouts/liquid-glass/index.ios.ts | 27 ++++++++++--------- packages/core/utils/constants.ios.ts | 6 +---- 5 files changed, 35 insertions(+), 40 deletions(-) diff --git a/packages/core/ui/core/view/index.ios.ts b/packages/core/ui/core/view/index.ios.ts index f63c0f995d..85b4c8baaf 100644 --- a/packages/core/ui/core/view/index.ios.ts +++ b/packages/core/ui/core/view/index.ios.ts @@ -1082,12 +1082,11 @@ export class View extends ViewCommon { public toUIGlassStyle(value?: GlassEffectVariant) { if (supportsGlass()) { - const glassEffectStyle = (globalThis as any)?.UIGlassEffectStyle; switch (value) { case 'regular': - return glassEffectStyle?.Regular ?? 0; + return UIGlassEffectStyle.Regular; case 'clear': - return glassEffectStyle?.Clear ?? 1; + return UIGlassEffectStyle.Clear; } } return 1; diff --git a/packages/core/ui/label/index.ios.ts b/packages/core/ui/label/index.ios.ts index 42e7cb5bb7..bad9acefd3 100644 --- a/packages/core/ui/label/index.ios.ts +++ b/packages/core/ui/label/index.ios.ts @@ -5,7 +5,6 @@ import { booleanConverter } from '../core/view-base'; import { View, CSSType } from '../core/view'; import { CoreTypes } from '../../core-types'; import { TextBase, whiteSpaceProperty, textOverflowProperty } from '../text-base'; -import { SDK_VERSION } from '../../utils/constants'; import { layout } from '../../utils'; import { ios } from '../styling/background'; @@ -53,14 +52,12 @@ export class Label extends TextBase implements LabelDefinition { } _requestLayoutOnTextChanged(): void { - if (SDK_VERSION < 18) { - if (this._fixedSize === FixedSize.BOTH) { - return; - } - if (this._fixedSize === FixedSize.WIDTH && !this.textWrap && this.getMeasuredHeight() > 0) { - // Single line label with fixed width will skip request layout on text change. - return; - } + if (this._fixedSize === FixedSize.BOTH) { + return; + } + if (this._fixedSize === FixedSize.WIDTH && !this.textWrap && this.getMeasuredHeight() > 0) { + // Single line label with fixed width will skip request layout on text change. + return; } super._requestLayoutOnTextChanged(); } diff --git a/packages/core/ui/layouts/liquid-glass-container/index.ios.ts b/packages/core/ui/layouts/liquid-glass-container/index.ios.ts index a17eb2b8d7..323edf9fe0 100644 --- a/packages/core/ui/layouts/liquid-glass-container/index.ios.ts +++ b/packages/core/ui/layouts/liquid-glass-container/index.ios.ts @@ -83,16 +83,18 @@ export class LiquidGlassContainer extends LiquidGlassContainerCommon { this.effectiveBorderTopWidth = 0; this.effectiveBorderBottomWidth = 0; - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - this.effectivePaddingLeft = pl; - this.effectivePaddingRight = pr; - this.effectivePaddingTop = pt; - this.effectivePaddingBottom = pb; - this.effectiveBorderLeftWidth = bl; - this.effectiveBorderRightWidth = br; - this.effectiveBorderTopWidth = bt; - this.effectiveBorderBottomWidth = bb; + try { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } finally { + this.effectivePaddingLeft = pl; + this.effectivePaddingRight = pr; + this.effectivePaddingTop = pt; + this.effectivePaddingBottom = pb; + this.effectiveBorderLeftWidth = bl; + this.effectiveBorderRightWidth = br; + this.effectiveBorderTopWidth = bt; + this.effectiveBorderBottomWidth = bb; + } } // When children animate with translate (layer transform), UIVisualEffectView-based diff --git a/packages/core/ui/layouts/liquid-glass/index.ios.ts b/packages/core/ui/layouts/liquid-glass/index.ios.ts index ef82617b53..e545dd29bb 100644 --- a/packages/core/ui/layouts/liquid-glass/index.ios.ts +++ b/packages/core/ui/layouts/liquid-glass/index.ios.ts @@ -76,16 +76,18 @@ export class LiquidGlass extends LiquidGlassCommon { this.effectiveBorderTopWidth = 0; this.effectiveBorderBottomWidth = 0; - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - this.effectivePaddingLeft = pl; - this.effectivePaddingRight = pr; - this.effectivePaddingTop = pt; - this.effectivePaddingBottom = pb; - this.effectiveBorderLeftWidth = bl; - this.effectiveBorderRightWidth = br; - this.effectiveBorderTopWidth = bt; - this.effectiveBorderBottomWidth = bb; + try { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } finally { + this.effectivePaddingLeft = pl; + this.effectivePaddingRight = pr; + this.effectivePaddingTop = pt; + this.effectivePaddingBottom = pb; + this.effectiveBorderLeftWidth = bl; + this.effectiveBorderRightWidth = br; + this.effectiveBorderTopWidth = bt; + this.effectiveBorderBottomWidth = bb; + } } public onLayout(left: number, top: number, right: number, bottom: number): void { @@ -108,12 +110,11 @@ export class LiquidGlass extends LiquidGlassCommon { export function toUIGlassStyle(value?: GlassEffectVariant) { if (supportsGlass()) { - const glassEffectStyle = (globalThis as any)?.UIGlassEffectStyle; switch (value) { case 'regular': - return glassEffectStyle?.Regular ?? 0; + return UIGlassEffectStyle.Regular; case 'clear': - return glassEffectStyle?.Clear ?? 1; + return UIGlassEffectStyle.Clear; } } return 1; diff --git a/packages/core/utils/constants.ios.ts b/packages/core/utils/constants.ios.ts index ef2769b93f..2b9a98b6e0 100644 --- a/packages/core/utils/constants.ios.ts +++ b/packages/core/utils/constants.ios.ts @@ -1,9 +1,5 @@ export const SDK_VERSION = parseFloat(UIDevice.currentDevice.systemVersion); -function hasRuntimeGlobal(name: 'UIGlassEffect' | 'UIGlassContainerEffect' | 'UIGlassEffectStyle'): boolean { - return typeof (globalThis as any)?.[name] !== 'undefined'; -} - export function supportsGlass(): boolean { - return __APPLE__ && SDK_VERSION >= 26 && hasRuntimeGlobal('UIGlassEffect') && hasRuntimeGlobal('UIGlassContainerEffect') && hasRuntimeGlobal('UIGlassEffectStyle'); + return __APPLE__ && SDK_VERSION >= 26; } From 9d35f48ad3c8ff9825849026522af265b91b1f22 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Mon, 30 Mar 2026 11:50:27 -0700 Subject: [PATCH 6/6] chore: add FlexboxLayout example in toolbox --- apps/toolbox/src/pages/glass-effects.xml | 26 ++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/apps/toolbox/src/pages/glass-effects.xml b/apps/toolbox/src/pages/glass-effects.xml index 58601674af..c457ccf70b 100644 --- a/apps/toolbox/src/pages/glass-effects.xml +++ b/apps/toolbox/src/pages/glass-effects.xml @@ -15,13 +15,13 @@