@27appstudio/react-native-bottom-toolbar 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.
package/README.md CHANGED
@@ -5,10 +5,10 @@ The platform's own bottom toolbar for React Native screens:
5
5
  - **iOS**: UIKit's navigation-controller toolbar, so you get what the system draws. On iOS 26 that's Liquid Glass (a lone item becomes a glass circle, like the bin in Photos), and earlier versions get the classic toolbar. Your app follows each iOS redesign without changes.
6
6
  - **Android**: Material 3 components. One button shows as a FAB; two or more show as the M3 Expressive floating toolbar. Both sit above the navigation bar.
7
7
 
8
- | | iOS 26 | iOS 18 | Android |
9
- |---|---|---|---|
10
- | Several items | <img src="docs/images/ios26-several.png" width="220" alt="iOS 26: a glass plus button on the left, pencil and share grouped in a glass capsule on the right"> | <img src="docs/images/ios18-several.png" width="220" alt="iOS 18: plus on the left, pencil and share on the right of the classic toolbar"> | <img src="docs/images/android-several.png" width="220" alt="Android: plus, pencil and share in a Material 3 floating toolbar"> |
11
- | One item, red `tintColor` | <img src="docs/images/ios26-single.png" width="220" alt="iOS 26: a red bin in a glass circle"> | <img src="docs/images/ios18-single.png" width="220" alt="iOS 18: a red bin at the trailing edge of the toolbar"> | <img src="docs/images/android-single.png" width="220" alt="Android: a Material 3 FAB with a red bin icon"> |
8
+ | | iOS 26 | iOS 18 | Android |
9
+ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
10
+ | Several items | <img src="docs/images/ios26-several.png" width="220" alt="iOS 26: a glass plus button on the left, pencil and share grouped in a glass capsule on the right"> | <img src="docs/images/ios18-several.png" width="220" alt="iOS 18: plus on the left, pencil and share on the right of the classic toolbar"> | <img src="docs/images/android-several.png" width="220" alt="Android: plus, pencil and share in a Material 3 floating toolbar"> |
11
+ | One item, red `tintColor` | <img src="docs/images/ios26-single.png" width="220" alt="iOS 26: a red bin in a glass circle"> | <img src="docs/images/ios18-single.png" width="220" alt="iOS 18: a red bin at the trailing edge of the toolbar"> | <img src="docs/images/android-single.png" width="220" alt="Android: a Material 3 FAB with a red bin icon"> |
12
12
 
13
13
  It's a TurboModule with no views of its own in JS, no Expo modules, and no config plugin.
14
14
 
