@ajuarezso/capacitor-liquid-glass 0.1.0 → 0.1.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.
@@ -9,12 +9,23 @@ export interface LiquidGlassTabItem {
9
9
  /** Optional badge value (e.g. "3" or "•"). */
10
10
  badge?: string;
11
11
  }
12
+ /**
13
+ * Visual style of the tab bar background.
14
+ * - `'default'` (default): Liquid Glass on iOS 26+ (translucent blurred).
15
+ * - `'ultraThin'`: minimal blur (`UIBlurEffect.Style.systemUltraThinMaterial`),
16
+ * more see-through than default.
17
+ * - `'transparent'`: no background, no blur — content behind shows through 100%.
18
+ * Trade-off: legibilidad puede sufrir sobre contenido caótico.
19
+ */
20
+ export type TabBarStyle = 'default' | 'ultraThin' | 'transparent';
12
21
  export interface ShowTabBarOptions {
13
22
  items: LiquidGlassTabItem[];
14
23
  /** Index of the initially selected item. Defaults to 0. */
15
24
  selectedIndex?: number;
16
25
  /** Tint color for selected state, hex "#RRGGBB". Defaults to iOS system tint. */
17
26
  tintColor?: string;
27
+ /** Visual style of the tab bar background. Defaults to `'default'`. */
28
+ tabBarStyle?: TabBarStyle;
18
29
  }
