diff --git a/CHANGELOG.md b/CHANGELOG.md
index 43bea5dbff..962c050d90 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,12 @@
# CHANGELOG
## x.x.x - x-x-x
+* [Added] Added appearance.applyLiquidGlass. When set to `true`, changes the values of various properties on the Appearance object used by PaymentSheet, PaymentSheet.FlowController, EmbeddedPaymentElement, CustomerSheet, and AddressViewController to match Liquid Glass when building with Xcode 26 or later and running on iOS 26. This includes appearance.cornerRadius, appearance.borderWidth, appearance.navigationBarStyle, colors.background, navigationBarStyle, and others. This feature is in public preview while we gather feedback and is subject to change. Please use https://github.com/stripe/stripe-ios/issues to file feedback!
+|
|
|
+| ------ | ------ |
+
+* [Added] appearance.navigationBarStyle. Setting to NavigationBarStyle.Glass will change the sheet navigation bar to a glassy appearance when building with Xcode 26 or later and running on iOS 26. Setting appearance.applyLiquidGlass to `true` will set this value to NavigationBarStyle.Glass.
## 0.54.1 - 2025-10-01
**Fixes**
diff --git a/example/src/screens/PaymentSheetAppearance.ts b/example/src/screens/PaymentSheetAppearance.ts
index 35f595ba4e..df2f48c657 100644
--- a/example/src/screens/PaymentSheetAppearance.ts
+++ b/example/src/screens/PaymentSheetAppearance.ts
@@ -1,7 +1,20 @@
import { Platform } from 'react-native';
-import type { PaymentSheet } from '@stripe/stripe-react-native';
+import {
+ NavigationBarStyle,
+ type PaymentSheet,
+} from '@stripe/stripe-react-native';
-const appearance: PaymentSheet.AppearanceParams = {
+const appearance: PaymentSheet.AppearanceParams = {};
+
+const liquidGlassAppearance: PaymentSheet.AppearanceParams = {
+ applyLiquidGlass: true,
+};
+
+const liquidGlassNavigationOnlyAppearance: PaymentSheet.AppearanceParams = {
+ navigationBarStyle: NavigationBarStyle.Glass,
+};
+
+const customAppearance: PaymentSheet.AppearanceParams = {
font: {
scale: 1.1,
family: Platform.OS === 'android' ? 'macondoregular' : 'Macondo-Regular',
@@ -64,3 +77,9 @@ const appearance: PaymentSheet.AppearanceParams = {
};
export default appearance;
+export {
+ appearance,
+ liquidGlassAppearance,
+ liquidGlassNavigationOnlyAppearance,
+ customAppearance,
+};
diff --git a/example/src/screens/PaymentsUICompleteScreen.tsx b/example/src/screens/PaymentsUICompleteScreen.tsx
index 156bda36f9..de8128c492 100644
--- a/example/src/screens/PaymentsUICompleteScreen.tsx
+++ b/example/src/screens/PaymentsUICompleteScreen.tsx
@@ -19,7 +19,20 @@ import CustomerSessionSwitch from '../components/CustomerSessionSwitch';
import PaymentScreen from '../components/PaymentScreen';
import { API_URL } from '../Config';
import { getClientSecretParams } from '../helpers';
-import appearance from './PaymentSheetAppearance';
+import {
+ appearance,
+ liquidGlassAppearance,
+ liquidGlassNavigationOnlyAppearance,
+ customAppearance,
+} from './PaymentSheetAppearance';
+import { Platform, View, Text, TouchableOpacity } from 'react-native';
+
+enum AppearanceSettings {
+ default = `default`,
+ glass = 'glass',
+ glassNavigation = 'glassNavigation',
+ custom = 'custom',
+}
export default function PaymentsUICompleteScreen() {
const { initPaymentSheet, presentPaymentSheet, resetPaymentSheetCustomer } =
@@ -27,6 +40,8 @@ export default function PaymentsUICompleteScreen() {
const [paymentSheetEnabled, setPaymentSheetEnabled] = useState(false);
const [loading, setLoading] = useState(false);
const [addressSheetVisible, setAddressSheetVisible] = useState(false);
+ const [appearanceSettings, setAppearanceSettings] =
+ useState(AppearanceSettings.default);
const [clientSecret, setClientSecret] = useState();
const [customerKeyType, setCustomerKeyType] = useState(
@@ -63,7 +78,6 @@ export default function PaymentsUICompleteScreen() {
};
}
};
-
const openPaymentSheet = async () => {
if (!clientSecret) {
return;
@@ -99,6 +113,19 @@ export default function PaymentsUICompleteScreen() {
setLoading(false);
};
+ const getAppearanceForSetting = (setting: AppearanceSettings) => {
+ switch (setting) {
+ case AppearanceSettings.default:
+ return appearance;
+ case AppearanceSettings.glass:
+ return liquidGlassAppearance;
+ case AppearanceSettings.glassNavigation:
+ return liquidGlassNavigationOnlyAppearance;
+ case AppearanceSettings.custom:
+ return customAppearance;
+ }
+ };
+
const initialisePaymentSheet = useCallback(
async (shippingDetails?: AddressDetails) => {
const { paymentIntent, customer, ...remainingParams } =
@@ -139,7 +166,7 @@ export default function PaymentsUICompleteScreen() {
defaultBillingDetails: billingDetails,
defaultShippingDetails: shippingDetails,
allowsDelayedPaymentMethods: true,
- appearance,
+ appearance: getAppearanceForSetting(appearanceSettings),
primaryButtonLabel: 'purchase!',
paymentMethodLayout: PaymentMethodLayout.Automatic,
removeSavedPaymentMethodMessage: 'remove this payment method?',
@@ -206,7 +233,7 @@ export default function PaymentsUICompleteScreen() {
);
}
},
- [customerKeyType, initPaymentSheet]
+ [customerKeyType, appearanceSettings, initPaymentSheet]
);
const toggleCustomerKeyType = (value: boolean) => {
@@ -242,6 +269,57 @@ export default function PaymentsUICompleteScreen() {
onValueChange={toggleCustomerKeyType}
value={customerKeyType === 'customer_session'}
/>
+ {Platform.OS === 'ios' && (
+
+
+ Appearance Style
+
+
+ {[
+ { title: 'Default', value: AppearanceSettings.default },
+ { title: 'Glass', value: AppearanceSettings.glass },
+ { title: 'Glass Nav', value: AppearanceSettings.glassNavigation },
+ { title: 'Custom', value: AppearanceSettings.custom },
+ ].map((option) => (
+ {
+ setAppearanceSettings(option.value);
+ }}
+ >
+
+ {option.title}
+
+
+ ))}
+
+
+ )}