react-native-platform-components 0.7.0 → 0.8.0

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.
Files changed (34) hide show
  1. package/README.md +106 -0
  2. package/android/src/main/java/com/platformcomponents/PCLiquidGlassView.kt +84 -0
  3. package/android/src/main/java/com/platformcomponents/PCLiquidGlassViewManager.kt +52 -0
  4. package/android/src/main/java/com/platformcomponents/PlatformComponentsPackage.kt +1 -0
  5. package/ios/PCLiquidGlass.h +10 -0
  6. package/ios/PCLiquidGlass.mm +140 -0
  7. package/ios/PCLiquidGlass.swift +354 -0
  8. package/ios/PCSelectionMenu.swift +1 -1
  9. package/lib/commonjs/LiquidGlass.js +72 -0
  10. package/lib/commonjs/LiquidGlass.js.map +1 -0
  11. package/lib/commonjs/LiquidGlassNativeComponent.ts +110 -0
  12. package/lib/commonjs/index.js +11 -0
  13. package/lib/commonjs/index.js.map +1 -1
  14. package/lib/module/LiquidGlass.js +64 -0
  15. package/lib/module/LiquidGlass.js.map +1 -0
  16. package/lib/module/LiquidGlassNativeComponent.ts +110 -0
  17. package/lib/module/index.js +1 -0
  18. package/lib/module/index.js.map +1 -1
  19. package/lib/typescript/commonjs/src/LiquidGlass.d.ts +96 -0
  20. package/lib/typescript/commonjs/src/LiquidGlass.d.ts.map +1 -0
  21. package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts +93 -0
  22. package/lib/typescript/commonjs/src/LiquidGlassNativeComponent.d.ts.map +1 -0
  23. package/lib/typescript/commonjs/src/index.d.ts +1 -0
  24. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  25. package/lib/typescript/module/src/LiquidGlass.d.ts +96 -0
  26. package/lib/typescript/module/src/LiquidGlass.d.ts.map +1 -0
  27. package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts +93 -0
  28. package/lib/typescript/module/src/LiquidGlassNativeComponent.d.ts.map +1 -0
  29. package/lib/typescript/module/src/index.d.ts +1 -0
  30. package/lib/typescript/module/src/index.d.ts.map +1 -1
  31. package/package.json +12 -4
  32. package/src/LiquidGlass.tsx +169 -0
  33. package/src/LiquidGlassNativeComponent.ts +110 -0
  34. package/src/index.tsx +1 -0
