@honeypathkar/react-native-lq-bottom-bar 0.0.0-stage → 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.
Files changed (34) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +349 -2
  3. package/android/build.gradle +78 -0
  4. package/android/src/main/AndroidManifest.xml +1 -0
  5. package/android/src/main/java/com/honeypathkar/lqbottombar/BackdropBlur.kt +428 -0
  6. package/android/src/main/java/com/honeypathkar/lqbottombar/LQBottomBarPackage.kt +34 -0
  7. package/android/src/main/java/com/honeypathkar/lqbottombar/LQBottomBarView.kt +503 -0
  8. package/android/src/main/java/com/honeypathkar/lqbottombar/LQBottomBarViewManager.kt +119 -0
  9. package/android/src/main/java/com/honeypathkar/lqbottombar/TabSelectedEvent.kt +30 -0
  10. package/ios/LQBottomBarView.swift +328 -0
  11. package/ios/LQBottomBarViewManager.m +21 -0
  12. package/ios/LQBottomBarViewManager.swift +36 -0
  13. package/lib/commonjs/NativeBottomBar.d.ts +33 -0
  14. package/lib/commonjs/NativeBottomBar.d.ts.map +1 -0
  15. package/lib/commonjs/NativeBottomBar.js +9 -0
  16. package/lib/commonjs/NativeBottomBar.js.map +1 -0
  17. package/lib/commonjs/index.d.ts +6 -0
  18. package/lib/commonjs/index.d.ts.map +1 -0
  19. package/lib/commonjs/index.js +131 -0
  20. package/lib/commonjs/index.js.map +1 -0
  21. package/lib/commonjs/rasterise.d.ts +20 -0
  22. package/lib/commonjs/rasterise.d.ts.map +1 -0
  23. package/lib/commonjs/rasterise.js +398 -0
  24. package/lib/commonjs/rasterise.js.map +1 -0
  25. package/lib/commonjs/types.d.ts +119 -0
  26. package/lib/commonjs/types.d.ts.map +1 -0
  27. package/lib/commonjs/types.js +3 -0
  28. package/lib/commonjs/types.js.map +1 -0
  29. package/package.json +65 -4
  30. package/react-native-lq-bottom-bar.podspec +27 -0
  31. package/src/NativeBottomBar.ts +43 -0
  32. package/src/index.tsx +139 -0
  33. package/src/rasterise.tsx +444 -0
  34. package/src/types.ts +136 -0
