@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.
Files changed (220) hide show
  1. package/dist/AlertDialog.jsx +123 -0
  2. package/dist/AmbientBackground.jsx +73 -0
  3. package/dist/ArtifactList.jsx +59 -0
  4. package/dist/Avatar.jsx +285 -0
  5. package/dist/Badge.jsx +154 -0
  6. package/dist/BottomSheetContainer.jsx +208 -0
  7. package/dist/BulkActionBar.jsx +717 -0
  8. package/dist/Button.jsx +344 -0
  9. package/dist/CaptureButton.jsx +104 -0
  10. package/dist/Card.jsx +371 -0
  11. package/dist/Checkbox.jsx +177 -0
  12. package/dist/Chip.jsx +79 -0
  13. package/dist/ColorSwatches.jsx +159 -0
  14. package/dist/ConfirmDialog.jsx +157 -0
  15. package/dist/DateTimeField.jsx +204 -0
  16. package/dist/Dialog.jsx +614 -0
  17. package/dist/DividedList.jsx +120 -0
  18. package/dist/DropdownMenu.jsx +849 -0
  19. package/dist/EmptyState.jsx +434 -0
  20. package/dist/ExpoWebRoot.jsx +134 -0
  21. package/dist/FloatingFAB.jsx +95 -0
  22. package/dist/FloatingSurface.jsx +226 -0
  23. package/dist/FloatingTabBar.jsx +403 -0
  24. package/dist/HeaderIconButton.jsx +53 -0
  25. package/dist/IconButton.jsx +157 -0
  26. package/dist/Input.jsx +96 -0
  27. package/dist/Label.jsx +96 -0
  28. package/dist/LabeledSwitchRow.jsx +170 -0
  29. package/dist/LiquidGlass.jsx +2 -0
  30. package/dist/ListRow.jsx +281 -0
  31. package/dist/LoadingState.jsx +205 -0
  32. package/dist/PageIndicator.jsx +128 -0
  33. package/dist/PageTitle.jsx +205 -0
  34. package/dist/Pager.jsx +105 -0
  35. package/dist/PasswordInput.jsx +120 -0
  36. package/dist/PillTabs.jsx +300 -0
  37. package/dist/PinnedBotTile.jsx +212 -0
  38. package/dist/Progress.jsx +147 -0
  39. package/dist/SafeAreaContainer.jsx +38 -0
  40. package/dist/ScreenContainer.jsx +117 -0
  41. package/dist/SearchInput.jsx +150 -0
  42. package/dist/SectionLabel.jsx +128 -0
  43. package/dist/Select.jsx +223 -0
  44. package/dist/Separator.jsx +95 -0
  45. package/dist/Sheet.jsx +343 -0
  46. package/dist/SheetRow.jsx +198 -0
  47. package/dist/Skeleton.jsx +311 -0
  48. package/dist/Spinner.jsx +195 -0
  49. package/dist/StackPageHeader.jsx +160 -0
  50. package/dist/StatGrid.jsx +74 -0
  51. package/dist/StatusDot.jsx +129 -0
  52. package/dist/SurfaceRow.jsx +143 -0
  53. package/dist/SwipeableRow.jsx +50 -0
  54. package/dist/Switch.jsx +130 -0
  55. package/dist/Tabs.jsx +385 -0
  56. package/dist/Textarea.jsx +103 -0
  57. package/dist/ThemeToggle.jsx +78 -0
  58. package/dist/Toast.jsx +396 -0
  59. package/dist/ai/activity-step-detail.jsx +179 -0
  60. package/dist/ai/activity-step-label.js +816 -0
  61. package/dist/ai/activity-step-types.js +14 -0
  62. package/dist/ai/activity-step.jsx +98 -0
  63. package/dist/ai/activity-tasks-utils.js +172 -0
  64. package/dist/ai/activity-timeline.js +47 -0
  65. package/dist/ai/attachments.jsx +258 -0
  66. package/dist/ai/card-button.jsx +188 -0
  67. package/dist/ai/chain-of-thought.jsx +459 -0
  68. package/dist/ai/chat-jump-rail.jsx +57 -0
  69. package/dist/ai/chat-text.js +44 -0
  70. package/dist/ai/chat-thread.jsx +135 -0
  71. package/dist/ai/choice-question.jsx +925 -0
  72. package/dist/ai/code-block.jsx +574 -0
  73. package/dist/ai/collapsible.jsx +275 -0
  74. package/dist/ai/conversation.jsx +723 -0
  75. package/dist/ai/file-chip.jsx +198 -0
  76. package/dist/ai/icon-button.jsx +179 -0
  77. package/dist/ai/index.js +37 -0
  78. package/dist/ai/message-action-sheet.jsx +408 -0
  79. package/dist/ai/message-quote.jsx +241 -0
  80. package/dist/ai/message.jsx +739 -0
  81. package/dist/ai/prompt-input-menu.jsx +365 -0
  82. package/dist/ai/prompt-input.jsx +626 -0
  83. package/dist/ai/reasoning.jsx +446 -0
  84. package/dist/ai/reply-quote-chip.jsx +278 -0
  85. package/dist/ai/response-text.jsx +130 -0
  86. package/dist/ai/shimmer.jsx +149 -0
  87. package/dist/ai/sources.jsx +260 -0
  88. package/dist/ai/subagent-cards.jsx +645 -0
  89. package/dist/ai/suggestion.jsx +186 -0
  90. package/dist/ai/tool-approval-card.jsx +359 -0
  91. package/dist/ai/trace.jsx +728 -0
  92. package/dist/ai/unified-diff.jsx +280 -0
  93. package/dist/ai/use-streaming-disclosure.js +70 -0
  94. package/dist/auth/AuthProviders.jsx +27 -0
  95. package/dist/auth/AuthScreen.jsx +292 -0
  96. package/dist/auth/GoogleSignInButton.jsx +188 -0
  97. package/dist/auth/SecondFactorScreen.jsx +133 -0
  98. package/dist/auth/SignInScreen.jsx +482 -0
  99. package/dist/auth/authErrors.js +131 -0
  100. package/dist/auth/index.js +11 -0
  101. package/dist/auth/totp.js +378 -0
  102. package/dist/blur.js +36 -0
  103. package/dist/brand/AppIcons.jsx +118 -0
  104. package/dist/brand/AppMark.jsx +128 -0
  105. package/dist/brand/AppWordmark.jsx +138 -0
  106. package/dist/brand/GoogleMark.jsx +71 -0
  107. package/dist/brand/ProviderIcon.jsx +192 -0
  108. package/dist/brand/familyApps.js +33 -0
  109. package/dist/brand/index.js +11 -0
  110. package/dist/brand/svg.js +252 -0
  111. package/dist/brand/vProAppBenefits.js +19 -0
  112. package/dist/cn.js +5 -0
  113. package/dist/colors.js +15 -0
  114. package/dist/configureTheme.js +72 -0
  115. package/dist/controlStyles.js +520 -0
  116. package/dist/definiteSize.js +12 -0
  117. package/dist/dialogLayout.js +18 -0
  118. package/dist/entries/ai.js +4 -0
  119. package/dist/entries/ambient.js +3 -0
  120. package/dist/entries/auth.js +5 -0
  121. package/dist/entries/bottom-sheet.js +2 -0
  122. package/dist/entries/brand.js +2 -0
  123. package/dist/entries/button.js +2 -0
  124. package/dist/entries/date-time.js +3 -0
  125. package/dist/entries/expo-router.js +4 -0
  126. package/dist/entries/expo-web-root.js +3 -0
  127. package/dist/entries/floating.js +7 -0
  128. package/dist/entries/gesture-handler.js +4 -0
  129. package/dist/entries/keyboard-controller.js +4 -0
  130. package/dist/entries/layout.js +16 -0
  131. package/dist/entries/markdown.js +4 -0
  132. package/dist/entries/marketing.js +3 -0
  133. package/dist/entries/page-title.js +7 -0
  134. package/dist/entries/password-input.js +3 -0
  135. package/dist/entries/primitives.js +57 -0
  136. package/dist/entries/search-input.js +3 -0
  137. package/dist/entries/tab-bar.js +4 -0
  138. package/dist/entries/theme.js +7 -0
  139. package/dist/entries/toast.js +5 -0
  140. package/dist/entries/video.js +3 -0
  141. package/dist/entries/webview.js +4 -0
  142. package/dist/examples/AiChatGallery.jsx +509 -0
  143. package/dist/examples/ParityGallery.jsx +1307 -0
  144. package/dist/floating.js +62 -0
  145. package/dist/glassBlur.jsx +145 -0
  146. package/dist/gradient.js +17 -0
  147. package/dist/haptics.js +44 -0
  148. package/dist/highlight.js +382 -0
  149. package/dist/index.js +85 -0
  150. package/dist/initials.js +4 -0
  151. package/dist/loadingGrid.js +81 -0
  152. package/dist/markdown/Markdown.jsx +515 -0
  153. package/dist/markdown/MarkdownTable.jsx +443 -0
  154. package/dist/markdown/tableText.js +68 -0
  155. package/dist/marketing/PricingModal.jsx +608 -0
  156. package/dist/marketing/UpgradeToProCard.jsx +164 -0
  157. package/dist/marketing/pricing.js +34 -0
  158. package/dist/media/ImageGallery.jsx +580 -0
  159. package/dist/media/MediaCard.jsx +162 -0
  160. package/dist/media/imageGrid.js +54 -0
  161. package/dist/motion.js +33 -0
  162. package/dist/pagerSwipe.js +104 -0
  163. package/dist/palette.js +104 -0
  164. package/dist/primitives/button.jsx +127 -0
  165. package/dist/primitives/card.jsx +249 -0
  166. package/dist/primitives/icon.jsx +37 -0
  167. package/dist/primitives/input.jsx +56 -0
  168. package/dist/primitives/keyboard-controller.jsx +207 -0
  169. package/dist/primitives/keyboard-parts.jsx +75 -0
  170. package/dist/primitives/native-only-animated-view.jsx +68 -0
  171. package/dist/primitives/overlay.jsx +391 -0
  172. package/dist/primitives/pager-gesture.jsx +131 -0
  173. package/dist/primitives/select-host.jsx +103 -0
  174. package/dist/primitives/select.jsx +555 -0
  175. package/dist/primitives/sheet-drag.jsx +420 -0
  176. package/dist/primitives/sheet-gesture.jsx +219 -0
  177. package/dist/primitives/swipe-row-gesture.jsx +341 -0
  178. package/dist/primitives/switch.jsx +105 -0
  179. package/dist/primitives/text.jsx +145 -0
  180. package/dist/primitives/toast-drag-gesture.jsx +94 -0
  181. package/dist/primitives/use-controllable-state.js +40 -0
  182. package/dist/primitives/web-click-guard.js +69 -0
  183. package/dist/push.js +166 -0
  184. package/dist/relativeTime.js +70 -0
  185. package/dist/router/RouterStackPageHeader.jsx +53 -0
  186. package/dist/selectA11y.js +32 -0
  187. package/dist/settings/MoreFromProjectV.jsx +168 -0
  188. package/dist/settings/SettingsEmptyState.jsx +102 -0
  189. package/dist/settings/SettingsField.jsx +49 -0
  190. package/dist/settings/SettingsSection.jsx +101 -0
  191. package/dist/settings/SettingsStack.jsx +17 -0
  192. package/dist/settings/SettingsToggleRow.jsx +163 -0
  193. package/dist/settings/projectVMobileApps.js +126 -0
  194. package/dist/settings/relaxedSizeStyle.js +11 -0
  195. package/dist/sheetDrag.js +76 -0
  196. package/dist/svgA11y.js +46 -0
  197. package/dist/swipeRow.js +161 -0
  198. package/dist/tabBarRoutes.js +41 -0
  199. package/dist/tabIndicator.js +139 -0
  200. package/dist/tailwind-preset.cjs +255 -0
  201. package/dist/tailwind-preset.d.cts +55 -0
  202. package/dist/theme.jsx +62 -0
  203. package/dist/toastChrome.js +110 -0
  204. package/dist/toastDrag.js +51 -0
  205. package/dist/toastStore.js +54 -0
  206. package/dist/tokens.js +70 -0
  207. package/dist/typography.js +40 -0
  208. package/dist/useReduceMotion.js +32 -0
  209. package/dist/useReduceTransparency.js +27 -0
  210. package/dist/useScheme.js +15 -0
  211. package/dist/video/InlineVideo.jsx +115 -0
  212. package/dist/webview/HtmlView.jsx +169 -0
  213. package/dist/webview/HtmlView.web.jsx +63 -0
  214. package/dist/webview/htmlView.js +43 -0
  215. package/package.json +70 -33
  216. package/src/DropdownMenu.tsx +28 -16
  217. package/src/FloatingTabBar.tsx +78 -41
  218. package/src/ai/conversation.tsx +12 -8
  219. package/src/glassBlur.tsx +47 -22
  220. package/src/primitives/swipe-row-gesture.tsx +11 -2