@@ -0,0 +1,354 @@
1
+ import UIKit
2
+
3
+ /// Glass effect style enum for bridging to ObjC++
4
+ @objc public enum PCLiquidGlassEffectStyle: Int {
5
+ case regular
6
+ case clear
7
+ case none
8
+
9
+ #if compiler(>=6.2)
10
+ @available(iOS 26.0, *)
11
+ var glassStyle: UIGlassEffect.Style? {
12
+ switch self {
13
+ case .regular:
14
+ return .regular
15
+ case .clear:
16
+ return .clear
17
+ case .none:
18
+ return nil
19
+ }
20
+ }
21
+ #endif
22
+ }
23
+
24
+ #if compiler(>=6.2)
25
+
26
+ /// The actual Liquid Glass view implementation for iOS 26+
27
+ /// Extends UIVisualEffectView to properly support UIGlassEffect
28
+ @available(iOS 26.0, *)
29
+ @objcMembers
30
+ public final class PCLiquidGlassView: UIVisualEffectView {
31
+
32
+ // MARK: - Static
33
+
34
+ @objc public static var isSupported: Bool {
35
+ return true
36
+ }
37
+
38
+ // MARK: - Props (set from ObjC++)
39
+
40
+ private var isFirstMount: Bool = true
41
+
42
+ /// Effect style: "clear", "regular", "none"
43
+ public var effectStyle: String = "regular" {
44
+ didSet { applyGlassEffect() }
45
+ }
46
+
47
+ /// Corner radius for the glass effect
48
+ public var glassCornerRadius: CGFloat = 0 {
49
+ didSet { applyCornerRadius() }
50
+ }
51
+
52
+ /// Enable touch interaction feedback
53
+ public var interactive: Bool = false
54
+
55
+ /// Tint color for the glass effect (hex string)
56
+ public var glassTintColor: String? {
57
+ didSet { applyGlassEffect() }
58
+ }
59
+
60
+ /// Color scheme: "light", "dark", "system"
61
+ public var colorScheme: String = "system" {
62
+ didSet { applyColorScheme() }
63
+ }
64
+
65
+ /// Shadow radius for glow effect
66
+ public var glassShadowRadius: CGFloat = 20 {
67
+ didSet { applyShadow() }
68
+ }
69
+
70
+ /// Manual highlight state control (no-op on iOS 26+, use `interactive` instead)
71
+ /// The native UIGlassEffect.isInteractive handles touch-based highlighting automatically
72
+ public var isHighlighted: Bool = false
73
+
74
+ /// Callback for press events with touch coordinates
75
+ public var onPressCallback: ((CGFloat, CGFloat) -> Void)?
76
+
77
+ // MARK: - Init
78
+
79
+ public override init(effect: UIVisualEffect?) {
80
+ super.init(effect: effect)
81
+ setup()
82
+ }
83
+
84
+ public required init?(coder: NSCoder) {
85
+ super.init(coder: coder)
86
+ setup()
87
+ }
88
+
89
+ private func setup() {
90
+ clipsToBounds = false
91
+ setupTapGesture()
92
+ }
93
+
94
+ private func setupTapGesture() {
95
+ let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
96
+ addGestureRecognizer(tap)
97
+ }
98
+
99
+ @objc private func handleTap(_ gesture: UITapGestureRecognizer) {
100
+ let location = gesture.location(in: self)
101
+ onPressCallback?(location.x, location.y)
102
+ }
103
+
104
+ // MARK: - Layout
105
+
106
+ public override func layoutSubviews() {
107
+ super.layoutSubviews()
108
+
109
+ // Apply glass effect on first layout when we have bounds
110
+ if effect == nil && bounds.size != .zero {
111
+ applyGlassEffect()
112
+ }
113
+ }
114
+
115
+ // MARK: - Public Setup (called from ObjC++ after props are set)
116
+
117
+ /// Call this after setting props to apply/re-apply the glass effect
118
+ @objc public func setupView() {
119
+ applyGlassEffect()
120
+ }
121
+
122
+ // MARK: - Glass Effect
123
+
124
+ private func applyGlassEffect() {
125
+ guard bounds.size != .zero else { return }
126
+
127
+ // Parse effect style
128
+ let style: PCLiquidGlassEffectStyle
129
+ switch effectStyle {
130
+ case "clear":
131
+ style = .clear
132
+ case "none":
133
+ style = .none
134
+ default:
135
+ style = .regular
136
+ }
137
+
138
+ // Handle "none" style
139
+ guard let glassStyle = style.glassStyle else {
140
+ UIView.animate(withDuration: 0.2) {
141
+ self.effect = nil
142
+ }
143
+ return
144
+ }
145
+
146
+ // Create the glass effect
147
+ let glassEffect = UIGlassEffect(style: glassStyle)
148
+ glassEffect.isInteractive = interactive
149
+
150
+ // Apply tint color
151
+ if let tintHex = glassTintColor, !tintHex.isEmpty,
152
+ let color = UIColor(pcHex: tintHex) {
153
+ glassEffect.tintColor = color
154
+ }
155
+
156
+ // Apply the effect
157
+ if isFirstMount {
158
+ self.effect = glassEffect
159
+ isFirstMount = false
160
+ } else {
161
+ UIView.animate(withDuration: 0.2) {
162
+ self.effect = glassEffect
163
+ }
164
+ }
165
+
166
+ applyCornerRadius()
167
+ applyShadow()
168
+ }
169
+
170
+ private func applyCornerRadius() {
171
+ layer.cornerRadius = glassCornerRadius
172
+ layer.cornerCurve = .continuous
173
+ // Don't clip to bounds - allow shadow to show
174
+ }
175
+
176
+ private func applyShadow() {
177
+ if glassShadowRadius > 0 {
178
+ layer.shadowColor = UIColor.white.cgColor
179
+ layer.shadowOpacity = 0.2
180
+ layer.shadowRadius = glassShadowRadius
181
+ layer.shadowOffset = .zero
182
+ layer.masksToBounds = false
183
+ } else {
184
+ layer.shadowOpacity = 0
185
+ }
186
+ }
187
+
188
+ private func applyColorScheme() {
189
+ switch colorScheme {
190
+ case "light":
191
+ overrideUserInterfaceStyle = .light
192
+ case "dark":
193
+ overrideUserInterfaceStyle = .dark
194
+ default:
195
+ overrideUserInterfaceStyle = .unspecified
196
+ }
197
+ applyGlassEffect()
198
+ }
199
+
200
+ // MARK: - Sizing
201
+
202
+ public override func sizeThatFits(_ size: CGSize) -> CGSize {
203
+ return size
204
+ }
205
+
206
+ public override var intrinsicContentSize: CGSize {
207
+ return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
208
+ }
209
+ }
210
+
211
+ #else
212
+
213
+ /// Fallback for older Swift compilers (pre-iOS 26 SDK)
214
+ /// Uses UIBlurEffect as a fallback
215
+ @objcMembers
216
+ public final class PCLiquidGlassView: UIVisualEffectView {
217
+
218
+ @objc public static var isSupported: Bool {
219
+ return false
220
+ }
221
+
222
+ public var effectStyle: String = "regular" {
223
+ didSet { applyFallbackEffect() }
224
+ }
225
+
226
+ public var glassCornerRadius: CGFloat = 0 {
227
+ didSet { applyCornerRadius() }
228
+ }
229
+
230
+ public var interactive: Bool = false
231
+ public var glassTintColor: String?
232
+ public var colorScheme: String = "system" {
233
+ didSet { applyColorScheme() }
234
+ }
235
+ public var glassShadowRadius: CGFloat = 20
236
+ public var isHighlighted: Bool = false
237
+ public var onPressCallback: ((CGFloat, CGFloat) -> Void)?
238
+
239
+ public override init(effect: UIVisualEffect?) {
240
+ super.init(effect: effect)
241
+ setup()
242
+ }
243
+
244
+ public required init?(coder: NSCoder) {
245
+ super.init(coder: coder)
246
+ setup()
247
+ }
248
+
249
+ private func setup() {
250
+ clipsToBounds = false
251
+ setupTapGesture()
252
+ applyFallbackEffect()
253
+ }
254
+
255
+ private func setupTapGesture() {
256
+ let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
257
+ addGestureRecognizer(tap)
258
+ }
259
+
260
+ @objc private func handleTap(_ gesture: UITapGestureRecognizer) {
261
+ let location = gesture.location(in: self)
262
+ onPressCallback?(location.x, location.y)
263
+ }
264
+
265
+ public override func layoutSubviews() {
266
+ super.layoutSubviews()
267
+ if effect == nil && bounds.size != .zero {
268
+ applyFallbackEffect()
269
+ }
270
+ }
271
+
272
+ /// Call this after setting props to apply/re-apply the effect
273
+ @objc public func setupView() {
274
+ applyFallbackEffect()
275
+ }
276
+
277
+ private func applyFallbackEffect() {
278
+ guard effectStyle != "none" else {
279
+ self.effect = nil
280
+ return
281
+ }
282
+
283
+ // Use thin blur materials as fallback
284
+ let blurStyle: UIBlurEffect.Style
285
+ switch (effectStyle, colorScheme) {
286
+ case ("clear", "dark"):
287
+ blurStyle = .systemUltraThinMaterialDark
288
+ case ("clear", "light"):
289
+ blurStyle = .systemUltraThinMaterialLight
290
+ case ("clear", _):
291
+ blurStyle = .systemUltraThinMaterial
292
+ case (_, "dark"):
293
+ blurStyle = .systemThinMaterialDark
294
+ case (_, "light"):
295
+ blurStyle = .systemThinMaterialLight
296
+ default:
297
+ blurStyle = .systemThinMaterial
298
+ }
299
+
300
+ self.effect = UIBlurEffect(style: blurStyle)
301
+ applyCornerRadius()
302
+ }
303
+
304
+ private func applyCornerRadius() {
305
+ layer.cornerRadius = glassCornerRadius
306
+ layer.cornerCurve = .continuous
307
+ clipsToBounds = glassCornerRadius > 0
308
+ }
309
+
310
+ private func applyColorScheme() {
311
+ switch colorScheme {
312
+ case "light":
313
+ overrideUserInterfaceStyle = .light
314
+ case "dark":
315
+ overrideUserInterfaceStyle = .dark
316
+ default:
317
+ overrideUserInterfaceStyle = .unspecified
318
+ }
319
+ applyFallbackEffect()
320
+ }
321
+ }
322
+
323
+ #endif
324
+
325
+ // MARK: - UIColor hex extension
326
+
327
+ private extension UIColor {
328
+ convenience init?(pcHex: String) {
329
+ var hexSanitized = pcHex.trimmingCharacters(in: .whitespacesAndNewlines)
330
+ hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "")
331
+
332
+ var rgb: UInt64 = 0
333
+ guard Scanner(string: hexSanitized).scanHexInt64(&rgb) else { return nil }
334
+
335
+ let length = hexSanitized.count
336
+ if length == 6 {
337
+ self.init(
338
+ red: CGFloat((rgb & 0xFF0000) >> 16) / 255.0,
339
+ green: CGFloat((rgb & 0x00FF00) >> 8) / 255.0,
340
+ blue: CGFloat(rgb & 0x0000FF) / 255.0,
341
+ alpha: 1.0
342
+ )
343
+ } else if length == 8 {
344
+ self.init(
345
+ red: CGFloat((rgb & 0xFF000000) >> 24) / 255.0,
346
+ green: CGFloat((rgb & 0x00FF0000) >> 16) / 255.0,
347
+ blue: CGFloat((rgb & 0x0000FF00) >> 8) / 255.0,
348
+ alpha: CGFloat(rgb & 0x000000FF) / 255.0
349
+ )
350
+ } else {
351
+ return nil
352
+ }
353
+ }
354
+ }
@@ -462,7 +462,7 @@ private class PCMenuViewController: UIViewController, UITableViewDelegate, UITab
462
462
  // Use liquid glass on iOS 26+, fall back to system material blur on older versions
