@vvedantb/native-ui 0.17.2 → 0.18.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/dist/AlertDialog.jsx +123 -0
- package/dist/AmbientBackground.jsx +73 -0
- package/dist/ArtifactList.jsx +59 -0
- package/dist/Avatar.jsx +285 -0
- package/dist/Badge.jsx +154 -0
- package/dist/BottomSheetContainer.jsx +208 -0
- package/dist/BulkActionBar.jsx +717 -0
- package/dist/Button.jsx +344 -0
- package/dist/CaptureButton.jsx +104 -0
- package/dist/Card.jsx +371 -0
- package/dist/Checkbox.jsx +177 -0
- package/dist/Chip.jsx +79 -0
- package/dist/ColorSwatches.jsx +159 -0
- package/dist/ConfirmDialog.jsx +157 -0
- package/dist/DateTimeField.jsx +204 -0
- package/dist/Dialog.jsx +614 -0
- package/dist/DividedList.jsx +120 -0
- package/dist/DropdownMenu.jsx +849 -0
- package/dist/EmptyState.jsx +434 -0
- package/dist/ExpoWebRoot.jsx +134 -0
- package/dist/FloatingFAB.jsx +95 -0
- package/dist/FloatingSurface.jsx +226 -0
- package/dist/FloatingTabBar.jsx +403 -0
- package/dist/HeaderIconButton.jsx +53 -0
- package/dist/IconButton.jsx +157 -0
- package/dist/Input.jsx +96 -0
- package/dist/Label.jsx +96 -0
- package/dist/LabeledSwitchRow.jsx +170 -0
- package/dist/LiquidGlass.jsx +2 -0
- package/dist/ListRow.jsx +281 -0
- package/dist/LoadingState.jsx +205 -0
- package/dist/PageIndicator.jsx +128 -0
- package/dist/PageTitle.jsx +205 -0
- package/dist/Pager.jsx +105 -0
- package/dist/PasswordInput.jsx +120 -0
- package/dist/PillTabs.jsx +300 -0
- package/dist/PinnedBotTile.jsx +212 -0
- package/dist/Progress.jsx +147 -0
- package/dist/SafeAreaContainer.jsx +38 -0
- package/dist/ScreenContainer.jsx +117 -0
- package/dist/SearchInput.jsx +150 -0
- package/dist/SectionLabel.jsx +128 -0
- package/dist/Select.jsx +223 -0
- package/dist/Separator.jsx +95 -0
- package/dist/Sheet.jsx +343 -0
- package/dist/SheetRow.jsx +198 -0
- package/dist/Skeleton.jsx +311 -0
- package/dist/Spinner.jsx +195 -0
- package/dist/StackPageHeader.jsx +160 -0
- package/dist/StatGrid.jsx +74 -0
- package/dist/StatusDot.jsx +129 -0
- package/dist/SurfaceRow.jsx +143 -0
- package/dist/SwipeableRow.jsx +50 -0
- package/dist/Switch.jsx +130 -0
- package/dist/Tabs.jsx +385 -0
- package/dist/Textarea.jsx +103 -0
- package/dist/ThemeToggle.jsx +78 -0
- package/dist/Toast.jsx +396 -0
- package/dist/ai/activity-step-detail.jsx +179 -0
- package/dist/ai/activity-step-label.js +816 -0
- package/dist/ai/activity-step-types.js +14 -0
- package/dist/ai/activity-step.jsx +98 -0
- package/dist/ai/activity-tasks-utils.js +172 -0
- package/dist/ai/activity-timeline.js +47 -0
- package/dist/ai/attachments.jsx +258 -0
- package/dist/ai/card-button.jsx +188 -0
- package/dist/ai/chain-of-thought.jsx +459 -0
- package/dist/ai/chat-jump-rail.jsx +57 -0
- package/dist/ai/chat-text.js +44 -0
- package/dist/ai/chat-thread.jsx +135 -0
- package/dist/ai/choice-question.jsx +925 -0
- package/dist/ai/code-block.jsx +574 -0
- package/dist/ai/collapsible.jsx +275 -0
- package/dist/ai/conversation.jsx +723 -0
- package/dist/ai/file-chip.jsx +198 -0
- package/dist/ai/icon-button.jsx +179 -0
- package/dist/ai/index.js +37 -0
- package/dist/ai/message-action-sheet.jsx +408 -0
- package/dist/ai/message-quote.jsx +241 -0
- package/dist/ai/message.jsx +739 -0
- package/dist/ai/prompt-input-menu.jsx +365 -0
- package/dist/ai/prompt-input.jsx +626 -0
- package/dist/ai/reasoning.jsx +446 -0
- package/dist/ai/reply-quote-chip.jsx +278 -0
- package/dist/ai/response-text.jsx +130 -0
- package/dist/ai/shimmer.jsx +149 -0
- package/dist/ai/sources.jsx +260 -0
- package/dist/ai/subagent-cards.jsx +645 -0
- package/dist/ai/suggestion.jsx +186 -0
- package/dist/ai/tool-approval-card.jsx +359 -0
- package/dist/ai/trace.jsx +728 -0
- package/dist/ai/unified-diff.jsx +280 -0
- package/dist/ai/use-streaming-disclosure.js +70 -0
- package/dist/auth/AuthProviders.jsx +27 -0
- package/dist/auth/AuthScreen.jsx +292 -0
- package/dist/auth/GoogleSignInButton.jsx +188 -0
- package/dist/auth/SecondFactorScreen.jsx +133 -0
- package/dist/auth/SignInScreen.jsx +482 -0
- package/dist/auth/authErrors.js +131 -0
- package/dist/auth/index.js +11 -0
- package/dist/auth/totp.js +378 -0
- package/dist/blur.js +36 -0
- package/dist/brand/AppIcons.jsx +118 -0
- package/dist/brand/AppMark.jsx +128 -0
- package/dist/brand/AppWordmark.jsx +138 -0
- package/dist/brand/GoogleMark.jsx +71 -0
- package/dist/brand/ProviderIcon.jsx +192 -0
- package/dist/brand/familyApps.js +33 -0
- package/dist/brand/index.js +11 -0
- package/dist/brand/svg.js +252 -0
- package/dist/brand/vProAppBenefits.js +19 -0
- package/dist/cn.js +5 -0
- package/dist/colors.js +15 -0
- package/dist/configureTheme.js +72 -0
- package/dist/controlStyles.js +520 -0
- package/dist/definiteSize.js +12 -0
- package/dist/dialogLayout.js +18 -0
- package/dist/entries/ai.js +4 -0
- package/dist/entries/ambient.js +3 -0
- package/dist/entries/auth.js +5 -0
- package/dist/entries/bottom-sheet.js +2 -0
- package/dist/entries/brand.js +2 -0
- package/dist/entries/button.js +2 -0
- package/dist/entries/date-time.js +3 -0
- package/dist/entries/expo-router.js +4 -0
- package/dist/entries/expo-web-root.js +3 -0
- package/dist/entries/floating.js +7 -0
- package/dist/entries/gesture-handler.js +4 -0
- package/dist/entries/keyboard-controller.js +4 -0
- package/dist/entries/layout.js +16 -0
- package/dist/entries/markdown.js +4 -0
- package/dist/entries/marketing.js +3 -0
- package/dist/entries/page-title.js +7 -0
- package/dist/entries/password-input.js +3 -0
- package/dist/entries/primitives.js +57 -0
- package/dist/entries/search-input.js +3 -0
- package/dist/entries/tab-bar.js +4 -0
- package/dist/entries/theme.js +7 -0
- package/dist/entries/toast.js +5 -0
- package/dist/entries/video.js +3 -0
- package/dist/entries/webview.js +4 -0
- package/dist/examples/AiChatGallery.jsx +509 -0
- package/dist/examples/ParityGallery.jsx +1307 -0
- package/dist/floating.js +62 -0
- package/dist/glassBlur.jsx +145 -0
- package/dist/gradient.js +17 -0
- package/dist/haptics.js +44 -0
- package/dist/highlight.js +382 -0
- package/dist/index.js +85 -0
- package/dist/initials.js +4 -0
- package/dist/loadingGrid.js +81 -0
- package/dist/markdown/Markdown.jsx +515 -0
- package/dist/markdown/MarkdownTable.jsx +443 -0
- package/dist/markdown/tableText.js +68 -0
- package/dist/marketing/PricingModal.jsx +608 -0
- package/dist/marketing/UpgradeToProCard.jsx +164 -0
- package/dist/marketing/pricing.js +34 -0
- package/dist/media/ImageGallery.jsx +580 -0
- package/dist/media/MediaCard.jsx +162 -0
- package/dist/media/imageGrid.js +54 -0
- package/dist/motion.js +33 -0
- package/dist/pagerSwipe.js +104 -0
- package/dist/palette.js +104 -0
- package/dist/primitives/button.jsx +127 -0
- package/dist/primitives/card.jsx +249 -0
- package/dist/primitives/icon.jsx +37 -0
- package/dist/primitives/input.jsx +56 -0
- package/dist/primitives/keyboard-controller.jsx +207 -0
- package/dist/primitives/keyboard-parts.jsx +75 -0
- package/dist/primitives/native-only-animated-view.jsx +68 -0
- package/dist/primitives/overlay.jsx +391 -0
- package/dist/primitives/pager-gesture.jsx +131 -0
- package/dist/primitives/select-host.jsx +103 -0
- package/dist/primitives/select.jsx +555 -0
- package/dist/primitives/sheet-drag.jsx +420 -0
- package/dist/primitives/sheet-gesture.jsx +219 -0
- package/dist/primitives/swipe-row-gesture.jsx +341 -0
- package/dist/primitives/switch.jsx +105 -0
- package/dist/primitives/text.jsx +145 -0
- package/dist/primitives/toast-drag-gesture.jsx +94 -0
- package/dist/primitives/use-controllable-state.js +40 -0
- package/dist/primitives/web-click-guard.js +69 -0
- package/dist/push.js +166 -0
- package/dist/relativeTime.js +70 -0
- package/dist/router/RouterStackPageHeader.jsx +53 -0
- package/dist/selectA11y.js +32 -0
- package/dist/settings/MoreFromProjectV.jsx +168 -0
- package/dist/settings/SettingsEmptyState.jsx +102 -0
- package/dist/settings/SettingsField.jsx +49 -0
- package/dist/settings/SettingsSection.jsx +101 -0
- package/dist/settings/SettingsStack.jsx +17 -0
- package/dist/settings/SettingsToggleRow.jsx +163 -0
- package/dist/settings/projectVMobileApps.js +126 -0
- package/dist/settings/relaxedSizeStyle.js +11 -0
- package/dist/sheetDrag.js +76 -0
- package/dist/svgA11y.js +46 -0
- package/dist/swipeRow.js +161 -0
- package/dist/tabBarRoutes.js +41 -0
- package/dist/tabIndicator.js +139 -0
- package/dist/tailwind-preset.cjs +255 -0
- package/dist/tailwind-preset.d.cts +55 -0
- package/dist/theme.jsx +62 -0
- package/dist/toastChrome.js +110 -0
- package/dist/toastDrag.js +51 -0
- package/dist/toastStore.js +54 -0
- package/dist/tokens.js +70 -0
- package/dist/typography.js +40 -0
- package/dist/useReduceMotion.js +32 -0
- package/dist/useReduceTransparency.js +27 -0
- package/dist/useScheme.js +15 -0
- package/dist/video/InlineVideo.jsx +115 -0
- package/dist/webview/HtmlView.jsx +169 -0
- package/dist/webview/HtmlView.web.jsx +63 -0
- package/dist/webview/htmlView.js +43 -0
- package/package.json +70 -33
- package/src/DropdownMenu.tsx +28 -16
- package/src/FloatingTabBar.tsx +78 -41
- package/src/ai/conversation.tsx +12 -8
- package/src/glassBlur.tsx +47 -22
- package/src/primitives/swipe-row-gesture.tsx +11 -2
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { c as _c } from "react/compiler-runtime";
|
|
2
|
+
import * as Slot from "@rn-primitives/slot";
|
|
3
|
+
import { createContext, Fragment, useContext, useEffect, useState } from "react";
|
|
4
|
+
import { Modal, Pressable, StyleSheet, View } from "react-native";
|
|
5
|
+
import Animated from "react-native-reanimated";
|
|
6
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
7
|
+
import { palette } from "../palette";
|
|
8
|
+
import { KeyboardAvoidingView, KeyboardLiftContext } from "./keyboard-parts";
|
|
9
|
+
import { useReduceMotion } from "../useReduceMotion";
|
|
10
|
+
import { useScheme } from "../useScheme";
|
|
11
|
+
import { SheetDragProvider, SheetGestureContext, slideSheetIn, slideSheetOut, useSheetBackdropStyle, useSheetDragState } from "./sheet-drag";
|
|
12
|
+
import { useControllableState } from "./use-controllable-state";
|
|
13
|
+
const OverlayContext = createContext(null);
|
|
14
|
+
export function useOverlay(part) {
|
|
15
|
+
const context = useContext(OverlayContext);
|
|
16
|
+
if (!context) {
|
|
17
|
+
throw new Error(`${part} must be inside its Dialog, AlertDialog or Sheet root.`);
|
|
18
|
+
}
|
|
19
|
+
return context;
|
|
20
|
+
}
|
|
21
|
+
/** Root shared by `Dialog`, `AlertDialog` and `Sheet`: holds the open state, renders no view. */
|
|
22
|
+
export function OverlayRoot(t0) {
|
|
23
|
+
const $ = _c(10);
|
|
24
|
+
const {
|
|
25
|
+
open,
|
|
26
|
+
defaultOpen: t1,
|
|
27
|
+
onOpenChange,
|
|
28
|
+
children
|
|
29
|
+
} = t0;
|
|
30
|
+
const defaultOpen = t1 === undefined ? false : t1;
|
|
31
|
+
let t2;
|
|
32
|
+
if ($[0] !== defaultOpen || $[1] !== onOpenChange || $[2] !== open) {
|
|
33
|
+
t2 = {
|
|
34
|
+
value: open,
|
|
35
|
+
defaultValue: defaultOpen,
|
|
36
|
+
onChange: onOpenChange
|
|
37
|
+
};
|
|
38
|
+
$[0] = defaultOpen;
|
|
39
|
+
$[1] = onOpenChange;
|
|
40
|
+
$[2] = open;
|
|
41
|
+
$[3] = t2;
|
|
42
|
+
} else {
|
|
43
|
+
t2 = $[3];
|
|
44
|
+
}
|
|
45
|
+
const [value, setValue] = useControllableState(t2);
|
|
46
|
+
let t3;
|
|
47
|
+
if ($[4] !== setValue || $[5] !== value) {
|
|
48
|
+
t3 = {
|
|
49
|
+
open: value,
|
|
50
|
+
setOpen: setValue
|
|
51
|
+
};
|
|
52
|
+
$[4] = setValue;
|
|
53
|
+
$[5] = value;
|
|
54
|
+
$[6] = t3;
|
|
55
|
+
} else {
|
|
56
|
+
t3 = $[6];
|
|
57
|
+
}
|
|
58
|
+
let t4;
|
|
59
|
+
if ($[7] !== children || $[8] !== t3) {
|
|
60
|
+
t4 = <OverlayContext.Provider value={t3}>{children}</OverlayContext.Provider>;
|
|
61
|
+
$[7] = children;
|
|
62
|
+
$[8] = t3;
|
|
63
|
+
$[9] = t4;
|
|
64
|
+
} else {
|
|
65
|
+
t4 = $[9];
|
|
66
|
+
}
|
|
67
|
+
return t4;
|
|
68
|
+
}
|
|
69
|
+
function OverlayPressable(t0) {
|
|
70
|
+
const $ = _c(14);
|
|
71
|
+
let asChild;
|
|
72
|
+
let next;
|
|
73
|
+
let onPress;
|
|
74
|
+
let part;
|
|
75
|
+
let props;
|
|
76
|
+
if ($[0] !== t0) {
|
|
77
|
+
({
|
|
78
|
+
asChild,
|
|
79
|
+
next,
|
|
80
|
+
part,
|
|
81
|
+
onPress,
|
|
82
|
+
...props
|
|
83
|
+
} = t0);
|
|
84
|
+
$[0] = t0;
|
|
85
|
+
$[1] = asChild;
|
|
86
|
+
$[2] = next;
|
|
87
|
+
$[3] = onPress;
|
|
88
|
+
$[4] = part;
|
|
89
|
+
$[5] = props;
|
|
90
|
+
} else {
|
|
91
|
+
asChild = $[1];
|
|
92
|
+
next = $[2];
|
|
93
|
+
onPress = $[3];
|
|
94
|
+
part = $[4];
|
|
95
|
+
props = $[5];
|
|
96
|
+
}
|
|
97
|
+
const {
|
|
98
|
+
setOpen
|
|
99
|
+
} = useOverlay(part);
|
|
100
|
+
const Component = asChild ? Slot.Pressable : Pressable;
|
|
101
|
+
let t1;
|
|
102
|
+
if ($[6] !== next || $[7] !== onPress || $[8] !== setOpen) {
|
|
103
|
+
t1 = event => {
|
|
104
|
+
onPress?.(event);
|
|
105
|
+
setOpen(next);
|
|
106
|
+
};
|
|
107
|
+
$[6] = next;
|
|
108
|
+
$[7] = onPress;
|
|
109
|
+
$[8] = setOpen;
|
|
110
|
+
$[9] = t1;
|
|
111
|
+
} else {
|
|
112
|
+
t1 = $[9];
|
|
113
|
+
}
|
|
114
|
+
let t2;
|
|
115
|
+
if ($[10] !== Component || $[11] !== props || $[12] !== t1) {
|
|
116
|
+
t2 = <Component accessibilityRole="button" {...props} onPress={t1} />;
|
|
117
|
+
$[10] = Component;
|
|
118
|
+
$[11] = props;
|
|
119
|
+
$[12] = t1;
|
|
120
|
+
$[13] = t2;
|
|
121
|
+
} else {
|
|
122
|
+
t2 = $[13];
|
|
123
|
+
}
|
|
124
|
+
return t2;
|
|
125
|
+
}
|
|
126
|
+
export function OverlayTrigger(props) {
|
|
127
|
+
const $ = _c(2);
|
|
128
|
+
let t0;
|
|
129
|
+
if ($[0] !== props) {
|
|
130
|
+
t0 = <OverlayPressable {...props} next={true} />;
|
|
131
|
+
$[0] = props;
|
|
132
|
+
$[1] = t0;
|
|
133
|
+
} else {
|
|
134
|
+
t0 = $[1];
|
|
135
|
+
}
|
|
136
|
+
return t0;
|
|
137
|
+
}
|
|
138
|
+
export function OverlayClose(props) {
|
|
139
|
+
const $ = _c(2);
|
|
140
|
+
let t0;
|
|
141
|
+
if ($[0] !== props) {
|
|
142
|
+
t0 = <OverlayPressable {...props} next={false} />;
|
|
143
|
+
$[0] = props;
|
|
144
|
+
$[1] = t0;
|
|
145
|
+
} else {
|
|
146
|
+
t0 = $[1];
|
|
147
|
+
}
|
|
148
|
+
return t0;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* RN `Modal` with a tinted backdrop, safe-area padding and keyboard avoidance
|
|
153
|
+
* (`KeyboardAvoidingView`: frame by frame with `KeyboardControllerProvider`).
|
|
154
|
+
* `placement="center"` centres the child (dialogs) inside the insets on every
|
|
155
|
+
* side, and the `Modal` fades in and out. `"bottom"` pins it to the bottom
|
|
156
|
+
* edge (sheets), which pad their own bottom inset: the sheet slides up on
|
|
157
|
+
* open and back down on close, however it closes, and may be dragged down to
|
|
158
|
+
* close (`SheetDragView`); the backdrop fades with the sheet's position. The
|
|
159
|
+
* `Modal` stays up until the sheet is out of sight. The backdrop closes the
|
|
160
|
+
* overlay only when `dismissible`; Android back and the VoiceOver escape
|
|
161
|
+
* gesture always close it, as Escape does on the web. With Reduce Motion on,
|
|
162
|
+
* overlays appear and leave in place. With the Gesture Handler parts
|
|
163
|
+
* (`GestureHandlerProvider`), the content sits in its own root view: on
|
|
164
|
+
* Android a `Modal` is a separate root, and without one there every gesture
|
|
165
|
+
* in it silently does nothing.
|
|
166
|
+
*/
|
|
167
|
+
export function OverlayModal(t0) {
|
|
168
|
+
const $ = _c(20);
|
|
169
|
+
const {
|
|
170
|
+
part,
|
|
171
|
+
placement,
|
|
172
|
+
dismissible,
|
|
173
|
+
onShow,
|
|
174
|
+
children
|
|
175
|
+
} = t0;
|
|
176
|
+
const {
|
|
177
|
+
open,
|
|
178
|
+
setOpen
|
|
179
|
+
} = useOverlay(part);
|
|
180
|
+
const reduceMotion = useReduceMotion();
|
|
181
|
+
const slides = placement === "bottom" && !reduceMotion;
|
|
182
|
+
const [shown, setShown] = useState(open);
|
|
183
|
+
if (open && !shown) {
|
|
184
|
+
setShown(true);
|
|
185
|
+
}
|
|
186
|
+
if (!open && shown && !slides) {
|
|
187
|
+
setShown(false);
|
|
188
|
+
}
|
|
189
|
+
let t1;
|
|
190
|
+
if ($[0] !== setOpen) {
|
|
191
|
+
t1 = () => setOpen(false);
|
|
192
|
+
$[0] = setOpen;
|
|
193
|
+
$[1] = t1;
|
|
194
|
+
} else {
|
|
195
|
+
t1 = $[1];
|
|
196
|
+
}
|
|
197
|
+
const close = t1;
|
|
198
|
+
const ModalRoot = useContext(SheetGestureContext)?.ModalRoot ?? Fragment;
|
|
199
|
+
const t2 = slides || reduceMotion ? "none" : "fade";
|
|
200
|
+
let t3;
|
|
201
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
202
|
+
t3 = () => setShown(false);
|
|
203
|
+
$[2] = t3;
|
|
204
|
+
} else {
|
|
205
|
+
t3 = $[2];
|
|
206
|
+
}
|
|
207
|
+
let t4;
|
|
208
|
+
if ($[3] !== children || $[4] !== close || $[5] !== dismissible || $[6] !== open || $[7] !== part || $[8] !== placement || $[9] !== slides) {
|
|
209
|
+
t4 = <OverlayModalBody placement={placement} dismissible={dismissible} open={open} slides={slides} close={close} onHidden={t3} part={part}>{children}</OverlayModalBody>;
|
|
210
|
+
$[3] = children;
|
|
211
|
+
$[4] = close;
|
|
212
|
+
$[5] = dismissible;
|
|
213
|
+
$[6] = open;
|
|
214
|
+
$[7] = part;
|
|
215
|
+
$[8] = placement;
|
|
216
|
+
$[9] = slides;
|
|
217
|
+
$[10] = t4;
|
|
218
|
+
} else {
|
|
219
|
+
t4 = $[10];
|
|
220
|
+
}
|
|
221
|
+
let t5;
|
|
222
|
+
if ($[11] !== ModalRoot || $[12] !== t4) {
|
|
223
|
+
t5 = <ModalRoot>{t4}</ModalRoot>;
|
|
224
|
+
$[11] = ModalRoot;
|
|
225
|
+
$[12] = t4;
|
|
226
|
+
$[13] = t5;
|
|
227
|
+
} else {
|
|
228
|
+
t5 = $[13];
|
|
229
|
+
}
|
|
230
|
+
let t6;
|
|
231
|
+
if ($[14] !== close || $[15] !== onShow || $[16] !== shown || $[17] !== t2 || $[18] !== t5) {
|
|
232
|
+
t6 = <Modal visible={shown} transparent={true} animationType={t2} statusBarTranslucent={true} onRequestClose={close} onShow={onShow}>{t5}</Modal>;
|
|
233
|
+
$[14] = close;
|
|
234
|
+
$[15] = onShow;
|
|
235
|
+
$[16] = shown;
|
|
236
|
+
$[17] = t2;
|
|
237
|
+
$[18] = t5;
|
|
238
|
+
$[19] = t6;
|
|
239
|
+
} else {
|
|
240
|
+
t6 = $[19];
|
|
241
|
+
}
|
|
242
|
+
return t6;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** The `Modal`'s content: mounted with each opening, so a sheet starts below the screen (or at rest). */
|
|
246
|
+
function OverlayModalBody(t0) {
|
|
247
|
+
const $ = _c(37);
|
|
248
|
+
const {
|
|
249
|
+
part,
|
|
250
|
+
placement,
|
|
251
|
+
dismissible,
|
|
252
|
+
open,
|
|
253
|
+
slides,
|
|
254
|
+
close,
|
|
255
|
+
onHidden,
|
|
256
|
+
children
|
|
257
|
+
} = t0;
|
|
258
|
+
const scheme = useScheme();
|
|
259
|
+
const insets = useSafeAreaInsets();
|
|
260
|
+
const drag = useSheetDragState(close, slides);
|
|
261
|
+
const backdropStyle = useSheetBackdropStyle(drag);
|
|
262
|
+
let t1;
|
|
263
|
+
if ($[0] !== drag || $[1] !== onHidden || $[2] !== open || $[3] !== slides) {
|
|
264
|
+
t1 = () => {
|
|
265
|
+
if (!slides) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (open) {
|
|
269
|
+
slideSheetIn(drag);
|
|
270
|
+
} else {
|
|
271
|
+
slideSheetOut(drag, onHidden);
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
$[0] = drag;
|
|
275
|
+
$[1] = onHidden;
|
|
276
|
+
$[2] = open;
|
|
277
|
+
$[3] = slides;
|
|
278
|
+
$[4] = t1;
|
|
279
|
+
} else {
|
|
280
|
+
t1 = $[4];
|
|
281
|
+
}
|
|
282
|
+
let t2;
|
|
283
|
+
if ($[5] !== open || $[6] !== slides) {
|
|
284
|
+
t2 = [open, slides];
|
|
285
|
+
$[5] = open;
|
|
286
|
+
$[6] = slides;
|
|
287
|
+
$[7] = t2;
|
|
288
|
+
} else {
|
|
289
|
+
t2 = $[7];
|
|
290
|
+
}
|
|
291
|
+
useEffect(t1, t2);
|
|
292
|
+
const t3 = palette.backdrop[scheme];
|
|
293
|
+
let t4;
|
|
294
|
+
if ($[8] !== t3) {
|
|
295
|
+
t4 = {
|
|
296
|
+
backgroundColor: t3
|
|
297
|
+
};
|
|
298
|
+
$[8] = t3;
|
|
299
|
+
$[9] = t4;
|
|
300
|
+
} else {
|
|
301
|
+
t4 = $[9];
|
|
302
|
+
}
|
|
303
|
+
let t5;
|
|
304
|
+
if ($[10] !== backdropStyle || $[11] !== t4) {
|
|
305
|
+
t5 = [StyleSheet.absoluteFill, t4, backdropStyle];
|
|
306
|
+
$[10] = backdropStyle;
|
|
307
|
+
$[11] = t4;
|
|
308
|
+
$[12] = t5;
|
|
309
|
+
} else {
|
|
310
|
+
t5 = $[12];
|
|
311
|
+
}
|
|
312
|
+
const t6 = `${part}-backdrop`;
|
|
313
|
+
const t7 = !dismissible;
|
|
314
|
+
let t8;
|
|
315
|
+
if ($[13] !== close || $[14] !== dismissible || $[15] !== t6 || $[16] !== t7) {
|
|
316
|
+
t8 = <Pressable testID={t6} accessible={dismissible} accessibilityRole="button" accessibilityLabel="Close" disabled={t7} onPress={close} style={StyleSheet.absoluteFill} />;
|
|
317
|
+
$[13] = close;
|
|
318
|
+
$[14] = dismissible;
|
|
319
|
+
$[15] = t6;
|
|
320
|
+
$[16] = t7;
|
|
321
|
+
$[17] = t8;
|
|
322
|
+
} else {
|
|
323
|
+
t8 = $[17];
|
|
324
|
+
}
|
|
325
|
+
let t9;
|
|
326
|
+
if ($[18] !== t5 || $[19] !== t8) {
|
|
327
|
+
t9 = <Animated.View pointerEvents="box-none" style={t5}>{t8}</Animated.View>;
|
|
328
|
+
$[18] = t5;
|
|
329
|
+
$[19] = t8;
|
|
330
|
+
$[20] = t9;
|
|
331
|
+
} else {
|
|
332
|
+
t9 = $[20];
|
|
333
|
+
}
|
|
334
|
+
let t10;
|
|
335
|
+
if ($[21] !== insets.bottom || $[22] !== insets.left || $[23] !== insets.right || $[24] !== insets.top || $[25] !== placement) {
|
|
336
|
+
t10 = [styles.fill, placement === "bottom" ? {
|
|
337
|
+
justifyContent: "flex-end",
|
|
338
|
+
paddingTop: insets.top + 16,
|
|
339
|
+
paddingLeft: insets.left,
|
|
340
|
+
paddingRight: insets.right
|
|
341
|
+
} : {
|
|
342
|
+
justifyContent: "center",
|
|
343
|
+
paddingTop: insets.top + 16,
|
|
344
|
+
paddingBottom: insets.bottom + 16,
|
|
345
|
+
paddingLeft: insets.left + 16,
|
|
346
|
+
paddingRight: insets.right + 16
|
|
347
|
+
}];
|
|
348
|
+
$[21] = insets.bottom;
|
|
349
|
+
$[22] = insets.left;
|
|
350
|
+
$[23] = insets.right;
|
|
351
|
+
$[24] = insets.top;
|
|
352
|
+
$[25] = placement;
|
|
353
|
+
$[26] = t10;
|
|
354
|
+
} else {
|
|
355
|
+
t10 = $[26];
|
|
356
|
+
}
|
|
357
|
+
let t11;
|
|
358
|
+
if ($[27] !== children || $[28] !== close || $[29] !== t10) {
|
|
359
|
+
t11 = <View pointerEvents="box-none" onAccessibilityEscape={close} style={t10}>{children}</View>;
|
|
360
|
+
$[27] = children;
|
|
361
|
+
$[28] = close;
|
|
362
|
+
$[29] = t10;
|
|
363
|
+
$[30] = t11;
|
|
364
|
+
} else {
|
|
365
|
+
t11 = $[30];
|
|
366
|
+
}
|
|
367
|
+
let t12;
|
|
368
|
+
if ($[31] !== t11 || $[32] !== t9) {
|
|
369
|
+
t12 = <KeyboardAvoidingView style={styles.fill}><KeyboardLiftContext.Provider value={false}>{t9}{t11}</KeyboardLiftContext.Provider></KeyboardAvoidingView>;
|
|
370
|
+
$[31] = t11;
|
|
371
|
+
$[32] = t9;
|
|
372
|
+
$[33] = t12;
|
|
373
|
+
} else {
|
|
374
|
+
t12 = $[33];
|
|
375
|
+
}
|
|
376
|
+
let t13;
|
|
377
|
+
if ($[34] !== drag || $[35] !== t12) {
|
|
378
|
+
t13 = <SheetDragProvider value={drag}>{t12}</SheetDragProvider>;
|
|
379
|
+
$[34] = drag;
|
|
380
|
+
$[35] = t12;
|
|
381
|
+
$[36] = t13;
|
|
382
|
+
} else {
|
|
383
|
+
t13 = $[36];
|
|
384
|
+
}
|
|
385
|
+
return t13;
|
|
386
|
+
}
|
|
387
|
+
const styles = StyleSheet.create({
|
|
388
|
+
fill: {
|
|
389
|
+
flex: 1
|
|
390
|
+
}
|
|
391
|
+
});
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
import { StyleSheet, View } from "react-native";
|
|
3
|
+
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
|
4
|
+
import Animated, { cancelAnimation, ReduceMotion, runOnJS, useAnimatedStyle, useSharedValue, withSpring, withTiming } from "react-native-reanimated";
|
|
5
|
+
import { selectionHaptic } from "../haptics";
|
|
6
|
+
import { InsidePagerContext } from "../Pager";
|
|
7
|
+
import { PAGER_ACTIVE_OFFSET_X, PAGER_FAIL_OFFSET_Y, pagerPosition, pagerSettle, pagesBetween } from "../pagerSwipe";
|
|
8
|
+
import { useWebClickGuard } from "./web-click-guard";
|
|
9
|
+
|
|
10
|
+
// The pager on Gesture Handler: the track phase and the release run as
|
|
11
|
+
// worklets on the UI thread, so the pages never lag the finger. The rules are
|
|
12
|
+
// plain worklets in `pagerSwipe`.
|
|
13
|
+
|
|
14
|
+
/** The release: springs on at the finger's speed, no bounce (an overshoot would flash the next page's edge). */
|
|
15
|
+
const PAGER_SPRING = {
|
|
16
|
+
duration: 250,
|
|
17
|
+
dampingRatio: 1,
|
|
18
|
+
reduceMotion: ReduceMotion.System
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** A page set from outside (a tab press) slides there; at once with Reduce Motion. */
|
|
22
|
+
const PAGER_SLIDE = {
|
|
23
|
+
duration: 220,
|
|
24
|
+
reduceMotion: ReduceMotion.System
|
|
25
|
+
};
|
|
26
|
+
export function GesturePager({
|
|
27
|
+
index,
|
|
28
|
+
count,
|
|
29
|
+
onIndexChange,
|
|
30
|
+
progress,
|
|
31
|
+
renderPage
|
|
32
|
+
}) {
|
|
33
|
+
const width = useSharedValue(0);
|
|
34
|
+
// Where the pages were when the finger caught them, and the finger's travel then.
|
|
35
|
+
const start = useSharedValue(0);
|
|
36
|
+
const startX = useSharedValue(0);
|
|
37
|
+
const [mounted, setMounted] = useState(() => new Set([index]));
|
|
38
|
+
const [shown, setShown] = useState(index);
|
|
39
|
+
// A page reached from outside is drawn from then on, with every page the
|
|
40
|
+
// slide there passes, so it never crosses a blank page.
|
|
41
|
+
if (shown !== index) {
|
|
42
|
+
setShown(index);
|
|
43
|
+
setMounted(new Set([...mounted, ...pagesBetween(shown, index)]));
|
|
44
|
+
}
|
|
45
|
+
// The page a swipe settled on, until the new `index` comes back: that one must not stop the spring.
|
|
46
|
+
const settling = useRef(null);
|
|
47
|
+
// A page set from outside slides there. An effect: a shared value is never
|
|
48
|
+
// written in render.
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const fromSwipe = settling.current === index;
|
|
51
|
+
settling.current = null;
|
|
52
|
+
if (fromSwipe) return;
|
|
53
|
+
progress.set(withTiming(index, PAGER_SLIDE));
|
|
54
|
+
}, [index, progress]);
|
|
55
|
+
const webClicks = useWebClickGuard();
|
|
56
|
+
const dragStarted = () => {
|
|
57
|
+
webClicks.swallowNext();
|
|
58
|
+
// Both neighbours, so the finger finds a page there.
|
|
59
|
+
setMounted(current => new Set([...current, index - 1, index + 1].filter(page => page >= 0 && page < count)));
|
|
60
|
+
};
|
|
61
|
+
const settled = page_0 => {
|
|
62
|
+
settling.current = page_0;
|
|
63
|
+
selectionHaptic();
|
|
64
|
+
onIndexChange(page_0);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Built on each render (for `index` and `count`): the detector keeps the
|
|
68
|
+
// same handler, and a drag in flight, and only takes the new config.
|
|
69
|
+
const pan = Gesture.Pan().enabled(count > 1)
|
|
70
|
+
// Clearly sideways only: a vertical drag is the page's scroll, and a row swipe starts sooner.
|
|
71
|
+
.activeOffsetX([-PAGER_ACTIVE_OFFSET_X, PAGER_ACTIVE_OFFSET_X]).failOffsetY([-PAGER_FAIL_OFFSET_Y, PAGER_FAIL_OFFSET_Y]).onStart(event => {
|
|
72
|
+
cancelAnimation(progress);
|
|
73
|
+
start.set(progress.get());
|
|
74
|
+
// Count from here, so the pages do not jump by the slop the drag needed to start.
|
|
75
|
+
startX.set(event.translationX);
|
|
76
|
+
runOnJS(dragStarted)();
|
|
77
|
+
})
|
|
78
|
+
// Track phase: one shared value write per frame, on the UI thread.
|
|
79
|
+
.onUpdate(event_0 => {
|
|
80
|
+
progress.set(pagerPosition(start.get(), event_0.translationX - startX.get(), width.get(), count));
|
|
81
|
+
}).onEnd(event_1 => {
|
|
82
|
+
const pageWidth = width.get();
|
|
83
|
+
const target = pagerSettle(progress.get(), event_1.velocityX, pageWidth, Math.round(start.get()), count);
|
|
84
|
+
// The finger's speed in pages per second, the unit of `progress`.
|
|
85
|
+
const velocity = pageWidth > 0 ? -event_1.velocityX / pageWidth : 0;
|
|
86
|
+
progress.set(withSpring(target, {
|
|
87
|
+
...PAGER_SPRING,
|
|
88
|
+
velocity
|
|
89
|
+
}));
|
|
90
|
+
if (target !== index) runOnJS(settled)(target);
|
|
91
|
+
});
|
|
92
|
+
const trackStyle = useAnimatedStyle(() => ({
|
|
93
|
+
transform: [{
|
|
94
|
+
translateX: `${-progress.get() * 100 / count}%`
|
|
95
|
+
}]
|
|
96
|
+
}));
|
|
97
|
+
return <InsidePagerContext.Provider value>
|
|
98
|
+
<View style={styles.clip} onLayout={event_2 => width.set(event_2.nativeEvent.layout.width)}>
|
|
99
|
+
<GestureDetector gesture={pan}>
|
|
100
|
+
<Animated.View style={[styles.fill, {
|
|
101
|
+
width: `${count * 100}%`
|
|
102
|
+
}, trackStyle]}>
|
|
103
|
+
<View ref={webClicks.ref} style={styles.track}>
|
|
104
|
+
{Array.from({
|
|
105
|
+
length: count
|
|
106
|
+
}, (_, page_1) => <View key={page_1}
|
|
107
|
+
// Off-screen pages are hidden from screen readers; the tabs above switch pages for them.
|
|
108
|
+
accessibilityElementsHidden={page_1 !== index} importantForAccessibility={page_1 === index ? "auto" : "no-hide-descendants"} style={{
|
|
109
|
+
width: `${100 / count}%`
|
|
110
|
+
}}>
|
|
111
|
+
{mounted.has(page_1) ? renderPage(page_1) : null}
|
|
112
|
+
</View>)}
|
|
113
|
+
</View>
|
|
114
|
+
</Animated.View>
|
|
115
|
+
</GestureDetector>
|
|
116
|
+
</View>
|
|
117
|
+
</InsidePagerContext.Provider>;
|
|
118
|
+
}
|
|
119
|
+
const styles = StyleSheet.create({
|
|
120
|
+
clip: {
|
|
121
|
+
flex: 1,
|
|
122
|
+
overflow: "hidden"
|
|
123
|
+
},
|
|
124
|
+
fill: {
|
|
125
|
+
flex: 1
|
|
126
|
+
},
|
|
127
|
+
track: {
|
|
128
|
+
flex: 1,
|
|
129
|
+
flexDirection: "row"
|
|
130
|
+
}
|
|
131
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { c as _c } from "react/compiler-runtime";
|
|
2
|
+
import * as SelectPrimitive from "@rn-primitives/select";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Modal, Platform, View } from "react-native";
|
|
5
|
+
import { FullWindowOverlay } from "react-native-screens";
|
|
6
|
+
import { useReduceMotion } from "../useReduceMotion";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Where `SelectContent` draws its options.
|
|
10
|
+
*
|
|
11
|
+
* - Android: a transparent RN `Modal` with a full-size `box-none` host, as
|
|
12
|
+
* `DropdownMenuContent` and `OverlayModal` use. The Modal is its own window,
|
|
13
|
+
* so options sit above an absolute tab bar or glass layer. `SelectContent`
|
|
14
|
+
* renders this host without a Portal, because a Modal inside a portal mounts
|
|
15
|
+
* empty. With no Portal there is no `open` gate from the primitive, so the
|
|
16
|
+
* host mounts the Modal only while the Select is open. Android back closes it.
|
|
17
|
+
* - iOS: `FullWindowOverlay`, which sits above native navigation chrome.
|
|
18
|
+
* - Web: no wrapper. Radix owns the layering.
|
|
19
|
+
*
|
|
20
|
+
* `Platform.OS` is read at render, not at import, so a test can switch it.
|
|
21
|
+
*/
|
|
22
|
+
export function SelectHost(t0) {
|
|
23
|
+
const $ = _c(15);
|
|
24
|
+
const {
|
|
25
|
+
children
|
|
26
|
+
} = t0;
|
|
27
|
+
const {
|
|
28
|
+
open,
|
|
29
|
+
onOpenChange,
|
|
30
|
+
setTriggerPosition,
|
|
31
|
+
setContentLayout
|
|
32
|
+
} = SelectPrimitive.useRootContext();
|
|
33
|
+
const reduceMotion = useReduceMotion();
|
|
34
|
+
if (Platform.OS === "ios") {
|
|
35
|
+
let t1;
|
|
36
|
+
if ($[0] !== children) {
|
|
37
|
+
t1 = <FullWindowOverlay>{children}</FullWindowOverlay>;
|
|
38
|
+
$[0] = children;
|
|
39
|
+
$[1] = t1;
|
|
40
|
+
} else {
|
|
41
|
+
t1 = $[1];
|
|
42
|
+
}
|
|
43
|
+
return t1;
|
|
44
|
+
}
|
|
45
|
+
if (Platform.OS !== "android") {
|
|
46
|
+
let t1;
|
|
47
|
+
if ($[2] !== children) {
|
|
48
|
+
t1 = <>{children}</>;
|
|
49
|
+
$[2] = children;
|
|
50
|
+
$[3] = t1;
|
|
51
|
+
} else {
|
|
52
|
+
t1 = $[3];
|
|
53
|
+
}
|
|
54
|
+
return t1;
|
|
55
|
+
}
|
|
56
|
+
if (!open) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
let t1;
|
|
60
|
+
if ($[4] !== onOpenChange || $[5] !== setContentLayout || $[6] !== setTriggerPosition) {
|
|
61
|
+
t1 = () => {
|
|
62
|
+
setTriggerPosition(null);
|
|
63
|
+
setContentLayout(null);
|
|
64
|
+
onOpenChange(false);
|
|
65
|
+
};
|
|
66
|
+
$[4] = onOpenChange;
|
|
67
|
+
$[5] = setContentLayout;
|
|
68
|
+
$[6] = setTriggerPosition;
|
|
69
|
+
$[7] = t1;
|
|
70
|
+
} else {
|
|
71
|
+
t1 = $[7];
|
|
72
|
+
}
|
|
73
|
+
const close = t1;
|
|
74
|
+
const t2 = reduceMotion ? "none" : "fade";
|
|
75
|
+
let t3;
|
|
76
|
+
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
|
|
77
|
+
t3 = {
|
|
78
|
+
flex: 1
|
|
79
|
+
};
|
|
80
|
+
$[8] = t3;
|
|
81
|
+
} else {
|
|
82
|
+
t3 = $[8];
|
|
83
|
+
}
|
|
84
|
+
let t4;
|
|
85
|
+
if ($[9] !== children) {
|
|
86
|
+
t4 = <View style={t3} pointerEvents="box-none" testID="SelectContent-host">{children}</View>;
|
|
87
|
+
$[9] = children;
|
|
88
|
+
$[10] = t4;
|
|
89
|
+
} else {
|
|
90
|
+
t4 = $[10];
|
|
91
|
+
}
|
|
92
|
+
let t5;
|
|
93
|
+
if ($[11] !== close || $[12] !== t2 || $[13] !== t4) {
|
|
94
|
+
t5 = <Modal visible={true} transparent={true} statusBarTranslucent={true} animationType={t2} onRequestClose={close}>{t4}</Modal>;
|
|
95
|
+
$[11] = close;
|
|
96
|
+
$[12] = t2;
|
|
97
|
+
$[13] = t4;
|
|
98
|
+
$[14] = t5;
|
|
99
|
+
} else {
|
|
100
|
+
t5 = $[14];
|
|
101
|
+
}
|
|
102
|
+
return t5;
|
|
103
|
+
}
|