@retray-dev/ui-kit 7.0.1 → 9.0.0
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/COMPONENTS.md +554 -11
- package/EXAMPLES.md +2 -2
- package/README.md +14 -8
- package/dist/Accordion.js +57 -5
- package/dist/Accordion.mjs +4 -3
- package/dist/AlertBanner.js +4 -1
- package/dist/AlertBanner.mjs +3 -2
- package/dist/AppHeader.d.mts +40 -0
- package/dist/AppHeader.d.ts +40 -0
- package/dist/AppHeader.js +515 -0
- package/dist/AppHeader.mjs +10 -0
- package/dist/Avatar.js +39 -29
- package/dist/Avatar.mjs +2 -1
- package/dist/Badge.js +11 -1
- package/dist/Badge.mjs +2 -1
- package/dist/Button.d.mts +8 -3
- package/dist/Button.d.ts +8 -3
- package/dist/Button.js +126 -108
- package/dist/Button.mjs +6 -5
- package/dist/ButtonGroup.mjs +1 -0
- package/dist/Card.js +90 -70
- package/dist/Card.mjs +5 -4
- package/dist/CategoryStrip.js +79 -22
- package/dist/CategoryStrip.mjs +6 -6
- package/dist/Checkbox.js +118 -86
- package/dist/Checkbox.mjs +5 -5
- package/dist/Chip.js +113 -80
- package/dist/Chip.mjs +5 -5
- package/dist/ConfirmDialog.js +140 -110
- package/dist/ConfirmDialog.mjs +7 -6
- package/dist/CurrencyDisplay.mjs +1 -0
- package/dist/CurrencyInput.d.mts +1 -1
- package/dist/CurrencyInput.d.ts +1 -1
- package/dist/CurrencyInput.js +9 -5
- package/dist/CurrencyInput.mjs +5 -4
- package/dist/DetailRow.mjs +1 -0
- package/dist/EmptyState.js +131 -111
- package/dist/EmptyState.mjs +7 -6
- package/dist/ErrorBoundary.d.mts +42 -0
- package/dist/ErrorBoundary.d.ts +42 -0
- package/dist/ErrorBoundary.js +351 -0
- package/dist/ErrorBoundary.mjs +7 -0
- package/dist/Form.mjs +1 -0
- package/dist/HolographicCard.d.mts +55 -0
- package/dist/HolographicCard.d.ts +55 -0
- package/dist/HolographicCard.js +316 -0
- package/dist/HolographicCard.mjs +191 -0
- package/dist/IconButton.d.mts +8 -3
- package/dist/IconButton.d.ts +8 -3
- package/dist/IconButton.js +115 -98
- package/dist/IconButton.mjs +5 -4
- package/dist/ImageViewer.d.mts +23 -0
- package/dist/ImageViewer.d.ts +23 -0
- package/dist/ImageViewer.js +582 -0
- package/dist/ImageViewer.mjs +8 -0
- package/dist/Input.mjs +4 -3
- package/dist/LabelValue.mjs +1 -0
- package/dist/ListGroup.mjs +1 -0
- package/dist/ListItem.js +131 -117
- package/dist/ListItem.mjs +6 -5
- package/dist/MediaCard.js +54 -6
- package/dist/MediaCard.mjs +6 -5
- package/dist/MenuGroup.mjs +1 -0
- package/dist/MenuItem.js +91 -79
- package/dist/MenuItem.mjs +6 -5
- package/dist/MonthPicker.d.mts +10 -2
- package/dist/MonthPicker.d.ts +10 -2
- package/dist/MonthPicker.js +80 -17
- package/dist/MonthPicker.mjs +3 -2
- package/dist/PagerDots.d.mts +35 -0
- package/dist/PagerDots.d.ts +35 -0
- package/dist/PagerDots.js +392 -0
- package/dist/PagerDots.mjs +7 -0
- package/dist/Pressable.d.mts +5 -5
- package/dist/Pressable.d.ts +5 -5
- package/dist/Pressable.js +97 -86
- package/dist/Pressable.mjs +5 -4
- package/dist/PricingCard.d.mts +50 -0
- package/dist/PricingCard.d.ts +50 -0
- package/dist/PricingCard.js +636 -0
- package/dist/PricingCard.mjs +11 -0
- package/dist/Progress.mjs +3 -2
- package/dist/RadioGroup.js +81 -30
- package/dist/RadioGroup.mjs +5 -5
- package/dist/RetrayProvider.d.mts +2 -0
- package/dist/RetrayProvider.d.ts +2 -0
- package/dist/RetrayProvider.js +214 -0
- package/dist/RetrayProvider.mjs +5 -0
- package/dist/Select.js +51 -4
- package/dist/Select.mjs +5 -4
- package/dist/SelectableGrid.d.mts +44 -0
- package/dist/SelectableGrid.d.ts +44 -0
- package/dist/SelectableGrid.js +448 -0
- package/dist/SelectableGrid.mjs +9 -0
- package/dist/Separator.mjs +1 -0
- package/dist/Sheet.d.mts +13 -1
- package/dist/Sheet.d.ts +13 -1
- package/dist/Sheet.js +115 -5
- package/dist/Sheet.mjs +4 -2
- package/dist/Skeleton.d.mts +50 -0
- package/dist/Skeleton.d.ts +50 -0
- package/dist/Skeleton.js +61 -0
- package/dist/Skeleton.mjs +4 -2
- package/dist/Slider.js +51 -4
- package/dist/Slider.mjs +3 -2
- package/dist/Spinner.js +28 -7
- package/dist/Spinner.mjs +2 -1
- package/dist/Switch.js +98 -48
- package/dist/Switch.mjs +4 -3
- package/dist/TabBar.d.mts +42 -0
- package/dist/TabBar.d.ts +42 -0
- package/dist/TabBar.js +361 -0
- package/dist/TabBar.mjs +6 -0
- package/dist/Tabs.js +92 -62
- package/dist/Tabs.mjs +5 -4
- package/dist/Text.js +16 -0
- package/dist/Text.mjs +2 -1
- package/dist/Textarea.mjs +4 -3
- package/dist/Toast.d.mts +7 -7
- package/dist/Toast.d.ts +7 -7
- package/dist/Toast.mjs +1 -0
- package/dist/Toggle.d.mts +6 -3
- package/dist/Toggle.d.ts +6 -3
- package/dist/Toggle.js +135 -120
- package/dist/Toggle.mjs +5 -5
- package/dist/VirtualList.mjs +1 -0
- package/dist/{chunk-7H2OR44A.mjs → chunk-26BCI223.mjs} +1 -1
- package/dist/{chunk-CRYBX2CM.mjs → chunk-2TFTAWVJ.mjs} +44 -59
- package/dist/chunk-3DKJ2GIC.mjs +30 -0
- package/dist/{chunk-KWCPOM6W.mjs → chunk-3U4SSNWP.mjs} +32 -48
- package/dist/chunk-4I7D47FH.mjs +139 -0
- package/dist/chunk-4K625MVM.mjs +142 -0
- package/dist/{chunk-MN7OG7IY.mjs → chunk-6OAZJ577.mjs} +6 -4
- package/dist/{chunk-L7E7TVEZ.mjs → chunk-756RAKE4.mjs} +2 -2
- package/dist/{chunk-HSPSMN6U.mjs → chunk-7QHVVCB3.mjs} +2 -2
- package/dist/{chunk-URLL5JBR.mjs → chunk-A3A6KNQN.mjs} +3 -3
- package/dist/chunk-AJ7ZDNBT.mjs +120 -0
- package/dist/{chunk-FTLJOUOQ.mjs → chunk-AV4EMIRH.mjs} +25 -28
- package/dist/chunk-AZJF2BLK.mjs +115 -0
- package/dist/chunk-BNP626TY.mjs +159 -0
- package/dist/{chunk-5IKW3VNC.mjs → chunk-DVK4G2GT.mjs} +17 -1
- package/dist/{chunk-6LQYY7HC.mjs → chunk-EH745HE5.mjs} +2 -2
- package/dist/chunk-EJ7ZPXOH.mjs +163 -0
- package/dist/{chunk-RKLHUDZS.mjs → chunk-GD6KXMG5.mjs} +29 -15
- package/dist/{chunk-RR2VQLKE.mjs → chunk-GQYFLP3D.mjs} +14 -17
- package/dist/{chunk-Y6MXOREN.mjs → chunk-ID72TK46.mjs} +8 -17
- package/dist/{chunk-NQGVLMWG.mjs → chunk-JMOZEC77.mjs} +1 -1
- package/dist/{chunk-GCWOGZYL.mjs → chunk-JT7HKXRB.mjs} +39 -29
- package/dist/{chunk-LWG526VX.mjs → chunk-KIHCWCWL.mjs} +47 -62
- package/dist/chunk-LXJIIOYQ.mjs +104 -0
- package/dist/{chunk-SBZYEV4S.mjs → chunk-M6ZXVBTK.mjs} +5 -2
- package/dist/{chunk-XDMN67KV.mjs → chunk-MAC465BB.mjs} +10 -8
- package/dist/chunk-MBMXYJJV.mjs +36 -0
- package/dist/chunk-MLF3EZFW.mjs +119 -0
- package/dist/chunk-NA7PARID.mjs +147 -0
- package/dist/{chunk-QXGYKWI7.mjs → chunk-O3HA6TYM.mjs} +9 -4
- package/dist/{chunk-63357L2X.mjs → chunk-OB4JUQ3O.mjs} +1 -1
- package/dist/{chunk-AU2VDY4P.mjs → chunk-PFZTM6D5.mjs} +52 -4
- package/dist/chunk-QKH5ZOD5.mjs +97 -0
- package/dist/{chunk-KZJRQOIU.mjs → chunk-TERDKCLE.mjs} +11 -1
- package/dist/{chunk-U4N7WF4Z.mjs → chunk-UREA2GYY.mjs} +28 -23
- package/dist/{chunk-TAJ2PQ2O.mjs → chunk-VGTDN7SW.mjs} +7 -6
- package/dist/{chunk-URDE3EUU.mjs → chunk-VQ57HWPL.mjs} +27 -15
- package/dist/chunk-WBOOUHSS.mjs +62 -0
- package/dist/{chunk-GNGLDL6Z.mjs → chunk-WJLKJMKR.mjs} +18 -0
- package/dist/{chunk-YZJAFS4P.mjs → chunk-X4G6APW6.mjs} +22 -19
- package/dist/chunk-Y6FXYEAI.mjs +8 -0
- package/dist/chunk-YFZ3ELX5.mjs +16 -0
- package/dist/{chunk-QCNARS3X.mjs → chunk-YNROWHQJ.mjs} +1 -1
- package/dist/chunk-Z4BVUWW6.mjs +196 -0
- package/dist/{chunk-GPOUINK5.mjs → chunk-ZJKGQMYH.mjs} +10 -27
- package/dist/index-wt-orHUi.d.mts +85 -0
- package/dist/index-wt-orHUi.d.ts +85 -0
- package/dist/index.d.mts +59 -51
- package/dist/index.d.ts +59 -51
- package/dist/index.js +1940 -744
- package/dist/index.mjs +49 -39
- package/package.json +35 -5
- package/src/components/Accordion/Accordion.tsx +12 -1
- package/src/components/AlertBanner/AlertBanner.tsx +5 -0
- package/src/components/AppHeader/AppHeader.tsx +172 -0
- package/src/components/AppHeader/index.ts +1 -0
- package/src/components/Avatar/Avatar.tsx +10 -2
- package/src/components/Badge/Badge.tsx +8 -1
- package/src/components/Button/Button.tsx +20 -27
- package/src/components/Card/Card.tsx +12 -23
- package/src/components/CategoryStrip/CategoryStrip.tsx +17 -21
- package/src/components/Checkbox/Checkbox.tsx +26 -40
- package/src/components/Chip/Chip.tsx +24 -33
- package/src/components/CurrencyInput/CurrencyInput.tsx +10 -8
- package/src/components/EmptyState/EmptyState.tsx +2 -1
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +153 -0
- package/src/components/ErrorBoundary/index.ts +1 -0
- package/src/components/HolographicCard/HolographicCard.tsx +315 -0
- package/src/components/HolographicCard/index.ts +1 -0
- package/src/components/IconButton/IconButton.tsx +19 -27
- package/src/components/ImageViewer/ImageViewer.tsx +290 -0
- package/src/components/ImageViewer/index.ts +1 -0
- package/src/components/ListItem/ListItem.tsx +70 -67
- package/src/components/MediaCard/MediaCard.tsx +8 -2
- package/src/components/MenuItem/MenuItem.tsx +10 -25
- package/src/components/MonthPicker/MonthPicker.tsx +39 -13
- package/src/components/MonthPicker/index.ts +1 -1
- package/src/components/PagerDots/PagerDots.tsx +200 -0
- package/src/components/PagerDots/index.ts +1 -0
- package/src/components/Pressable/Pressable.tsx +19 -35
- package/src/components/PricingCard/PricingCard.tsx +220 -0
- package/src/components/PricingCard/index.ts +1 -0
- package/src/components/RadioGroup/RadioGroup.tsx +14 -27
- package/src/components/RetrayProvider/RetrayProvider.tsx +59 -0
- package/src/components/RetrayProvider/index.ts +1 -0
- package/src/components/SelectableGrid/SelectableGrid.tsx +205 -0
- package/src/components/SelectableGrid/index.ts +1 -0
- package/src/components/Sheet/Sheet.tsx +65 -1
- package/src/components/Skeleton/Skeleton.tsx +142 -1
- package/src/components/Spinner/Spinner.tsx +17 -2
- package/src/components/Switch/Switch.tsx +30 -58
- package/src/components/TabBar/TabBar.tsx +169 -0
- package/src/components/TabBar/index.ts +1 -0
- package/src/components/Tabs/Tabs.tsx +23 -26
- package/src/components/Text/Text.tsx +2 -0
- package/src/components/Toggle/Toggle.tsx +35 -51
- package/src/fonts.ts +4 -1
- package/src/index.ts +23 -2
- package/src/utils/animations.ts +29 -1
- package/src/utils/fontGuard.ts +34 -0
- package/src/utils/haptics.ts +211 -9
- package/src/utils/pressable.ts +66 -0
- package/dist/chunk-76PFOSM2.mjs +0 -41
- package/dist/chunk-DITNP6PL.mjs +0 -106
- package/dist/chunk-JBLL7U3U.mjs +0 -64
- package/dist/chunk-LG4DO3DK.mjs +0 -174
- package/dist/chunk-RMMK64W5.mjs +0 -54
- package/dist/chunk-RTC3CFXF.mjs +0 -29
package/dist/Skeleton.d.mts
CHANGED
|
@@ -13,5 +13,55 @@ interface SkeletonProps {
|
|
|
13
13
|
style?: ViewStyle;
|
|
14
14
|
}
|
|
15
15
|
declare function Skeleton({ width, height, borderRadius, preset, diameter, style, }: SkeletonProps): React.JSX.Element;
|
|
16
|
+
declare namespace Skeleton {
|
|
17
|
+
var MediaCard: typeof MediaCardSkeleton;
|
|
18
|
+
var ListItem: typeof ListItemSkeleton;
|
|
19
|
+
var List: typeof ListSkeleton;
|
|
20
|
+
}
|
|
21
|
+
declare const aspectRatioMap: {
|
|
22
|
+
readonly '1:1': 1;
|
|
23
|
+
readonly '4:3': number;
|
|
24
|
+
readonly '16:9': number;
|
|
25
|
+
readonly '4:5': number;
|
|
26
|
+
readonly '3:2': number;
|
|
27
|
+
};
|
|
28
|
+
type MediaCardSkeletonAspectRatio = keyof typeof aspectRatioMap;
|
|
29
|
+
interface MediaCardSkeletonProps {
|
|
30
|
+
/** Image aspect ratio — match your `MediaCard`. Defaults to `'4:3'`. */
|
|
31
|
+
aspectRatio?: MediaCardSkeletonAspectRatio;
|
|
32
|
+
/** Show the subtitle/caption line below the title. Defaults to true. */
|
|
33
|
+
showSubtitle?: boolean;
|
|
34
|
+
style?: ViewStyle;
|
|
35
|
+
}
|
|
36
|
+
/** Loading placeholder matching `<MediaCard>` — image block + title/subtitle lines. */
|
|
37
|
+
declare function MediaCardSkeleton({ aspectRatio, showSubtitle, style }: MediaCardSkeletonProps): React.JSX.Element;
|
|
38
|
+
interface ListItemSkeletonProps {
|
|
39
|
+
/** Render a circular leading avatar placeholder. Defaults to true. */
|
|
40
|
+
showAvatar?: boolean;
|
|
41
|
+
/** Render a secondary subtitle line. Defaults to true. */
|
|
42
|
+
showSubtitle?: boolean;
|
|
43
|
+
style?: ViewStyle;
|
|
44
|
+
}
|
|
45
|
+
/** Loading placeholder matching `<ListItem>` — leading circle + title/subtitle lines. */
|
|
46
|
+
declare function ListItemSkeleton({ showAvatar, showSubtitle, style }: ListItemSkeletonProps): React.JSX.Element;
|
|
47
|
+
interface ListSkeletonProps {
|
|
48
|
+
/** Number of placeholder rows/cells. Defaults to 6. */
|
|
49
|
+
count?: number;
|
|
50
|
+
/** 1 = stacked list of `ListItemSkeleton`; >1 = grid of `MediaCardSkeleton`. Defaults to 1. */
|
|
51
|
+
columns?: number;
|
|
52
|
+
/** Gap between items (dp). Defaults to 12. */
|
|
53
|
+
gap?: number;
|
|
54
|
+
/** Grid only — aspect ratio of each `MediaCardSkeleton`. Defaults to `'4:3'`. */
|
|
55
|
+
aspectRatio?: MediaCardSkeletonAspectRatio;
|
|
56
|
+
/** List only — show the leading avatar circle. Defaults to true. */
|
|
57
|
+
showAvatar?: boolean;
|
|
58
|
+
style?: ViewStyle;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Repeated loading placeholder for a `VirtualList` / list / grid. `columns={1}`
|
|
62
|
+
* renders stacked `ListItemSkeleton`s; `columns>1` renders a wrapping grid of
|
|
63
|
+
* `MediaCardSkeleton`s. Render this as the list's content while `data` is empty.
|
|
64
|
+
*/
|
|
65
|
+
declare function ListSkeleton({ count, columns, gap, aspectRatio, showAvatar, style, }: ListSkeletonProps): React.JSX.Element;
|
|
16
66
|
|
|
17
67
|
export { Skeleton, type SkeletonProps };
|
package/dist/Skeleton.d.ts
CHANGED
|
@@ -13,5 +13,55 @@ interface SkeletonProps {
|
|
|
13
13
|
style?: ViewStyle;
|
|
14
14
|
}
|
|
15
15
|
declare function Skeleton({ width, height, borderRadius, preset, diameter, style, }: SkeletonProps): React.JSX.Element;
|
|
16
|
+
declare namespace Skeleton {
|
|
17
|
+
var MediaCard: typeof MediaCardSkeleton;
|
|
18
|
+
var ListItem: typeof ListItemSkeleton;
|
|
19
|
+
var List: typeof ListSkeleton;
|
|
20
|
+
}
|
|
21
|
+
declare const aspectRatioMap: {
|
|
22
|
+
readonly '1:1': 1;
|
|
23
|
+
readonly '4:3': number;
|
|
24
|
+
readonly '16:9': number;
|
|
25
|
+
readonly '4:5': number;
|
|
26
|
+
readonly '3:2': number;
|
|
27
|
+
};
|
|
28
|
+
type MediaCardSkeletonAspectRatio = keyof typeof aspectRatioMap;
|
|
29
|
+
interface MediaCardSkeletonProps {
|
|
30
|
+
/** Image aspect ratio — match your `MediaCard`. Defaults to `'4:3'`. */
|
|
31
|
+
aspectRatio?: MediaCardSkeletonAspectRatio;
|
|
32
|
+
/** Show the subtitle/caption line below the title. Defaults to true. */
|
|
33
|
+
showSubtitle?: boolean;
|
|
34
|
+
style?: ViewStyle;
|
|
35
|
+
}
|
|
36
|
+
/** Loading placeholder matching `<MediaCard>` — image block + title/subtitle lines. */
|
|
37
|
+
declare function MediaCardSkeleton({ aspectRatio, showSubtitle, style }: MediaCardSkeletonProps): React.JSX.Element;
|
|
38
|
+
interface ListItemSkeletonProps {
|
|
39
|
+
/** Render a circular leading avatar placeholder. Defaults to true. */
|
|
40
|
+
showAvatar?: boolean;
|
|
41
|
+
/** Render a secondary subtitle line. Defaults to true. */
|
|
42
|
+
showSubtitle?: boolean;
|
|
43
|
+
style?: ViewStyle;
|
|
44
|
+
}
|
|
45
|
+
/** Loading placeholder matching `<ListItem>` — leading circle + title/subtitle lines. */
|
|
46
|
+
declare function ListItemSkeleton({ showAvatar, showSubtitle, style }: ListItemSkeletonProps): React.JSX.Element;
|
|
47
|
+
interface ListSkeletonProps {
|
|
48
|
+
/** Number of placeholder rows/cells. Defaults to 6. */
|
|
49
|
+
count?: number;
|
|
50
|
+
/** 1 = stacked list of `ListItemSkeleton`; >1 = grid of `MediaCardSkeleton`. Defaults to 1. */
|
|
51
|
+
columns?: number;
|
|
52
|
+
/** Gap between items (dp). Defaults to 12. */
|
|
53
|
+
gap?: number;
|
|
54
|
+
/** Grid only — aspect ratio of each `MediaCardSkeleton`. Defaults to `'4:3'`. */
|
|
55
|
+
aspectRatio?: MediaCardSkeletonAspectRatio;
|
|
56
|
+
/** List only — show the leading avatar circle. Defaults to true. */
|
|
57
|
+
showAvatar?: boolean;
|
|
58
|
+
style?: ViewStyle;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Repeated loading placeholder for a `VirtualList` / list / grid. `columns={1}`
|
|
62
|
+
* renders stacked `ListItemSkeleton`s; `columns>1` renders a wrapping grid of
|
|
63
|
+
* `MediaCardSkeleton`s. Render this as the list's content while `data` is empty.
|
|
64
|
+
*/
|
|
65
|
+
declare function ListSkeleton({ count, columns, gap, aspectRatio, showAvatar, style, }: ListSkeletonProps): React.JSX.Element;
|
|
16
66
|
|
|
17
67
|
export { Skeleton, type SkeletonProps };
|
package/dist/Skeleton.js
CHANGED
|
@@ -133,6 +133,7 @@ function useTheme() {
|
|
|
133
133
|
}
|
|
134
134
|
var isWeb = reactNative.Platform.OS === "web";
|
|
135
135
|
var s = isWeb ? (n) => n : reactNativeSizeMatters.scale;
|
|
136
|
+
var vs = isWeb ? (n) => n : reactNativeSizeMatters.verticalScale;
|
|
136
137
|
var TIMINGS = {
|
|
137
138
|
/** Skeleton shimmer cycle (full pass). */
|
|
138
139
|
shimmer: { duration: 1400 }
|
|
@@ -146,6 +147,11 @@ var TIMINGS = {
|
|
|
146
147
|
collapse: Animated.Easing.in(Animated.Easing.ease)
|
|
147
148
|
});
|
|
148
149
|
|
|
150
|
+
// src/tokens.ts
|
|
151
|
+
var RADIUS = {
|
|
152
|
+
xs: 4,
|
|
153
|
+
md: 14};
|
|
154
|
+
|
|
149
155
|
// src/components/Skeleton/Skeleton.tsx
|
|
150
156
|
function Skeleton({
|
|
151
157
|
width = "100%",
|
|
@@ -196,10 +202,65 @@ function Skeleton({
|
|
|
196
202
|
))
|
|
197
203
|
);
|
|
198
204
|
}
|
|
205
|
+
var aspectRatioMap = {
|
|
206
|
+
"1:1": 1,
|
|
207
|
+
"4:3": 3 / 4,
|
|
208
|
+
"16:9": 9 / 16,
|
|
209
|
+
"4:5": 5 / 4,
|
|
210
|
+
"3:2": 2 / 3
|
|
211
|
+
};
|
|
212
|
+
function MediaCardSkeleton({ aspectRatio = "4:3", showSubtitle = true, style }) {
|
|
213
|
+
const ratio = aspectRatioMap[aspectRatio];
|
|
214
|
+
return /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style }, /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: { paddingTop: `${ratio * 100}%` } }, /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: reactNative.StyleSheet.absoluteFill }, /* @__PURE__ */ React2__default.default.createElement(Skeleton, { width: "100%", height: void 0, style: skeletonStyles.fill, borderRadius: RADIUS.md }))), /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: skeletonStyles.meta }, /* @__PURE__ */ React2__default.default.createElement(Skeleton, { width: "70%", height: vs(14), borderRadius: RADIUS.xs }), showSubtitle ? /* @__PURE__ */ React2__default.default.createElement(Skeleton, { width: "45%", height: vs(12), borderRadius: RADIUS.xs }) : null));
|
|
215
|
+
}
|
|
216
|
+
function ListItemSkeleton({ showAvatar = true, showSubtitle = true, style }) {
|
|
217
|
+
return /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: [skeletonStyles.row, style] }, showAvatar ? /* @__PURE__ */ React2__default.default.createElement(Skeleton, { preset: "circle", diameter: 40 }) : null, /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: skeletonStyles.rowText }, /* @__PURE__ */ React2__default.default.createElement(Skeleton, { width: "60%", height: vs(14), borderRadius: RADIUS.xs }), showSubtitle ? /* @__PURE__ */ React2__default.default.createElement(Skeleton, { width: "40%", height: vs(12), borderRadius: RADIUS.xs }) : null));
|
|
218
|
+
}
|
|
219
|
+
function ListSkeleton({
|
|
220
|
+
count = 6,
|
|
221
|
+
columns = 1,
|
|
222
|
+
gap = 12,
|
|
223
|
+
aspectRatio = "4:3",
|
|
224
|
+
showAvatar = true,
|
|
225
|
+
style
|
|
226
|
+
}) {
|
|
227
|
+
if (columns <= 1) {
|
|
228
|
+
return /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: [{ gap: vs(gap) }, style] }, Array.from({ length: count }).map((_, i) => /* @__PURE__ */ React2__default.default.createElement(ListItemSkeleton, { key: i, showAvatar })));
|
|
229
|
+
}
|
|
230
|
+
const widthPct = `${100 / columns}%`;
|
|
231
|
+
return /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: [skeletonStyles.grid, { marginHorizontal: -s(gap) / 2 }, style] }, Array.from({ length: count }).map((_, i) => /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { key: i, style: { width: widthPct, paddingHorizontal: s(gap) / 2, marginBottom: vs(gap) } }, /* @__PURE__ */ React2__default.default.createElement(MediaCardSkeleton, { aspectRatio }))));
|
|
232
|
+
}
|
|
233
|
+
Skeleton.MediaCard = MediaCardSkeleton;
|
|
234
|
+
Skeleton.ListItem = ListItemSkeleton;
|
|
235
|
+
Skeleton.List = ListSkeleton;
|
|
199
236
|
var styles = reactNative.StyleSheet.create({
|
|
200
237
|
base: {
|
|
201
238
|
overflow: "hidden"
|
|
202
239
|
}
|
|
203
240
|
});
|
|
241
|
+
var skeletonStyles = reactNative.StyleSheet.create({
|
|
242
|
+
grid: {
|
|
243
|
+
flexDirection: "row",
|
|
244
|
+
flexWrap: "wrap"
|
|
245
|
+
},
|
|
246
|
+
fill: {
|
|
247
|
+
width: "100%",
|
|
248
|
+
height: "100%"
|
|
249
|
+
},
|
|
250
|
+
meta: {
|
|
251
|
+
paddingTop: vs(8),
|
|
252
|
+
gap: vs(6)
|
|
253
|
+
},
|
|
254
|
+
row: {
|
|
255
|
+
flexDirection: "row",
|
|
256
|
+
alignItems: "center",
|
|
257
|
+
gap: s(12),
|
|
258
|
+
paddingVertical: vs(8)
|
|
259
|
+
},
|
|
260
|
+
rowText: {
|
|
261
|
+
flex: 1,
|
|
262
|
+
gap: vs(6)
|
|
263
|
+
}
|
|
264
|
+
});
|
|
204
265
|
|
|
205
266
|
exports.Skeleton = Skeleton;
|
package/dist/Skeleton.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export { Skeleton } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { Skeleton } from './chunk-AJ7ZDNBT.mjs';
|
|
2
|
+
import './chunk-DVK4G2GT.mjs';
|
|
3
|
+
import './chunk-QY3X2UYR.mjs';
|
|
3
4
|
import './chunk-SOYNZDVY.mjs';
|
|
4
5
|
import './chunk-2CE3TQVY.mjs';
|
|
6
|
+
import './chunk-Y6FXYEAI.mjs';
|
package/dist/Slider.js
CHANGED
|
@@ -10,18 +10,65 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
10
10
|
var React2__default = /*#__PURE__*/_interopDefault(React2);
|
|
11
11
|
var RNSlider__default = /*#__PURE__*/_interopDefault(RNSlider);
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
14
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
15
|
+
}) : x)(function(x) {
|
|
16
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
17
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
18
|
+
});
|
|
14
19
|
var _haptics = null;
|
|
20
|
+
var _hapticsLoaded = false;
|
|
15
21
|
async function getHaptics() {
|
|
16
22
|
if (reactNative.Platform.OS === "web") return null;
|
|
17
|
-
if (!
|
|
18
|
-
|
|
23
|
+
if (!_hapticsLoaded) {
|
|
24
|
+
_hapticsLoaded = true;
|
|
25
|
+
try {
|
|
26
|
+
_haptics = await import('expo-haptics');
|
|
27
|
+
} catch {
|
|
28
|
+
_haptics = null;
|
|
29
|
+
}
|
|
19
30
|
}
|
|
20
31
|
return _haptics;
|
|
21
32
|
}
|
|
33
|
+
var _pulsar = null;
|
|
34
|
+
var _pulsarChecked = false;
|
|
35
|
+
var _pulsarAvailable = false;
|
|
36
|
+
function isPulsarNativeRegistered() {
|
|
37
|
+
try {
|
|
38
|
+
const g = globalThis;
|
|
39
|
+
if (typeof g.__turboModuleProxy === "function") {
|
|
40
|
+
return g.__turboModuleProxy("RNPulsar") != null;
|
|
41
|
+
}
|
|
42
|
+
return reactNative.NativeModules?.RNPulsar != null;
|
|
43
|
+
} catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function getPulsar() {
|
|
48
|
+
if (reactNative.Platform.OS === "web") return null;
|
|
49
|
+
if (!_pulsarChecked) {
|
|
50
|
+
_pulsarChecked = true;
|
|
51
|
+
try {
|
|
52
|
+
if (isPulsarNativeRegistered()) {
|
|
53
|
+
_pulsar = __require("react-native-pulsar");
|
|
54
|
+
_pulsarAvailable = true;
|
|
55
|
+
}
|
|
56
|
+
} catch {
|
|
57
|
+
_pulsar = null;
|
|
58
|
+
_pulsarAvailable = false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return _pulsarAvailable ? _pulsar : null;
|
|
62
|
+
}
|
|
22
63
|
function selectionAsync() {
|
|
23
64
|
if (reactNative.Platform.OS === "web") return;
|
|
24
|
-
getHaptics().then((h) =>
|
|
65
|
+
getHaptics().then((h) => {
|
|
66
|
+
if (h) {
|
|
67
|
+
h.selectionAsync();
|
|
68
|
+
} else {
|
|
69
|
+
getPulsar()?.Presets.System.selection();
|
|
70
|
+
}
|
|
71
|
+
});
|
|
25
72
|
}
|
|
26
73
|
|
|
27
74
|
// src/theme/colorUtils.ts
|
package/dist/Slider.mjs
CHANGED
package/dist/Spinner.js
CHANGED
|
@@ -146,17 +146,38 @@ var labelFontSize = {
|
|
|
146
146
|
};
|
|
147
147
|
function Spinner({ size = "md", color, label, ...props }) {
|
|
148
148
|
const { colors } = useTheme();
|
|
149
|
+
const a11yLabel = label || "Loading";
|
|
149
150
|
if (label) {
|
|
150
|
-
return /* @__PURE__ */ React2__default.default.createElement(
|
|
151
|
-
reactNative.
|
|
151
|
+
return /* @__PURE__ */ React2__default.default.createElement(
|
|
152
|
+
reactNative.View,
|
|
152
153
|
{
|
|
153
|
-
style:
|
|
154
|
-
|
|
154
|
+
style: styles.wrapper,
|
|
155
|
+
accessibilityRole: "progressbar",
|
|
156
|
+
accessibilityLabel: a11yLabel,
|
|
157
|
+
accessibilityState: { busy: true }
|
|
155
158
|
},
|
|
156
|
-
|
|
157
|
-
|
|
159
|
+
/* @__PURE__ */ React2__default.default.createElement(reactNative.ActivityIndicator, { size: sizeMap[size], color: color ?? colors.primary, ...props }),
|
|
160
|
+
/* @__PURE__ */ React2__default.default.createElement(
|
|
161
|
+
reactNative.Text,
|
|
162
|
+
{
|
|
163
|
+
style: [styles.label, { color: colors.foregroundMuted, fontSize: labelFontSize[size] }],
|
|
164
|
+
allowFontScaling: true
|
|
165
|
+
},
|
|
166
|
+
label
|
|
167
|
+
)
|
|
168
|
+
);
|
|
158
169
|
}
|
|
159
|
-
return /* @__PURE__ */ React2__default.default.createElement(
|
|
170
|
+
return /* @__PURE__ */ React2__default.default.createElement(
|
|
171
|
+
reactNative.ActivityIndicator,
|
|
172
|
+
{
|
|
173
|
+
size: sizeMap[size],
|
|
174
|
+
color: color ?? colors.primary,
|
|
175
|
+
accessibilityRole: "progressbar",
|
|
176
|
+
accessibilityLabel: a11yLabel,
|
|
177
|
+
accessibilityState: { busy: true },
|
|
178
|
+
...props
|
|
179
|
+
}
|
|
180
|
+
);
|
|
160
181
|
}
|
|
161
182
|
var styles = reactNative.StyleSheet.create({
|
|
162
183
|
wrapper: {
|
package/dist/Spinner.mjs
CHANGED
package/dist/Switch.js
CHANGED
|
@@ -2,27 +2,74 @@
|
|
|
2
2
|
|
|
3
3
|
var React2 = require('react');
|
|
4
4
|
var reactNative = require('react-native');
|
|
5
|
-
var
|
|
5
|
+
var reactNativeEase = require('react-native-ease');
|
|
6
6
|
var vectorIcons = require('@expo/vector-icons');
|
|
7
7
|
var reactNativeSizeMatters = require('react-native-size-matters');
|
|
8
|
+
var reactNativeReanimated = require('react-native-reanimated');
|
|
8
9
|
|
|
9
10
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
11
|
|
|
11
12
|
var React2__default = /*#__PURE__*/_interopDefault(React2);
|
|
12
|
-
var Animated__default = /*#__PURE__*/_interopDefault(Animated);
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
15
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
16
|
+
}) : x)(function(x) {
|
|
17
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
18
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
19
|
+
});
|
|
15
20
|
var _haptics = null;
|
|
21
|
+
var _hapticsLoaded = false;
|
|
16
22
|
async function getHaptics() {
|
|
17
23
|
if (reactNative.Platform.OS === "web") return null;
|
|
18
|
-
if (!
|
|
19
|
-
|
|
24
|
+
if (!_hapticsLoaded) {
|
|
25
|
+
_hapticsLoaded = true;
|
|
26
|
+
try {
|
|
27
|
+
_haptics = await import('expo-haptics');
|
|
28
|
+
} catch {
|
|
29
|
+
_haptics = null;
|
|
30
|
+
}
|
|
20
31
|
}
|
|
21
32
|
return _haptics;
|
|
22
33
|
}
|
|
34
|
+
var _pulsar = null;
|
|
35
|
+
var _pulsarChecked = false;
|
|
36
|
+
var _pulsarAvailable = false;
|
|
37
|
+
function isPulsarNativeRegistered() {
|
|
38
|
+
try {
|
|
39
|
+
const g = globalThis;
|
|
40
|
+
if (typeof g.__turboModuleProxy === "function") {
|
|
41
|
+
return g.__turboModuleProxy("RNPulsar") != null;
|
|
42
|
+
}
|
|
43
|
+
return reactNative.NativeModules?.RNPulsar != null;
|
|
44
|
+
} catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function getPulsar() {
|
|
49
|
+
if (reactNative.Platform.OS === "web") return null;
|
|
50
|
+
if (!_pulsarChecked) {
|
|
51
|
+
_pulsarChecked = true;
|
|
52
|
+
try {
|
|
53
|
+
if (isPulsarNativeRegistered()) {
|
|
54
|
+
_pulsar = __require("react-native-pulsar");
|
|
55
|
+
_pulsarAvailable = true;
|
|
56
|
+
}
|
|
57
|
+
} catch {
|
|
58
|
+
_pulsar = null;
|
|
59
|
+
_pulsarAvailable = false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return _pulsarAvailable ? _pulsar : null;
|
|
63
|
+
}
|
|
23
64
|
function selectionAsync() {
|
|
24
65
|
if (reactNative.Platform.OS === "web") return;
|
|
25
|
-
getHaptics().then((h) =>
|
|
66
|
+
getHaptics().then((h) => {
|
|
67
|
+
if (h) {
|
|
68
|
+
h.selectionAsync();
|
|
69
|
+
} else {
|
|
70
|
+
getPulsar()?.Presets.System.selection();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
26
73
|
}
|
|
27
74
|
|
|
28
75
|
// src/theme/colorUtils.ts
|
|
@@ -145,20 +192,32 @@ function useTheme() {
|
|
|
145
192
|
}
|
|
146
193
|
var isWeb = reactNative.Platform.OS === "web";
|
|
147
194
|
var s = isWeb ? (n) => n : reactNativeSizeMatters.scale;
|
|
148
|
-
var SPRINGS = {
|
|
149
|
-
/** Elastic indicator — Switch thumb, RadioGroup dot. */
|
|
150
|
-
elastic: { stiffness: 320, damping: 22, mass: 0.7 }
|
|
151
|
-
};
|
|
152
195
|
var TIMINGS = {
|
|
153
196
|
/** Color/opacity transitions on toggles, checkboxes, switches. */
|
|
154
197
|
state: { duration: 160 }};
|
|
155
|
-
|
|
198
|
+
({
|
|
156
199
|
/** Material-style ease-out — natural deceleration for state changes. */
|
|
157
|
-
standard:
|
|
200
|
+
standard: reactNativeReanimated.Easing.bezier(0.2, 0, 0, 1),
|
|
158
201
|
/** Strong ease-out for expanding surfaces (Accordion open). */
|
|
159
|
-
expand:
|
|
202
|
+
expand: reactNativeReanimated.Easing.bezier(0.23, 1, 0.32, 1),
|
|
160
203
|
/** Quick ease-in for collapsing. */
|
|
161
|
-
collapse:
|
|
204
|
+
collapse: reactNativeReanimated.Easing.in(reactNativeReanimated.Easing.ease)
|
|
205
|
+
});
|
|
206
|
+
var COLOR_TRANSITION = {
|
|
207
|
+
type: "timing",
|
|
208
|
+
duration: TIMINGS.state.duration,
|
|
209
|
+
easing: [0.2, 0, 0, 1]
|
|
210
|
+
};
|
|
211
|
+
var OPACITY_TRANSITION = {
|
|
212
|
+
type: "timing",
|
|
213
|
+
duration: TIMINGS.state.duration,
|
|
214
|
+
easing: [0.2, 0, 0, 1]
|
|
215
|
+
};
|
|
216
|
+
var SPRING_ELASTIC = {
|
|
217
|
+
type: "spring",
|
|
218
|
+
stiffness: 320,
|
|
219
|
+
damping: 22,
|
|
220
|
+
mass: 0.7
|
|
162
221
|
};
|
|
163
222
|
|
|
164
223
|
// src/components/Switch/Switch.tsx
|
|
@@ -170,34 +229,6 @@ var THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2;
|
|
|
170
229
|
var ICON_SIZE = s(13);
|
|
171
230
|
function Switch({ checked = false, onCheckedChange, disabled, style, accessibilityLabel }) {
|
|
172
231
|
const { colors } = useTheme();
|
|
173
|
-
const progress = Animated.useSharedValue(checked ? 1 : 0);
|
|
174
|
-
React2.useEffect(() => {
|
|
175
|
-
progress.value = Animated.withSpring(checked ? 1 : 0, SPRINGS.elastic);
|
|
176
|
-
}, [checked, progress]);
|
|
177
|
-
const thumbStyle = Animated.useAnimatedStyle(() => ({
|
|
178
|
-
transform: [{ translateX: progress.value * THUMB_TRAVEL }]
|
|
179
|
-
}));
|
|
180
|
-
const trackStyle = Animated.useAnimatedStyle(() => ({
|
|
181
|
-
backgroundColor: Animated.interpolateColor(
|
|
182
|
-
progress.value,
|
|
183
|
-
[0, 1],
|
|
184
|
-
[colors.surfaceStrong, colors.primary]
|
|
185
|
-
)
|
|
186
|
-
}));
|
|
187
|
-
const trackBorderStyle = Animated.useAnimatedStyle(() => ({
|
|
188
|
-
borderWidth: 1.5,
|
|
189
|
-
borderColor: Animated.interpolateColor(
|
|
190
|
-
progress.value,
|
|
191
|
-
[0, 1],
|
|
192
|
-
[colors.border, "transparent"]
|
|
193
|
-
)
|
|
194
|
-
}));
|
|
195
|
-
const checkIconStyle = Animated.useAnimatedStyle(() => ({
|
|
196
|
-
opacity: Animated.withTiming(checked ? 1 : 0, { duration: TIMINGS.state.duration, easing: EASINGS.standard })
|
|
197
|
-
}));
|
|
198
|
-
const crossIconStyle = Animated.useAnimatedStyle(() => ({
|
|
199
|
-
opacity: Animated.withTiming(checked ? 0 : 1, { duration: TIMINGS.state.duration, easing: EASINGS.standard })
|
|
200
|
-
}));
|
|
201
232
|
return /* @__PURE__ */ React2__default.default.createElement(reactNative.View, { style: [{ opacity: disabled ? 0.45 : 1, alignSelf: "flex-start" }, style] }, /* @__PURE__ */ React2__default.default.createElement(
|
|
202
233
|
reactNative.TouchableOpacity,
|
|
203
234
|
{
|
|
@@ -213,14 +244,33 @@ function Switch({ checked = false, onCheckedChange, disabled, style, accessibili
|
|
|
213
244
|
accessibilityState: { checked, disabled: !!disabled },
|
|
214
245
|
style: styles.touchable
|
|
215
246
|
},
|
|
216
|
-
/* @__PURE__ */ React2__default.default.createElement(
|
|
217
|
-
|
|
247
|
+
/* @__PURE__ */ React2__default.default.createElement(
|
|
248
|
+
reactNativeEase.EaseView,
|
|
218
249
|
{
|
|
219
|
-
style:
|
|
250
|
+
style: styles.track,
|
|
251
|
+
animate: { backgroundColor: checked ? colors.primary : colors.surfaceStrong },
|
|
252
|
+
transition: COLOR_TRANSITION
|
|
220
253
|
},
|
|
221
|
-
/* @__PURE__ */ React2__default.default.createElement(
|
|
222
|
-
|
|
223
|
-
|
|
254
|
+
/* @__PURE__ */ React2__default.default.createElement(
|
|
255
|
+
reactNativeEase.EaseView,
|
|
256
|
+
{
|
|
257
|
+
style: [styles.trackBorder, { borderWidth: 1.5 }],
|
|
258
|
+
pointerEvents: "none",
|
|
259
|
+
animate: { borderColor: checked ? "transparent" : colors.border },
|
|
260
|
+
transition: COLOR_TRANSITION
|
|
261
|
+
}
|
|
262
|
+
),
|
|
263
|
+
/* @__PURE__ */ React2__default.default.createElement(
|
|
264
|
+
reactNativeEase.EaseView,
|
|
265
|
+
{
|
|
266
|
+
style: [styles.thumb, { backgroundColor: colors.primaryForeground }],
|
|
267
|
+
animate: { translateX: checked ? THUMB_TRAVEL : 0 },
|
|
268
|
+
transition: SPRING_ELASTIC
|
|
269
|
+
},
|
|
270
|
+
/* @__PURE__ */ React2__default.default.createElement(reactNativeEase.EaseView, { style: styles.iconWrapper, animate: { opacity: checked ? 1 : 0 }, transition: OPACITY_TRANSITION }, /* @__PURE__ */ React2__default.default.createElement(vectorIcons.Feather, { name: "check", size: ICON_SIZE, color: colors.primary })),
|
|
271
|
+
/* @__PURE__ */ React2__default.default.createElement(reactNativeEase.EaseView, { style: styles.iconWrapper, animate: { opacity: checked ? 0 : 1 }, transition: OPACITY_TRANSITION }, /* @__PURE__ */ React2__default.default.createElement(vectorIcons.Feather, { name: "x", size: ICON_SIZE, color: colors.foregroundMuted }))
|
|
272
|
+
)
|
|
273
|
+
)
|
|
224
274
|
));
|
|
225
275
|
}
|
|
226
276
|
var styles = reactNative.StyleSheet.create({
|
package/dist/Switch.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { Switch } from './chunk-
|
|
2
|
-
import './chunk-
|
|
3
|
-
import './chunk-
|
|
1
|
+
export { Switch } from './chunk-QKH5ZOD5.mjs';
|
|
2
|
+
import './chunk-EJ7ZPXOH.mjs';
|
|
3
|
+
import './chunk-DVK4G2GT.mjs';
|
|
4
4
|
import './chunk-SOYNZDVY.mjs';
|
|
5
5
|
import './chunk-2CE3TQVY.mjs';
|
|
6
|
+
import './chunk-Y6FXYEAI.mjs';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ViewStyle } from 'react-native';
|
|
3
|
+
|
|
4
|
+
interface TabBarItem {
|
|
5
|
+
/** Unique key for the tab. */
|
|
6
|
+
key: string;
|
|
7
|
+
/** Label under the icon. Omit for an icon-only tab. */
|
|
8
|
+
label?: string;
|
|
9
|
+
/** Icon name (active + inactive share the name; color signals state). */
|
|
10
|
+
iconName?: string;
|
|
11
|
+
/** Custom icon node — receives no state, overrides `iconName`. */
|
|
12
|
+
icon?: React.ReactNode;
|
|
13
|
+
/** Badge overlay — `true` shows a dot, a number shows a count (capped at 99). */
|
|
14
|
+
badge?: boolean | number;
|
|
15
|
+
}
|
|
16
|
+
interface TabBarProps {
|
|
17
|
+
items: TabBarItem[];
|
|
18
|
+
/** Key of the active tab. */
|
|
19
|
+
activeKey: string;
|
|
20
|
+
onTabPress: (key: string) => void;
|
|
21
|
+
/** Active tint. Defaults to theme `primary`. */
|
|
22
|
+
activeColor?: string;
|
|
23
|
+
/** Inactive tint. Defaults to theme `foregroundMuted`. */
|
|
24
|
+
inactiveColor?: string;
|
|
25
|
+
/** Apply the bottom safe-area inset as padding. Defaults to true. */
|
|
26
|
+
withSafeArea?: boolean;
|
|
27
|
+
style?: ViewStyle;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Bottom tab bar — icon + label tabs with active tint and badge support. Pair
|
|
31
|
+
* with your navigator, or drive it with local state for a single-screen app.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* <TabBar
|
|
35
|
+
* items={[{ key: 'home', label: 'Home', iconName: 'home' }, { key: 'profile', label: 'Profile', iconName: 'user', badge: 3 }]}
|
|
36
|
+
* activeKey={tab}
|
|
37
|
+
* onTabPress={setTab}
|
|
38
|
+
* />
|
|
39
|
+
*/
|
|
40
|
+
declare function TabBar({ items, activeKey, onTabPress, activeColor, inactiveColor, withSafeArea, style, }: TabBarProps): React.JSX.Element;
|
|
41
|
+
|
|
42
|
+
export { TabBar, type TabBarItem, type TabBarProps };
|
package/dist/TabBar.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ViewStyle } from 'react-native';
|
|
3
|
+
|
|
4
|
+
interface TabBarItem {
|
|
5
|
+
/** Unique key for the tab. */
|
|
6
|
+
key: string;
|
|
7
|
+
/** Label under the icon. Omit for an icon-only tab. */
|
|
8
|
+
label?: string;
|
|
9
|
+
/** Icon name (active + inactive share the name; color signals state). */
|
|
10
|
+
iconName?: string;
|
|
11
|
+
/** Custom icon node — receives no state, overrides `iconName`. */
|
|
12
|
+
icon?: React.ReactNode;
|
|
13
|
+
/** Badge overlay — `true` shows a dot, a number shows a count (capped at 99). */
|
|
14
|
+
badge?: boolean | number;
|
|
15
|
+
}
|
|
16
|
+
interface TabBarProps {
|
|
17
|
+
items: TabBarItem[];
|
|
18
|
+
/** Key of the active tab. */
|
|
19
|
+
activeKey: string;
|
|
20
|
+
onTabPress: (key: string) => void;
|
|
21
|
+
/** Active tint. Defaults to theme `primary`. */
|
|
22
|
+
activeColor?: string;
|
|
23
|
+
/** Inactive tint. Defaults to theme `foregroundMuted`. */
|
|
24
|
+
inactiveColor?: string;
|
|
25
|
+
/** Apply the bottom safe-area inset as padding. Defaults to true. */
|
|
26
|
+
withSafeArea?: boolean;
|
|
27
|
+
style?: ViewStyle;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Bottom tab bar — icon + label tabs with active tint and badge support. Pair
|
|
31
|
+
* with your navigator, or drive it with local state for a single-screen app.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* <TabBar
|
|
35
|
+
* items={[{ key: 'home', label: 'Home', iconName: 'home' }, { key: 'profile', label: 'Profile', iconName: 'user', badge: 3 }]}
|
|
36
|
+
* activeKey={tab}
|
|
37
|
+
* onTabPress={setTab}
|
|
38
|
+
* />
|
|
39
|
+
*/
|
|
40
|
+
declare function TabBar({ items, activeKey, onTabPress, activeColor, inactiveColor, withSafeArea, style, }: TabBarProps): React.JSX.Element;
|
|
41
|
+
|
|
42
|
+
export { TabBar, type TabBarItem, type TabBarProps };
|