463
463
  let effectView: UIVisualEffectView
464
464
  if #available(iOS 26, *) {
465
- var glassEffect = UIGlassEffect()
465
+ let glassEffect = UIGlassEffect()
466
466
  glassEffect.isInteractive = true
467
467
  effectView = UIVisualEffectView(effect: glassEffect)
468
468
  } else {
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.LiquidGlass = LiquidGlass;
7
+ exports.isLiquidGlassSupported = void 0;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ var _reactNative = require("react-native");
10
+ var _LiquidGlassNativeComponent = _interopRequireDefault(require("./LiquidGlassNativeComponent"));
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14
+ // LiquidGlass.tsx
15
+
16
+ /**
17
+ * Whether the LiquidGlass effect is supported on the current device.
18
+ * Returns true on iOS 26+ (with Liquid Glass support), false otherwise.
19
+ *
20
+ * Use this to conditionally render fallback UI on unsupported devices.
21
+ */
22
+ const isLiquidGlassSupported = exports.isLiquidGlassSupported = _reactNative.Platform.OS === 'ios' && Number(_reactNative.Platform.Version) >= 26;
23
+ function LiquidGlass(props) {
24
+ const {
25
+ style,
26
+ cornerRadius = 0,
27
+ ios,
28
+ android,
29
+ children,
30
+ onPress,
31
+ ...viewProps
32
+ } = props;
33
+
34
+ // Normalize iOS props for native layer (strings for codegen)
35
+ const nativeIos = (0, _react.useMemo)(() => {
36
+ if (_reactNative.Platform.OS !== 'ios' || !ios) return undefined;
37
+ return {
38
+ effect: ios.effect,
39
+ interactive: ios.interactive ? 'true' : 'false',
40
+ tintColor: ios.tintColor,
41
+ colorScheme: ios.colorScheme,
42
+ shadowRadius: ios.shadowRadius,
43
+ isHighlighted: ios.isHighlighted ? 'true' : 'false'
44
+ };
45
+ }, [ios]);
46
+
47
+ // Normalize Android props
48
+ const nativeAndroid = (0, _react.useMemo)(() => {
49
+ if (_reactNative.Platform.OS !== 'android' || !android) return undefined;
50
+ return {
51
+ fallbackBackgroundColor: android.fallbackBackgroundColor
52
+ };
53
+ }, [android]);
54
+
55
+ // Handle native press event
56
+ const handlePress = (0, _react.useCallback)(event => {
57
+ onPress?.({
58
+ x: event.nativeEvent.x,
59
+ y: event.nativeEvent.y
60
+ });
61
+ }, [onPress]);
62
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_LiquidGlassNativeComponent.default, {
63
+ style: style,
64
+ cornerRadius: cornerRadius,
65
+ ios: nativeIos,
66
+ android: nativeAndroid,
67
+ onGlassPress: onPress ? handlePress : undefined,
68
+ ...viewProps,
69
+ children: children
70
+ });
71
+ }
72
+ //# sourceMappingURL=LiquidGlass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_LiquidGlassNativeComponent","_interopRequireDefault","_jsxRuntime","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","isLiquidGlassSupported","exports","Platform","OS","Number","Version","LiquidGlass","props","style","cornerRadius","ios","android","children","onPress","viewProps","nativeIos","useMemo","undefined","effect","interactive","tintColor","colorScheme","shadowRadius","isHighlighted","nativeAndroid","fallbackBackgroundColor","handlePress","useCallback","event","x","nativeEvent","y","jsx","onGlassPress"],"sourceRoot":"../../src","sources":["LiquidGlass.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,110 @@
1
+ // LiquidGlassNativeComponent.ts
2
+ import type { CodegenTypes, HostComponent, ViewProps } from 'react-native';
3
+ import { codegenNativeComponent } from 'react-native';
4
+
5
+ /**
6
+ * Glass effect intensity/style.
7
+ * - 'clear': More transparent, subtle glass effect
8
+ * - 'regular': Standard blur intensity (default)
9
+ * - 'none': No glass effect (useful for animating materialization)
10
+ */
11
+ export type LiquidGlassEffect = 'clear' | 'regular' | 'none';
12
+
13
+ /**
14
+ * Color scheme for the glass effect.
15
+ * - 'light': Force light appearance
16
+ * - 'dark': Force dark appearance
17
+ * - 'system': Follow system appearance (default)
18
+ */
19
+ export type LiquidGlassColorScheme = 'light' | 'dark' | 'system';
20
+
21
+ /**
22
+ * iOS-specific configuration.
23
+ */
24
+ export type LiquidGlassIOSProps = Readonly<{
25
+ /**
26
+ * Glass effect style.
27
+ * @default 'regular'
28
+ */
29
+ effect?: string; // LiquidGlassEffect
30
+
31
+ /**
32
+ * Enables touch interaction effects when pressing the view.
33
+ * Note: Only applies on component mount; cannot be changed dynamically.
34
+ * @default false
35
+ */
36
+ interactive?: string; // 'true' | 'false'
37
+
38
+ /**
39
+ * Overlay tint color applied to the glass effect.
40
+ * Accepts hex color strings (e.g., '#FF0000', '#FF000080').
41
+ */
42
+ tintColor?: string;
43
+
44
+ /**
45
+ * Appearance adaptation mode.
46
+ * @default 'system'
47
+ */
48
+ colorScheme?: string; // LiquidGlassColorScheme
49
+
50
+ /**
51
+ * Shadow radius for the glass effect.
52
+ * @default 20
53
+ */
54
+ shadowRadius?: CodegenTypes.Float;
55
+
56
+ /**
57
+ * Whether the view is highlighted (pressed state).
58
+ */
59
+ isHighlighted?: string; // 'true' | 'false'
60
+ }>;
61
+
62
+ /**
63
+ * Android-specific configuration (stub - LiquidGlass is iOS only).
64
+ */
65
+ export type LiquidGlassAndroidProps = Readonly<{
66
+ /**
67
+ * Fallback background color for Android (since glass effect is not supported).
68
+ * If not provided, renders as transparent.
69
+ */
70
+ fallbackBackgroundColor?: string;
71
+ }>;
72
+
73
+ /**
74
+ * Event emitted when the glass view is pressed.
75
+ */
76
+ export type LiquidGlassPressEvent = Readonly<{
77
+ /** X coordinate of touch relative to view bounds */
78
+ x: CodegenTypes.Float;
79
+ /** Y coordinate of touch relative to view bounds */
80
+ y: CodegenTypes.Float;
81
+ }>;
82
+
83
+ export interface LiquidGlassNativeProps extends ViewProps {
84
+ /**
85
+ * Corner radius for the glass effect.
86
+ * Applied uniformly to all corners.
87
+ * @default 0
88
+ */
89
+ cornerRadius?: CodegenTypes.WithDefault<CodegenTypes.Float, 0>;
90
+
91
+ /**
92
+ * iOS-specific props.
93
+ */
94
+ ios?: LiquidGlassIOSProps;
95
+
96
+ /**
97
+ * Android-specific props.
98
+ */
99
+ android?: LiquidGlassAndroidProps;
100
+
101
+ /**
102
+ * Fired when the glass view is pressed.
103
+ * Includes touch coordinates relative to view bounds.
104
+ */
105
+ onGlassPress?: CodegenTypes.DirectEventHandler<LiquidGlassPressEvent>;
106
+ }
107
+
108
+ export default codegenNativeComponent<LiquidGlassNativeProps>(
109
+ 'PCLiquidGlass'
110
+ ) as HostComponent<LiquidGlassNativeProps>;
@@ -47,6 +47,17 @@ Object.keys(_SegmentedControl).forEach(function (key) {
47
47
  }
48
48
  });
