@xpufx/paseo-top 0.4.4 → 0.4.7

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 (130) hide show
  1. package/OVERVIEW.md +18 -0
  2. package/client/host-ui.tsx +184 -0
  3. package/client/multi-host-view.tsx +57 -43
  4. package/client/multi-host.ts +36 -13
  5. package/client/pill-labels.ts +94 -1
  6. package/client/pill.tsx +692 -616
  7. package/client/resources-query.ts +1 -1
  8. package/client/settings-events.ts +1 -1
  9. package/client/settings-ui.tsx +86 -9
  10. package/client/surface.tsx +308 -276
  11. package/client/telemetry-copy.ts +8 -2
  12. package/client/telemetry.tsx +372 -321
  13. package/client/turn-panel.tsx +126 -104
  14. package/client/vendor/paseo-plugin-helper/{host.ts → core/host.ts} +9 -3
  15. package/client/vendor/paseo-plugin-helper/core/index.ts +76 -0
  16. package/client/vendor/paseo-plugin-helper/core/plugin-load-count.ts +89 -0
  17. package/client/vendor/paseo-plugin-helper/{query-refresh.ts → core/query-refresh.ts} +2 -2
  18. package/client/vendor/paseo-plugin-helper/{query.ts → core/query.ts} +2 -2
  19. package/client/vendor/paseo-plugin-helper/{settings.ts → core/settings.ts} +1 -1
  20. package/client/vendor/paseo-plugin-helper/{shared-settings.ts → core/shared-settings.ts} +2 -2
  21. package/client/vendor/paseo-plugin-helper/{utils → lifecycle}/clipboard.ts +2 -2
  22. package/client/vendor/paseo-plugin-helper/lifecycle/flair.ts +26 -0
  23. package/client/vendor/paseo-plugin-helper/{theme/color-utils.ts → lifecycle/host-color.ts} +95 -38
  24. package/client/vendor/paseo-plugin-helper/lifecycle/host-theme.tsx +109 -0
  25. package/client/vendor/paseo-plugin-helper/lifecycle/index.ts +23 -0
  26. package/client/vendor/paseo-plugin-helper/lifecycle/multi-host.ts +66 -0
  27. package/client/vendor/paseo-plugin-helper/{panel.tsx → lifecycle/panel.tsx} +7 -7
  28. package/client/vendor/paseo-plugin-helper/{pill.tsx → lifecycle/pill.tsx} +51 -18
  29. package/client/vendor/paseo-plugin-helper/lifecycle/providers.tsx +46 -0
  30. package/client/vendor/paseo-plugin-helper/lifecycle/scroll-owner.ts +26 -0
  31. package/client/vendor/paseo-plugin-helper/{surface.tsx → lifecycle/surface.tsx} +6 -6
  32. package/client/vendor/paseo-plugin-helper/ui/color.ts +1 -0
  33. package/client/vendor/paseo-plugin-helper/ui/content.tsx +1326 -0
  34. package/client/vendor/paseo-plugin-helper/ui/controls.tsx +1018 -0
  35. package/client/vendor/paseo-plugin-helper/{components/DataTable.tsx → ui/data.tsx} +50 -58
  36. package/client/vendor/paseo-plugin-helper/ui/index.ts +44 -0
  37. package/client/vendor/paseo-plugin-helper/ui/layout.tsx +263 -0
  38. package/client/vendor/paseo-plugin-helper/ui/modal.tsx +111 -0
  39. package/client/vendor/paseo-plugin-helper/ui/plugin-reload-banner.tsx +119 -0
  40. package/client/vendor/paseo-plugin-helper/{settings-screen.tsx → ui/settings-screen.tsx} +3 -3
  41. package/client/vendor/paseo-plugin-helper/ui/settings.ts +36 -0
  42. package/client/vendor/paseo-plugin-helper/ui/text.tsx +821 -0
  43. package/client/vendor/paseo-plugin-helper/ui/theme.tsx +1 -0
  44. package/client/vendor/permission-audit/client.tsx +706 -0
  45. package/client/vendor/permission-audit/index.tsx +1 -0
  46. package/index.client.tsx +58 -37
  47. package/index.server.ts +256 -234
  48. package/npm-shrinkwrap.json +44 -0
  49. package/package.json +8 -4
  50. package/paseo-plugin.json +2 -0
  51. package/screenshots/1-paseo-top-modal-system.jpg +0 -0
  52. package/screenshots/2-paseo-top-modal-workspace.jpg +0 -0
  53. package/screenshots/3-paseo-top-modal-settings.jpg +0 -0
  54. package/screenshots/4-paseo-top-modal-about.jpg +0 -0
  55. package/screenshots/paseo-top-dashboard.jpg +0 -0
  56. package/screenshots/paseo-top-general-view.jpg +0 -0
  57. package/server/resources.ts +98 -0
  58. package/server/vendor/paseo-plugin-helper/custom-pills.ts +70 -0
  59. package/server/vendor/paseo-plugin-helper/index.ts +2 -0
  60. package/server/vendor/paseo-plugin-helper/logger.ts +5 -16
  61. package/server/vendor/paseo-plugin-helper/rpc-guard.ts +2 -2
  62. package/server/vendor/paseo-plugin-helper/storage-guard.ts +294 -0
  63. package/server/vendor/paseo-plugin-helper/storage.ts +36 -2
  64. package/server/vendor/paseo-plugin-helper/telemetry.ts +486 -0
  65. package/server/vendor/paseo-plugin-helper/tickets.ts +18 -67
  66. package/server/vendor/permission-audit/index.ts +1 -0
  67. package/server/vendor/permission-audit/server.ts +839 -0
  68. package/shared/helper-version.ts +1 -1
  69. package/shared/multi-host.ts +153 -159
  70. package/shared/resources.ts +145 -0
  71. package/shared/vendor/paseo-plugin-helper/async.ts +14 -7
  72. package/shared/vendor/paseo-plugin-helper/features.ts +244 -0
  73. package/shared/vendor/paseo-plugin-helper/forge.ts +27 -0
  74. package/shared/vendor/paseo-plugin-helper/index.ts +1 -0
  75. package/shared/vendor/paseo-plugin-helper/tickets.ts +122 -28
  76. package/shared/vendor/permission-audit/filter.ts +61 -0
  77. package/shared/vendor/permission-audit/index.ts +2 -0
  78. package/shared/vendor/permission-audit/shared.ts +119 -0
  79. package/shared/version.ts +1 -1
  80. package/client/vendor/paseo-plugin-helper/components/AboutSection.tsx +0 -493
  81. package/client/vendor/paseo-plugin-helper/components/AttentionBeacon.tsx +0 -250
  82. package/client/vendor/paseo-plugin-helper/components/Badge.tsx +0 -168
  83. package/client/vendor/paseo-plugin-helper/components/Button.tsx +0 -204
  84. package/client/vendor/paseo-plugin-helper/components/Card.tsx +0 -257
  85. package/client/vendor/paseo-plugin-helper/components/CodeBlock.tsx +0 -196
  86. package/client/vendor/paseo-plugin-helper/components/Collapsible.tsx +0 -277
  87. package/client/vendor/paseo-plugin-helper/components/CommandBox.tsx +0 -172
  88. package/client/vendor/paseo-plugin-helper/components/CopyButton.tsx +0 -180
  89. package/client/vendor/paseo-plugin-helper/components/EmptyState.tsx +0 -97
  90. package/client/vendor/paseo-plugin-helper/components/HighlightedText.tsx +0 -70
  91. package/client/vendor/paseo-plugin-helper/components/InlineButton.tsx +0 -88
  92. package/client/vendor/paseo-plugin-helper/components/InteractiveRow.tsx +0 -142
  93. package/client/vendor/paseo-plugin-helper/components/KeyValue.tsx +0 -446
  94. package/client/vendor/paseo-plugin-helper/components/MetricGauge.tsx +0 -247
  95. package/client/vendor/paseo-plugin-helper/components/ProgressBar.tsx +0 -117
  96. package/client/vendor/paseo-plugin-helper/components/Responsive.tsx +0 -53
  97. package/client/vendor/paseo-plugin-helper/components/SearchInput.tsx +0 -132
  98. package/client/vendor/paseo-plugin-helper/components/SectionHeader.tsx +0 -87
  99. package/client/vendor/paseo-plugin-helper/components/Select.tsx +0 -283
  100. package/client/vendor/paseo-plugin-helper/components/StatusDot.tsx +0 -80
  101. package/client/vendor/paseo-plugin-helper/components/Tabs.tsx +0 -319
  102. package/client/vendor/paseo-plugin-helper/components/TextInput.tsx +0 -150
  103. package/client/vendor/paseo-plugin-helper/components/Toggle.tsx +0 -163
  104. package/client/vendor/paseo-plugin-helper/components/TruncatedText.tsx +0 -157
  105. package/client/vendor/paseo-plugin-helper/components/index.ts +0 -26
  106. package/client/vendor/paseo-plugin-helper/custom-pills.tsx +0 -225
  107. package/client/vendor/paseo-plugin-helper/forge-icon.tsx +0 -79
  108. package/client/vendor/paseo-plugin-helper/icon.tsx +0 -39
  109. package/client/vendor/paseo-plugin-helper/index.ts +0 -30
  110. package/client/vendor/paseo-plugin-helper/layout/ActionBar.tsx +0 -49
  111. package/client/vendor/paseo-plugin-helper/layout/FormRow.tsx +0 -103
  112. package/client/vendor/paseo-plugin-helper/layout/Grid.tsx +0 -65
  113. package/client/vendor/paseo-plugin-helper/layout/ModalBody.tsx +0 -368
  114. package/client/vendor/paseo-plugin-helper/layout/ModalContent.tsx +0 -51
  115. package/client/vendor/paseo-plugin-helper/layout/Row.tsx +0 -39
  116. package/client/vendor/paseo-plugin-helper/layout/Stack.tsx +0 -39
  117. package/client/vendor/paseo-plugin-helper/layout/index.ts +0 -7
  118. package/client/vendor/paseo-plugin-helper/styles/index.ts +0 -1
  119. package/client/vendor/paseo-plugin-helper/styles/recipes.ts +0 -550
  120. package/client/vendor/paseo-plugin-helper/theme/flair.ts +0 -76
  121. package/client/vendor/paseo-plugin-helper/theme/host-variables.ts +0 -121
  122. package/client/vendor/paseo-plugin-helper/theme/index.ts +0 -7
  123. package/client/vendor/paseo-plugin-helper/theme/provider.tsx +0 -178
  124. package/client/vendor/paseo-plugin-helper/theme/responsive.ts +0 -213
  125. package/client/vendor/paseo-plugin-helper/theme/tokens.ts +0 -200
  126. package/client/vendor/paseo-plugin-helper/theme/useResponsive.ts +0 -57
  127. package/client/vendor/paseo-plugin-helper/tickets.tsx +0 -766
  128. /package/client/vendor/paseo-plugin-helper/{command-center.ts → core/command-center.ts} +0 -0
  129. /package/client/vendor/paseo-plugin-helper/{snapshot.ts → core/snapshot.ts} +0 -0
  130. /package/client/vendor/paseo-plugin-helper/{utils → lifecycle}/haptics.ts +0 -0
