Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions example/ios/LiquidGlassExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,10 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-LiquidGlassExample/Pods-LiquidGlassExample-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-LiquidGlassExample/Pods-LiquidGlassExample-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-LiquidGlassExample/Pods-LiquidGlassExample-frameworks.sh\"\n";
Expand Down Expand Up @@ -234,14 +230,10 @@
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-LiquidGlassExample/Pods-LiquidGlassExample-resources-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-LiquidGlassExample/Pods-LiquidGlassExample-resources-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-LiquidGlassExample/Pods-LiquidGlassExample-resources.sh\"\n";
Expand Down
82 changes: 80 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
PODS:
- ComputableLayout (0.7.0):
- DGSwiftUtilities (~> 0.11)
- ContextMenuAuxiliaryPreview (0.5.2):
- DGSwiftUtilities (~> 0.29)
- DGSwiftUtilities (0.47.0)
- FBLazyVector (0.81.4)
- hermes-engine (0.81.4):
- hermes-engine/Pre-built (= 0.81.4)
- hermes-engine/Pre-built (0.81.4)
- LiquidGlass (0.3.0):
- LiquidGlass (0.4.2):
- hermes-engine
- RCTRequired
- RCTTypeSafety
Expand Down Expand Up @@ -1304,6 +1309,62 @@ PODS:
- React-RCTFBReactNativeSpec
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- react-native-ios-context-menu (3.2.1):
- ContextMenuAuxiliaryPreview (~> 0.5)
- DGSwiftUtilities
- hermes-engine
- RCTRequired
- RCTTypeSafety
- React-Core
- React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-jsi
- React-jsinspector
- React-jsinspectortracing
- react-native-ios-utilities
- React-NativeModulesApple
- React-RCTAppDelegate
- React-RCTFabric
- React-renderercss
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- Yoga
- react-native-ios-utilities (5.2.0):
- ComputableLayout (~> 0.7)
- DGSwiftUtilities (~> 0.46)
- hermes-engine
- RCTRequired
- RCTTypeSafety
- React-Core
- React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-jsi
- React-jsinspector
- React-jsinspectortracing
- React-jsitooling
- React-NativeModulesApple
- React-RCTAppDelegate
- React-RCTFabric
- React-renderercss
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- Yoga
- react-native-safe-area-context (5.6.1):
- hermes-engine
- RCTRequired
Expand Down Expand Up @@ -1808,6 +1869,8 @@ DEPENDENCIES:
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
- React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
- react-native-ios-context-menu (from `../node_modules/react-native-ios-context-menu`)
- react-native-ios-utilities (from `../node_modules/react-native-ios-utilities`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
Expand Down Expand Up @@ -1843,6 +1906,12 @@ DEPENDENCIES:
- ReactNativeDependencies (from `../node_modules/react-native/third-party-podspecs/ReactNativeDependencies.podspec`)
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)

SPEC REPOS:
trunk:
- ComputableLayout
- ContextMenuAuxiliaryPreview
- DGSwiftUtilities

EXTERNAL SOURCES:
FBLazyVector:
:path: "../node_modules/react-native/Libraries/FBLazyVector"
Expand Down Expand Up @@ -1917,6 +1986,10 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon"
React-microtasksnativemodule:
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/microtasks"
react-native-ios-context-menu:
:path: "../node_modules/react-native-ios-context-menu"
react-native-ios-utilities:
:path: "../node_modules/react-native-ios-utilities"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
react-native-slider:
Expand Down Expand Up @@ -1987,9 +2060,12 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"