49
49
  });
50
+ var _LiquidGlass = require("./LiquidGlass");
51
+ Object.keys(_LiquidGlass).forEach(function (key) {
52
+ if (key === "default" || key === "__esModule") return;
53
+ if (key in exports && exports[key] === _LiquidGlass[key]) return;
54
+ Object.defineProperty(exports, key, {
55
+ enumerable: true,
56
+ get: function () {
57
+ return _LiquidGlass[key];
58
+ }
59
+ });
60
+ });
50
61
  var _sharedTypes = require("./sharedTypes");
51
62
  Object.keys(_sharedTypes).forEach(function (key) {
52
63
  if (key === "default" || key === "__esModule") return;
@@ -1 +1 @@
1
- {"version":3,"names":["_DatePicker","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_SelectionMenu","_ContextMenu","_SegmentedControl","_sharedTypes"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;AAAA,IAAAA,WAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,WAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,WAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,WAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,cAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,cAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,cAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,cAAA,CAAAL,GAAA;IAAA;EAAA;AAAA;AACA,IAAAM,YAAA,GAAAV,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAQ,YAAA,EAAAP,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAM,YAAA,CAAAN,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAE,YAAA,CAAAN,GAAA;IAAA;EAAA;AAAA;AACA,IAAAO,iBAAA,GAAAX,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAS,iBAAA,EAAAR,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAO,iBAAA,CAAAP,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAG,iBAAA,CAAAP,GAAA;IAAA;EAAA;AAAA;AACA,IAAAQ,YAAA,GAAAZ,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAU,YAAA,EAAAT,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAQ,YAAA,CAAAR,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAI,YAAA,CAAAR,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
1
+ {"version":3,"names":["_DatePicker","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_SelectionMenu","_ContextMenu","_SegmentedControl","_LiquidGlass","_sharedTypes"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;AAAA,IAAAA,WAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,WAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,WAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,WAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,cAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,cAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,cAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,cAAA,CAAAL,GAAA;IAAA;EAAA;AAAA;AACA,IAAAM,YAAA,GAAAV,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAQ,YAAA,EAAAP,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAM,YAAA,CAAAN,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAE,YAAA,CAAAN,GAAA;IAAA;EAAA;AAAA;AACA,IAAAO,iBAAA,GAAAX,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAS,iBAAA,EAAAR,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAO,iBAAA,CAAAP,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAG,iBAAA,CAAAP,GAAA;IAAA;EAAA;AAAA;AACA,IAAAQ,YAAA,GAAAZ,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAU,YAAA,EAAAT,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAQ,YAAA,CAAAR,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAI,YAAA,CAAAR,GAAA;IAAA;EAAA;AAAA;AACA,IAAAS,YAAA,GAAAb,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAW,YAAA,EAAAV,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAS,YAAA,CAAAT,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAK,YAAA,CAAAT,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ // LiquidGlass.tsx
4
+ import React, { useCallback, useMemo } from 'react';
5
+ import { Platform } from 'react-native';
6
+ import NativeLiquidGlass from './LiquidGlassNativeComponent';
7
+ import { jsx as _jsx } from "react/jsx-runtime";
8
+ /**
9
+ * Whether the LiquidGlass effect is supported on the current device.
10
+ * Returns true on iOS 26+ (with Liquid Glass support), false otherwise.
11
+ *
12
+ * Use this to conditionally render fallback UI on unsupported devices.
13
+ */
14
+ export const isLiquidGlassSupported = Platform.OS === 'ios' && Number(Platform.Version) >= 26;
15
+ export function LiquidGlass(props) {
16
+ const {
17
+ style,
18
+ cornerRadius = 0,
19
+ ios,
20
+ android,
21
+ children,
22
+ onPress,
23
+ ...viewProps
24
+ } = props;
25
+
26
+ // Normalize iOS props for native layer (strings for codegen)
27
+ const nativeIos = useMemo(() => {
28
+ if (Platform.OS !== 'ios' || !ios) return undefined;
29
+ return {
30
+ effect: ios.effect,
31
+ interactive: ios.interactive ? 'true' : 'false',
32
+ tintColor: ios.tintColor,
33
+ colorScheme: ios.colorScheme,
34
+ shadowRadius: ios.shadowRadius,
35
+ isHighlighted: ios.isHighlighted ? 'true' : 'false'
36
+ };
37
+ }, [ios]);
38
+
39
+ // Normalize Android props
40
+ const nativeAndroid = useMemo(() => {
41
+ if (Platform.OS !== 'android' || !android) return undefined;
42
+ return {
43
+ fallbackBackgroundColor: android.fallbackBackgroundColor
44
+ };
45
+ }, [android]);
46
+
47
+ // Handle native press event
48
+ const handlePress = useCallback(event => {
49
+ onPress?.({
50
+ x: event.nativeEvent.x,
51
+ y: event.nativeEvent.y
52
+ });
53
+ }, [onPress]);
54
+ return /*#__PURE__*/_jsx(NativeLiquidGlass, {
55
+ style: style,
56
+ cornerRadius: cornerRadius,
57
+ ios: nativeIos,
58
+ android: nativeAndroid,
59
+ onGlassPress: onPress ? handlePress : undefined,
60
+ ...viewProps,
61
+ children: children
62
+ });
63
+ }
64
+ //# sourceMappingURL=LiquidGlass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","useCallback","useMemo","Platform","NativeLiquidGlass","jsx","_jsx","isLiquidGlassSupported","OS","Number","Version","LiquidGlass","props","style","cornerRadius","ios","android","children","onPress","viewProps","nativeIos","undefined","effect","interactive","tintColor","colorScheme","shadowRadius","isHighlighted","nativeAndroid","fallbackBackgroundColor","handlePress","event","x","nativeEvent","y","onGlassPress"],"sourceRoot":"../../src","sources":["LiquidGlass.tsx"],"mappings":";;AAAA;AACA,OAAOA,KAAK,IAAIC,WAAW,EAAEC,OAAO,QAAQ,OAAO;AACnD,SAASC,QAAQ,QAAwB,cAAc;AAEvD,OAAOC,iBAAiB,MAIjB,8BAA8B;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAQtC;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,sBAA+B,GAC1CJ,QAAQ,CAACK,EAAE,KAAK,KAAK,IAAIC,MAAM,CAACN,QAAQ,CAACO,OAAO,CAAC,IAAI,EAAE;AA6FzD,OAAO,SAASC,WAAWA,CAACC,KAAuB,EAAsB;EACvE,MAAM;IACJC,KAAK;IACLC,YAAY,GAAG,CAAC;IAChBC,GAAG;IACHC,OAAO;IACPC,QAAQ;IACRC,OAAO;IACP,GAAGC;EACL,CAAC,GAAGP,KAAK;;EAET;EACA,MAAMQ,SAAS,GAAGlB,OAAO,CAAC,MAAM;IAC9B,IAAIC,QAAQ,CAACK,EAAE,KAAK,KAAK,IAAI,CAACO,GAAG,EAAE,OAAOM,SAAS;IACnD,OAAO;MACLC,MAAM,EAAEP,GAAG,CAACO,MAAM;MAClBC,WAAW,EAAER,GAAG,CAACQ,WAAW,GAAG,MAAM,GAAG,OAAO;MAC/CC,SAAS,EAAET,GAAG,CAACS,SAAS;MACxBC,WAAW,EAAEV,GAAG,CAACU,WAAW;MAC5BC,YAAY,EAAEX,GAAG,CAACW,YAAY;MAC9BC,aAAa,EAAEZ,GAAG,CAACY,aAAa,GAAG,MAAM,GAAG;IAC9C,CAAC;EACH,CAAC,EAAE,CAACZ,GAAG,CAAC,CAAC;;EAET;EACA,MAAMa,aAAa,GAAG1B,OAAO,CAAC,MAAM;IAClC,IAAIC,QAAQ,CAACK,EAAE,KAAK,SAAS,IAAI,CAACQ,OAAO,EAAE,OAAOK,SAAS;IAC3D,OAAO;MACLQ,uBAAuB,EAAEb,OAAO,CAACa;IACnC,CAAC;EACH,CAAC,EAAE,CAACb,OAAO,CAAC,CAAC;;EAEb;EACA,MAAMc,WAAW,GAAG7B,WAAW,CAC5B8B,KAAgD,IAAK;IACpDb,OAAO,GAAG;MAAEc,CAAC,EAAED,KAAK,CAACE,WAAW,CAACD,CAAC;MAAEE,CAAC,EAAEH,KAAK,CAACE,WAAW,CAACC;IAAE,CAAC,CAAC;EAC/D,CAAC,EACD,CAAChB,OAAO,CACV,CAAC;EAED,oBACEZ,IAAA,CAACF,iBAAiB;IAChBS,KAAK,EAAEA,KAAM;IACbC,YAAY,EAAEA,YAAa;IAC3BC,GAAG,EAAEK,SAAU;IACfJ,OAAO,EAAEY,aAAc;IACvBO,YAAY,EAAEjB,OAAO,GAAGY,WAAW,GAAGT,SAAU;IAAA,GAC5CF,SAAS;IAAAF,QAAA,EAEZA;EAAQ,CACQ,CAAC;AAExB","ignoreList":[]}