@@ -1,257 +0,0 @@
1
- import React, { type ReactNode } from "react";
2
- import { StyleSheet, Text, View, type StyleProp, type TextStyle, type ViewStyle } from "react-native";
3
- import { getClientHost } from "../host";
4
- import { usePluginTheme } from "../theme/provider";
5
- import { HighlightedText } from "./HighlightedText";
6
- import type { SurfaceStyle } from "../theme/flair";
7
-
8
- export interface CardProps {
9
- children: ReactNode;
10
- variant?: SurfaceStyle;
11
- style?: StyleProp<ViewStyle>;
12
- noPadding?: boolean;
13
- }
14
-
15
- export interface CardHeaderProps {
16
- title: string;
17
- subtitle?: string;
18
- value?: string | number | ReactNode;
19
- badge?: ReactNode;
20
- action?: ReactNode;
21
- icon?: string;
22
- style?: StyleProp<ViewStyle>;
23
- titleStyle?: StyleProp<TextStyle>;
24
- subtitleStyle?: StyleProp<TextStyle>;
25
- /**
26
- * When set, every case-insensitive (literal, non-regex) occurrence of the
27
- * query inside `title` is painted with the accent highlight. With no literal
28
- * or token hit the whole title is marked, so a fuzzy match still reads.
29
- */
30
- highlightQuery?: string;
31
- }
32
-
33
- // TEMPORARY DIAGNOSTIC (#555) — one-shot probe logging the host icon the
34
- // first CardHeader render resolves, right before it is used; strip once the
35
- // missing-binding cause is confirmed.
36
- let cardHeaderIconProbeFired = false;
37
-
38
- export function CardHeader({
39
- title,
40
- subtitle,
41
- value,
42
- badge,
43
- action,
44
- icon,
45
- style,
46
- titleStyle,
47
- subtitleStyle,
48
- highlightQuery,
49
- }: CardHeaderProps) {
50
- const { Icon } = getClientHost();
51
- // TEMPORARY DIAGNOSTIC (#555) — strip once the missing-binding cause is
52
- // confirmed. A probe that throws must never crash the header itself.
53
- try {
54
- if (!cardHeaderIconProbeFired) {
55
- cardHeaderIconProbeFired = true;
56
- const describe = (value: unknown): string => {
57
- if (value === undefined) return "undefined";
58
- if (value === null) return "null";
59
- if (typeof value === "function") {
60
- const named = (value as { displayName?: string; name?: string }).displayName
61
- ?? (value as { name?: string }).name;
62
- return `function(${named || "(anonymous)"})`;
63
- }
64
- if (typeof value === "object") {
65
- const symbolTag = (value as { $$typeof?: unknown }).$$typeof;
66
- return `object($$typeof=${String(symbolTag)}, render=${typeof (value as { render?: unknown }).render})`;
67
- }
68
- return typeof value;
69
- };
70
- console.warn(
71
- "[2fado] CardHeader probe: icon=", icon ?? "(no icon prop)",
72
- "resolved host Icon=", `typeofIcon=${typeof Icon}`, describe(Icon),
73
- );
74
- }
75
- } catch (err) {
76
- console.warn("[2fado] CardHeader probe failed:", err);
77
- }
78
- const { colors, flair, typography, padding, isCompact } = usePluginTheme();
79
-
80
- return (
81
- <View
82
- style={[
83
- styles.headerContainer,
84
- // Density-aware gap below the header. A hardcoded 8 wasted vertical
85
- // space under the compact preset (xpufx-org/paseo#213).
86
- { marginBottom: padding.gap },
87
- // On a compact/narrow surface, stack the title block above the action
88
- // row instead of sharing one line. Sharing the line lets a wide action
89
- // group (badges + toggle + buttons) hold its intrinsic width while the
90
- // title column collapses to its longest word, wrapping one character
91
- // per line and spilling the actions past the card (xpufx-org/paseo#202).
92
- isCompact && styles.headerContainerCompact,
93
- style,
94
- ]}
95
- >
96
- <View style={[styles.headerLeft, isCompact && styles.headerLeftCompact]}>
97
- {icon ? <Icon name={icon} size={15} color={colors.foregroundMuted} /> : null}
98
- <View style={styles.titleColumn}>
99
- <Text
100
- style={[
101
- styles.headerTitle,
102
- {
103
- color: colors.foreground,
104
- ...typography.heading,
105
- textTransform:
106
- flair.headingTransform === "uppercase" ? "uppercase" : "none",
107
- },
108
- titleStyle,
109
- ]}
110
- >
111
- {highlightQuery ? (
112
- <HighlightedText text={title} query={highlightQuery} fuzzyFallback />
113
- ) : (
114
- title
115
- )}
116
- </Text>
117
- {subtitle ? (
118
- <Text
119
- style={[
120
- styles.headerSubtitle,
121
- { color: colors.foregroundMuted, ...typography.caption },
122
- subtitleStyle,
123
- ]}
124
- >
125
- {subtitle}
126
- </Text>
127
- ) : null}
128
- </View>
129
- </View>
130
-
131
- <View style={[styles.headerRight, isCompact && styles.headerRightCompact]}>
132
- {badge ? <View style={{ marginRight: 6 }}>{badge}</View> : null}
133
- {typeof value === "string" || typeof value === "number" ? (
134
- <Text
135
- style={[
136
- styles.headerValue,
137
- { color: colors.foreground, ...typography.bodyStrong },
138
- ]}
139
- >
140
- {value}
141
- </Text>
142
- ) : (
143
- value
144
- )}
145
- {action}
146
- </View>
147
- </View>
148
- );
149
- }
150
-
151
- export function Card({ children, variant, style, noPadding = false }: CardProps) {
152
- const { colors, flair, resolveRadius, padding, alpha } = usePluginTheme();
153
-
154
- const effectiveVariant = variant || flair.surfaceStyle;
155
- const radius = resolveRadius("md");
156
-
157
- let bg = colors.surface0;
158
- let border = colors.border;
159
-
160
- if (effectiveVariant === "tinted") {
161
- bg = alpha(colors.accent, 0.04);
162
- border = alpha(colors.accent, 0.2);
163
- } else if (effectiveVariant === "elevated") {
164
- bg = colors.surface1;
165
- border = colors.border;
166
- }
167
-
168
- return (
169
- <View
170
- style={[
171
- styles.card,
172
- {
173
- backgroundColor: bg,
174
- borderColor: border,
175
- borderRadius: radius,
176
- borderWidth: flair.borderWidth,
177
- paddingHorizontal: noPadding ? 0 : padding.horizontal,
178
- paddingVertical: noPadding ? 0 : padding.vertical,
179
- },
180
- style,
181
- ]}
182
- >
183
- {children}
184
- </View>
185
- );
186
- }
187
-
188
- Card.Header = CardHeader;
189
-
190
- const styles = StyleSheet.create({
191
- card: {
192
- overflow: "hidden",
193
- width: "100%",
194
- },
195
- headerContainer: {
196
- flexDirection: "row",
197
- alignItems: "center",
198
- justifyContent: "space-between",
199
- flexWrap: "wrap",
200
- gap: 8,
201
- width: "100%",
202
- },
203
- headerContainerCompact: {
204
- flexDirection: "column",
205
- alignItems: "stretch",
206
- justifyContent: "flex-start",
207
- flexWrap: "nowrap",
208
- },
209
- headerLeft: {
210
- flexDirection: "row",
211
- alignItems: "center",
212
- gap: 8,
213
- // `flex: 1` written out: the compact override has to reset the basis too,
214
- // and `flex` + explicit flex* keys in one flattened style is ambiguous.
215
- flexGrow: 1,
216
- flexShrink: 1,
217
- flexBasis: 0,
218
- minWidth: 0,
219
- },
220
- // Release `flex: 1` (basis 0) in the stacked column so the title block takes
221
- // the full width and wraps at word boundaries instead of collapsing to its
222
- // longest word.
223
- headerLeftCompact: {
224
- flexGrow: 0,
225
- flexShrink: 0,
226
- flexBasis: "auto",
227
- width: "100%",
228
- },
229
- titleColumn: {
230
- gap: 1,
231
- flexShrink: 1,
232
- },
233
- headerTitle: {
234
- fontWeight: "600",
235
- },
236
- headerSubtitle: {
237
- fontWeight: "400",
238
- },
239
- headerRight: {
240
- flexDirection: "row",
241
- alignItems: "center",
242
- gap: 6,
243
- flexShrink: 0,
244
- },
245
- // The action group may wrap onto multiple lines once the title owns its own
246
- // row; letting it shrink + wrap keeps a long badge/toggle/button set inside
247
- // the card instead of overflowing it.
248
- headerRightCompact: {
249
- flexShrink: 1,
250
- flexWrap: "wrap",
251
- justifyContent: "flex-start",
252
- minWidth: 0,
253
- },
254
- headerValue: {
255
- fontWeight: "600",
256
- },
257
- });
@@ -1,196 +0,0 @@
1
- import React, { useState } from "react";
2
- import {
3
- Platform,
4
- Pressable,
5
- ScrollView as FallbackScrollView,
6
- StyleSheet,
7
- Text,
8
- View,
9
- type StyleProp,
10
- type TextStyle,
11
- type ViewStyle,
12
- } from "react-native";
13
- import { getClientHost } from "../host";
14
- import { usePluginTheme } from "../theme/provider";
15
- import { copyToClipboard } from "../utils/clipboard";
16
-
17
- export interface CodeBlockProps {
18
- code: string;
19
- language?: string;
20
- title?: string;
21
- maxHeight?: number;
22
- copyable?: boolean;
23
- style?: StyleProp<ViewStyle>;
24
- textStyle?: StyleProp<TextStyle>;
25
- }
26
-
27
- export function CodeBlock({
28
- code,
29
- language,
30
- title,
31
- maxHeight = 320,
32
- copyable = true,
33
- style,
34
- textStyle,
35
- }: CodeBlockProps) {
36
- const { Icon, useToast } = getClientHost();
37
- // Inner snippet scrollers are NEVER the host sheet scroller: the host
38
- // ScrollView is a sheet-gesture pan controller, so using it horizontally or
39
- // nested inside the host sheet collapses to height 0 / crashes the gesture
40
- // handler (#219). Plain React Native ScrollViews own this bounded box.
41
- const { colors, resolveRadius, isCompact, touchTargetMin, alpha } = usePluginTheme();
42
- const toast = useToast();
43
- const [copied, setCopied] = useState(false);
44
-
45
- const radius = resolveRadius("md");
46
-
47
- const handleCopy = async () => {
48
- const ok = await copyToClipboard(code, {
49
- toast,
50
- toastMessage: title || "Code",
51
- });
52
- if (ok) {
53
- setCopied(true);
54
- setTimeout(() => setCopied(false), 2000);
55
- }
56
- };
57
-
58
- const fontFamily = Platform.select({
59
- ios: "Menlo",
60
- android: "monospace",
61
- default: "monospace",
62
- });
63
-
64
- return (
65
- <View
66
- style={[
67
- styles.container,
68
- {
69
- backgroundColor: colors.surface0,
70
- borderColor: colors.border,
71
- borderRadius: radius,
72
- },
73
- style,
74
- ]}
75
- >
76
- {(title || language || copyable) && (
77
- <View
78
- style={[
79
- styles.header,
80
- {
81
- borderBottomColor: alpha(colors.border, 0.7),
82
- },
83
- ]}
84
- >
85
- <View style={styles.headerLeft}>
86
- {title ? (
87
- <Text style={[styles.title, { color: colors.foreground }]}>{title}</Text>
88
- ) : language ? (
89
- <Text style={[styles.language, { color: colors.foregroundMuted }]}>
90
- {language.toUpperCase()}
91
- </Text>
92
- ) : null}
93
- </View>
94
- {copyable && (
95
- <Pressable
96
- onPress={handleCopy}
97
- hitSlop={Math.max(0, (touchTargetMin - 28) / 2)}
98
- style={({ pressed }) => [
99
- styles.copyButton,
100
- {
101
- backgroundColor: pressed ? colors.surface2 : colors.surface1,
102
- borderColor: colors.border,
103
- borderRadius: radius - 2,
104
- },
105
- ]}
106
- >
107
- <Icon
108
- name={copied ? "Check" : "Copy"}
109
- size={12}
110
- color={copied ? colors.statusSuccess : colors.foregroundMuted}
111
- />
112
- <Text
113
- style={[
114
- styles.copyText,
115
- { color: copied ? colors.statusSuccess : colors.foregroundMuted },
116
- ]}
117
- >
118
- {copied ? "Copied!" : "Copy"}
119
- </Text>
120
- </Pressable>
121
- )}
122
- </View>
123
- )}
124
-
125
- <FallbackScrollView
126
- nestedScrollEnabled
127
- style={{ maxHeight }}
128
- contentContainerStyle={styles.scrollContent}
129
- >
130
- <FallbackScrollView horizontal showsHorizontalScrollIndicator>
131
- <Text
132
- selectable
133
- style={[
134
- styles.codeText,
135
- {
136
- color: colors.foreground,
137
- fontFamily,
138
- fontSize: isCompact ? 11 : 12,
139
- },
140
- textStyle,
141
- ]}
142
- >
143
- {code}
144
- </Text>
145
- </FallbackScrollView>
146
- </FallbackScrollView>
147
- </View>
148
- );
149
- }
150
-
151
- const styles = StyleSheet.create({
152
- container: {
153
- borderWidth: 1,
154
- overflow: "hidden",
155
- },
156
- header: {
157
- flexDirection: "row",
158
- alignItems: "center",
159
- justifyContent: "space-between",
160
- paddingHorizontal: 10,
161
- paddingVertical: 6,
162
- borderBottomWidth: 1,
163
- },
164
- headerLeft: {
165
- flexDirection: "row",
166
- alignItems: "center",
167
- gap: 8,
168
- },
169
- title: {
170
- fontSize: 12,
171
- fontWeight: "600",
172
- },
173
- language: {
174
- fontSize: 10,
175
- fontWeight: "700",
176
- letterSpacing: 0.5,
177
- },
178
- copyButton: {
179
- flexDirection: "row",
180
- alignItems: "center",
181
- gap: 4,
182
- paddingHorizontal: 8,
183
- paddingVertical: 3,
184
- borderWidth: 1,
185
- },
186
- copyText: {
187
- fontSize: 11,
188
- fontWeight: "500",
189
- },
190
- scrollContent: {
191
- padding: 10,
192
- },
193
- codeText: {
194
- lineHeight: 18,
195
- },
196
- });