react-native-magic-tab-bar 1.0.1 → 2.0.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.
package/README.md CHANGED
@@ -1,25 +1,53 @@
1
1
  # react-native-magic-tab-bar
2
2
 
3
- A customizable, animated floating tab bar for **Expo Router** (SDK 56+). You bring
4
- your own icons and labels — the package handles the layout, the active-pill
5
- animation, and the navigation wiring.
6
-
7
- > Built on Expo Router's headless tabs (`expo-router/ui`). It works in any
8
- > Expo Router project on iOS and Android. (Bare React Native / React Navigation
9
- > is not supported yet see [Roadmap](#roadmap).)
3
+ A customizable, animated **floating tab bar for [Expo Router](https://docs.expo.dev/router/introduction/)** (SDK 56+). You bring your own icons and labels — the package handles the layout, the active-pill animation, and the navigation wiring.
4
+
5
+ > Built on Expo Router's headless tabs (`expo-router/ui`). Works in any Expo Router project on **iOS and Android**. (Bare React Native / React Navigation is not supported yet — see [Roadmap](#roadmap).)
6
+
7
+ ## Features
8
+
9
+ - 🎯 **Drop-in** replaces your Expo Router tabs layout; bring your own icons.
10
+ - ✨ **Animated active pill** with a spring you can tune.
11
+ - 🏷️ **Flexible labels** — beside or below the icon; show on the active tab, always, or never.
12
+ - 🔴 **Badges** — dots or counts on any tab.
13
+ - 🧊 **Glass / blur / transparent** backgrounds (native iOS Liquid Glass supported).
14
+ - 📳 **Haptics** and **press callbacks** (great for "scroll to top" on re-press).
15
+ - ➕ **Action (FAB) tab** for a raised center button.
16
+ - 🪶 **Light mode** — a compact, icon-only bar you can switch on **per tab** (e.g. only on an immersive full-screen feed), with a smooth transition.
17
+ - 🎨 **Fully themeable** via a single `theme` prop.
18
+
19
+ ## Table of contents
20
+
21
+ - [Installation](#installation)
22
+ - [Quick start](#quick-start)
23
+ - [Recipes](#recipes)
24
+ - [Labels](#labels)
25
+ - [Badges](#badges)
26
+ - [Haptics and press callbacks](#haptics-and-press-callbacks)
27
+ - [Disabled tabs](#disabled-tabs)
28
+ - [Action (FAB) tab](#action-fab-tab)
29
+ - [Glass, blur and transparency](#glass-blur-and-transparency)
30
+ - [Light mode](#light-mode-compact-bar)
31
+ - [Theming](#theming)
32
+ - [API](#api)
33
+ - [Development](#development)
34
+ - [Roadmap](#roadmap)
35
+ - [License](#license)
10
36
 
11
37
  ## Screenshots
12
38
 
13
39
  <p align="center">
14
- <img src="https://raw.githubusercontent.com/Bhavinpethani04/react-native-magic-tab-bar/main/assets/screenshots/ios.png" alt="MagicTabs on iOS" width="280" />
40
+ <img src="https://raw.githubusercontent.com/Bhavinpethani04/react-native-magic-tab-bar/main/assets/gifs/ios.gif" alt="MagicTabs on iOS" width="280" />
15
41
  &nbsp;&nbsp;&nbsp;
16
- <img src="https://raw.githubusercontent.com/Bhavinpethani04/react-native-magic-tab-bar/main/assets/screenshots/android.png" alt="MagicTabs on Android" width="280" />
42
+ <img src="https://raw.githubusercontent.com/Bhavinpethani04/react-native-magic-tab-bar/main/assets/gifs/android.gif" alt="MagicTabs on Android" width="280" />
17
43
  </p>
18
44
 
19
45
  <p align="center"><sub>iOS (left) &middot; Android (right)</sub></p>
20
46
 
21
47
  ## Installation
22
48
 
49
+ > **Requirements:** an [Expo Router](https://docs.expo.dev/router/introduction/) project (Expo SDK 56+) with an `app/` directory. Works on iOS & Android.
50
+
23
51
  ```bash
24
52
  npm install react-native-magic-tab-bar
25
53
  ```
@@ -32,79 +60,248 @@ These are normally already present in an Expo Router app:
32
60
  npx expo install expo-router react-native-reanimated react-native-safe-area-context react-native-worklets
33
61
  ```
34
62
 
35
- Make sure the Reanimated/Worklets Babel plugin is enabled (Expo SDK 56's
36
- `babel-preset-expo` configures this automatically).
63
+ Make sure the Reanimated/Worklets Babel plugin is enabled (Expo SDK 56's `babel-preset-expo` configures this automatically).
64
+
65
+ ### Optional dependencies
66
+
67
+ Install these only if you use the matching feature — the library works without them:
37
68
 
38
- ## Usage
69
+ ```bash
70
+ npx expo install expo-glass-effect # native iOS Liquid Glass (glass prop)
71
+ npx expo install expo-haptics # selection haptics (haptics prop)
72
+ npx expo install @expo/vector-icons # only for the /default-tabs demo set
73
+ ```
39
74
 
40
- Use `MagicTabs` as your tab navigator in an `app/_layout.tsx`. Each entry in
41
- `tabs` maps a route to an icon and label:
75
+ ## Quick start
76
+
77
+ Use `MagicTabs` as your tab navigator in `app/_layout.tsx`. Each entry in `tabs` maps a route to an icon and label:
42
78
 
43
79
  ```tsx
44
80
  // app/_layout.tsx
45
- import { MagicTabs, type MagicTabIconProps } from "react-native-magic-tab-bar";
46
- import { Home, Search, User } from "./icons"; // any icon components you like
81
+ import { MagicTabs } from "react-native-magic-tab-bar";
82
+ import { Ionicons } from "@expo/vector-icons";
47
83
 
48
84
  export default function Layout() {
49
85
  return (
50
86
  <MagicTabs
51
87
  tabs={[
52
- { name: "index", href: "/", label: "Home", icon: ({ color, size }) => <Home color={color} size={size} /> },
53
- { name: "search", href: "/search", label: "Search", icon: ({ color, size }) => <Search color={color} size={size} /> },
54
- { name: "profile", href: "/profile", label: "Profile", icon: ({ color, size }) => <User color={color} size={size} /> },
88
+ { name: "index", href: "/", label: "Home", icon: ({ color, size }) => <Ionicons name="home" color={color} size={size} /> },
89
+ { name: "search", href: "/search", label: "Search", icon: ({ color, size }) => <Ionicons name="search" color={color} size={size} /> },
90
+ { name: "profile", href: "/profile", label: "Profile", icon: ({ color, size }) => <Ionicons name="person" color={color} size={size} /> },
55
91
  ]}
56
92
  />
57
93
  );
58
94
  }
59
95
  ```
60
96
 
61
- The `name` must match the route file in your `app/` directory (e.g. `index`,
62
- `search`, `profile`), and `href` is where the tab navigates.
97
+ - `name` must match the route file in your `app/` directory (e.g. `index`, `search`, `profile`).
98
+ - `href` is where the tab navigates.
99
+ - `icon` receives `{ focused, color, size }` so you can swap glyphs/colors for the active state.
100
+
101
+ > `MagicTabs` renders Expo Router's `<Tabs>` for you — put it straight in `app/_layout.tsx`. There's no separate `<Tabs>` wrapper to set up.
102
+
103
+ **Tip — filled vs. outline icons:** use `focused` to swap the glyph on the active tab:
104
+
105
+ ```tsx
106
+ icon: ({ focused, color, size }) => (
107
+ <Ionicons name={focused ? "home" : "home-outline"} color={color} size={size} />
108
+ );
109
+ ```
110
+
111
+ > **Want a ready-made set for a quick look?** Import the demo tabs from the subpath (this is the only thing that pulls in `@expo/vector-icons`, so the core stays dependency-free):
112
+ >
113
+ > ```tsx
114
+ > import { defaultTabs } from "react-native-magic-tab-bar/default-tabs";
115
+ >
116
+ > <MagicTabs tabs={defaultTabs} />;
117
+ > ```
118
+
119
+ ## Recipes
63
120
 
64
- ### The glass / blur look
121
+ ### Labels
65
122
 
66
- Pass `renderBackground` to render any view behind the bar e.g. a blur:
123
+ Labels are **beside** the icon by default (`labelPosition="right"`), shown only on the **active** tab.
67
124
 
68
125
  ```tsx
69
- import { GlassView } from "expo-glass-effect"; // or @react-native-community/blur on bare RN
126
+ <MagicTabs tabs={tabs} labelPosition="bottom" showLabels="always" /> // Material-style bar
127
+ <MagicTabs tabs={tabs} showLabels={false} /> // icon-only bar
128
+ ```
129
+
130
+ | `showLabels` | Effect |
131
+ | --- | --- |
132
+ | `true` / `"active"` | Label on the focused tab only *(default)* |
133
+ | `"always"` | Label on every tab *(requires `labelPosition="bottom"`)* |
134
+ | `false` / `"never"` | Icon-only |
70
135
 
136
+ `labelPosition` is `"right"` (default) or `"bottom"`. You can also override visibility per tab with `showLabel` on the tab config.
137
+
138
+ ### Badges
139
+
140
+ ```tsx
141
+ { name: "inbox", href: "/inbox", label: "Inbox", badge: 5, icon }, // count bubble
142
+ { name: "alerts", href: "/alerts", label: "Alerts", badge: true, icon }, // dot
143
+ ```
144
+
145
+ `badge` accepts a `number`, `string`, or `boolean` (`true` = dot). Numbers above 99 show as `99+`. Colors come from `theme.badgeColor` / `theme.badgeTextColor`.
146
+
147
+ ### Haptics and press callbacks
148
+
149
+ ```tsx
71
150
  <MagicTabs
72
151
  tabs={tabs}
73
- renderBackground={() => <GlassView style={{ flex: 1 }} />}
74
- />;
152
+ haptics // selection haptic on tap (needs expo-haptics)
153
+ onTabPress={(name, focused) => {
154
+ if (focused) scrollToTop(name); // re-pressing the active tab
155
+ }}
156
+ />
75
157
  ```
76
158
 
77
- When `renderBackground` is omitted, a solid `barColor` is used.
159
+ `onTabPress` / `onTabLongPress` receive `(name, focused)`, where `focused` tells you the tab was **already** active — perfect for scroll-to-top or reset-stack behavior.
160
+
161
+ ### Disabled tabs
162
+
163
+ ```tsx
164
+ { name: "soon", href: "/soon", label: "Soon", disabled: true, icon }
165
+ ```
166
+
167
+ Dims the tab and blocks navigation to it.
168
+
169
+ ### Action (FAB) tab
170
+
171
+ Render a raised, circular center button:
172
+
173
+ ```tsx
174
+ { name: "create", href: "/create", variant: "action", icon }
175
+ ```
176
+
177
+ Uses `theme.actionColor` / `theme.actionIconColor`.
178
+
179
+ ### Glass, blur and transparency
180
+
181
+ ```tsx
182
+ <MagicTabs tabs={tabs} glass /> // native iOS Liquid Glass (iOS 26+)
183
+ <MagicTabs tabs={tabs} isTransparent transparency={0.4} />// translucent bar
184
+ <MagicTabs tabs={tabs} renderBackground={() => <MyBlurView />} /> // any custom background
185
+ ```
186
+
187
+ - `glass` uses `expo-glass-effect` on iOS 26+ and falls back to the translucent `barColor` elsewhere.
188
+ - `renderBackground` renders any view behind the bar; when omitted, a solid `barColor` is used.
189
+
190
+ ### Light mode (compact bar)
191
+
192
+ A shorter, **icon-only** bar (65% width, floating higher). Turn it on for the whole bar, or **per tab** so it only appears on an immersive screen:
193
+
194
+ ```tsx
195
+ // Whole bar
196
+ <MagicTabs tabs={tabs} isLight lightBottomMargin={40} />
197
+
198
+ // Per tab — the bar morphs to light only while "explore" is the active route
199
+ <MagicTabs
200
+ tabs={[
201
+ { name: "index", href: "/", label: "Home", icon },
202
+ { name: "explore", href: "/explore", label: "Explore", icon, isLight: true },
203
+ { name: "profile", href: "/profile", label: "Profile", icon },
204
+ ]}
205
+ />
206
+ ```
207
+
208
+ The transition between the normal and light bar is animated. `lightBottomMargin` (default `14`) controls the extra gap above the screen edge in light mode.
209
+
210
+ ### Theming
211
+
212
+ Everything visual — colors, sizes, corner radius, the animation spring — lives in one `theme` prop. Override any subset; the rest falls back to `defaultTheme`.
213
+
214
+ **The colors that matter most:**
215
+
216
+ | Token | Controls |
217
+ | --- | --- |
218
+ | `barColor` | the bar's background |
219
+ | `activePillColor` | the pill highlight behind the **active** tab |
220
+ | `activeColor` | the active tab's icon + label |
221
+ | `inactiveColor` | the icons of **inactive** tabs |
222
+ | `badgeColor` / `badgeTextColor` | the badge bubble + its text |
223
+ | `actionColor` / `actionIconColor` | the [action (FAB) tab](#action-fab-tab) |
224
+
225
+ ```tsx
226
+ <MagicTabs
227
+ tabs={tabs}
228
+ theme={{
229
+ barColor: "#17171C", // dark bar
230
+ activePillColor: "#2563EB", // blue highlight behind the active tab
231
+ activeColor: "#FFFFFF", // active icon/label
232
+ inactiveColor: "#9BA0AA", // inactive icons
233
+ radius: 24, // rounder bar & pill
234
+ spring: { mass: 0.6, damping: 16, stiffness: 200 }, // snappier animation
235
+ }}
236
+ />
237
+ ```
238
+
239
+ See the [full token list with defaults](#magictabbartheme) for sizes (`iconSize`, `height`, `fontSize`), spacing (`horizontalMargin`, `bottomInset`) and more.
78
240
 
79
241
  ## API
80
242
 
81
243
  ### `<MagicTabs />`
82
244
 
83
- | Prop | Type | Default | Description |
84
- | ------------------ | --------------------------------- | ------------ | ------------------------------------------------- |
85
- | `tabs` | `MagicTabConfig[]` | | The tabs, in order. |
86
- | `theme` | `Partial<MagicTabBarTheme>` | `defaultTheme` | Override any visual token. |
87
- | `variant` | `'floating' \| 'docked'` | `'floating'` | Float over content, or dock in flow. |
88
- | `renderBackground` | `() => ReactNode` | | Custom background (blur/glass) behind the bar. |
245
+ | Prop | Type | Default | Description |
246
+ | --- | --- | --- | --- |
247
+ | `tabs` | `MagicTabConfig[]` | **required** | The tabs, in order. |
248
+ | `theme` | `Partial<MagicTabBarTheme>` | `defaultTheme` | Override any visual token. |
249
+ | `showLabels` | `boolean \| 'active' \| 'always' \| 'never'` | `'active'` | When labels are shown. `'always'` needs `labelPosition="bottom"`. |
250
+ | `labelPosition` | `'right' \| 'bottom'` | `'right'` | Label beside or below the icon. |
251
+ | `variant` | `'floating' \| 'docked'` | `'floating'` | Float over content, or dock in flow. |
252
+ | `isLight` | `boolean` | `false` | Force the compact light bar for all tabs. |
253
+ | `lightBottomMargin` | `number` | `14` | Extra bottom gap in light mode only. |
254
+ | `isTransparent` | `boolean` | `false` | Make the bar background see-through. |
255
+ | `transparency` | `number` | `0.6` | Bar opacity `0–1` while `isTransparent`. |
256
+ | `glass` | `boolean` | `false` | Native iOS Liquid Glass (needs `expo-glass-effect`). |
257
+ | `renderBackground` | `() => ReactNode` | — | Custom background (blur/glass) behind the bar. |
258
+ | `haptics` | `boolean` | `false` | Selection haptic on press (needs `expo-haptics`). |
259
+ | `onTabPress` | `(name, focused) => void` | — | Fired on tab press. |
260
+ | `onTabLongPress` | `(name, focused) => void` | — | Fired on tab long-press. |
89
261
 
90
262
  ### `MagicTabConfig`
91
263
 
92
- | Field | Type | Description |
93
- | ------- | ------------------------------------------ | --------------------------------------------- |
94
- | `name` | `string` | Route name (matches the file in `app/`). |
95
- | `href` | `Href` | Destination, e.g. `/` or `/search`. |
96
- | `label` | `string?` | Shown next to the icon while active. |
97
- | `icon` | `(p: MagicTabIconProps) => ReactNode` | Renders the icon. Gets `{ focused, color, size }`. |
98
-
99
- ### Theming (`MagicTabBarTheme`)
100
-
101
- `barColor`, `activePillColor`, `activeColor`, `inactiveColor`, `iconSize`,
102
- `height`, `radius`, `horizontalMargin`, `bottomInset`. See `defaultTheme`.
264
+ | Field | Type | Description |
265
+ | --- | --- | --- |
266
+ | `name` | `string` | Route name (matches the file in `app/`). |
267
+ | `href` | `Href` | Destination, e.g. `/` or `/search`. |
268
+ | `icon` | `(p: MagicTabIconProps) => ReactNode` | Renders the icon. Gets `{ focused, color, size }`. |
269
+ | `label` | `string?` | Text label. |
270
+ | `showLabel` | `boolean?` | Per-tab override of `showLabels`. |
271
+ | `badge` | `number \| string \| boolean?` | Dot (`true`) or count bubble. |
272
+ | `disabled` | `boolean?` | Dim the tab and block navigation. |
273
+ | `variant` | `'action'?` | Render as a raised FAB button. |
274
+ | `isLight` | `boolean?` | Switch the whole bar to light mode while this tab is active. |
275
+
276
+ ### `MagicTabBarTheme`
277
+
278
+ | Token | Default | |
279
+ | --- | --- | --- |
280
+ | `barColor` | `rgba(38,38,40,0.94)` | Bar background |
281
+ | `activePillColor` | `rgba(120,120,124,0.55)` | Active-tab pill |
282
+ | `activeColor` | `#FFFFFF` | Active icon/label color |
283
+ | `inactiveColor` | `#FFFFFF` | Inactive icon color |
284
+ | `iconSize` | `22` | Icon size |
285
+ | `fontSize` | `12` | Active label size |
286
+ | `height` | `56` | Bar height |
287
+ | `radius` | `28` | Bar & pill corner radius |
288
+ | `badgeColor` | `#FF3B30` | Badge background |
289
+ | `badgeTextColor` | `#FFFFFF` | Badge text |
290
+ | `actionColor` | `#0A84FF` | Action (FAB) background |
291
+ | `actionIconColor` | `#FFFFFF` | Action (FAB) icon |
292
+ | `horizontalMargin` | `14` | Side margin from screen edges |
293
+ | `bottomInset` | `10` | Extra space below the bar |
294
+ | `spring` | `{ mass: 0.6, damping: 18, stiffness: 180 }` | Pill/label animation |
295
+
296
+ ### Exported types
297
+
298
+ `MagicTabConfig`, `MagicTabIconProps`, `MagicTabBarTheme`, `MagicTabBarVariant`, `MagicTabPressHandler`, `MagicLabelMode`, `MagicLabelPosition`, `MagicSpringConfig`, plus the `defaultTheme` value.
299
+
300
+ > `defaultTabs` is exported from the `react-native-magic-tab-bar/default-tabs` subpath (not the main entry), so the core adds **zero runtime dependencies**.
103
301
 
104
302
  ## Development
105
303
 
106
- This repo is a monorepo: the library lives at the root (`src/`) and `example/`
107
- is a runnable Expo app that imports the library straight from source.
304
+ This repo is a monorepo: the library lives at the root (`src/`) and `example/` is a runnable Expo app that imports the library straight from source.
108
305
 
109
306
  ```bash
110
307
  # from the repo root
@@ -116,6 +313,8 @@ Editing files in `src/` hot-reloads in the example app.
116
313
 
117
314
  ### Building / publishing
118
315
 
316
+ > Publishing is restricted to package maintainers.
317
+
119
318
  ```bash
120
319
  npm run build # react-native-builder-bob -> lib/ (ESM + d.ts)
121
320
  npm publish
@@ -2,8 +2,23 @@
2
2
 
3
3
  import { forwardRef } from "react";
4
4
  import { StyleSheet, View } from "react-native";
5
+ import Animated, { LinearTransition } from "react-native-reanimated";
5
6
  import { useSafeAreaInsets } from "react-native-safe-area-context";
6
7
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
+ /**
9
+ * Layout transition used to morph the bar between its normal and compact
10
+ * "light" shapes (width, height and bottom margin) when the active tab changes.
11
+ */
12
+ const barTransition = LinearTransition.springify().mass(0.5).damping(16).stiffness(160);
13
+
14
+ /** Extra bar height when labels sit below icons, so they have room to breathe. */
15
+ const BOTTOM_LABEL_EXTRA_HEIGHT = 6;
16
+
17
+ /** Fixed height of the compact "light" bar. */
18
+ const LIGHT_BAR_HEIGHT = 46;
19
+
20
+ /** Default extra bottom margin added below the bar in "light" mode. */
21
+ const LIGHT_EXTRA_BOTTOM_MARGIN = 14;
7
22
  /**
8
23
  * `expo-glass-effect` is an optional peer dependency. We load it through a
9
24
  * guarded `require` so the library still installs and runs for consumers who
@@ -28,16 +43,25 @@ export const MIN_BAR_OPACITY = 0.1;
28
43
  export const MagicTabBar = /*#__PURE__*/forwardRef(function MagicTabBar({
29
44
  theme,
30
45
  variant = "floating",
46
+ labelPosition = "right",
31
47
  isTransparent = false,
32
48
  transparency = 0.6,
33
49
  glass = false,
34
50
  renderBackground,
51
+ isLight = false,
52
+ lightBottomMargin = LIGHT_EXTRA_BOTTOM_MARGIN,
35
53
  children,
36
54
  style,
37
55
  ...rest
38
56
  }, ref) {
39
57
  const insets = useSafeAreaInsets();
40
58
  const floating = variant !== "docked";
59
+ // "Light" mode is a fixed, compact height. Otherwise stacked (bottom) labels
60
+ // need more vertical room than the icon-only / side-by-side layouts, so the
61
+ // bar grows a little in that mode.
62
+ const barHeight = isLight ? LIGHT_BAR_HEIGHT : labelPosition === "bottom" ? theme.height + BOTTOM_LABEL_EXTRA_HEIGHT : theme.height;
63
+ // "Light" mode floats a little higher off the bottom edge.
64
+ const extraBottomMargin = isLight ? lightBottomMargin : 0;
41
65
  // Native Liquid Glass needs the optional `expo-glass-effect` dep and iOS
42
66
  // 26+; everywhere else we fall back to the translucent color background.
43
67
  const useGlass = glass && !!glassEffect?.isLiquidGlassAvailable();
@@ -50,13 +74,17 @@ export const MagicTabBar = /*#__PURE__*/forwardRef(function MagicTabBar({
50
74
  return /*#__PURE__*/_jsx(View, {
51
75
  ref: ref,
52
76
  pointerEvents: "box-none",
53
- style: [floating ? styles.floatingWrapper : styles.dockedWrapper, {
54
- paddingHorizontal: theme.horizontalMargin,
55
- paddingBottom: (floating ? insets.bottom : 0) + theme.bottomInset
77
+ style: [floating ? styles.floatingWrapper : styles.dockedWrapper,
78
+ // Light mode centers a narrower bar; drop the side padding so the
79
+ // bar's width is measured against the full screen width.
80
+ isLight && styles.lightWrapper, {
81
+ paddingHorizontal: isLight ? 0 : theme.horizontalMargin,
82
+ paddingBottom: (floating ? insets.bottom : 0) + theme.bottomInset + extraBottomMargin
56
83
  }],
57
- children: /*#__PURE__*/_jsxs(View, {
58
- style: [styles.bar, !seeThrough && styles.barShadow, {
59
- height: theme.height,
84
+ children: /*#__PURE__*/_jsxs(Animated.View, {
85
+ layout: barTransition,
86
+ style: [styles.bar, !seeThrough && styles.barShadow, isLight && styles.lightBar, {
87
+ height: barHeight,
60
88
  borderRadius: theme.radius
61
89
  }],
62
90
  children: [renderBackground ? /*#__PURE__*/_jsx(View, {
@@ -89,7 +117,7 @@ export const MagicTabBar = /*#__PURE__*/forwardRef(function MagicTabBar({
89
117
  opacity: barOpacity
90
118
  }]
91
119
  }), /*#__PURE__*/_jsx(View, {
92
- style: [styles.row, style],
120
+ style: [isLight ? styles.lightRow : styles.row, style],
93
121
  ...rest,
94
122
  children: children
95
123
  })]
@@ -109,6 +137,13 @@ const styles = StyleSheet.create({
109
137
  bar: {
110
138
  flexDirection: "row"
111
139
  },
140
+ // Light mode: a narrower bar (65% of screen width) centered by its wrapper.
141
+ lightWrapper: {
142
+ alignItems: "center"
143
+ },
144
+ lightBar: {
145
+ width: "65%"
146
+ },
112
147
  barShadow: {
113
148
  shadowColor: "#000",
114
149
  shadowOpacity: 0.25,
@@ -125,6 +160,14 @@ const styles = StyleSheet.create({
125
160
  alignItems: "center",
126
161
  justifyContent: "space-around",
127
162
  paddingHorizontal: 6
163
+ },
164
+ // Compact "light" row: tighter horizontal padding around the small icons.
165
+ lightRow: {
166
+ flex: 1,
167
+ flexDirection: "row",
168
+ alignItems: "center",
169
+ justifyContent: "space-around",
170
+ paddingHorizontal: 10
128
171
  }
129
172
  });
130
173
  //# sourceMappingURL=MagicTabBar.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["forwardRef","StyleSheet","View","useSafeAreaInsets","jsx","_jsx","jsxs","_jsxs","glassEffect","require","MIN_BAR_OPACITY","MagicTabBar","theme","variant","isTransparent","transparency","glass","renderBackground","children","style","rest","ref","insets","floating","useGlass","isLiquidGlassAvailable","barOpacity","Math","min","max","seeThrough","pointerEvents","styles","floatingWrapper","dockedWrapper","paddingHorizontal","horizontalMargin","paddingBottom","bottom","bottomInset","bar","barShadow","height","borderRadius","radius","absoluteFill","overflow","GlassView","glassEffectStyle","tintColor","barColor","backgroundColor","opacity","row","create","position","left","right","width","flexDirection","shadowColor","shadowOpacity","shadowRadius","shadowOffset","elevation","flex","alignItems","justifyContent"],"sourceRoot":"../../src","sources":["MagicTabBar.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["forwardRef","StyleSheet","View","Animated","LinearTransition","useSafeAreaInsets","jsx","_jsx","jsxs","_jsxs","barTransition","springify","mass","damping","stiffness","BOTTOM_LABEL_EXTRA_HEIGHT","LIGHT_BAR_HEIGHT","LIGHT_EXTRA_BOTTOM_MARGIN","glassEffect","require","MIN_BAR_OPACITY","MagicTabBar","theme","variant","labelPosition","isTransparent","transparency","glass","renderBackground","isLight","lightBottomMargin","children","style","rest","ref","insets","floating","barHeight","height","extraBottomMargin","useGlass","isLiquidGlassAvailable","barOpacity","Math","min","max","seeThrough","pointerEvents","styles","floatingWrapper","dockedWrapper","lightWrapper","paddingHorizontal","horizontalMargin","paddingBottom","bottom","bottomInset","layout","bar","barShadow","lightBar","borderRadius","radius","absoluteFill","overflow","GlassView","glassEffectStyle","tintColor","barColor","backgroundColor","opacity","lightRow","row","create","position","left","right","width","flexDirection","alignItems","shadowColor","shadowOpacity","shadowRadius","shadowOffset","elevation","flex","justifyContent"],"sourceRoot":"../../src","sources":["MagicTabBar.tsx"],"mappings":"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","ignoreList":[]}