@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,443 @@
|
|
|
1
|
+
import { c as _c } from "react/compiler-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Modal, ScrollView, Text, View } from "react-native";
|
|
4
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
5
|
+
import { IconCopy, IconMaximize, IconX } from "@tabler/icons-react-native";
|
|
6
|
+
import { ChatIconButton } from "../ai/icon-button";
|
|
7
|
+
import { withAlpha } from "../palette";
|
|
8
|
+
import { Sheet, SheetBody, SheetContent, SheetHeader, SheetTitle } from "../Sheet";
|
|
9
|
+
import { SheetRow } from "../SheetRow";
|
|
10
|
+
import { tokens } from "../tokens";
|
|
11
|
+
import { useReduceMotion } from "../useReduceMotion";
|
|
12
|
+
import { useScheme } from "../useScheme";
|
|
13
|
+
import { markdownTableColumnWidths, markdownTableText } from "./tableText";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Web `.markdown table` and its Streamdown wrapper: text at 0.93em with
|
|
17
|
+
* line-height 1.5, cells `0.45rem 0.75rem`, header cells semibold, rows split
|
|
18
|
+
* by the border at 70% (the header's in the full border), the table 0.65rem
|
|
19
|
+
* inside the code-block panel (padding `0.25rem 0.3rem 0.4rem`), below the
|
|
20
|
+
* row of table actions (`flex justify-end gap-1`, 24 buttons, then `gap-2`).
|
|
21
|
+
*/
|
|
22
|
+
export const MARKDOWN_TABLE = {
|
|
23
|
+
fontScale: 0.93,
|
|
24
|
+
lineHeight: 1.5,
|
|
25
|
+
cellPaddingX: 12,
|
|
26
|
+
cellPaddingY: 7,
|
|
27
|
+
panelPadding: {
|
|
28
|
+
top: 4,
|
|
29
|
+
x: 5,
|
|
30
|
+
bottom: 6
|
|
31
|
+
},
|
|
32
|
+
tableMargin: 10,
|
|
33
|
+
/** The web action row: 24 buttons in a 27 row. */
|
|
34
|
+
actionsHeight: 27,
|
|
35
|
+
/**
|
|
36
|
+
* The web buttons sit 4 apart; here 16, so each slops to 44 without
|
|
37
|
+
* taking its neighbour's taps.
|
|
38
|
+
*/
|
|
39
|
+
actionsGap: 16
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The full-screen table sizes each column to its text, as the web table does
|
|
44
|
+
* (`markdownTableColumnWidths`). 8.5 a character fits the 12 mono of inline
|
|
45
|
+
* code with its chip padding, so a code cell does not wrap; body text is narrower.
|
|
46
|
+
*/
|
|
47
|
+
const FULL_SCREEN_COLUMN = {
|
|
48
|
+
charWidth: 8.5,
|
|
49
|
+
min: 72,
|
|
50
|
+
max: 320
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/** The web Copy table menu, in its order. */
|
|
54
|
+
const COPY_FORMATS = [{
|
|
55
|
+
format: "markdown",
|
|
56
|
+
title: "Markdown"
|
|
57
|
+
}, {
|
|
58
|
+
format: "csv",
|
|
59
|
+
title: "CSV"
|
|
60
|
+
}, {
|
|
61
|
+
format: "tsv",
|
|
62
|
+
title: "TSV"
|
|
63
|
+
}];
|
|
64
|
+
/**
|
|
65
|
+
* The cells as rows. `widths` gives every column its own width (the
|
|
66
|
+
* full-screen view, which scrolls sideways); without it the columns share the
|
|
67
|
+
* width equally and the cells wrap, so they line up in a chat column.
|
|
68
|
+
*/
|
|
69
|
+
function TableRows(t0) {
|
|
70
|
+
const $ = _c(17);
|
|
71
|
+
const {
|
|
72
|
+
header,
|
|
73
|
+
rows,
|
|
74
|
+
color,
|
|
75
|
+
widths
|
|
76
|
+
} = t0;
|
|
77
|
+
const scheme = useScheme();
|
|
78
|
+
const {
|
|
79
|
+
cellPaddingX,
|
|
80
|
+
cellPaddingY
|
|
81
|
+
} = MARKDOWN_TABLE;
|
|
82
|
+
let t1;
|
|
83
|
+
if ($[0] !== scheme) {
|
|
84
|
+
t1 = index => index === 1 ? tokens.color.border[scheme] : withAlpha(tokens.color.border[scheme], 0.7);
|
|
85
|
+
$[0] = scheme;
|
|
86
|
+
$[1] = t1;
|
|
87
|
+
} else {
|
|
88
|
+
t1 = $[1];
|
|
89
|
+
}
|
|
90
|
+
const rule = t1;
|
|
91
|
+
let t2;
|
|
92
|
+
if ($[2] !== color || $[3] !== rule || $[4] !== widths) {
|
|
93
|
+
t2 = (cells, index_0) => <View key={index_0} style={{
|
|
94
|
+
flexDirection: "row",
|
|
95
|
+
borderTopWidth: index_0 > 0 ? 1 : 0,
|
|
96
|
+
borderTopColor: rule(index_0)
|
|
97
|
+
}}>{cells.map((cell, cellIndex) => <View key={cellIndex} style={[{
|
|
98
|
+
paddingHorizontal: cellPaddingX,
|
|
99
|
+
paddingVertical: cellPaddingY
|
|
100
|
+
}, widths ? {
|
|
101
|
+
width: widths[cellIndex]
|
|
102
|
+
} : {
|
|
103
|
+
flex: 1
|
|
104
|
+
}]}><Text style={{
|
|
105
|
+
color
|
|
106
|
+
}}>{cell}</Text></View>)}</View>;
|
|
107
|
+
$[2] = color;
|
|
108
|
+
$[3] = rule;
|
|
109
|
+
$[4] = widths;
|
|
110
|
+
$[5] = t2;
|
|
111
|
+
} else {
|
|
112
|
+
t2 = $[5];
|
|
113
|
+
}
|
|
114
|
+
const row = t2;
|
|
115
|
+
let t3;
|
|
116
|
+
if ($[6] !== header || $[7] !== row) {
|
|
117
|
+
t3 = row(header, 0);
|
|
118
|
+
$[6] = header;
|
|
119
|
+
$[7] = row;
|
|
120
|
+
$[8] = t3;
|
|
121
|
+
} else {
|
|
122
|
+
t3 = $[8];
|
|
123
|
+
}
|
|
124
|
+
let t4;
|
|
125
|
+
if ($[9] !== row || $[10] !== rows) {
|
|
126
|
+
let t5;
|
|
127
|
+
if ($[12] !== row) {
|
|
128
|
+
t5 = (cells_0, index_1) => row(cells_0, index_1 + 1);
|
|
129
|
+
$[12] = row;
|
|
130
|
+
$[13] = t5;
|
|
131
|
+
} else {
|
|
132
|
+
t5 = $[13];
|
|
133
|
+
}
|
|
134
|
+
t4 = rows.map(t5);
|
|
135
|
+
$[9] = row;
|
|
136
|
+
$[10] = rows;
|
|
137
|
+
$[11] = t4;
|
|
138
|
+
} else {
|
|
139
|
+
t4 = $[11];
|
|
140
|
+
}
|
|
141
|
+
let t5;
|
|
142
|
+
if ($[14] !== t3 || $[15] !== t4) {
|
|
143
|
+
t5 = <>{t3}{t4}</>;
|
|
144
|
+
$[14] = t3;
|
|
145
|
+
$[15] = t4;
|
|
146
|
+
$[16] = t5;
|
|
147
|
+
} else {
|
|
148
|
+
t5 = $[16];
|
|
149
|
+
}
|
|
150
|
+
return t5;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* A markdown table on the web's panel, with the web table actions a phone
|
|
155
|
+
* can use: Copy table (a sheet of Markdown, CSV and TSV, as the web menu)
|
|
156
|
+
* and View fullscreen (the table at its own column widths, scrolling
|
|
157
|
+
* sideways, for a table too wide for the chat). The web's Download table is
|
|
158
|
+
* left out: a phone saves a file through a share sheet, which native-ui does
|
|
159
|
+
* not bundle, and the copy formats carry the same text.
|
|
160
|
+
*/
|
|
161
|
+
export function MarkdownTable(t0) {
|
|
162
|
+
const $ = _c(65);
|
|
163
|
+
const {
|
|
164
|
+
header,
|
|
165
|
+
rows,
|
|
166
|
+
data,
|
|
167
|
+
color,
|
|
168
|
+
onCopy
|
|
169
|
+
} = t0;
|
|
170
|
+
const scheme = useScheme();
|
|
171
|
+
const insets = useSafeAreaInsets();
|
|
172
|
+
const reduceMotion = useReduceMotion();
|
|
173
|
+
const [copyOpen, setCopyOpen] = useState(false);
|
|
174
|
+
const [fullScreen, setFullScreen] = useState(false);
|
|
175
|
+
const {
|
|
176
|
+
panelPadding,
|
|
177
|
+
tableMargin,
|
|
178
|
+
actionsHeight,
|
|
179
|
+
actionsGap
|
|
180
|
+
} = MARKDOWN_TABLE;
|
|
181
|
+
const muted = tokens.color.muted[scheme];
|
|
182
|
+
const t1 = tokens.color.surfaceSecondary[scheme];
|
|
183
|
+
let t2;
|
|
184
|
+
if ($[0] !== t1) {
|
|
185
|
+
t2 = {
|
|
186
|
+
borderRadius: tokens.radius.lg,
|
|
187
|
+
backgroundColor: t1,
|
|
188
|
+
paddingTop: panelPadding.top,
|
|
189
|
+
paddingHorizontal: panelPadding.x,
|
|
190
|
+
paddingBottom: panelPadding.bottom
|
|
191
|
+
};
|
|
192
|
+
$[0] = t1;
|
|
193
|
+
$[1] = t2;
|
|
194
|
+
} else {
|
|
195
|
+
t2 = $[1];
|
|
196
|
+
}
|
|
197
|
+
const panel = t2;
|
|
198
|
+
let t3;
|
|
199
|
+
if ($[2] !== data || $[3] !== onCopy) {
|
|
200
|
+
t3 = async format => {
|
|
201
|
+
setCopyOpen(false);
|
|
202
|
+
await onCopy?.(markdownTableText(data, format));
|
|
203
|
+
};
|
|
204
|
+
$[2] = data;
|
|
205
|
+
$[3] = onCopy;
|
|
206
|
+
$[4] = t3;
|
|
207
|
+
} else {
|
|
208
|
+
t3 = $[4];
|
|
209
|
+
}
|
|
210
|
+
const copy = t3;
|
|
211
|
+
let t4;
|
|
212
|
+
if ($[5] !== muted || $[6] !== onCopy) {
|
|
213
|
+
t4 = onCopy ? <ChatIconButton icon={IconCopy} label="Copy table" size="xs" iconColor={muted} onPress={() => setCopyOpen(true)} /> : null;
|
|
214
|
+
$[5] = muted;
|
|
215
|
+
$[6] = onCopy;
|
|
216
|
+
$[7] = t4;
|
|
217
|
+
} else {
|
|
218
|
+
t4 = $[7];
|
|
219
|
+
}
|
|
220
|
+
const copyButton = t4;
|
|
221
|
+
let t5;
|
|
222
|
+
if ($[8] !== data) {
|
|
223
|
+
t5 = markdownTableColumnWidths(data, {
|
|
224
|
+
...FULL_SCREEN_COLUMN,
|
|
225
|
+
padding: MARKDOWN_TABLE.cellPaddingX * 2
|
|
226
|
+
});
|
|
227
|
+
$[8] = data;
|
|
228
|
+
$[9] = t5;
|
|
229
|
+
} else {
|
|
230
|
+
t5 = $[9];
|
|
231
|
+
}
|
|
232
|
+
const widths = t5;
|
|
233
|
+
let t6;
|
|
234
|
+
if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
|
|
235
|
+
t6 = {
|
|
236
|
+
height: actionsHeight,
|
|
237
|
+
gap: actionsGap
|
|
238
|
+
};
|
|
239
|
+
$[10] = t6;
|
|
240
|
+
} else {
|
|
241
|
+
t6 = $[10];
|
|
242
|
+
}
|
|
243
|
+
let t7;
|
|
244
|
+
if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
|
|
245
|
+
t7 = () => setFullScreen(true);
|
|
246
|
+
$[11] = t7;
|
|
247
|
+
} else {
|
|
248
|
+
t7 = $[11];
|
|
249
|
+
}
|
|
250
|
+
let t8;
|
|
251
|
+
if ($[12] !== muted) {
|
|
252
|
+
t8 = <ChatIconButton icon={IconMaximize} label="View fullscreen" size="xs" iconColor={muted} onPress={t7} />;
|
|
253
|
+
$[12] = muted;
|
|
254
|
+
$[13] = t8;
|
|
255
|
+
} else {
|
|
256
|
+
t8 = $[13];
|
|
257
|
+
}
|
|
258
|
+
let t9;
|
|
259
|
+
if ($[14] !== copyButton || $[15] !== t8) {
|
|
260
|
+
t9 = <View className="flex-row items-center justify-end" style={t6}>{copyButton}{t8}</View>;
|
|
261
|
+
$[14] = copyButton;
|
|
262
|
+
$[15] = t8;
|
|
263
|
+
$[16] = t9;
|
|
264
|
+
} else {
|
|
265
|
+
t9 = $[16];
|
|
266
|
+
}
|
|
267
|
+
let t10;
|
|
268
|
+
if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
|
|
269
|
+
t10 = {
|
|
270
|
+
marginTop: tableMargin,
|
|
271
|
+
marginBottom: tableMargin
|
|
272
|
+
};
|
|
273
|
+
$[17] = t10;
|
|
274
|
+
} else {
|
|
275
|
+
t10 = $[17];
|
|
276
|
+
}
|
|
277
|
+
let t11;
|
|
278
|
+
if ($[18] !== color || $[19] !== header || $[20] !== rows) {
|
|
279
|
+
t11 = <View style={t10}><TableRows header={header} rows={rows} color={color} /></View>;
|
|
280
|
+
$[18] = color;
|
|
281
|
+
$[19] = header;
|
|
282
|
+
$[20] = rows;
|
|
283
|
+
$[21] = t11;
|
|
284
|
+
} else {
|
|
285
|
+
t11 = $[21];
|
|
286
|
+
}
|
|
287
|
+
let t12;
|
|
288
|
+
if ($[22] !== copy || $[23] !== copyOpen || $[24] !== onCopy) {
|
|
289
|
+
t12 = onCopy ? <Sheet open={copyOpen} onOpenChange={setCopyOpen}><SheetContent className="gap-3 px-3"><SheetHeader className="px-2"><SheetTitle>Copy table</SheetTitle></SheetHeader><SheetBody contentContainerClassName="gap-3">{COPY_FORMATS.map(t13 => {
|
|
290
|
+
const {
|
|
291
|
+
format: format_0,
|
|
292
|
+
title
|
|
293
|
+
} = t13;
|
|
294
|
+
return <SheetRow key={format_0} title={title} onPress={() => void copy(format_0)} />;
|
|
295
|
+
})}</SheetBody></SheetContent></Sheet> : null;
|
|
296
|
+
$[22] = copy;
|
|
297
|
+
$[23] = copyOpen;
|
|
298
|
+
$[24] = onCopy;
|
|
299
|
+
$[25] = t12;
|
|
300
|
+
} else {
|
|
301
|
+
t12 = $[25];
|
|
302
|
+
}
|
|
303
|
+
const t13 = reduceMotion ? "none" : "fade";
|
|
304
|
+
let t14;
|
|
305
|
+
if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
|
|
306
|
+
t14 = () => setFullScreen(false);
|
|
307
|
+
$[26] = t14;
|
|
308
|
+
} else {
|
|
309
|
+
t14 = $[26];
|
|
310
|
+
}
|
|
311
|
+
const t15 = tokens.color.background[scheme];
|
|
312
|
+
let t16;
|
|
313
|
+
if ($[27] !== insets.bottom || $[28] !== insets.left || $[29] !== insets.right || $[30] !== insets.top || $[31] !== t15) {
|
|
314
|
+
t16 = {
|
|
315
|
+
backgroundColor: t15,
|
|
316
|
+
paddingTop: insets.top,
|
|
317
|
+
paddingBottom: insets.bottom,
|
|
318
|
+
paddingLeft: insets.left,
|
|
319
|
+
paddingRight: insets.right
|
|
320
|
+
};
|
|
321
|
+
$[27] = insets.bottom;
|
|
322
|
+
$[28] = insets.left;
|
|
323
|
+
$[29] = insets.right;
|
|
324
|
+
$[30] = insets.top;
|
|
325
|
+
$[31] = t15;
|
|
326
|
+
$[32] = t16;
|
|
327
|
+
} else {
|
|
328
|
+
t16 = $[32];
|
|
329
|
+
}
|
|
330
|
+
let t17;
|
|
331
|
+
if ($[33] === Symbol.for("react.memo_cache_sentinel")) {
|
|
332
|
+
t17 = {
|
|
333
|
+
gap: actionsGap
|
|
334
|
+
};
|
|
335
|
+
$[33] = t17;
|
|
336
|
+
} else {
|
|
337
|
+
t17 = $[33];
|
|
338
|
+
}
|
|
339
|
+
let t18;
|
|
340
|
+
if ($[34] === Symbol.for("react.memo_cache_sentinel")) {
|
|
341
|
+
t18 = () => setFullScreen(false);
|
|
342
|
+
$[34] = t18;
|
|
343
|
+
} else {
|
|
344
|
+
t18 = $[34];
|
|
345
|
+
}
|
|
346
|
+
let t19;
|
|
347
|
+
if ($[35] !== muted) {
|
|
348
|
+
t19 = <ChatIconButton icon={IconX} label="Exit fullscreen" iconColor={muted} onPress={t18} />;
|
|
349
|
+
$[35] = muted;
|
|
350
|
+
$[36] = t19;
|
|
351
|
+
} else {
|
|
352
|
+
t19 = $[36];
|
|
353
|
+
}
|
|
354
|
+
let t20;
|
|
355
|
+
if ($[37] !== copyButton || $[38] !== t19) {
|
|
356
|
+
t20 = <View className="flex-row items-center justify-end px-2 py-1.5" style={t17}>{copyButton}{t19}</View>;
|
|
357
|
+
$[37] = copyButton;
|
|
358
|
+
$[38] = t19;
|
|
359
|
+
$[39] = t20;
|
|
360
|
+
} else {
|
|
361
|
+
t20 = $[39];
|
|
362
|
+
}
|
|
363
|
+
let t21;
|
|
364
|
+
if ($[40] === Symbol.for("react.memo_cache_sentinel")) {
|
|
365
|
+
t21 = {
|
|
366
|
+
padding: 16
|
|
367
|
+
};
|
|
368
|
+
$[40] = t21;
|
|
369
|
+
} else {
|
|
370
|
+
t21 = $[40];
|
|
371
|
+
}
|
|
372
|
+
let t22;
|
|
373
|
+
if ($[41] === Symbol.for("react.memo_cache_sentinel")) {
|
|
374
|
+
t22 = {
|
|
375
|
+
flexGrow: 1
|
|
376
|
+
};
|
|
377
|
+
$[41] = t22;
|
|
378
|
+
} else {
|
|
379
|
+
t22 = $[41];
|
|
380
|
+
}
|
|
381
|
+
let t23;
|
|
382
|
+
if ($[42] === Symbol.for("react.memo_cache_sentinel")) {
|
|
383
|
+
t23 = {
|
|
384
|
+
marginVertical: tableMargin
|
|
385
|
+
};
|
|
386
|
+
$[42] = t23;
|
|
387
|
+
} else {
|
|
388
|
+
t23 = $[42];
|
|
389
|
+
}
|
|
390
|
+
let t24;
|
|
391
|
+
if ($[43] !== color || $[44] !== header || $[45] !== rows || $[46] !== widths) {
|
|
392
|
+
t24 = <View style={t23}><TableRows header={header} rows={rows} color={color} widths={widths} /></View>;
|
|
393
|
+
$[43] = color;
|
|
394
|
+
$[44] = header;
|
|
395
|
+
$[45] = rows;
|
|
396
|
+
$[46] = widths;
|
|
397
|
+
$[47] = t24;
|
|
398
|
+
} else {
|
|
399
|
+
t24 = $[47];
|
|
400
|
+
}
|
|
401
|
+
let t25;
|
|
402
|
+
if ($[48] !== panel || $[49] !== t24) {
|
|
403
|
+
t25 = <ScrollView contentContainerStyle={t21}><ScrollView horizontal={true} contentContainerStyle={t22}><View style={panel}>{t24}</View></ScrollView></ScrollView>;
|
|
404
|
+
$[48] = panel;
|
|
405
|
+
$[49] = t24;
|
|
406
|
+
$[50] = t25;
|
|
407
|
+
} else {
|
|
408
|
+
t25 = $[50];
|
|
409
|
+
}
|
|
410
|
+
let t26;
|
|
411
|
+
if ($[51] !== t16 || $[52] !== t20 || $[53] !== t25) {
|
|
412
|
+
t26 = <View className="flex-1" accessibilityViewIsModal={true} style={t16}>{t20}{t25}</View>;
|
|
413
|
+
$[51] = t16;
|
|
414
|
+
$[52] = t20;
|
|
415
|
+
$[53] = t25;
|
|
416
|
+
$[54] = t26;
|
|
417
|
+
} else {
|
|
418
|
+
t26 = $[54];
|
|
419
|
+
}
|
|
420
|
+
let t27;
|
|
421
|
+
if ($[55] !== fullScreen || $[56] !== t13 || $[57] !== t26) {
|
|
422
|
+
t27 = <Modal visible={fullScreen} animationType={t13} statusBarTranslucent={true} onRequestClose={t14}>{t26}</Modal>;
|
|
423
|
+
$[55] = fullScreen;
|
|
424
|
+
$[56] = t13;
|
|
425
|
+
$[57] = t26;
|
|
426
|
+
$[58] = t27;
|
|
427
|
+
} else {
|
|
428
|
+
t27 = $[58];
|
|
429
|
+
}
|
|
430
|
+
let t28;
|
|
431
|
+
if ($[59] !== panel || $[60] !== t11 || $[61] !== t12 || $[62] !== t27 || $[63] !== t9) {
|
|
432
|
+
t28 = <View style={panel}>{t9}{t11}{t12}{t27}</View>;
|
|
433
|
+
$[59] = panel;
|
|
434
|
+
$[60] = t11;
|
|
435
|
+
$[61] = t12;
|
|
436
|
+
$[62] = t27;
|
|
437
|
+
$[63] = t9;
|
|
438
|
+
$[64] = t28;
|
|
439
|
+
} else {
|
|
440
|
+
t28 = $[64];
|
|
441
|
+
}
|
|
442
|
+
return t28;
|
|
443
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A markdown table as text, for the table's copy actions: the formats and
|
|
3
|
+
* escaping of the web table controls (Streamdown's Copy table: Markdown, CSV
|
|
4
|
+
* and TSV), from each cell's plain text.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** CSV: a cell with a comma, quote or line break is quoted, its quotes doubled. Lines join with `\n`. */
|
|
8
|
+
function toCsv({
|
|
9
|
+
headers,
|
|
10
|
+
rows
|
|
11
|
+
}) {
|
|
12
|
+
const cell = text => /[",\n\r]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text;
|
|
13
|
+
return [...(headers.length > 0 ? [headers] : []), ...rows].map(row => row.map(cell).join(",")).join("\n");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** TSV: tabs and line breaks in a cell are written as `\t`, `\n` and `\r`. */
|
|
17
|
+
function toTsv({
|
|
18
|
+
headers,
|
|
19
|
+
rows
|
|
20
|
+
}) {
|
|
21
|
+
const cell = text => text.replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
|
|
22
|
+
return [...(headers.length > 0 ? [headers] : []), ...rows].map(row => row.map(cell).join("\t")).join("\n");
|
|
23
|
+
}
|
|
24
|
+
const MARKDOWN_ESCAPES = {
|
|
25
|
+
"\\": "\\\\",
|
|
26
|
+
"|": "\\|",
|
|
27
|
+
"\n": "<br>",
|
|
28
|
+
"&": "&",
|
|
29
|
+
"<": "<",
|
|
30
|
+
">": ">"
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/** GitHub markdown: pipes and backslashes escaped, line breaks as `<br>`, short rows padded to the header. */
|
|
34
|
+
function toMarkdown({
|
|
35
|
+
headers,
|
|
36
|
+
rows
|
|
37
|
+
}) {
|
|
38
|
+
if (headers.length === 0) return "";
|
|
39
|
+
const cell = text => text.replace(/[\\|\n&<>]/g, char => MARKDOWN_ESCAPES[char] ?? char);
|
|
40
|
+
const line = cells => `| ${cells.join(" | ")} |`;
|
|
41
|
+
return [line(headers.map(cell)), line(headers.map(() => "---")), ...rows.map(row => line(row.length < headers.length ? headers.map((_, index) => cell(row[index] ?? "")) : row.map(cell)))].join("\n");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** The table in one of the copy formats. */
|
|
45
|
+
export function markdownTableText(data, format) {
|
|
46
|
+
if (format === "csv") return toCsv(data);
|
|
47
|
+
if (format === "tsv") return toTsv(data);
|
|
48
|
+
return toMarkdown(data);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Column widths for the full-screen table, where columns size to their text
|
|
53
|
+
* as the web table does: React Native has no table layout, so the longest
|
|
54
|
+
* line in each column, at `charWidth` a character plus the cell padding,
|
|
55
|
+
* clamped to `[min, max]`.
|
|
56
|
+
*/
|
|
57
|
+
export function markdownTableColumnWidths(data, {
|
|
58
|
+
charWidth,
|
|
59
|
+
padding,
|
|
60
|
+
min,
|
|
61
|
+
max
|
|
62
|
+
}) {
|
|
63
|
+
return data.headers.map((header, column) => {
|
|
64
|
+
const cells = [header, ...data.rows.map(row => row[column] ?? "")];
|
|
65
|
+
const longest = Math.max(...cells.flatMap(text => text.split("\n").map(line => line.length)));
|
|
66
|
+
return Math.min(max, Math.max(min, Math.ceil(longest * charWidth + padding)));
|
|
67
|
+
});
|
|
68
|
+
}
|