SPEC CHECKSUMS:
ComputableLayout: c50faffac4ed9f8f05b0ce5e6f3a60df1f6042c8
ContextMenuAuxiliaryPreview: 20be0be795b783b68f8792732eed4bed9f202c1c
DGSwiftUtilities: 567f8d5ee618f0b7afb185b17aa45ff356315a0f
FBLazyVector: 9e0cd874afd81d9a4d36679daca991b58b260d42
hermes-engine: 35c763d57c9832d0eef764316ca1c4d043581394
LiquidGlass: 2684e8e6ef8a1d206c6009f98271f1d42d42a3dc
LiquidGlass: 6937b48f2c38c97bc4f512aad93f582e86cd7afa
RCTDeprecation: 7487d6dda857ccd4cb3dd6ecfccdc3170e85dcbc
RCTRequired: 54128b7df8be566881d48c7234724a78cb9b6157
RCTTypeSafety: d2b07797a79e45d7b19e1cd2f53c79ab419fe217
Expand Down Expand Up @@ -2023,6 +2099,8 @@ SPEC CHECKSUMS:
React-logger: 7b234de35acb469ce76d6bbb0457f664d6f32f62
React-Mapbuffer: fbe1da882a187e5898bdf125e1cc6e603d27ecae
React-microtasksnativemodule: 76905804171d8ccbe69329fc84c57eb7934add7f
react-native-ios-context-menu: 9f23509b5722166590c4c53180991319cc44e286
react-native-ios-utilities: 14afbb6d64f67dce464df5e4bf09d3e80334adde
react-native-safe-area-context: 42a1b4f8774b577d03b53de7326e3d5757fe9513
react-native-slider: 8c562583722c396a3682f451f0b6e68e351ec3b9
React-NativeModulesApple: a9464983ccc0f66f45e93558671f60fc7536e438
Expand Down
5 changes: 4 additions & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
"@react-native/new-app-screen": "0.81.4",
"react": "19.1.0",
"react-native": "0.81.4",
"react-native-safe-area-context": "^5.5.2"
"react-native-ios-context-menu": "3.2.1",
"react-native-ios-utilities": "5.2.0",
"react-native-safe-area-context": "^5.5.2",
"zeego": "^3.0.6"
},
"devDependencies": {
"@babel/core": "^7.25.2",
Expand Down
54 changes: 53 additions & 1 deletion example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react-native/no-inline-styles */
import {
ScrollView,
StyleSheet,
Expand All @@ -8,6 +7,7 @@ import {
Animated,
View,
Pressable,
PlatformColor,
} from 'react-native';
import {
LiquidGlassView,
Expand All @@ -16,6 +16,40 @@ import {
type LiquidGlassViewProps,
} from '@callstack/liquid-glass';
import { useEffect, useState } from 'react';
import * as DropdownMenu from 'zeego/dropdown-menu';

function DropdownMenuButton({ title }: { title?: string }) {
return (
<DropdownMenu.Root>
<DropdownMenu.Trigger>
<Text style={styles.dropdownTrigger}>{title}</Text>
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Item key="first">
<DropdownMenu.ItemTitle>First</DropdownMenu.ItemTitle>
</DropdownMenu.Item>
<DropdownMenu.Item key="second">
<DropdownMenu.ItemTitle>Second</DropdownMenu.ItemTitle>
</DropdownMenu.Item>
<DropdownMenu.Item key="third">
<DropdownMenu.ItemTitle>Third</DropdownMenu.ItemTitle>
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Root>
);
}

function LiquidToolBar() {
return (
<LiquidGlassView style={styles.toolbar}>
<DropdownMenuButton title="File" />
<DropdownMenuButton title="Edit" />
<DropdownMenuButton title="View" />
<DropdownMenuButton title="Window" />
<DropdownMenuButton title="Help" />
</LiquidGlassView>
);
}

const AnimatedLiquidGlassView =
Animated.createAnimatedComponent(LiquidGlassView);
Expand All @@ -42,6 +76,7 @@ export default function App() {
<Button />
<MergingCircles />
</ScrollView>
<LiquidToolBar />
</>
);
}
Expand Down Expand Up @@ -252,4 +287,21 @@ const styles = StyleSheet.create({
flexDirection: 'row',
gap: 10,
},
toolbar: {
flexDirection: 'row',
gap: 10,
padding: 10,
position: 'absolute',
borderRadius: 40,
bottom: 50,
left: 20,
right: 20,
justifyContent: 'center',
},
dropdownTrigger: {
padding: 10,
color: PlatformColor('labelColor'),
fontFamily: 'System',
fontWeight: '600',
},
});
30 changes: 27 additions & 3 deletions ios/LiquidGlassView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ @interface LiquidGlassView () <RCTLiquidGlassViewViewProtocol>

@implementation LiquidGlassView {
LiquidGlassViewImpl * _view;
BOOL _needsInvalidateLayer;
}

+ (ComponentDescriptorProvider)componentDescriptorProvider
Expand Down Expand Up @@ -102,9 +103,10 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
needsSetup = YES;
}

if (oldViewProps.borderRadii != newViewProps.borderRadii) {
_view.layer.cornerRadius = self.layer.cornerRadius;
_view.layer.cornerCurve = self.layer.cornerCurve;
// `border`
if (oldViewProps.borderStyles != newViewProps.borderStyles || oldViewProps.borderRadii != newViewProps.borderRadii ||
oldViewProps.borderColors != newViewProps.borderColors) {
_needsInvalidateLayer = YES;
}

if (needsSetup) {
Expand All @@ -114,6 +116,28 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
[super updateProps:props oldProps:oldProps];
}

- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask {
[super finalizeUpdates:updateMask];

if (!_needsInvalidateLayer) {
return;
}

_needsInvalidateLayer = NO;

if (@available(iOS 26.0, *)) {
const auto borderMetrics = _props->resolveBorderMetrics(_layoutMetrics);

if (!borderMetrics.borderRadii.isUniform()) {
// TODO: Handle non uniform border radius
NSLog(@"[@callstack/liquid-glass] Using uneven border radius is not yet supported on glass elements.");
}

// Use topLeft.horizontal same as React Native RCTViewComponentView implementation: https://github.com/facebook/react-native/blob/b823b26a3765cbf4506df0981e3350e0bae3ad62/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm#L988C26-L988C80
_view.cornerConfiguration = [UICornerConfiguration configurationWithRadius:[UICornerRadius fixedRadius:borderMetrics.borderRadii.topLeft.horizontal]];
}
}

- (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
oldLayoutMetrics:(const LayoutMetrics &)oldLayoutMetrics
{
Expand Down
Loading
Loading