19
30
  export interface SetSelectedTabOptions {
20
31
  /** Either pass numeric index or the item id. */
@@ -23,6 +23,7 @@ public class LiquidGlassPlugin: CAPPlugin, CAPBridgedPlugin {
23
23
  }
24
24
  let selectedIndex = call.getInt("selectedIndex") ?? 0
25
25
  let tintHex = call.getString("tintColor")
26
+ let styleRaw = call.getString("tabBarStyle") ?? "default"
26
27
 
27
28
  let items = rawItems.compactMap { LiquidGlassTabItem(dictionary: $0) }
28
29
  guard !items.isEmpty else {
@@ -32,7 +33,7 @@ public class LiquidGlassPlugin: CAPPlugin, CAPBridgedPlugin {
32
33
 
33
34
  DispatchQueue.main.async { [weak self] in
34
35
  guard let self else { return }
35
- self.presentTabBar(items: items, selectedIndex: selectedIndex, tintHex: tintHex)
36
+ self.presentTabBar(items: items, selectedIndex: selectedIndex, tintHex: tintHex, styleRaw: styleRaw)
36
37
  call.resolve()
37
38
  }
38
39
  }
@@ -85,7 +86,7 @@ public class LiquidGlassPlugin: CAPPlugin, CAPBridgedPlugin {
85
86
  }
86
87
  }
87
88
 
88
- private func presentTabBar(items: [LiquidGlassTabItem], selectedIndex: Int, tintHex: String?) {
89
+ private func presentTabBar(items: [LiquidGlassTabItem], selectedIndex: Int, tintHex: String?, styleRaw: String) {
89
90
  guard let window = UIApplication.shared.capacitorWindow else { return }
90
91
 
91
92
  if tabBarOverlay == nil {
@@ -102,8 +103,9 @@ public class LiquidGlassPlugin: CAPPlugin, CAPBridgedPlugin {
102
103
  tabBarOverlay = overlay
103
104
  }
104
105
 
106
+ let style = LiquidGlassTabBarStyle(rawValue: styleRaw) ?? .default
105
107
  tabBarOverlay?.attach(to: window)
106
- tabBarOverlay?.configure(items: items, selectedIndex: selectedIndex, tintHex: tintHex)
108
+ tabBarOverlay?.configure(items: items, selectedIndex: selectedIndex, tintHex: tintHex, style: style)
107
109
  tabBarOverlay?.show()
108
110
  }
109
111
  }
@@ -21,6 +21,16 @@ struct LiquidGlassTabItem {
21
21
  }
22
22
  }
23
23
 
24
+ /// Visual style of the tab bar background.
25
+ enum LiquidGlassTabBarStyle: String {
26
+ /// Translucent blurred — auto-applies Liquid Glass on iOS 26+ SDK.
27
+ case `default`
28
+ /// Minimal blur (`systemUltraThinMaterial`) — more see-through than default.
29
+ case ultraThin
30
+ /// No background, no blur — content behind shows through 100%.
31
+ case transparent
32
+ }
33
+
24
34
  /// A floating UITabBar overlay that adopts iOS 26 Liquid Glass automatically
25
35
  /// when the app is built against the iOS 26 SDK. On earlier iOS the bar falls
26
36
  /// back to the translucent blurred UITabBar appearance.
@@ -43,13 +53,9 @@ final class LiquidGlassTabBarOverlay: NSObject {
43
53
  tabBar.translatesAutoresizingMaskIntoConstraints = false
44
54
  tabBar.delegate = self
45
55
 
46
- // Default appearance triggers Liquid Glass automatically on iOS 26.
47
- let appearance = UITabBarAppearance()
48
- appearance.configureWithDefaultBackground()
49
- tabBar.standardAppearance = appearance
50
- if #available(iOS 15.0, *) {
51
- tabBar.scrollEdgeAppearance = appearance
52
- }
56
+ // Default appearance: triggers Liquid Glass automatically on iOS 26+.
57
+ // (Sobreescrito en `configure(...)` si el caller pidió otro estilo).
58
+ applyAppearance(tabBar, style: .default)
53
59
 
54
60
  window.addSubview(tabBar)
55
61
 
@@ -63,7 +69,32 @@ final class LiquidGlassTabBarOverlay: NSObject {
63
69
  emitLayout()
64
70
  }
65
71
 
66
- func configure(items: [LiquidGlassTabItem], selectedIndex: Int, tintHex: String?) {
72
+ /// Aplica el appearance correspondiente al estilo solicitado.
73
+ /// - `default`: Liquid Glass (iOS 26+) o blur translúcido como fallback.
74
+ /// - `ultraThin`: blur mínimo `systemUltraThinMaterial` — más ver-through.
75
+ /// - `transparent`: sin background ni blur — content behind se ve completo.
76
+ private func applyAppearance(_ tabBar: UITabBar, style: LiquidGlassTabBarStyle) {
77
+ let appearance = UITabBarAppearance()
78
+ switch style {
79
+ case .default:
80
+ appearance.configureWithDefaultBackground()
81
+ case .ultraThin:
82
+ appearance.configureWithDefaultBackground()
83
+ appearance.backgroundEffect = UIBlurEffect(style: .systemUltraThinMaterial)
84
+ appearance.backgroundColor = UIColor.clear
85
+ case .transparent:
86
+ appearance.configureWithTransparentBackground()
87
+ appearance.backgroundEffect = nil
88
+ appearance.backgroundColor = UIColor.clear
89
+ appearance.shadowColor = UIColor.clear
90
+ }
91
+ tabBar.standardAppearance = appearance
92
+ if #available(iOS 15.0, *) {
93
+ tabBar.scrollEdgeAppearance = appearance
94
+ }
95
+ }
96
+
97
+ func configure(items: [LiquidGlassTabItem], selectedIndex: Int, tintHex: String?, style: LiquidGlassTabBarStyle) {
67
98
  guard let tabBar else { return }
68
99
 
69
100
  // Preserve selection across re-configs (badge changes, etc.)
@@ -73,6 +104,9 @@ final class LiquidGlassTabBarOverlay: NSObject {
73
104
 
74
105
  self.items = items
75
106
 
107
+ // Re-aplica appearance por si el caller cambió de estilo en runtime.
108
+ applyAppearance(tabBar, style: style)
109
+
76
110
  let uiItems: [UITabBarItem] = items.enumerated().map { index, item in
77
111
  let tab = UITabBarItem(
78
112
  title: item.label,
@@ -108,12 +142,46 @@ final class LiquidGlassTabBarOverlay: NSObject {
108
142
  }
109
143
 
110
144
  func show() {
111
- tabBar?.isHidden = false
145
+ guard let tabBar = tabBar else { return }
146
+ // Si ya está visible, no hacer nada (evita flicker en re-show consecutivos)
147
+ if !tabBar.isHidden && tabBar.alpha == 1.0 { emitLayout(); return }
148
+ // Reset estado pre-animación
149
+ tabBar.isHidden = false
150
+ tabBar.alpha = 0
151
+ tabBar.transform = CGAffineTransform(translationX: 0, y: 20)
152
+ // Fade-in + slide-up (curva native iOS para apariciones)
153
+ UIView.animate(
154
+ withDuration: 0.28,
155
+ delay: 0,
156
+ usingSpringWithDamping: 0.85,
157
+ initialSpringVelocity: 0,
158
+ options: [.curveEaseOut, .allowUserInteraction],
159
+ animations: {
160
+ tabBar.alpha = 1
161
+ tabBar.transform = .identity
162
+ },
163
+ completion: nil
164
+ )
112
165
  emitLayout()
113
166
  }
114
167
 
115
168
  func hide() {
116
- tabBar?.isHidden = true
169
+ guard let tabBar = tabBar else { return }
170
+ if tabBar.isHidden { return }
171
+ // Fade-out + slide-down (más rápido que el show — el exit es snappy)
172
+ UIView.animate(
173
+ withDuration: 0.18,
174
+ delay: 0,
175
+ options: [.curveEaseIn, .allowUserInteraction],
176
+ animations: {
177
+ tabBar.alpha = 0
178
+ tabBar.transform = CGAffineTransform(translationX: 0, y: 20)
179
+ },
180
+ completion: { _ in
181
+ tabBar.isHidden = true
182
+ tabBar.transform = .identity
183
+ }
184
+ )
117
185
  }
118
186
 
119
187
  func setSelectedIndex(_ index: Int) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ajuarezso/capacitor-liquid-glass",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "iOS 26 Liquid Glass native chrome (TabBar, NavigationBar, Alerts, Sheets) for Capacitor apps. Falls back gracefully on iOS < 26 and Android.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",