@@ -0,0 +1,159 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { Pressable, View } from "react-native";
3
+ import { IconCheck } from "@tabler/icons-react-native";
4
+ import { cn } from "./cn";
5
+ import { touchSlop } from "./controlStyles";
6
+ import { selectionHaptic } from "./haptics";
7
+ import { withAlpha } from "./palette";
8
+ import { useLargerText } from "./theme";
9
+ import { tokens } from "./tokens";
10
+ import { useScheme } from "./useScheme";
11
+ /** Swatch diameters, one step up with larger text. */
12
+ const DIAMETER = {
13
+ regular: {
14
+ sm: 24,
15
+ md: 32,
16
+ lg: 40
17
+ },
18
+ larger: {
19
+ sm: 32,
20
+ md: 40,
21
+ lg: 48
22
+ }
23
+ };
24
+
25
+ /** Selection ring width and the gap between the ring and the swatch. */
26
+ const RING = 2;
27
+ const RING_GAP = 2;
28
+
29
+ /**
30
+ * The check colour on a swatch: black or white, whichever has the higher WCAG
31
+ * contrast with it. `null` when the colour is not `#rgb` or `#rrggbb`, and the
32
+ * ring alone marks the selection.
33
+ */
34
+ export function swatchCheckColor(color) {
35
+ const short = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(color);
36
+ const hex = short ? `#${short[1]}${short[1]}${short[2]}${short[2]}${short[3]}${short[3]}` : color;
37
+ if (!/^#[0-9a-f]{6}$/i.test(hex)) return null;
38
+ const n = Number.parseInt(hex.slice(1), 16);
39
+ const linear = channel => {
40
+ const c = channel / 255;
41
+ return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
42
+ };
43
+ const luminance = 0.2126 * linear(n >> 16 & 255) + 0.7152 * linear(n >> 8 & 255) + 0.0722 * linear(n & 255);
44
+ // Contrast with white is 1.05 / (L + 0.05); with black, (L + 0.05) / 0.05.
45
+ return 1.05 / (luminance + 0.05) >= (luminance + 0.05) / 0.05 ? tokens.color.white : tokens.color.black;
46
+ }
47
+
48
+ /**
49
+ * Pick one colour from a row of round swatches that wraps. The selected swatch
50
+ * has a ring in the foreground colour and a check in black or white, whichever
51
+ * reads on it. Each swatch has a faint outline, so white shows on a white
52
+ * surface. A radio group for VoiceOver and TalkBack: each swatch is a radio
53
+ * named by `labels` (or its colour string). A `md` swatch is 32 across and 40
54
+ * with its ring, and reaches 44 with its hit slop; the 12 gap keeps the slops
55
+ * of neighbouring swatches apart.
56
+ */
57
+ export function ColorSwatches(t0) {
58
+ const $ = _c(28);
59
+ const {
60
+ value,
61
+ onChange,
62
+ colors,
63
+ size: t1,
64
+ labels,
65
+ accessibilityLabel,
66
+ testID,
67
+ disabled: t2
68
+ } = t0;
69
+ const size = t1 === undefined ? "md" : t1;
70
+ const disabled = t2 === undefined ? false : t2;
71
+ const scheme = useScheme();
72
+ const largerText = useLargerText();
73
+ const diameter = DIAMETER[largerText ? "larger" : "regular"][size];
74
+ const outer = diameter + 2 * (RING + RING_GAP);
75
+ let t3;
76
+ if ($[0] !== value) {
77
+ t3 = value.toLowerCase();
78
+ $[0] = value;
79
+ $[1] = t3;
80
+ } else {
81
+ t3 = $[1];
82
+ }
83
+ const selected = t3;
84
+ const t4 = disabled && "opacity-50";
85
+ let t5;
86
+ if ($[2] !== t4) {
87
+ t5 = cn("flex-row flex-wrap gap-3", t4);
88
+ $[2] = t4;
89
+ $[3] = t5;
90
+ } else {
91
+ t5 = $[3];
92
+ }
93
+ let t6;
94
+ if ($[4] !== colors || $[5] !== diameter || $[6] !== disabled || $[7] !== labels || $[8] !== onChange || $[9] !== outer || $[10] !== scheme || $[11] !== selected || $[12] !== testID) {
95
+ let t7;
96
+ if ($[14] !== diameter || $[15] !== disabled || $[16] !== labels || $[17] !== onChange || $[18] !== outer || $[19] !== scheme || $[20] !== selected || $[21] !== testID) {
97
+ t7 = (color, index) => {
98
+ const isSelected = color.toLowerCase() === selected;
99
+ const check = isSelected ? swatchCheckColor(color) : null;
100
+ return <Pressable key={`${color}-${index}`} testID={testID ? `${testID}-${index}` : undefined} accessibilityRole="radio" accessibilityLabel={labels?.[index] ?? color} accessibilityState={{
101
+ checked: isSelected,
102
+ disabled
103
+ }} hitSlop={touchSlop(outer)} disabled={disabled} onPress={() => {
104
+ selectionHaptic();
105
+ onChange(color);
106
+ }} className="items-center justify-center active:opacity-70" style={{
107
+ width: outer,
108
+ height: outer,
109
+ borderRadius: outer / 2,
110
+ borderWidth: RING,
111
+ borderColor: isSelected ? tokens.color.foreground[scheme] : "transparent"
112
+ }}><View className="items-center justify-center" style={{
113
+ width: diameter,
114
+ height: diameter,
115
+ borderRadius: diameter / 2,
116
+ backgroundColor: color,
117
+ borderWidth: 1,
118
+ borderColor: withAlpha(tokens.color.foreground[scheme], 0.12)
119
+ }}>{check ? <IconCheck size={Math.round(diameter / 2)} color={check} strokeWidth={2} /> : null}</View></Pressable>;
120
+ };
121
+ $[14] = diameter;
122
+ $[15] = disabled;
123
+ $[16] = labels;
124
+ $[17] = onChange;
125
+ $[18] = outer;
126
+ $[19] = scheme;
127
+ $[20] = selected;
128
+ $[21] = testID;
129
+ $[22] = t7;
130
+ } else {
131
+ t7 = $[22];
132
+ }
133
+ t6 = colors.map(t7);
134
+ $[4] = colors;
135
+ $[5] = diameter;
136
+ $[6] = disabled;
137
+ $[7] = labels;
138
+ $[8] = onChange;
139
+ $[9] = outer;
140
+ $[10] = scheme;
141
+ $[11] = selected;
142
+ $[12] = testID;
143
+ $[13] = t6;
144
+ } else {
145
+ t6 = $[13];
146
+ }
147
+ let t7;
148
+ if ($[23] !== accessibilityLabel || $[24] !== t5 || $[25] !== t6 || $[26] !== testID) {
149
+ t7 = <View testID={testID} accessibilityRole="radiogroup" accessibilityLabel={accessibilityLabel} className={t5}>{t6}</View>;
150
+ $[23] = accessibilityLabel;
151
+ $[24] = t5;
152
+ $[25] = t6;
153
+ $[26] = testID;
154
+ $[27] = t7;
155
+ } else {
156
+ t7 = $[27];
157
+ }
158
+ return t7;
159
+ }
@@ -0,0 +1,157 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "./AlertDialog";
3
+ import { impactHaptic } from "./haptics";
4
+ import { useControllableState } from "./primitives/use-controllable-state";
5
+ /**
6
+ * Blocking confirm dialog that closes on either button: the web `ConfirmDialog`
7
+ * legacy props with `size="default"`. Every close but Confirm (Cancel, Android
8
+ * back, the VoiceOver escape) calls `onCancel`, as the web `onOpenChange`
9
+ * close does. The `sm` / `md` sizes and the composable `ConfirmDialog.*`
10
+ * parts are web-only; compose `AlertDialog` parts instead.
11
+ */
12
+ export function ConfirmDialog(t0) {
13
+ const $ = _c(39);
14
+ const {
15
+ open,
16
+ defaultOpen,
17
+ onOpenChange,
18
+ title,
19
+ description,
20
+ cancelLabel: t1,
21
+ confirmLabel: t2,
22
+ onCancel,
23
+ onConfirm,
24
+ variant: t3,
25
+ confirmDisabled,
26
+ children,
27
+ testID
28
+ } = t0;
29
+ const cancelLabel = t1 === undefined ? "Cancel" : t1;
30
+ const confirmLabel = t2 === undefined ? "Confirm" : t2;
31
+ const variant = t3 === undefined ? "default" : t3;
32
+ const t4 = defaultOpen ?? false;
33
+ let t5;
34
+ if ($[0] !== onOpenChange || $[1] !== open || $[2] !== t4) {
35
+ t5 = {
36
+ value: open,
37
+ defaultValue: t4,
38
+ onChange: onOpenChange
39
+ };
40
+ $[0] = onOpenChange;
41
+ $[1] = open;
42
+ $[2] = t4;
43
+ $[3] = t5;
44
+ } else {
45
+ t5 = $[3];
46
+ }
47
+ const [isOpen, setOpen] = useControllableState(t5);
48
+ let t6;
49
+ if ($[4] !== onCancel || $[5] !== setOpen) {
50
+ t6 = next => {
51
+ if (!next) {
52
+ onCancel?.();
53
+ }
54
+ setOpen(next);
55
+ };
56
+ $[4] = onCancel;
57
+ $[5] = setOpen;
58
+ $[6] = t6;
59
+ } else {
60
+ t6 = $[6];
61
+ }
62
+ let t7;
63
+ if ($[7] !== title) {
64
+ t7 = <AlertDialogTitle>{title}</AlertDialogTitle>;
65
+ $[7] = title;
66
+ $[8] = t7;
67
+ } else {
68
+ t7 = $[8];
69
+ }
70
+ let t8;
71
+ if ($[9] !== description) {
72
+ t8 = description != null ? <AlertDialogDescription>{description}</AlertDialogDescription> : null;
73
+ $[9] = description;
74
+ $[10] = t8;
75
+ } else {
76
+ t8 = $[10];
77
+ }
78
+ let t9;
79
+ if ($[11] !== t7 || $[12] !== t8) {
80
+ t9 = <AlertDialogHeader>{t7}{t8}</AlertDialogHeader>;
81
+ $[11] = t7;
82
+ $[12] = t8;
83
+ $[13] = t9;
84
+ } else {
85
+ t9 = $[13];
86
+ }
87
+ const t10 = testID ? `${testID}-cancel` : undefined;
88
+ let t11;
89
+ if ($[14] !== cancelLabel || $[15] !== t10) {
90
+ t11 = <AlertDialogCancel testID={t10}>{cancelLabel}</AlertDialogCancel>;
91
+ $[14] = cancelLabel;
92
+ $[15] = t10;
93
+ $[16] = t11;
94
+ } else {
95
+ t11 = $[16];
96
+ }
97
+ const t12 = testID ? `${testID}-confirm` : undefined;
98
+ let t13;
99
+ if ($[17] !== onConfirm || $[18] !== setOpen || $[19] !== variant) {
100
+ t13 = () => {
101
+ if (variant === "destructive") {
102
+ impactHaptic("medium");
103
+ }
104
+ onConfirm?.();
105
+ setOpen(false);
106
+ };
107
+ $[17] = onConfirm;
108
+ $[18] = setOpen;
109
+ $[19] = variant;
110
+ $[20] = t13;
111
+ } else {
112
+ t13 = $[20];
113
+ }
114
+ let t14;
115
+ if ($[21] !== confirmDisabled || $[22] !== confirmLabel || $[23] !== t12 || $[24] !== t13 || $[25] !== variant) {
116
+ t14 = <AlertDialogAction testID={t12} variant={variant} disabled={confirmDisabled} onPress={t13}>{confirmLabel}</AlertDialogAction>;
117
+ $[21] = confirmDisabled;
118
+ $[22] = confirmLabel;
119
+ $[23] = t12;
120
+ $[24] = t13;
121
+ $[25] = variant;
122
+ $[26] = t14;
123
+ } else {
124
+ t14 = $[26];
125
+ }
126
+ let t15;
127
+ if ($[27] !== t11 || $[28] !== t14) {
128
+ t15 = <AlertDialogFooter>{t11}{t14}</AlertDialogFooter>;
129
+ $[27] = t11;
130
+ $[28] = t14;
131
+ $[29] = t15;
132
+ } else {
133
+ t15 = $[29];
134
+ }
135
+ let t16;
136
+ if ($[30] !== t15 || $[31] !== t9 || $[32] !== testID) {
137
+ t16 = <AlertDialogContent testID={testID}>{t9}{t15}</AlertDialogContent>;
138
+ $[30] = t15;
139
+ $[31] = t9;
140
+ $[32] = testID;
141
+ $[33] = t16;
142
+ } else {
143
+ t16 = $[33];
144
+ }
145
+ let t17;
146
+ if ($[34] !== children || $[35] !== isOpen || $[36] !== t16 || $[37] !== t6) {
147
+ t17 = <AlertDialog open={isOpen} onOpenChange={t6}>{children}{t16}</AlertDialog>;
148
+ $[34] = children;
149
+ $[35] = isOpen;
150
+ $[36] = t16;
151
+ $[37] = t6;
152
+ $[38] = t17;
153
+ } else {
154
+ t17 = $[38];
155
+ }
156
+ return t17;
157
+ }
@@ -0,0 +1,204 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { useState } from "react";
3
+ import { Platform, Pressable, Text, View } from "react-native";
4
+ import DateTimePicker from "@react-native-community/datetimepicker";
5
+ import dayjs from "dayjs";
6
+ import { IconX } from "@tabler/icons-react-native";
7
+ import { MIN_TOUCH_TARGET, textStyle, typeStyle } from "./controlStyles";
8
+ import { palette } from "./palette";
9
+ import { useLargerText } from "./theme";
10
+ import { tokens } from "./tokens";
11
+ import { useScheme } from "./useScheme";
12
+ const DEFAULT_PLACEHOLDER = {
13
+ date: "Select date",
14
+ time: "Select time"
15
+ };
16
+
17
+ /**
18
+ * The date the picker opens on: `value`, or with no value `now`, held back to
19
+ * `maximumDate` when that is earlier.
20
+ */
21
+ export function pickerSeed(value, maximumDate, now = new Date()) {
22
+ if (value) return value;
23
+ return maximumDate && maximumDate.getTime() < now.getTime() ? maximumDate : now;
24
+ }
25
+
26
+ /**
27
+ * Date and time buttons that open the system picker below them. `mode="date"`
28
+ * shows the date button only. A `null` value shows `placeholder` in the field
29
+ * placeholder colour, and the picker opens on today (or `maximumDate`, if
30
+ * earlier); picking calls `onChange`. With `onClear`, a 44 clear button
31
+ * follows the buttons while there is a value. On iOS the spinner sets the
32
+ * value when it is turned. The buttons have the web `bg-secondary` fill
33
+ * (`palette.default`) as a style, so it follows the scheme.
34
+ */
35
+ export function DateTimeField(t0) {
36
+ const $ = _c(45);
37
+ const {
38
+ value,
39
+ onChange,
40
+ mode: t1,
41
+ maximumDate,
42
+ placeholder,
43
+ onClear,
44
+ clearLabel,
45
+ testID
46
+ } = t0;
47
+ const mode = t1 === undefined ? "datetime" : t1;
48
+ const largerText = useLargerText();
49
+ const scheme = useScheme();
50
+ const [picker, setPicker] = useState(null);
51
+ let t2;
52
+ if ($[0] !== onChange) {
53
+ t2 = (event, next) => {
54
+ if (Platform.OS === "android") {
55
+ setPicker(null);
56
+ }
57
+ if (event.type === "set" && next) {
58
+ onChange(next);
59
+ }
60
+ };
61
+ $[0] = onChange;
62
+ $[1] = t2;
63
+ } else {
64
+ t2 = $[1];
65
+ }
66
+ const handleChange = t2;
67
+ let t3;
68
+ if ($[2] !== placeholder || $[3] !== value) {
69
+ t3 = (button, format) => value ? dayjs(value).format(format) : placeholder ?? DEFAULT_PLACEHOLDER[button];
70
+ $[2] = placeholder;
71
+ $[3] = value;
72
+ $[4] = t3;
73
+ } else {
74
+ t3 = $[4];
75
+ }
76
+ const label = t3;
77
+ let t4;
78
+ if ($[5] !== label) {
79
+ t4 = label("date", "D MMM YYYY");
80
+ $[5] = label;
81
+ $[6] = t4;
82
+ } else {
83
+ t4 = $[6];
84
+ }
85
+ let t5;
86
+ if ($[7] !== t4) {
87
+ t5 = {
88
+ mode: "date",
89
+ label: t4
90
+ };
91
+ $[7] = t4;
92
+ $[8] = t5;
93
+ } else {
94
+ t5 = $[8];
95
+ }
96
+ const dateButton = t5;
97
+ let t6;
98
+ if ($[9] !== label) {
99
+ t6 = label("time", "HH:mm");
100
+ $[9] = label;
101
+ $[10] = t6;
102
+ } else {
103
+ t6 = $[10];
104
+ }
105
+ let t7;
106
+ if ($[11] !== t6) {
107
+ t7 = {
108
+ mode: "time",
109
+ label: t6
110
+ };
111
+ $[11] = t6;
112
+ $[12] = t7;
113
+ } else {
114
+ t7 = $[12];
115
+ }
116
+ const timeButton = t7;
117
+ let t8;
118
+ if ($[13] !== dateButton || $[14] !== mode || $[15] !== timeButton) {
119
+ t8 = mode === "datetime" ? [dateButton, timeButton] : mode === "date" ? [dateButton] : [timeButton];
120
+ $[13] = dateButton;
121
+ $[14] = mode;
122
+ $[15] = timeButton;
123
+ $[16] = t8;
124
+ } else {
125
+ t8 = $[16];
126
+ }
127
+ const buttons = t8;
128
+ let t9;
129
+ if ($[17] !== scheme || $[18] !== value) {
130
+ t9 = value ? textStyle("foreground", scheme) : {
131
+ color: palette.fieldPlaceholder[scheme]
132
+ };
133
+ $[17] = scheme;
134
+ $[18] = value;
135
+ $[19] = t9;
136
+ } else {
137
+ t9 = $[19];
138
+ }
139
+ const textColor = t9;
140
+ let t10;
141
+ if ($[20] !== buttons || $[21] !== largerText || $[22] !== scheme || $[23] !== testID || $[24] !== textColor) {
142
+ t10 = buttons.map(button_0 => <Pressable key={button_0.mode} testID={testID ? `${testID}-${button_0.mode}` : undefined} accessibilityRole="button" accessibilityLabel={button_0.label} onPress={() => setPicker(current => current === button_0.mode ? null : button_0.mode)} className={`${largerText ? "min-h-16" : "min-h-14"} flex-1 justify-center rounded-lg px-4 py-2 active:opacity-70`} style={{
143
+ backgroundColor: palette.default[scheme]
144
+ }}><Text className={`${largerText ? "text-xl" : "text-lg"} font-instrument-sans-semibold`} style={[textColor, typeStyle("semibold")]}>{button_0.label}</Text></Pressable>);
145
+ $[20] = buttons;
146
+ $[21] = largerText;
147
+ $[22] = scheme;
148
+ $[23] = testID;
149
+ $[24] = textColor;
150
+ $[25] = t10;
151
+ } else {
152
+ t10 = $[25];
153
+ }
154
+ let t11;
155
+ if ($[26] !== clearLabel || $[27] !== largerText || $[28] !== mode || $[29] !== onClear || $[30] !== scheme || $[31] !== testID || $[32] !== value) {
156
+ t11 = onClear && value ? <Pressable testID={testID ? `${testID}-clear` : undefined} accessibilityRole="button" accessibilityLabel={clearLabel ?? (mode === "time" ? "Clear time" : "Clear date")} onPress={() => {
157
+ setPicker(null);
158
+ onClear();
159
+ }} className="items-center justify-center rounded-full active:opacity-70" style={{
160
+ width: MIN_TOUCH_TARGET,
161
+ height: MIN_TOUCH_TARGET
162
+ }}><IconX size={largerText ? 24 : 20} color={tokens.color.muted[scheme]} /></Pressable> : null;
163
+ $[26] = clearLabel;
164
+ $[27] = largerText;
165
+ $[28] = mode;
166
+ $[29] = onClear;
167
+ $[30] = scheme;
168
+ $[31] = testID;
169
+ $[32] = value;
170
+ $[33] = t11;
171
+ } else {
172
+ t11 = $[33];
173
+ }
174
+ let t12;
175
+ if ($[34] !== t10 || $[35] !== t11) {
176
+ t12 = <View className="flex-row items-center gap-3">{t10}{t11}</View>;
177
+ $[34] = t10;
178
+ $[35] = t11;
179
+ $[36] = t12;
180
+ } else {
181
+ t12 = $[36];
182
+ }
183
+ let t13;
184
+ if ($[37] !== handleChange || $[38] !== maximumDate || $[39] !== picker || $[40] !== value) {
185
+ t13 = picker ? <DateTimePicker value={pickerSeed(value, maximumDate)} mode={picker} is24Hour={true} maximumDate={picker === "date" ? maximumDate : undefined} display={Platform.OS === "ios" ? "spinner" : "default"} onChange={handleChange} /> : null;
186
+ $[37] = handleChange;
187
+ $[38] = maximumDate;
188
+ $[39] = picker;
189
+ $[40] = value;
190
+ $[41] = t13;
191
+ } else {
192
+ t13 = $[41];
193
+ }
194
+ let t14;
195
+ if ($[42] !== t12 || $[43] !== t13) {
196
+ t14 = <View className="gap-2">{t12}{t13}</View>;
197
+ $[42] = t12;
198
+ $[43] = t13;
199
+ $[44] = t14;
200
+ } else {
201
+ t14 = $[44];
202
+ }
203
+ return t14;
204
+ }