@xaui/native 0.0.21 → 0.0.24
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 +195 -2
- package/dist/alert/index.js +1 -2
- package/dist/app-bar/index.cjs +217 -0
- package/dist/app-bar/index.d.cts +52 -0
- package/dist/app-bar/index.d.ts +52 -0
- package/dist/app-bar/index.js +142 -0
- package/dist/autocomplete/index.js +48 -36
- package/dist/avatar/index.js +1 -2
- package/dist/badge/index.js +1 -2
- package/dist/bottom-sheet/index.js +1 -2
- package/dist/bottom-tab-bar/index.cjs +571 -0
- package/dist/bottom-tab-bar/index.d.cts +211 -0
- package/dist/bottom-tab-bar/index.d.ts +211 -0
- package/dist/bottom-tab-bar/index.js +497 -0
- package/dist/button/index.d.cts +102 -5
- package/dist/button/index.d.ts +102 -5
- package/dist/button/index.js +2 -3
- package/dist/button.type-j1ZdkkSl.d.cts +4 -0
- package/dist/button.type-j1ZdkkSl.d.ts +4 -0
- package/dist/card/index.cjs +2 -0
- package/dist/card/index.d.cts +6 -1
- package/dist/card/index.d.ts +6 -1
- package/dist/card/index.js +4 -2
- package/dist/carousel/index.js +1 -1
- package/dist/chart/index.cjs +1067 -0
- package/dist/chart/index.d.cts +218 -0
- package/dist/chart/index.d.ts +218 -0
- package/dist/chart/index.js +1026 -0
- package/dist/checkbox/index.js +1 -2
- package/dist/chip/index.js +1 -2
- package/dist/chunk-3XSXTM3G.js +661 -0
- package/dist/chunk-4KSZLONZ.js +79 -0
- package/dist/{chunk-DXXNBF5P.js → chunk-CZFDZPAS.js} +0 -5
- package/dist/{chunk-LTKYHG5V.js → chunk-GHCVNQET.js} +12 -5
- package/dist/chunk-I4V5Y5GD.js +76 -0
- package/dist/{chunk-F7WH4DMG.js → chunk-UI5L26KD.js} +1 -1
- package/dist/{chunk-LUBWRVI2.js → chunk-ULJSCNPE.js} +1 -1
- package/dist/chunk-URBEEDFX.js +79 -0
- package/dist/core/index.js +3 -5
- package/dist/datepicker/index.js +1 -2
- package/dist/divider/index.js +2 -3
- package/dist/drawer/index.cjs +310 -0
- package/dist/drawer/index.d.cts +58 -0
- package/dist/drawer/index.d.ts +58 -0
- package/dist/drawer/index.js +236 -0
- package/dist/{accordion → expansion-panel}/index.cjs +45 -45
- package/dist/{accordion → expansion-panel}/index.d.cts +30 -30
- package/dist/{accordion → expansion-panel}/index.d.ts +30 -30
- package/dist/{accordion → expansion-panel}/index.js +40 -41
- package/dist/fab/index.d.cts +3 -3
- package/dist/fab/index.d.ts +3 -3
- package/dist/fab/index.js +3 -4
- package/dist/fab-menu/index.d.cts +2 -2
- package/dist/fab-menu/index.d.ts +2 -2
- package/dist/fab-menu/index.js +3 -4
- package/dist/{fab.type-Ba0QMprb.d.ts → fab.type-CgIYqQlT.d.ts} +1 -1
- package/dist/{fab.type-U09H8B7D.d.cts → fab.type-l2vjG8-p.d.cts} +1 -1
- package/dist/feature-discovery/index.cjs +531 -0
- package/dist/feature-discovery/index.d.cts +82 -0
- package/dist/feature-discovery/index.d.ts +82 -0
- package/dist/feature-discovery/index.js +464 -0
- package/dist/indicator/index.js +2 -3
- package/dist/input/index.cjs +258 -164
- package/dist/input/index.d.cts +15 -1
- package/dist/input/index.d.ts +15 -1
- package/dist/input/index.js +219 -126
- package/dist/list/index.js +1 -2
- package/dist/menu/index.js +2 -2
- package/dist/menubox/index.cjs +369 -0
- package/dist/menubox/index.d.cts +98 -0
- package/dist/menubox/index.d.ts +98 -0
- package/dist/menubox/index.js +296 -0
- package/dist/pager/index.cjs +243 -0
- package/dist/pager/index.d.cts +93 -0
- package/dist/pager/index.d.ts +93 -0
- package/dist/pager/index.js +205 -0
- package/dist/progress/index.js +1 -2
- package/dist/radio/index.cjs +537 -0
- package/dist/radio/index.d.cts +145 -0
- package/dist/radio/index.d.ts +145 -0
- package/dist/radio/index.js +464 -0
- package/dist/segment-button/index.js +2 -2
- package/dist/select/index.js +22 -10
- package/dist/skeleton/index.js +2 -2
- package/dist/slider/index.cjs +655 -0
- package/dist/slider/index.d.cts +171 -0
- package/dist/slider/index.d.ts +171 -0
- package/dist/slider/index.js +575 -0
- package/dist/stepper/index.cjs +624 -0
- package/dist/stepper/index.d.cts +137 -0
- package/dist/stepper/index.d.ts +137 -0
- package/dist/stepper/index.js +549 -0
- package/dist/switch/index.js +1 -2
- package/dist/tabs/index.cjs +523 -0
- package/dist/tabs/index.d.cts +176 -0
- package/dist/tabs/index.d.ts +176 -0
- package/dist/tabs/index.js +438 -0
- package/dist/timepicker/index.cjs +1280 -0
- package/dist/timepicker/index.d.cts +215 -0
- package/dist/timepicker/index.d.ts +215 -0
- package/dist/timepicker/index.js +1181 -0
- package/dist/toolbar/index.cjs +395 -0
- package/dist/toolbar/index.d.cts +100 -0
- package/dist/toolbar/index.d.ts +100 -0
- package/dist/toolbar/index.js +325 -0
- package/dist/typography/index.js +1 -2
- package/dist/view/index.cjs +16 -2
- package/dist/view/index.js +16 -2
- package/package.json +73 -8
- package/dist/button.type-D8tzEBo7.d.ts +0 -104
- package/dist/button.type-ikaWzhIg.d.cts +0 -104
- package/dist/chunk-GBHQCAKW.js +0 -19
- package/dist/chunk-JEGEPGVU.js +0 -287
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useXUITheme
|
|
3
|
+
} from "../chunk-4KSZLONZ.js";
|
|
4
|
+
|
|
5
|
+
// src/components/menubox/menubox.tsx
|
|
6
|
+
import React, { useMemo, Children, isValidElement } from "react";
|
|
7
|
+
import { View } from "react-native";
|
|
8
|
+
|
|
9
|
+
// src/components/menubox/menubox-context.ts
|
|
10
|
+
import { createContext, useContext } from "react";
|
|
11
|
+
var MenuBoxContext = createContext(null);
|
|
12
|
+
|
|
13
|
+
// src/components/menubox/menubox.style.ts
|
|
14
|
+
import { StyleSheet } from "react-native";
|
|
15
|
+
var styles = StyleSheet.create({
|
|
16
|
+
container: {
|
|
17
|
+
overflow: "hidden"
|
|
18
|
+
},
|
|
19
|
+
item: {
|
|
20
|
+
flexDirection: "row",
|
|
21
|
+
alignItems: "center",
|
|
22
|
+
gap: 12
|
|
23
|
+
},
|
|
24
|
+
content: {
|
|
25
|
+
flex: 1,
|
|
26
|
+
gap: 2
|
|
27
|
+
},
|
|
28
|
+
title: {
|
|
29
|
+
fontWeight: "500"
|
|
30
|
+
},
|
|
31
|
+
description: {
|
|
32
|
+
opacity: 0.6
|
|
33
|
+
},
|
|
34
|
+
disabled: {
|
|
35
|
+
opacity: 0.5
|
|
36
|
+
},
|
|
37
|
+
divider: {
|
|
38
|
+
height: 1,
|
|
39
|
+
marginLeft: 56
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// src/components/menubox/menubox.tsx
|
|
44
|
+
var MenuBox = ({
|
|
45
|
+
children,
|
|
46
|
+
size = "md",
|
|
47
|
+
radius = "lg",
|
|
48
|
+
themeColor = "default",
|
|
49
|
+
spacing = 0,
|
|
50
|
+
style,
|
|
51
|
+
backgroundColor
|
|
52
|
+
}) => {
|
|
53
|
+
const theme = useXUITheme();
|
|
54
|
+
const itemCount = Children.count(children);
|
|
55
|
+
const itemKeys = useMemo(() => {
|
|
56
|
+
const keys = [];
|
|
57
|
+
Children.forEach(children, (child) => {
|
|
58
|
+
if (isValidElement(child)) {
|
|
59
|
+
const props = child.props;
|
|
60
|
+
if (props.itemKey) {
|
|
61
|
+
keys.push(props.itemKey);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return keys;
|
|
66
|
+
}, [children]);
|
|
67
|
+
const getItemIndex = (itemKey) => {
|
|
68
|
+
return itemKeys.indexOf(itemKey);
|
|
69
|
+
};
|
|
70
|
+
const bgColor = backgroundColor ?? theme.colors.default.background;
|
|
71
|
+
const contextValue = useMemo(
|
|
72
|
+
() => ({
|
|
73
|
+
size,
|
|
74
|
+
radius,
|
|
75
|
+
themeColor,
|
|
76
|
+
backgroundColor: bgColor,
|
|
77
|
+
itemCount,
|
|
78
|
+
spacing,
|
|
79
|
+
getItemIndex
|
|
80
|
+
}),
|
|
81
|
+
[size, radius, themeColor, bgColor, itemCount, spacing, getItemIndex]
|
|
82
|
+
);
|
|
83
|
+
return /* @__PURE__ */ React.createElement(MenuBoxContext.Provider, { value: contextValue }, /* @__PURE__ */ React.createElement(View, { style: [styles.container, style] }, children));
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// src/components/menubox/menubox-item.tsx
|
|
87
|
+
import React2, { useContext as useContext2 } from "react";
|
|
88
|
+
import { Animated as Animated2, Pressable, Text, View as View2 } from "react-native";
|
|
89
|
+
|
|
90
|
+
// src/components/menubox/menubox.hook.ts
|
|
91
|
+
import { useMemo as useMemo2 } from "react";
|
|
92
|
+
var useMenuBoxItemSizeStyles = (size) => {
|
|
93
|
+
const theme = useXUITheme();
|
|
94
|
+
return useMemo2(() => {
|
|
95
|
+
const sizes = {
|
|
96
|
+
xs: {
|
|
97
|
+
paddingVertical: theme.spacing.sm,
|
|
98
|
+
paddingHorizontal: theme.spacing.sm,
|
|
99
|
+
titleSize: theme.fontSizes.xs,
|
|
100
|
+
descriptionSize: theme.fontSizes.xs
|
|
101
|
+
},
|
|
102
|
+
sm: {
|
|
103
|
+
paddingVertical: theme.spacing.sm,
|
|
104
|
+
paddingHorizontal: theme.spacing.md,
|
|
105
|
+
titleSize: theme.fontSizes.sm,
|
|
106
|
+
descriptionSize: theme.fontSizes.xs
|
|
107
|
+
},
|
|
108
|
+
md: {
|
|
109
|
+
paddingVertical: theme.spacing.md,
|
|
110
|
+
paddingHorizontal: theme.spacing.md,
|
|
111
|
+
titleSize: theme.fontSizes.md,
|
|
112
|
+
descriptionSize: theme.fontSizes.sm
|
|
113
|
+
},
|
|
114
|
+
lg: {
|
|
115
|
+
paddingVertical: theme.spacing.lg,
|
|
116
|
+
paddingHorizontal: theme.spacing.lg,
|
|
117
|
+
titleSize: theme.fontSizes.lg,
|
|
118
|
+
descriptionSize: theme.fontSizes.md
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
return sizes[size];
|
|
122
|
+
}, [size, theme]);
|
|
123
|
+
};
|
|
124
|
+
var useMenuBoxRadiusStyles = (radius, isFirst, isLast) => {
|
|
125
|
+
const theme = useXUITheme();
|
|
126
|
+
return useMemo2(() => {
|
|
127
|
+
const radiusMap = {
|
|
128
|
+
none: theme.borderRadius.none,
|
|
129
|
+
sm: theme.borderRadius.md,
|
|
130
|
+
md: theme.borderRadius.lg,
|
|
131
|
+
lg: theme.borderRadius.xl,
|
|
132
|
+
full: theme.borderRadius.full
|
|
133
|
+
};
|
|
134
|
+
const r = radiusMap[radius];
|
|
135
|
+
return {
|
|
136
|
+
borderTopLeftRadius: isFirst ? r : 0,
|
|
137
|
+
borderTopRightRadius: isFirst ? r : 0,
|
|
138
|
+
borderBottomLeftRadius: isLast ? r : 0,
|
|
139
|
+
borderBottomRightRadius: isLast ? r : 0
|
|
140
|
+
};
|
|
141
|
+
}, [radius, isFirst, isLast, theme]);
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// src/components/menubox/menubox.animation.ts
|
|
145
|
+
import { Animated } from "react-native";
|
|
146
|
+
var runMenuBoxPressInAnimation = (animatedScale, animatedOpacity) => {
|
|
147
|
+
Animated.parallel([
|
|
148
|
+
Animated.spring(animatedScale, {
|
|
149
|
+
toValue: 0.99,
|
|
150
|
+
useNativeDriver: true,
|
|
151
|
+
speed: 50,
|
|
152
|
+
bounciness: 0
|
|
153
|
+
}),
|
|
154
|
+
Animated.timing(animatedOpacity, {
|
|
155
|
+
toValue: 0.8,
|
|
156
|
+
duration: 100,
|
|
157
|
+
useNativeDriver: true
|
|
158
|
+
})
|
|
159
|
+
]).start();
|
|
160
|
+
};
|
|
161
|
+
var runMenuBoxPressOutAnimation = (animatedScale, animatedOpacity) => {
|
|
162
|
+
Animated.parallel([
|
|
163
|
+
Animated.spring(animatedScale, {
|
|
164
|
+
toValue: 1,
|
|
165
|
+
useNativeDriver: true,
|
|
166
|
+
speed: 50,
|
|
167
|
+
bounciness: 0
|
|
168
|
+
}),
|
|
169
|
+
Animated.timing(animatedOpacity, {
|
|
170
|
+
toValue: 1,
|
|
171
|
+
duration: 100,
|
|
172
|
+
useNativeDriver: true
|
|
173
|
+
})
|
|
174
|
+
]).start();
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// src/components/menubox/menubox-item.tsx
|
|
178
|
+
var MenuBoxItem = (props) => {
|
|
179
|
+
const context = useContext2(MenuBoxContext);
|
|
180
|
+
const theme = useXUITheme();
|
|
181
|
+
const animatedScale = React2.useRef(new Animated2.Value(1)).current;
|
|
182
|
+
const animatedOpacity = React2.useRef(new Animated2.Value(1)).current;
|
|
183
|
+
const {
|
|
184
|
+
itemKey,
|
|
185
|
+
title,
|
|
186
|
+
description,
|
|
187
|
+
startContent,
|
|
188
|
+
endContent,
|
|
189
|
+
isDisabled = false,
|
|
190
|
+
customAppearance,
|
|
191
|
+
onPress
|
|
192
|
+
} = props;
|
|
193
|
+
const size = context?.size ?? "md";
|
|
194
|
+
const radius = context?.radius ?? "lg";
|
|
195
|
+
const itemBackgroundColor = context?.backgroundColor ?? (theme.mode === "dark" ? theme.colors.default.background : theme.colors.background);
|
|
196
|
+
const spacing = context?.spacing ?? 0;
|
|
197
|
+
const itemCount = context?.itemCount ?? 1;
|
|
198
|
+
const index = context?.getItemIndex(itemKey) ?? 0;
|
|
199
|
+
const isFirst = index === 0;
|
|
200
|
+
const isLast = index === itemCount - 1;
|
|
201
|
+
const sizeStyles = useMenuBoxItemSizeStyles(size);
|
|
202
|
+
const radiusStyles = useMenuBoxRadiusStyles(radius, isFirst, isLast);
|
|
203
|
+
const titleColor = isDisabled ? theme.colors.foreground + "50" : theme.colors.foreground;
|
|
204
|
+
const descriptionColor = isDisabled ? theme.colors.foreground + "50" : theme.colors.foreground + "99";
|
|
205
|
+
const handlePress = () => {
|
|
206
|
+
if (isDisabled) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
onPress?.({});
|
|
210
|
+
};
|
|
211
|
+
const handlePressIn = () => {
|
|
212
|
+
if (!isDisabled) {
|
|
213
|
+
runMenuBoxPressInAnimation(animatedScale, animatedOpacity);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
const handlePressOut = () => {
|
|
217
|
+
if (!isDisabled) {
|
|
218
|
+
runMenuBoxPressOutAnimation(animatedScale, animatedOpacity);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
const renderTitle = () => {
|
|
222
|
+
if (typeof title === "string" || typeof title === "number") {
|
|
223
|
+
return /* @__PURE__ */ React2.createElement(
|
|
224
|
+
Text,
|
|
225
|
+
{
|
|
226
|
+
style: [
|
|
227
|
+
styles.title,
|
|
228
|
+
{ fontSize: sizeStyles.titleSize, color: titleColor },
|
|
229
|
+
customAppearance?.title
|
|
230
|
+
],
|
|
231
|
+
numberOfLines: 1
|
|
232
|
+
},
|
|
233
|
+
title
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
return title;
|
|
237
|
+
};
|
|
238
|
+
const renderDescription = () => {
|
|
239
|
+
if (!description) return null;
|
|
240
|
+
if (typeof description === "string" || typeof description === "number") {
|
|
241
|
+
return /* @__PURE__ */ React2.createElement(
|
|
242
|
+
Text,
|
|
243
|
+
{
|
|
244
|
+
style: [
|
|
245
|
+
styles.description,
|
|
246
|
+
{ fontSize: sizeStyles.descriptionSize, color: descriptionColor },
|
|
247
|
+
customAppearance?.description
|
|
248
|
+
],
|
|
249
|
+
numberOfLines: 1
|
|
250
|
+
},
|
|
251
|
+
description
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
return description;
|
|
255
|
+
};
|
|
256
|
+
const content = /* @__PURE__ */ React2.createElement(
|
|
257
|
+
Animated2.View,
|
|
258
|
+
{
|
|
259
|
+
style: [
|
|
260
|
+
styles.item,
|
|
261
|
+
{
|
|
262
|
+
paddingVertical: sizeStyles.paddingVertical,
|
|
263
|
+
paddingHorizontal: sizeStyles.paddingHorizontal,
|
|
264
|
+
backgroundColor: itemBackgroundColor,
|
|
265
|
+
transform: [{ scale: animatedScale }],
|
|
266
|
+
opacity: animatedOpacity
|
|
267
|
+
},
|
|
268
|
+
radiusStyles,
|
|
269
|
+
isDisabled && styles.disabled,
|
|
270
|
+
customAppearance?.container
|
|
271
|
+
]
|
|
272
|
+
},
|
|
273
|
+
startContent && /* @__PURE__ */ React2.createElement(View2, { style: customAppearance?.content }, startContent),
|
|
274
|
+
/* @__PURE__ */ React2.createElement(View2, { style: [styles.content, customAppearance?.content] }, renderTitle(), renderDescription()),
|
|
275
|
+
endContent && /* @__PURE__ */ React2.createElement(View2, { style: customAppearance?.content }, endContent)
|
|
276
|
+
);
|
|
277
|
+
return /* @__PURE__ */ React2.createElement(
|
|
278
|
+
Pressable,
|
|
279
|
+
{
|
|
280
|
+
onPress: handlePress,
|
|
281
|
+
onPressIn: handlePressIn,
|
|
282
|
+
onPressOut: handlePressOut,
|
|
283
|
+
disabled: isDisabled,
|
|
284
|
+
style: [
|
|
285
|
+
radiusStyles,
|
|
286
|
+
{ overflow: "hidden" },
|
|
287
|
+
!isLast && { marginBottom: spacing }
|
|
288
|
+
]
|
|
289
|
+
},
|
|
290
|
+
content
|
|
291
|
+
);
|
|
292
|
+
};
|
|
293
|
+
export {
|
|
294
|
+
MenuBox,
|
|
295
|
+
MenuBoxItem
|
|
296
|
+
};
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/components/pager/index.ts
|
|
31
|
+
var pager_exports = {};
|
|
32
|
+
__export(pager_exports, {
|
|
33
|
+
Pager: () => Pager,
|
|
34
|
+
PagerItem: () => PagerItem
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(pager_exports);
|
|
37
|
+
|
|
38
|
+
// src/components/pager/pager.tsx
|
|
39
|
+
var import_react = __toESM(require("react"), 1);
|
|
40
|
+
var import_react_native2 = require("react-native");
|
|
41
|
+
|
|
42
|
+
// src/components/pager/pager.style.ts
|
|
43
|
+
var import_react_native = require("react-native");
|
|
44
|
+
var styles = import_react_native.StyleSheet.create({
|
|
45
|
+
container: {
|
|
46
|
+
width: "100%"
|
|
47
|
+
},
|
|
48
|
+
fullscreenContainer: {
|
|
49
|
+
flex: 1
|
|
50
|
+
},
|
|
51
|
+
fullscreenScrollView: {
|
|
52
|
+
flex: 1
|
|
53
|
+
},
|
|
54
|
+
page: {
|
|
55
|
+
width: "100%"
|
|
56
|
+
},
|
|
57
|
+
fullscreenPage: {
|
|
58
|
+
flex: 1
|
|
59
|
+
},
|
|
60
|
+
indicatorContainer: {
|
|
61
|
+
marginTop: 12,
|
|
62
|
+
flexDirection: "row",
|
|
63
|
+
alignItems: "center",
|
|
64
|
+
justifyContent: "center"
|
|
65
|
+
},
|
|
66
|
+
fullscreenIndicatorContainer: {
|
|
67
|
+
position: "absolute",
|
|
68
|
+
bottom: 16,
|
|
69
|
+
left: 16,
|
|
70
|
+
right: 16,
|
|
71
|
+
marginTop: 0,
|
|
72
|
+
zIndex: 1,
|
|
73
|
+
elevation: 1
|
|
74
|
+
},
|
|
75
|
+
indicator: {
|
|
76
|
+
width: 8,
|
|
77
|
+
height: 8,
|
|
78
|
+
marginHorizontal: 3,
|
|
79
|
+
borderRadius: 999,
|
|
80
|
+
backgroundColor: "#D1D5DB"
|
|
81
|
+
},
|
|
82
|
+
activeIndicator: {
|
|
83
|
+
width: 18,
|
|
84
|
+
backgroundColor: "#111827"
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// src/components/pager/pager-item.tsx
|
|
89
|
+
var PagerItem = () => null;
|
|
90
|
+
PagerItem.displayName = "PagerItem";
|
|
91
|
+
|
|
92
|
+
// src/components/pager/pager.tsx
|
|
93
|
+
function clampPage(page, max) {
|
|
94
|
+
return Math.max(0, Math.min(page, max));
|
|
95
|
+
}
|
|
96
|
+
function toPages(children) {
|
|
97
|
+
return import_react.default.Children.toArray(children).flatMap((child, index) => {
|
|
98
|
+
if (!import_react.default.isValidElement(child) || child.type !== PagerItem) {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
return [
|
|
102
|
+
{
|
|
103
|
+
key: child.key != null ? String(child.key) : `page-${String(index)}`,
|
|
104
|
+
content: child.props.children
|
|
105
|
+
}
|
|
106
|
+
];
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
var Pager = ({
|
|
110
|
+
isFullscreen = false,
|
|
111
|
+
isfullscreen,
|
|
112
|
+
page: controlledPage,
|
|
113
|
+
defaultPage = 0,
|
|
114
|
+
onPageChange,
|
|
115
|
+
swipeEnabled = true,
|
|
116
|
+
showIndicator = true,
|
|
117
|
+
renderIndicator,
|
|
118
|
+
children,
|
|
119
|
+
customAppearance
|
|
120
|
+
}) => {
|
|
121
|
+
const isPagerFullscreen = isFullscreen || isfullscreen === true;
|
|
122
|
+
const pages = (0, import_react.useMemo)(() => toPages(children), [children]);
|
|
123
|
+
const maxPage = Math.max(0, pages.length - 1);
|
|
124
|
+
const isControlled = controlledPage !== void 0;
|
|
125
|
+
const [internalPage, setInternalPage] = (0, import_react.useState)(clampPage(defaultPage, maxPage));
|
|
126
|
+
const [containerWidth, setContainerWidth] = (0, import_react.useState)(0);
|
|
127
|
+
const scrollViewRef = (0, import_react.useRef)(null);
|
|
128
|
+
const initialScrollAppliedRef = (0, import_react.useRef)(false);
|
|
129
|
+
const activePage = clampPage(
|
|
130
|
+
isControlled ? controlledPage ?? 0 : internalPage,
|
|
131
|
+
maxPage
|
|
132
|
+
);
|
|
133
|
+
(0, import_react.useEffect)(() => {
|
|
134
|
+
if (isControlled || pages.length === 0) return;
|
|
135
|
+
setInternalPage((prev) => clampPage(prev, maxPage));
|
|
136
|
+
}, [isControlled, maxPage, pages.length]);
|
|
137
|
+
(0, import_react.useEffect)(() => {
|
|
138
|
+
if (containerWidth <= 0) return;
|
|
139
|
+
if (pages.length <= 1) return;
|
|
140
|
+
const x = activePage * containerWidth;
|
|
141
|
+
if (!initialScrollAppliedRef.current) {
|
|
142
|
+
initialScrollAppliedRef.current = true;
|
|
143
|
+
scrollViewRef.current?.scrollTo({ x, animated: false });
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
scrollViewRef.current?.scrollTo({ x, animated: true });
|
|
147
|
+
}, [activePage, containerWidth, pages.length]);
|
|
148
|
+
const handleLayout = (0, import_react.useCallback)((event) => {
|
|
149
|
+
setContainerWidth(event.nativeEvent.layout.width);
|
|
150
|
+
}, []);
|
|
151
|
+
const commitPageChange = (0, import_react.useCallback)(
|
|
152
|
+
(nextPage) => {
|
|
153
|
+
if (!isControlled) {
|
|
154
|
+
setInternalPage(nextPage);
|
|
155
|
+
}
|
|
156
|
+
onPageChange?.(nextPage);
|
|
157
|
+
},
|
|
158
|
+
[isControlled, onPageChange]
|
|
159
|
+
);
|
|
160
|
+
const handleMomentumScrollEnd = (0, import_react.useCallback)(
|
|
161
|
+
(event) => {
|
|
162
|
+
if (containerWidth <= 0 || pages.length === 0) return;
|
|
163
|
+
const rawPage = Math.round(event.nativeEvent.contentOffset.x / containerWidth);
|
|
164
|
+
const nextPage = clampPage(rawPage, maxPage);
|
|
165
|
+
if (nextPage !== activePage) {
|
|
166
|
+
commitPageChange(nextPage);
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
[activePage, commitPageChange, containerWidth, maxPage, pages.length]
|
|
170
|
+
);
|
|
171
|
+
return /* @__PURE__ */ import_react.default.createElement(
|
|
172
|
+
import_react_native2.View,
|
|
173
|
+
{
|
|
174
|
+
onLayout: handleLayout,
|
|
175
|
+
style: [
|
|
176
|
+
styles.container,
|
|
177
|
+
isPagerFullscreen && styles.fullscreenContainer,
|
|
178
|
+
customAppearance?.container
|
|
179
|
+
]
|
|
180
|
+
},
|
|
181
|
+
/* @__PURE__ */ import_react.default.createElement(
|
|
182
|
+
import_react_native2.ScrollView,
|
|
183
|
+
{
|
|
184
|
+
ref: scrollViewRef,
|
|
185
|
+
horizontal: true,
|
|
186
|
+
pagingEnabled: true,
|
|
187
|
+
showsHorizontalScrollIndicator: false,
|
|
188
|
+
scrollEnabled: swipeEnabled,
|
|
189
|
+
onMomentumScrollEnd: handleMomentumScrollEnd,
|
|
190
|
+
style: [
|
|
191
|
+
isPagerFullscreen && styles.fullscreenScrollView,
|
|
192
|
+
customAppearance?.scrollView
|
|
193
|
+
]
|
|
194
|
+
},
|
|
195
|
+
pages.map((pagerPage) => /* @__PURE__ */ import_react.default.createElement(
|
|
196
|
+
import_react_native2.View,
|
|
197
|
+
{
|
|
198
|
+
key: pagerPage.key,
|
|
199
|
+
style: [
|
|
200
|
+
styles.page,
|
|
201
|
+
isPagerFullscreen && styles.fullscreenPage,
|
|
202
|
+
customAppearance?.page,
|
|
203
|
+
containerWidth > 0 && { width: containerWidth }
|
|
204
|
+
]
|
|
205
|
+
},
|
|
206
|
+
pagerPage.content
|
|
207
|
+
))
|
|
208
|
+
),
|
|
209
|
+
showIndicator && pages.length > 1 && /* @__PURE__ */ import_react.default.createElement(
|
|
210
|
+
import_react_native2.View,
|
|
211
|
+
{
|
|
212
|
+
style: [
|
|
213
|
+
styles.indicatorContainer,
|
|
214
|
+
customAppearance?.indicatorContainer,
|
|
215
|
+
isPagerFullscreen && styles.fullscreenIndicatorContainer
|
|
216
|
+
]
|
|
217
|
+
},
|
|
218
|
+
pages.map((_, index) => {
|
|
219
|
+
const isActive = index === activePage;
|
|
220
|
+
if (renderIndicator) {
|
|
221
|
+
return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, { key: `indicator-${String(index)}` }, renderIndicator({ index, isActive, total: pages.length }));
|
|
222
|
+
}
|
|
223
|
+
return /* @__PURE__ */ import_react.default.createElement(
|
|
224
|
+
import_react_native2.View,
|
|
225
|
+
{
|
|
226
|
+
key: `indicator-${String(index)}`,
|
|
227
|
+
style: [
|
|
228
|
+
styles.indicator,
|
|
229
|
+
customAppearance?.indicator,
|
|
230
|
+
isActive && styles.activeIndicator,
|
|
231
|
+
isActive && customAppearance?.activeIndicator
|
|
232
|
+
]
|
|
233
|
+
}
|
|
234
|
+
);
|
|
235
|
+
})
|
|
236
|
+
)
|
|
237
|
+
);
|
|
238
|
+
};
|
|
239
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
240
|
+
0 && (module.exports = {
|
|
241
|
+
Pager,
|
|
242
|
+
PagerItem
|
|
243
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { ViewStyle } from 'react-native';
|
|
3
|
+
|
|
4
|
+
type PagerIndicatorRenderState = {
|
|
5
|
+
index: number;
|
|
6
|
+
isActive: boolean;
|
|
7
|
+
total: number;
|
|
8
|
+
};
|
|
9
|
+
type PagerCustomAppearance = {
|
|
10
|
+
/**
|
|
11
|
+
* Custom styles for the outer wrapper.
|
|
12
|
+
*/
|
|
13
|
+
container?: ViewStyle;
|
|
14
|
+
/**
|
|
15
|
+
* Custom styles for the internal scroll view.
|
|
16
|
+
*/
|
|
17
|
+
scrollView?: ViewStyle;
|
|
18
|
+
/**
|
|
19
|
+
* Custom styles applied to each page wrapper.
|
|
20
|
+
*/
|
|
21
|
+
page?: ViewStyle;
|
|
22
|
+
/**
|
|
23
|
+
* Custom styles for the indicator row.
|
|
24
|
+
*/
|
|
25
|
+
indicatorContainer?: ViewStyle;
|
|
26
|
+
/**
|
|
27
|
+
* Custom styles for each indicator item.
|
|
28
|
+
*/
|
|
29
|
+
indicator?: ViewStyle;
|
|
30
|
+
/**
|
|
31
|
+
* Custom styles for the active indicator item.
|
|
32
|
+
*/
|
|
33
|
+
activeIndicator?: ViewStyle;
|
|
34
|
+
};
|
|
35
|
+
type PagerProps = {
|
|
36
|
+
/**
|
|
37
|
+
* Whether the pager should fill its parent and render indicators inside.
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
isFullscreen?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Alias of `isFullscreen`.
|
|
43
|
+
* @default false
|
|
44
|
+
*/
|
|
45
|
+
isfullscreen?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Controlled active page index.
|
|
48
|
+
*/
|
|
49
|
+
page?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Default active page index (uncontrolled mode).
|
|
52
|
+
* @default 0
|
|
53
|
+
*/
|
|
54
|
+
defaultPage?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Callback fired when active page changes.
|
|
57
|
+
*/
|
|
58
|
+
onPageChange?: (page: number) => void;
|
|
59
|
+
/**
|
|
60
|
+
* Whether swipe gesture is enabled.
|
|
61
|
+
* @default true
|
|
62
|
+
*/
|
|
63
|
+
swipeEnabled?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Whether to render indicators.
|
|
66
|
+
* @default true
|
|
67
|
+
*/
|
|
68
|
+
showIndicator?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Optional custom indicator renderer.
|
|
71
|
+
*/
|
|
72
|
+
renderIndicator?: (state: PagerIndicatorRenderState) => ReactNode;
|
|
73
|
+
/**
|
|
74
|
+
* Pager pages. Prefer using `PagerItem`.
|
|
75
|
+
*/
|
|
76
|
+
children: ReactNode;
|
|
77
|
+
/**
|
|
78
|
+
* Appearance overrides.
|
|
79
|
+
*/
|
|
80
|
+
customAppearance?: PagerCustomAppearance;
|
|
81
|
+
};
|
|
82
|
+
type PagerItemProps = {
|
|
83
|
+
/**
|
|
84
|
+
* Page content.
|
|
85
|
+
*/
|
|
86
|
+
children?: ReactNode;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
declare const Pager: React.FC<PagerProps>;
|
|
90
|
+
|
|
91
|
+
declare const PagerItem: React.FC<PagerItemProps>;
|
|
92
|
+
|
|
93
|
+
export { Pager, type PagerIndicatorRenderState, PagerItem, type PagerItemProps, type PagerProps };
|