react-native-collapsible-tabs-reanimated 0.1.0-beta
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/LICENSE +21 -0
- package/README.md +232 -0
- package/lib/commonjs/Bar.js +247 -0
- package/lib/commonjs/Bar.js.map +1 -0
- package/lib/commonjs/Button.js +150 -0
- package/lib/commonjs/Button.js.map +1 -0
- package/lib/commonjs/Context.js +21 -0
- package/lib/commonjs/Context.js.map +1 -0
- package/lib/commonjs/FlashList.js +91 -0
- package/lib/commonjs/FlashList.js.map +1 -0
- package/lib/commonjs/Header.js +54 -0
- package/lib/commonjs/Header.js.map +1 -0
- package/lib/commonjs/Indicator.js +156 -0
- package/lib/commonjs/Indicator.js.map +1 -0
- package/lib/commonjs/Lazy.js +87 -0
- package/lib/commonjs/Lazy.js.map +1 -0
- package/lib/commonjs/LegendList.js +86 -0
- package/lib/commonjs/LegendList.js.map +1 -0
- package/lib/commonjs/List.js +83 -0
- package/lib/commonjs/List.js.map +1 -0
- package/lib/commonjs/Pager.js +93 -0
- package/lib/commonjs/Pager.js.map +1 -0
- package/lib/commonjs/Root.js +169 -0
- package/lib/commonjs/Root.js.map +1 -0
- package/lib/commonjs/ScrollView.js +85 -0
- package/lib/commonjs/ScrollView.js.map +1 -0
- package/lib/commonjs/StaticHeader.js +37 -0
- package/lib/commonjs/StaticHeader.js.map +1 -0
- package/lib/commonjs/StickyHeader.js +37 -0
- package/lib/commonjs/StickyHeader.js.map +1 -0
- package/lib/commonjs/Tab.js +86 -0
- package/lib/commonjs/Tab.js.map +1 -0
- package/lib/commonjs/flash-list.js +14 -0
- package/lib/commonjs/flash-list.js.map +1 -0
- package/lib/commonjs/index.js +128 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/legend-list.js +14 -0
- package/lib/commonjs/legend-list.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/useStableCallback.js +15 -0
- package/lib/commonjs/useStableCallback.js.map +1 -0
- package/lib/module/Bar.js +242 -0
- package/lib/module/Bar.js.map +1 -0
- package/lib/module/Button.js +145 -0
- package/lib/module/Button.js.map +1 -0
- package/lib/module/Context.js +16 -0
- package/lib/module/Context.js.map +1 -0
- package/lib/module/FlashList.js +86 -0
- package/lib/module/FlashList.js.map +1 -0
- package/lib/module/Header.js +49 -0
- package/lib/module/Header.js.map +1 -0
- package/lib/module/Indicator.js +151 -0
- package/lib/module/Indicator.js.map +1 -0
- package/lib/module/Lazy.js +82 -0
- package/lib/module/Lazy.js.map +1 -0
- package/lib/module/LegendList.js +81 -0
- package/lib/module/LegendList.js.map +1 -0
- package/lib/module/List.js +78 -0
- package/lib/module/List.js.map +1 -0
- package/lib/module/Pager.js +87 -0
- package/lib/module/Pager.js.map +1 -0
- package/lib/module/Root.js +165 -0
- package/lib/module/Root.js.map +1 -0
- package/lib/module/ScrollView.js +80 -0
- package/lib/module/ScrollView.js.map +1 -0
- package/lib/module/StaticHeader.js +32 -0
- package/lib/module/StaticHeader.js.map +1 -0
- package/lib/module/StickyHeader.js +32 -0
- package/lib/module/StickyHeader.js.map +1 -0
- package/lib/module/Tab.js +81 -0
- package/lib/module/Tab.js.map +1 -0
- package/lib/module/flash-list.js +4 -0
- package/lib/module/flash-list.js.map +1 -0
- package/lib/module/index.js +44 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/legend-list.js +4 -0
- package/lib/module/legend-list.js.map +1 -0
- package/lib/module/useStableCallback.js +11 -0
- package/lib/module/useStableCallback.js.map +1 -0
- package/lib/typescript/Bar.d.ts +22 -0
- package/lib/typescript/Bar.d.ts.map +1 -0
- package/lib/typescript/Button.d.ts +32 -0
- package/lib/typescript/Button.d.ts.map +1 -0
- package/lib/typescript/Context.d.ts +37 -0
- package/lib/typescript/Context.d.ts.map +1 -0
- package/lib/typescript/FlashList.d.ts +6 -0
- package/lib/typescript/FlashList.d.ts.map +1 -0
- package/lib/typescript/Header.d.ts +7 -0
- package/lib/typescript/Header.d.ts.map +1 -0
- package/lib/typescript/Indicator.d.ts +11 -0
- package/lib/typescript/Indicator.d.ts.map +1 -0
- package/lib/typescript/Lazy.d.ts +36 -0
- package/lib/typescript/Lazy.d.ts.map +1 -0
- package/lib/typescript/LegendList.d.ts +6 -0
- package/lib/typescript/LegendList.d.ts.map +1 -0
- package/lib/typescript/List.d.ts +6 -0
- package/lib/typescript/List.d.ts.map +1 -0
- package/lib/typescript/Pager.d.ts +15 -0
- package/lib/typescript/Pager.d.ts.map +1 -0
- package/lib/typescript/Root.d.ts +14 -0
- package/lib/typescript/Root.d.ts.map +1 -0
- package/lib/typescript/ScrollView.d.ts +6 -0
- package/lib/typescript/ScrollView.d.ts.map +1 -0
- package/lib/typescript/StaticHeader.d.ts +7 -0
- package/lib/typescript/StaticHeader.d.ts.map +1 -0
- package/lib/typescript/StickyHeader.d.ts +7 -0
- package/lib/typescript/StickyHeader.d.ts.map +1 -0
- package/lib/typescript/Tab.d.ts +31 -0
- package/lib/typescript/Tab.d.ts.map +1 -0
- package/lib/typescript/flash-list.d.ts +3 -0
- package/lib/typescript/flash-list.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +69 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/legend-list.d.ts +3 -0
- package/lib/typescript/legend-list.d.ts.map +1 -0
- package/lib/typescript/useStableCallback.d.ts +2 -0
- package/lib/typescript/useStableCallback.d.ts.map +1 -0
- package/package.json +112 -0
- package/src/Bar.tsx +359 -0
- package/src/Button.tsx +219 -0
- package/src/Context.tsx +44 -0
- package/src/FlashList.tsx +150 -0
- package/src/Header.tsx +45 -0
- package/src/Indicator.tsx +193 -0
- package/src/Lazy.tsx +110 -0
- package/src/LegendList.tsx +130 -0
- package/src/List.tsx +115 -0
- package/src/Pager.tsx +134 -0
- package/src/Root.tsx +194 -0
- package/src/ScrollView.tsx +116 -0
- package/src/StaticHeader.tsx +30 -0
- package/src/StickyHeader.tsx +30 -0
- package/src/Tab.tsx +89 -0
- package/src/flash-list.ts +2 -0
- package/src/index.ts +54 -0
- package/src/legend-list.ts +2 -0
- package/src/useStableCallback.ts +11 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# react-native-collapsible-tabs-reanimated
|
|
2
|
+
|
|
3
|
+
Collapsible tab views for React Native powered by Reanimated, Gesture Handler, and Pager View.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install react-native-collapsible-tabs-reanimated react-native-reanimated react-native-gesture-handler react-native-pager-view react-native-worklets
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Make sure Reanimated is configured in your app. See the [Reanimated installation guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started) for the required Babel plugin and native setup.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { useCallback } from "react";
|
|
17
|
+
import CollapsibleTabs from "react-native-collapsible-tabs-reanimated";
|
|
18
|
+
|
|
19
|
+
export function Example() {
|
|
20
|
+
const keyExtractor = useCallback((item: number) => String(item), []);
|
|
21
|
+
const renderItem = useCallback(({ item }: { item: number }) => null, []);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<CollapsibleTabs.Root pageLength={2}>
|
|
25
|
+
<CollapsibleTabs.Header>
|
|
26
|
+
<CollapsibleTabs.StaticHeader>
|
|
27
|
+
{/* Collapses on scroll */}
|
|
28
|
+
</CollapsibleTabs.StaticHeader>
|
|
29
|
+
<CollapsibleTabs.StickyHeader>
|
|
30
|
+
<CollapsibleTabs.Bar>
|
|
31
|
+
<CollapsibleTabs.Button index={0} name="First">
|
|
32
|
+
First
|
|
33
|
+
</CollapsibleTabs.Button>
|
|
34
|
+
<CollapsibleTabs.Button index={1} name="Second">
|
|
35
|
+
Second
|
|
36
|
+
</CollapsibleTabs.Button>
|
|
37
|
+
<CollapsibleTabs.MaterialIndicator />
|
|
38
|
+
</CollapsibleTabs.Bar>
|
|
39
|
+
</CollapsibleTabs.StickyHeader>
|
|
40
|
+
</CollapsibleTabs.Header>
|
|
41
|
+
|
|
42
|
+
<CollapsibleTabs.Pager>
|
|
43
|
+
<CollapsibleTabs.Tab index={0}>
|
|
44
|
+
<CollapsibleTabs.List
|
|
45
|
+
data={[1, 2, 3]}
|
|
46
|
+
keyExtractor={keyExtractor}
|
|
47
|
+
renderItem={renderItem}
|
|
48
|
+
/>
|
|
49
|
+
</CollapsibleTabs.Tab>
|
|
50
|
+
<CollapsibleTabs.Tab index={1}>
|
|
51
|
+
<CollapsibleTabs.List
|
|
52
|
+
data={[4, 5, 6]}
|
|
53
|
+
keyExtractor={keyExtractor}
|
|
54
|
+
renderItem={renderItem}
|
|
55
|
+
/>
|
|
56
|
+
</CollapsibleTabs.Tab>
|
|
57
|
+
</CollapsibleTabs.Pager>
|
|
58
|
+
</CollapsibleTabs.Root>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## FlashList
|
|
64
|
+
|
|
65
|
+
`CollapsibleFlashList` is a drop-in replacement for `CollapsibleTabs.List` backed by `@shopify/flash-list`. It lives in a separate entry point so the dependency remains optional.
|
|
66
|
+
|
|
67
|
+
**Install the peer dependency:**
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
npm install @shopify/flash-list
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Import from the sub-path:**
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import { CollapsibleFlashList } from "react-native-collapsible-tabs-reanimated/flash-list";
|
|
77
|
+
import type { ListRenderItemInfo } from "@shopify/flash-list";
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Use inside a `CollapsibleTabs.Tab`** exactly as you would use `@shopify/flash-list`'s `FlashList`. The component must be rendered as a direct child of `CollapsibleTabs.Tab`:
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
import { useCallback } from "react";
|
|
84
|
+
import CollapsibleTabs from "react-native-collapsible-tabs-reanimated";
|
|
85
|
+
import { CollapsibleFlashList } from "react-native-collapsible-tabs-reanimated/flash-list";
|
|
86
|
+
|
|
87
|
+
type Item = { id: string; label: string };
|
|
88
|
+
|
|
89
|
+
export function FlashListTab({ data }: { data: Item[] }) {
|
|
90
|
+
const keyExtractor = useCallback((item: Item) => item.id, []);
|
|
91
|
+
const renderItem = useCallback(
|
|
92
|
+
({ item }: { item: Item }) => <MyRow item={item} />,
|
|
93
|
+
[],
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<CollapsibleTabs.Tab index={0}>
|
|
98
|
+
<CollapsibleFlashList
|
|
99
|
+
data={data}
|
|
100
|
+
keyExtractor={keyExtractor}
|
|
101
|
+
renderItem={renderItem}
|
|
102
|
+
estimatedItemSize={72}
|
|
103
|
+
/>
|
|
104
|
+
</CollapsibleTabs.Tab>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`CollapsibleFlashList` accepts all props from `FlashList` except `renderScrollComponent`, which is managed internally. `stickyHeaderIndices` is supported.
|
|
110
|
+
|
|
111
|
+
## LegendList
|
|
112
|
+
|
|
113
|
+
`CollapsibleLegendList` wraps `@legendapp/list` (v3+) with the same collapsible gesture integration. It also lives behind an optional sub-path entry.
|
|
114
|
+
|
|
115
|
+
**Install the peer dependency:**
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
npm install @legendapp/list
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Import from the sub-path:**
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
import { CollapsibleLegendList } from "react-native-collapsible-tabs-reanimated/legend-list";
|
|
125
|
+
import type { LegendListRenderItemProps } from "@legendapp/list/react-native";
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Use inside a `CollapsibleTabs.Tab`:**
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
import { useCallback } from "react";
|
|
132
|
+
import CollapsibleTabs from "react-native-collapsible-tabs-reanimated";
|
|
133
|
+
import { CollapsibleLegendList } from "react-native-collapsible-tabs-reanimated/legend-list";
|
|
134
|
+
import type { LegendListRenderItemProps } from "@legendapp/list/react-native";
|
|
135
|
+
|
|
136
|
+
type Item = { id: string; label: string };
|
|
137
|
+
|
|
138
|
+
export function LegendListTab({ data }: { data: Item[] }) {
|
|
139
|
+
const keyExtractor = useCallback((item: Item) => item.id, []);
|
|
140
|
+
const renderItem = useCallback(
|
|
141
|
+
({ item }: LegendListRenderItemProps<Item>) => <MyRow item={item} />,
|
|
142
|
+
[],
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<CollapsibleTabs.Tab index={1}>
|
|
147
|
+
<CollapsibleLegendList
|
|
148
|
+
data={data}
|
|
149
|
+
keyExtractor={keyExtractor}
|
|
150
|
+
renderItem={renderItem}
|
|
151
|
+
estimatedItemSize={72}
|
|
152
|
+
recycleItems
|
|
153
|
+
/>
|
|
154
|
+
</CollapsibleTabs.Tab>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`CollapsibleLegendList` accepts all props from `LegendList`. `stickyHeaderIndices` is supported.
|
|
160
|
+
|
|
161
|
+
## Example App
|
|
162
|
+
|
|
163
|
+
The `example` folder contains a runnable Expo SDK 56 app that demonstrates `ScrollView`, `List`, `CollapsibleFlashList`, and `CollapsibleLegendList` tabs side by side.
|
|
164
|
+
|
|
165
|
+
**Prerequisites:** Node.js ≥ 18, the [Expo CLI](https://docs.expo.dev/more/expo-cli/), and either an Android emulator / iOS simulator or the Expo Go app on a physical device.
|
|
166
|
+
|
|
167
|
+
```sh
|
|
168
|
+
# From the repository root — installs both root and example dependencies
|
|
169
|
+
npm install
|
|
170
|
+
|
|
171
|
+
# Start the Metro bundler
|
|
172
|
+
cd example
|
|
173
|
+
npx expo start
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Press `a` to open on Android, `i` for iOS, or scan the QR code with Expo Go.
|
|
177
|
+
|
|
178
|
+
**Run on Android with a local build:**
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
cd example
|
|
182
|
+
npx expo run:android
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Run on iOS with a local build:**
|
|
186
|
+
|
|
187
|
+
```sh
|
|
188
|
+
cd example
|
|
189
|
+
npx expo run:ios
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
> The example resolves `react-native-collapsible-tabs-reanimated` from the local workspace source (`workspace:*`), so any changes you make to `src/` are reflected immediately without a separate build step.
|
|
193
|
+
|
|
194
|
+
## Lazy Tab Customization
|
|
195
|
+
|
|
196
|
+
`CollapsibleTabs.Tab` mounts its children lazily by default. Pass `lazy={false}` to mount eagerly, or use `lazyProps` to fine-tune the lazy behaviour:
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
<CollapsibleTabs.Tab
|
|
200
|
+
index={0}
|
|
201
|
+
loader={<ActivityIndicator />}
|
|
202
|
+
loaderStyle={{
|
|
203
|
+
minHeight: 160,
|
|
204
|
+
alignItems: "center",
|
|
205
|
+
justifyContent: "center",
|
|
206
|
+
}}
|
|
207
|
+
lazyProps={{
|
|
208
|
+
enteringDuration: 280,
|
|
209
|
+
enteringDelay: 0,
|
|
210
|
+
exitingDuration: 120,
|
|
211
|
+
placeholderProps: { accessibilityLabel: "Loading tab content" },
|
|
212
|
+
containerProps: { testID: "first-tab-content" },
|
|
213
|
+
onMount: () => {
|
|
214
|
+
// Called once the tab content is allowed to mount.
|
|
215
|
+
},
|
|
216
|
+
}}
|
|
217
|
+
>
|
|
218
|
+
<CollapsibleTabs.List
|
|
219
|
+
data={[1, 2, 3]}
|
|
220
|
+
keyExtractor={keyExtractor}
|
|
221
|
+
renderItem={renderItem}
|
|
222
|
+
/>
|
|
223
|
+
</CollapsibleTabs.Tab>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
For lower-level use cases, `Lazy`, `LazyProps`, and `LazyPlaceholderInfo` are exported directly.
|
|
227
|
+
|
|
228
|
+
## Notes
|
|
229
|
+
|
|
230
|
+
- Colors, labels, scroll buttons, indicators, and lazy placeholders are all configurable through props — the package has no opinion on your app's theme.
|
|
231
|
+
- `@shopify/flash-list` and `@legendapp/list` are optional peer dependencies. Install only what you use.
|
|
232
|
+
- Each tab keeps its own independent scroll offset. The active tab's offset drives the collapsible header gesture.
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _reactNativeGestureHandler = require("react-native-gesture-handler");
|
|
10
|
+
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
|
|
11
|
+
var _Context = require("./Context");
|
|
12
|
+
var _reactNativeWorklets = require("react-native-worklets");
|
|
13
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
|
+
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); }
|
|
15
|
+
const AnimatedScrollView = _reactNativeReanimated.default.createAnimatedComponent(_reactNativeGestureHandler.ScrollView);
|
|
16
|
+
const Bar = ({
|
|
17
|
+
scrollEnabled = true,
|
|
18
|
+
fullWidth,
|
|
19
|
+
scrollButtons = true,
|
|
20
|
+
left,
|
|
21
|
+
right,
|
|
22
|
+
containerProps,
|
|
23
|
+
children,
|
|
24
|
+
scrollContainerStyle,
|
|
25
|
+
tabButtonsGap = 0,
|
|
26
|
+
backgroundColor = "#ffffff",
|
|
27
|
+
scrollButtonBackgroundColor = "rgba(255, 255, 255, 0.95)",
|
|
28
|
+
scrollButtonIconColor = "rgba(48, 48, 48, 0.7)",
|
|
29
|
+
renderScrollButtonIcon,
|
|
30
|
+
...props
|
|
31
|
+
}) => {
|
|
32
|
+
const {
|
|
33
|
+
pageDecimal,
|
|
34
|
+
itemLayout
|
|
35
|
+
} = (0, _Context.useCollapsibleTabsContext)();
|
|
36
|
+
const [barSize, setBarSize] = (0, _react.useState)({
|
|
37
|
+
width: 0,
|
|
38
|
+
height: 0,
|
|
39
|
+
measured: false
|
|
40
|
+
});
|
|
41
|
+
const contentWidth = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
42
|
+
const layoutWidth = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
43
|
+
const scrollRef = (0, _reactNativeReanimated.useAnimatedRef)();
|
|
44
|
+
const scrollX = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
45
|
+
const leftButtonOpacity = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
46
|
+
const rightButtonOpacity = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
47
|
+
(0, _reactNativeReanimated.useAnimatedReaction)(() => {
|
|
48
|
+
if (!scrollButtons || layoutWidth.value === 0 || contentWidth.value === 0) return {
|
|
49
|
+
showLeft: false,
|
|
50
|
+
showRight: false
|
|
51
|
+
};
|
|
52
|
+
const maxScroll = contentWidth.value - layoutWidth.value;
|
|
53
|
+
const isScrollable = maxScroll > 1;
|
|
54
|
+
return {
|
|
55
|
+
showLeft: isScrollable && scrollX.value > 10,
|
|
56
|
+
showRight: isScrollable && scrollX.value < maxScroll - 10
|
|
57
|
+
};
|
|
58
|
+
}, (curr, prev) => {
|
|
59
|
+
if (curr.showLeft !== prev?.showLeft) leftButtonOpacity.value = (0, _reactNativeReanimated.withTiming)(curr.showLeft ? 1 : 0);
|
|
60
|
+
if (curr.showRight !== prev?.showRight) rightButtonOpacity.value = (0, _reactNativeReanimated.withTiming)(curr.showRight ? 1 : 0);
|
|
61
|
+
}, [scrollButtons]);
|
|
62
|
+
const onScroll = (0, _reactNativeReanimated.useAnimatedScrollHandler)(evt => {
|
|
63
|
+
scrollX.value = evt.contentOffset.x;
|
|
64
|
+
});
|
|
65
|
+
const scrollByButton = (0, _react.useCallback)(dir => {
|
|
66
|
+
"worklet";
|
|
67
|
+
|
|
68
|
+
const step = layoutWidth.value / 2;
|
|
69
|
+
const current = scrollX.value;
|
|
70
|
+
const target = dir === "left" ? current - step : current + step;
|
|
71
|
+
const maxScroll = contentWidth.value - layoutWidth.value;
|
|
72
|
+
(0, _reactNativeReanimated.scrollTo)(scrollRef, Math.max(0, Math.min(target, maxScroll > 0 ? maxScroll : 0)), 0, true);
|
|
73
|
+
}, [contentWidth, layoutWidth, scrollRef, scrollX]);
|
|
74
|
+
const handlePress = (0, _react.useCallback)(dir => {
|
|
75
|
+
(0, _reactNativeWorklets.scheduleOnUI)(scrollByButton, dir);
|
|
76
|
+
}, [scrollByButton]);
|
|
77
|
+
const interpolationTable = (0, _reactNativeReanimated.useDerivedValue)(() => {
|
|
78
|
+
if (itemLayout.length <= 1) return null;
|
|
79
|
+
const inputRange = new Array(itemLayout.length);
|
|
80
|
+
const outputRange = new Array(itemLayout.length);
|
|
81
|
+
const halfBar = barSize.width / 2;
|
|
82
|
+
for (let index = 0; index < itemLayout.length; index += 1) {
|
|
83
|
+
inputRange[index] = index;
|
|
84
|
+
const item = itemLayout[index];
|
|
85
|
+
outputRange[index] = +(item.x + item.width / 2 - halfBar).toFixed(2);
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
inputRange,
|
|
89
|
+
outputRange
|
|
90
|
+
};
|
|
91
|
+
}, [barSize.width, itemLayout]);
|
|
92
|
+
const centerOffset = (0, _reactNativeReanimated.useDerivedValue)(() => {
|
|
93
|
+
if (!interpolationTable.value) return 0;
|
|
94
|
+
return (0, _reactNativeReanimated.interpolate)(+pageDecimal.value.toFixed(3), interpolationTable.value.inputRange, interpolationTable.value.outputRange, "identity");
|
|
95
|
+
}, [interpolationTable]);
|
|
96
|
+
(0, _reactNativeReanimated.useAnimatedReaction)(() => Math.round(centerOffset.value), (value, prev) => {
|
|
97
|
+
if (value !== prev) (0, _reactNativeReanimated.scrollTo)(scrollRef, value, 0, true);
|
|
98
|
+
});
|
|
99
|
+
const contentContainerStyle = (0, _react.useMemo)(() => ({
|
|
100
|
+
flex: fullWidth ? 1 : 0,
|
|
101
|
+
gap: tabButtonsGap
|
|
102
|
+
}), [fullWidth, tabButtonsGap]);
|
|
103
|
+
const onContentSizeChange = (0, _react.useCallback)(width => {
|
|
104
|
+
contentWidth.value = width;
|
|
105
|
+
}, [contentWidth]);
|
|
106
|
+
const onLayout = (0, _react.useCallback)(evt => {
|
|
107
|
+
layoutWidth.value = evt.nativeEvent.layout.width;
|
|
108
|
+
}, [layoutWidth]);
|
|
109
|
+
const containerOnLayout = containerProps?.onLayout;
|
|
110
|
+
const onContainerLayout = (0, _react.useCallback)(evt => {
|
|
111
|
+
const {
|
|
112
|
+
width,
|
|
113
|
+
height
|
|
114
|
+
} = evt.nativeEvent.layout;
|
|
115
|
+
setBarSize(prev => prev.width === width && prev.height === height ? prev : {
|
|
116
|
+
width,
|
|
117
|
+
height,
|
|
118
|
+
measured: true
|
|
119
|
+
});
|
|
120
|
+
containerOnLayout?.(evt);
|
|
121
|
+
}, [containerOnLayout]);
|
|
122
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
123
|
+
...containerProps,
|
|
124
|
+
style: [styles.containerRow, {
|
|
125
|
+
backgroundColor
|
|
126
|
+
}, containerProps?.style],
|
|
127
|
+
onLayout: onContainerLayout,
|
|
128
|
+
collapsable: false,
|
|
129
|
+
children: [left, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
130
|
+
style: [styles.scrollContainer, scrollContainerStyle],
|
|
131
|
+
children: [!!scrollButtons && /*#__PURE__*/(0, _jsxRuntime.jsx)(ScrollButton, {
|
|
132
|
+
dir: "left",
|
|
133
|
+
buttonProgress: leftButtonOpacity,
|
|
134
|
+
handlePress: handlePress,
|
|
135
|
+
backgroundColor: scrollButtonBackgroundColor,
|
|
136
|
+
iconColor: scrollButtonIconColor,
|
|
137
|
+
renderIcon: renderScrollButtonIcon
|
|
138
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(AnimatedScrollView, {
|
|
139
|
+
ref: scrollRef,
|
|
140
|
+
horizontal: true,
|
|
141
|
+
showsHorizontalScrollIndicator: false,
|
|
142
|
+
scrollEventThrottle: 16,
|
|
143
|
+
keyboardShouldPersistTaps: "handled",
|
|
144
|
+
scrollEnabled: scrollEnabled,
|
|
145
|
+
contentContainerStyle: contentContainerStyle,
|
|
146
|
+
directionalLockEnabled: true,
|
|
147
|
+
onContentSizeChange: onContentSizeChange,
|
|
148
|
+
onLayout: onLayout,
|
|
149
|
+
onScroll: onScroll,
|
|
150
|
+
bounces: false,
|
|
151
|
+
collapsable: false,
|
|
152
|
+
...props,
|
|
153
|
+
children: children
|
|
154
|
+
}), !!scrollButtons && /*#__PURE__*/(0, _jsxRuntime.jsx)(ScrollButton, {
|
|
155
|
+
dir: "right",
|
|
156
|
+
buttonProgress: rightButtonOpacity,
|
|
157
|
+
handlePress: handlePress,
|
|
158
|
+
backgroundColor: scrollButtonBackgroundColor,
|
|
159
|
+
iconColor: scrollButtonIconColor,
|
|
160
|
+
renderIcon: renderScrollButtonIcon
|
|
161
|
+
})]
|
|
162
|
+
}), right]
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
const ScrollButton = /*#__PURE__*/(0, _react.memo)(({
|
|
166
|
+
dir,
|
|
167
|
+
buttonProgress,
|
|
168
|
+
handlePress,
|
|
169
|
+
backgroundColor,
|
|
170
|
+
iconColor,
|
|
171
|
+
renderIcon
|
|
172
|
+
}) => {
|
|
173
|
+
const isLeft = dir === "left";
|
|
174
|
+
const width = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
175
|
+
const animatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
|
|
176
|
+
const opacity = buttonProgress.value;
|
|
177
|
+
return {
|
|
178
|
+
opacity,
|
|
179
|
+
transform: [{
|
|
180
|
+
translateX: (0, _reactNativeReanimated.interpolate)(opacity, [0, 1], [isLeft ? -width.value : width.value, 0])
|
|
181
|
+
}],
|
|
182
|
+
pointerEvents: opacity === 0 ? "none" : "auto"
|
|
183
|
+
};
|
|
184
|
+
}, [isLeft]);
|
|
185
|
+
const onLayoutButton = (0, _react.useCallback)(evt => {
|
|
186
|
+
width.value = evt.nativeEvent.layout.width;
|
|
187
|
+
}, [width]);
|
|
188
|
+
const onPress = (0, _react.useCallback)(() => handlePress(dir), [dir, handlePress]);
|
|
189
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
190
|
+
style: [isLeft ? scrollButtonStyles.containerLeft : scrollButtonStyles.containerRight, {
|
|
191
|
+
backgroundColor
|
|
192
|
+
}, animatedStyle],
|
|
193
|
+
onLayout: onLayoutButton,
|
|
194
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.Pressable, {
|
|
195
|
+
style: scrollButtonStyles.button,
|
|
196
|
+
onPress: onPress,
|
|
197
|
+
children: renderIcon ? renderIcon(dir) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
198
|
+
style: [scrollButtonStyles.icon, {
|
|
199
|
+
color: iconColor
|
|
200
|
+
}],
|
|
201
|
+
children: isLeft ? "<" : ">"
|
|
202
|
+
})
|
|
203
|
+
})
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
const styles = _reactNative.StyleSheet.create({
|
|
207
|
+
containerRow: {
|
|
208
|
+
position: "relative",
|
|
209
|
+
flexDirection: "row",
|
|
210
|
+
alignItems: "center"
|
|
211
|
+
},
|
|
212
|
+
scrollContainer: {
|
|
213
|
+
flex: 1,
|
|
214
|
+
flexDirection: "row",
|
|
215
|
+
alignItems: "center",
|
|
216
|
+
justifyContent: "center",
|
|
217
|
+
position: "relative",
|
|
218
|
+
paddingHorizontal: 20
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
const scrollButtonStyles = _reactNative.StyleSheet.create({
|
|
222
|
+
containerLeft: {
|
|
223
|
+
position: "absolute",
|
|
224
|
+
left: 0,
|
|
225
|
+
zIndex: 2,
|
|
226
|
+
height: "100%"
|
|
227
|
+
},
|
|
228
|
+
containerRight: {
|
|
229
|
+
position: "absolute",
|
|
230
|
+
right: 0,
|
|
231
|
+
zIndex: 2,
|
|
232
|
+
height: "100%"
|
|
233
|
+
},
|
|
234
|
+
button: {
|
|
235
|
+
paddingHorizontal: 12,
|
|
236
|
+
paddingVertical: 4,
|
|
237
|
+
height: "100%",
|
|
238
|
+
justifyContent: "center"
|
|
239
|
+
},
|
|
240
|
+
icon: {
|
|
241
|
+
fontSize: 16,
|
|
242
|
+
fontWeight: "700"
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
Bar.displayName = "CollapsibleTabs.Bar";
|
|
246
|
+
var _default = exports.default = /*#__PURE__*/(0, _react.memo)(Bar);
|
|
247
|
+
//# sourceMappingURL=Bar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNative","_reactNativeGestureHandler","_reactNativeReanimated","_interopRequireWildcard","_Context","_reactNativeWorklets","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","AnimatedScrollView","Animated","createAnimatedComponent","ScrollView","Bar","scrollEnabled","fullWidth","scrollButtons","left","right","containerProps","children","scrollContainerStyle","tabButtonsGap","backgroundColor","scrollButtonBackgroundColor","scrollButtonIconColor","renderScrollButtonIcon","props","pageDecimal","itemLayout","useCollapsibleTabsContext","barSize","setBarSize","useState","width","height","measured","contentWidth","useSharedValue","layoutWidth","scrollRef","useAnimatedRef","scrollX","leftButtonOpacity","rightButtonOpacity","useAnimatedReaction","value","showLeft","showRight","maxScroll","isScrollable","curr","prev","withTiming","onScroll","useAnimatedScrollHandler","evt","contentOffset","x","scrollByButton","useCallback","dir","step","current","target","scrollTo","Math","max","min","handlePress","scheduleOnUI","interpolationTable","useDerivedValue","length","inputRange","Array","outputRange","halfBar","index","item","toFixed","centerOffset","interpolate","round","contentContainerStyle","useMemo","flex","gap","onContentSizeChange","onLayout","nativeEvent","layout","containerOnLayout","onContainerLayout","jsxs","View","style","styles","containerRow","collapsable","scrollContainer","jsx","ScrollButton","buttonProgress","iconColor","renderIcon","ref","horizontal","showsHorizontalScrollIndicator","scrollEventThrottle","keyboardShouldPersistTaps","directionalLockEnabled","bounces","memo","isLeft","animatedStyle","useAnimatedStyle","opacity","transform","translateX","pointerEvents","onLayoutButton","onPress","scrollButtonStyles","containerLeft","containerRight","Pressable","button","Text","icon","color","StyleSheet","create","position","flexDirection","alignItems","justifyContent","paddingHorizontal","zIndex","paddingVertical","fontSize","fontWeight","displayName","_default","exports"],"sourceRoot":"..\\..\\src","sources":["Bar.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _reactNativeGestureHandler = require("react-native-gesture-handler");
|
|
10
|
+
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
|
|
11
|
+
var _Context = require("./Context");
|
|
12
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
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
|
+
const Button = ({
|
|
15
|
+
index,
|
|
16
|
+
name,
|
|
17
|
+
onPress,
|
|
18
|
+
style,
|
|
19
|
+
fullWidth,
|
|
20
|
+
labelStyle,
|
|
21
|
+
labelProps,
|
|
22
|
+
activeLabelStyle,
|
|
23
|
+
activeStyle,
|
|
24
|
+
children,
|
|
25
|
+
contentWrapperStyle,
|
|
26
|
+
activeLabelColor = "#111827",
|
|
27
|
+
inactiveLabelColor = "#9ca3af",
|
|
28
|
+
...props
|
|
29
|
+
}) => {
|
|
30
|
+
const {
|
|
31
|
+
activeTabIndex,
|
|
32
|
+
activeTabIndexValue,
|
|
33
|
+
pageDecimal,
|
|
34
|
+
pagerRef,
|
|
35
|
+
registerButton,
|
|
36
|
+
itemLayout
|
|
37
|
+
} = (0, _Context.useCollapsibleTabsContext)();
|
|
38
|
+
const isActive = activeTabIndexValue === index;
|
|
39
|
+
const combinedStaticLabelStyle = (0, _react.useMemo)(() => [styles.label, labelStyle, activeLabelStyle && isActive && activeLabelStyle], [activeLabelStyle, isActive, labelStyle]);
|
|
40
|
+
const animatedLabelStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
|
|
41
|
+
const color = (0, _reactNativeReanimated.interpolateColor)(pageDecimal.value, [index - 1, index, index + 1], [inactiveLabelColor, activeLabelColor, inactiveLabelColor]);
|
|
42
|
+
return {
|
|
43
|
+
color
|
|
44
|
+
};
|
|
45
|
+
}, [activeLabelColor, inactiveLabelColor, index, pageDecimal]);
|
|
46
|
+
const handleOnPress = (0, _react.useCallback)(event => {
|
|
47
|
+
onPress?.(event);
|
|
48
|
+
if (pagerRef.current) {
|
|
49
|
+
pagerRef.current.setPage(index);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
activeTabIndex.value = index;
|
|
53
|
+
pageDecimal.value = (0, _reactNativeReanimated.withTiming)(index);
|
|
54
|
+
}, [activeTabIndex, index, onPress, pageDecimal, pagerRef]);
|
|
55
|
+
const pressableLayoutRef = (0, _react.useRef)(null);
|
|
56
|
+
const contentLayoutRef = (0, _react.useRef)(null);
|
|
57
|
+
const commitLayout = (0, _react.useCallback)(() => {
|
|
58
|
+
const pressable = pressableLayoutRef.current;
|
|
59
|
+
const content = contentLayoutRef.current;
|
|
60
|
+
if (!pressable || !content) return;
|
|
61
|
+
registerButton({
|
|
62
|
+
width: content.width,
|
|
63
|
+
height: content.height,
|
|
64
|
+
x: pressable.x + content.x,
|
|
65
|
+
y: pressable.y + content.y,
|
|
66
|
+
name,
|
|
67
|
+
index
|
|
68
|
+
});
|
|
69
|
+
}, [index, name, registerButton]);
|
|
70
|
+
const onLayout = (0, _react.useCallback)(event => {
|
|
71
|
+
props.onLayout?.(event);
|
|
72
|
+
const {
|
|
73
|
+
x,
|
|
74
|
+
y
|
|
75
|
+
} = event.nativeEvent.layout;
|
|
76
|
+
pressableLayoutRef.current = {
|
|
77
|
+
x,
|
|
78
|
+
y
|
|
79
|
+
};
|
|
80
|
+
commitLayout();
|
|
81
|
+
}, [commitLayout, props]);
|
|
82
|
+
const onContentLayout = (0, _react.useCallback)(event => {
|
|
83
|
+
const {
|
|
84
|
+
x,
|
|
85
|
+
y,
|
|
86
|
+
width,
|
|
87
|
+
height
|
|
88
|
+
} = event.nativeEvent.layout;
|
|
89
|
+
contentLayoutRef.current = {
|
|
90
|
+
x,
|
|
91
|
+
y,
|
|
92
|
+
width,
|
|
93
|
+
height
|
|
94
|
+
};
|
|
95
|
+
commitLayout();
|
|
96
|
+
}, [commitLayout]);
|
|
97
|
+
const isLast = itemLayout.length - 1 === index;
|
|
98
|
+
const isFirst = index === 0;
|
|
99
|
+
const mergedStyle = (0, _react.useMemo)(() => [styles.pressable, isFirst && {
|
|
100
|
+
paddingLeft: 0
|
|
101
|
+
}, isLast && {
|
|
102
|
+
paddingRight: 0
|
|
103
|
+
}, fullWidth && styles.fullWidth, style, isActive && activeStyle], [activeStyle, fullWidth, isActive, isFirst, isLast, style]);
|
|
104
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.Pressable, {
|
|
105
|
+
onPress: handleOnPress,
|
|
106
|
+
...props,
|
|
107
|
+
onLayout: onLayout,
|
|
108
|
+
style: mergedStyle,
|
|
109
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
110
|
+
onLayout: onContentLayout,
|
|
111
|
+
style: [styles.contentWrapper, contentWrapperStyle],
|
|
112
|
+
children: typeof children === "function" ? children({
|
|
113
|
+
isActive,
|
|
114
|
+
index,
|
|
115
|
+
name,
|
|
116
|
+
style: combinedStaticLabelStyle,
|
|
117
|
+
animatedStyle: animatedLabelStyle,
|
|
118
|
+
pageDecimal
|
|
119
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.Text, {
|
|
120
|
+
style: [combinedStaticLabelStyle, animatedLabelStyle],
|
|
121
|
+
numberOfLines: 1,
|
|
122
|
+
...labelProps,
|
|
123
|
+
children: children
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
const styles = _reactNative.StyleSheet.create({
|
|
129
|
+
pressable: {
|
|
130
|
+
paddingVertical: 16,
|
|
131
|
+
paddingHorizontal: 10
|
|
132
|
+
},
|
|
133
|
+
fullWidth: {
|
|
134
|
+
flex: 1
|
|
135
|
+
},
|
|
136
|
+
contentWrapper: {
|
|
137
|
+
position: "relative",
|
|
138
|
+
alignSelf: "center"
|
|
139
|
+
},
|
|
140
|
+
label: {
|
|
141
|
+
fontSize: 14,
|
|
142
|
+
lineHeight: 18,
|
|
143
|
+
fontWeight: "700",
|
|
144
|
+
fontVariant: ["tabular-nums"],
|
|
145
|
+
textAlign: "center"
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
Button.displayName = "CollapsibleTabs.Button";
|
|
149
|
+
var _default = exports.default = /*#__PURE__*/(0, _react.memo)(Button);
|
|
150
|
+
//# sourceMappingURL=Button.js.map
|