@@ -42,7 +42,9 @@ Requirements:
42
42
  ```tsx
43
43
  import { useBottomToolbar } from '@27appstudio/react-native-bottom-toolbar/react-navigation';
44
44
 
45
- function ExpenseScreen({ navigation }: NativeStackScreenProps<Params, 'Expense'>) {
45
+ function ExpenseScreen({
46
+ navigation,
47
+ }: NativeStackScreenProps<Params, 'Expense'>) {
46
48
  useBottomToolbar(navigation, [
47
49
  {
48
50
  id: 'delete',
@@ -67,7 +69,12 @@ show(
67
69
  [
68
70
  { id: 'add', systemImage: 'plus', androidIcon: 'ic_add', onPress: add },
69
71
  { type: 'flexibleSpace' },
70
- { id: 'share', systemImage: 'square.and.arrow.up', androidIcon: 'ic_share', onPress: share },
72
+ {
73
+ id: 'share',
74
+ systemImage: 'square.and.arrow.up',
75
+ androidIcon: 'ic_share',
76
+ onPress: share,
77
+ },
71
78
  ],
72
79
  { tintColor: '#0A7D6E' }
73
80
  );
@@ -83,13 +90,13 @@ On iOS, `show` targets the visible navigation controller's top screen, and waits
83
90
 
84
91
  Replaces the items of any toolbar already shown.
85
92
 
86
- | Item | Fields |
87
- |---|---|
88
- | Button (default) | `id` (required), `onPress`, `systemImage` (iOS SF Symbol), `androidIcon` (drawable name), `title` (used when there's no icon), `accessibilityLabel` (defaults to `title`), `disabled` |
89
- | `{ type: 'flexibleSpace' }` | iOS: pushes the items apart. Android: ignored. |
90
- | `{ type: 'fixedSpace', width? }` | iOS: a fixed gap; on iOS 26 it also splits glass groups. Android: ignored. |
93
+ | Item | Fields |
94
+ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
95
+ | Button (default) | `id` (required), `onPress`, `systemImage` (iOS SF Symbol), `androidIcon` (drawable name), `title` (used when there's no icon), `accessibilityLabel` (defaults to `title`), `disabled` |
96
+ | `{ type: 'flexibleSpace' }` | iOS: pushes the items apart. Android: ignored. |
97
+ | `{ type: 'fixedSpace', width? }` | iOS: a fixed gap; on iOS 26 it also splits glass groups. Android: ignored. |
91
98
 
92
- When `items` contains no space, iOS puts the buttons at the trailing edge.
99
+ When `items` contains no space, iOS puts the buttons at the trailing edge. When it contains no button at all (`[]` or spacers only), `show` hides the toolbar, as `hide()` does, so a screen can pass an empty array while it has nothing to offer.
93
100
 
94
101
  `options.tintColor` sets the icon and title color. iOS defaults to the navigation bar's tint (matching the header buttons); Android defaults to the Material 3 theme.
95
102
 
@@ -16,11 +16,19 @@ let buttons = [];
16
16
  * on top.
17
17
  * - Android: a Material 3 FAB for one button, a floating toolbar for more,
18
18
  * above the navigation bar. Spacers are ignored.
19
+ *
20
+ * Without any button (an empty array, or spacers only) it hides the toolbar, as
21
+ * `hide` does: on iOS an empty bar would still take the bottom band's touches and
22
+ * add its height to the scroll views' insets.
19
23
  */
20
24
  export function show(items, options = {}) {
21
25
  if (!NativeBottomToolbar) {
22
26
  return;
23
27
  }
28
+ if (!items.some(isButton)) {
29
+ hide();
30
+ return;
31
+ }
24
32
  buttons = items.filter(isButton);
25
33
  const tintColor = processColor(options.tintColor);
26
34
  NativeBottomToolbar.show(items.map(item => isButton(item) ? {
@@ -1 +1 @@
1
- {"version":3,"names":["processColor","NativeBottomToolbar","isAvailable","buttons","show","items","options","filter","isButton","tintColor","map","item","accessibilityLabel","title","onPress","undefined","type","hide","addPressListener","listener","subscription","onItemPress","remove","id","find","button"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAEA,SAASA,YAAY,QAAQ,cAAc;AAE3C,OAAOC,mBAAmB,MAAM,0BAAuB;AASvD;AACA,OAAO,MAAMC,WAAW,GAAGD,mBAAmB,IAAI,IAAI;AAEtD,IAAIE,OAAwB,GAAG,EAAE;;AAEjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,IAAIA,CAACC,KAAoB,EAAEC,OAAuB,GAAG,CAAC,CAAC,EAAE;EACvE,IAAI,CAACL,mBAAmB,EAAE;IACxB;EACF;EACAE,OAAO,GAAGE,KAAK,CAACE,MAAM,CAACC,QAAQ,CAAC;EAChC,MAAMC,SAAS,GAAGT,YAAY,CAACM,OAAO,CAACG,SAAS,CAAC;EACjDR,mBAAmB,CAACG,IAAI,CACtBC,KAAK,CAACK,GAAG,CAAEC,IAAI,IACbH,QAAQ,CAACG,IAAI,CAAC,GACV;IACE,GAAGA,IAAI;IACPC,kBAAkB,EAAED,IAAI,CAACC,kBAAkB,IAAID,IAAI,CAACE,KAAK;IACzDC,OAAO,EAAEC,SAAS;IAClBC,IAAI,EAAE;EACR,CAAC,GACDL,IACN,CAAC,EACD,OAAOF,SAAS,KAAK,QAAQ,GAAG;IAAEA;EAAU,CAAC,GAAG,CAAC,CACnD,CAAC;AACH;;AAEA;AACA,OAAO,SAASQ,IAAIA,CAAA,EAAG;EACrBd,OAAO,GAAG,EAAE;EACZF,mBAAmB,EAAEgB,IAAI,CAAC,CAAC;AAC7B;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASC,gBAAgBA,CAACC,QAA8B,EAAE;EAC/D,MAAMC,YAAY,GAAGnB,mBAAmB,EAAEoB,WAAW,CAACF,QAAQ,CAAC;EAC/D,OAAO,MAAMC,YAAY,EAAEE,MAAM,CAAC,CAAC;AACrC;AAEA,SAASd,QAAQA,CAACG,IAAiB,EAAyB;EAC1D,OAAOA,IAAI,CAACK,IAAI,KAAKD,SAAS,IAAIJ,IAAI,CAACK,IAAI,KAAK,QAAQ;AAC1D;AAEAf,mBAAmB,EAAEoB,WAAW,CAAEE,EAAE,IAClCpB,OAAO,CAACqB,IAAI,CAAEC,MAAM,IAAKA,MAAM,CAACF,EAAE,KAAKA,EAAE,CAAC,EAAET,OAAO,GAAG,CACxD,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["processColor","NativeBottomToolbar","isAvailable","buttons","show","items","options","some","isButton","hide","filter","tintColor","map","item","accessibilityLabel","title","onPress","undefined","type","addPressListener","listener","subscription","onItemPress","remove","id","find","button"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAEA,SAASA,YAAY,QAAQ,cAAc;AAE3C,OAAOC,mBAAmB,MAAM,0BAAuB;AASvD;AACA,OAAO,MAAMC,WAAW,GAAGD,mBAAmB,IAAI,IAAI;AAEtD,IAAIE,OAAwB,GAAG,EAAE;;AAEjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,IAAIA,CAACC,KAAoB,EAAEC,OAAuB,GAAG,CAAC,CAAC,EAAE;EACvE,IAAI,CAACL,mBAAmB,EAAE;IACxB;EACF;EACA,IAAI,CAACI,KAAK,CAACE,IAAI,CAACC,QAAQ,CAAC,EAAE;IACzBC,IAAI,CAAC,CAAC;IACN;EACF;EACAN,OAAO,GAAGE,KAAK,CAACK,MAAM,CAACF,QAAQ,CAAC;EAChC,MAAMG,SAAS,GAAGX,YAAY,CAACM,OAAO,CAACK,SAAS,CAAC;EACjDV,mBAAmB,CAACG,IAAI,CACtBC,KAAK,CAACO,GAAG,CAAEC,IAAI,IACbL,QAAQ,CAACK,IAAI,CAAC,GACV;IACE,GAAGA,IAAI;IACPC,kBAAkB,EAAED,IAAI,CAACC,kBAAkB,IAAID,IAAI,CAACE,KAAK;IACzDC,OAAO,EAAEC,SAAS;IAClBC,IAAI,EAAE;EACR,CAAC,GACDL,IACN,CAAC,EACD,OAAOF,SAAS,KAAK,QAAQ,GAAG;IAAEA;EAAU,CAAC,GAAG,CAAC,CACnD,CAAC;AACH;;AAEA;AACA,OAAO,SAASF,IAAIA,CAAA,EAAG;EACrBN,OAAO,GAAG,EAAE;EACZF,mBAAmB,EAAEQ,IAAI,CAAC,CAAC;AAC7B;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASU,gBAAgBA,CAACC,QAA8B,EAAE;EAC/D,MAAMC,YAAY,GAAGpB,mBAAmB,EAAEqB,WAAW,CAACF,QAAQ,CAAC;EAC/D,OAAO,MAAMC,YAAY,EAAEE,MAAM,CAAC,CAAC;AACrC;AAEA,SAASf,QAAQA,CAACK,IAAiB,EAAyB;EAC1D,OAAOA,IAAI,CAACK,IAAI,KAAKD,SAAS,IAAIJ,IAAI,CAACK,IAAI,KAAK,QAAQ;AAC1D;AAEAjB,mBAAmB,EAAEqB,WAAW,CAAEE,EAAE,IAClCrB,OAAO,CAACsB,IAAI,CAAEC,MAAM,IAAKA,MAAM,CAACF,EAAE,KAAKA,EAAE,CAAC,EAAER,OAAO,GAAG,CACxD,CAAC","ignoreList":[]}
@@ -12,6 +12,10 @@ export declare const isAvailable: boolean;
12
12
  * on top.
13
13
  * - Android: a Material 3 FAB for one button, a floating toolbar for more,
14
14
  * above the navigation bar. Spacers are ignored.
15
+ *
16
+ * Without any button (an empty array, or spacers only) it hides the toolbar, as
17
+ * `hide` does: on iOS an empty bar would still take the bottom band's touches and
18
+ * add its height to the scroll views' insets.
15
19
  */
16
20
  export declare function show(items: ToolbarItem[], options?: ToolbarOptions): void;
17
21
  /** Hides the toolbar. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,WAAW,EAAE,cAAc,EAAE,MAAM,YAAS,CAAC;AAM1E,YAAY,EACV,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,GACb,MAAM,YAAS,CAAC;AAEjB,iFAAiF;AACjF,eAAO,MAAM,WAAW,SAA8B,CAAC;AAIvD;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,OAAO,GAAE,cAAmB,QAmBtE;AAED,yBAAyB;AACzB,wBAAgB,IAAI,SAGnB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,0BAG9D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,WAAW,EAAE,cAAc,EAAE,MAAM,YAAS,CAAC;AAM1E,YAAY,EACV,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,GACb,MAAM,YAAS,CAAC;AAEjB,iFAAiF;AACjF,eAAO,MAAM,WAAW,SAA8B,CAAC;AAIvD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,OAAO,GAAE,cAAmB,QAuBtE;AAED,yBAAyB;AACzB,wBAAgB,IAAI,SAGnB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,0BAG9D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@27appstudio/react-native-bottom-toolbar",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Native bottom toolbar for React Native: UIKit's toolbar on iOS (Liquid Glass on iOS 26) and a Material 3 floating toolbar on Android.",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -154,10 +154,10 @@
154
154
  "tagName": "v${version}"
155
155
  },
156
156
  "npm": {
157
- "publish": true
157
+ "publish": false
158
158
  },
159
159
  "github": {
160
- "release": true
160
+ "release": false
161
161
  },
162
162
  "plugins": {
163
163
  "@release-it/conventional-changelog": {
package/src/index.tsx CHANGED
@@ -26,11 +26,19 @@ let buttons: ToolbarButton[] = [];
26
26
  * on top.
27
27
  * - Android: a Material 3 FAB for one button, a floating toolbar for more,
28
28
  * above the navigation bar. Spacers are ignored.
29
+ *
30
+ * Without any button (an empty array, or spacers only) it hides the toolbar, as
31
+ * `hide` does: on iOS an empty bar would still take the bottom band's touches and
32
+ * add its height to the scroll views' insets.
29
33
  */
30
34
  export function show(items: ToolbarItem[], options: ToolbarOptions = {}) {
31
35
  if (!NativeBottomToolbar) {
32
36
  return;
33
37
  }
38
+ if (!items.some(isButton)) {
39
+ hide();
40
+ return;
41
+ }
34
42
  buttons = items.filter(isButton);
35
43
  const tintColor = processColor(options.tintColor);
36
44
  NativeBottomToolbar.show(