package/src/types.ts ADDED
@@ -0,0 +1,136 @@
1
+ import type { ReactElement } from 'react';
2
+ import type {
3
+ ImageSourcePropType,
4
+ StyleProp,
5
+ ViewProps,
6
+ ViewStyle,
7
+ } from 'react-native';
8
+
9
+ /**
10
+ * What an item's icon can be.
11
+ *
12
+ * The union is wide because the two platforms want opposite things and the
13
+ * caller should not have to care which.
14
+ *
15
+ * A native `UITabBar` draws its own items and accepts only `UIImage`, so a
16
+ * React element has to BECOME an image before it reaches the bar. The JS
17
+ * Android bar has no such constraint and renders the element directly, at
18
+ * full fidelity. `src/rasterise.tsx` is the bridge between those two facts.
19
+ */
20
+ export type LQIcon =
21
+ /**
22
+ * A react-native-svg element — which is what a lucide icon is, under the
23
+ * hood. Rasterised once on iOS, rendered live on Android.
24
+ */
25
+ | ReactElement
26
+ /**
27
+ * The same, but told whether it is selected. Preferred over a bare element
28
+ * when the icon changes shape (not just tint) between states: an outline
29
+ * glyph when idle and a filled one when active, which is what this app's
30
+ * own set does.
31
+ *
32
+ * iOS calls this ONCE, with `selected: false`, because UIKit owns the
33
+ * selected appearance — see `tintable`.
34
+ */
35
+ | ((state: LQIconState) => ReactElement)
36
+ /** `require('./home.png')`, or `{ uri }`. */
37
+ | ImageSourcePropType
38
+ /** A name in the app's own asset catalogue. iOS only. */
39
+ | { name: string }
40
+ /** An SF Symbol. iOS only; ignored on Android. */
41
+ | { sfSymbol: string };
42
+
43
+ export interface LQIconState {
44
+ selected: boolean;
45
+ /** `selectedColor` when selected, `unselectedColor` otherwise. */
46
+ color: string;
47
+ size: number;
48
+ }
49
+
50
+ export interface LQBottomBarItem {
51
+ /** Shown under the glyph unless `labeled` is false. */
52
+ title?: string;
53
+ icon: LQIcon;
54
+
55
+ /**
56
+ * A STABLE identity for this item's icon, and the cache key the
57
+ * rasteriser memoises on.
58
+ *
59
+ * Without it the key is derived from the icon's component type and its
60
+ * props, which is correct but costs a serialisation per render and misses
61
+ * when a prop is a function or a style object. Pass this whenever the item
62
+ * list is static, which it almost always is.
63
+ */
64
+ key?: string;
65
+
66
+ /**
67
+ * Whether UIKit may TINT this glyph, iOS only. Default true.
68
+ *
69
+ * True renders the image as a template: the alpha channel is the shape and
70
+ * the system picks the colour, selected against unselected. That is what
71
+ * makes one artwork cover both states and what makes the glyph follow the
72
+ * platform's own selected-state treatment.
73
+ *
74
+ * Set it false for an icon whose own colours ARE the content — an avatar, a
75
+ * brand mark — which then looks identical in both states.
76
+ */
77
+ tintable?: boolean;
78
+
79
+ /** Accessibility label. Falls back to `title`. */
80
+ accessibilityLabel?: string;
81
+ }
82
+
83
+ export interface LQBottomBarProps {
84
+ items: LQBottomBarItem[];
85
+
86
+ /**
87
+ * Which item is lit. JS OWNS THIS, on both platforms: `onTabSelected` is a
88
+ * report, not a commit, so a press that should not switch tabs (one that
89
+ * opens a detail screen instead, say) cannot desync the bar.
90
+ */
91
+ selectedIndex: number;
92
+
93
+ /** Tint for the selected item. Leave unset for the system default. */
94
+ selectedColor?: string;
95
+
96
+ /** Tint for everything else. */
97
+ unselectedColor?: string;
98
+
99
+ /** False hides the titles and re-centres the glyphs. Default true. */
100
+ labeled?: boolean;
101
+
102
+ /** Glyph size in points. Default 24. */
103
+ iconSize?: number;
104
+
105
+ onTabSelected?: (index: number) => void;
106
+
107
+ style?: StyleProp<ViewStyle>;
108
+
109
+ /**
110
+ * Forwarded to the native view, because a bar is very often absolutely
111
+ * positioned over a scrollable page.
112
+ *
113
+ * `"box-none"` is the useful value there: the bar's own items stay tappable
114
+ * while the empty space around them — the safe-area strip below, the gap
115
+ * either side of an inset pill — passes touches through to the content
116
+ * underneath instead of swallowing them.
117
+ */
118
+ pointerEvents?: ViewProps['pointerEvents'];
119
+
120
+ /**
121
+ * Android only: blur strength behind the bar, 0 disables it and leaves the
122
+ * flat `androidBackgroundColor` scrim. Default 20.
123
+ */
124
+ blurAmount?: number;
125
+
126
+ /**
127
+ * Android only: the material's TINT, painted over the blurred backdrop.
128
+ *
129
+ * That order is how UIKit composes a material — blur first, then a
130
+ * translucent colour on top — and it is why this must stay translucent. An
131
+ * opaque value stops being a tint and becomes a lid: the blur is still
132
+ * computed, still costs a software draw of the tree every frame, and is
133
+ * completely hidden behind it.
134
+ */
135
+ androidBackgroundColor?: string;
136
+ }