@adminide-stack/yantra-mobile 12.0.108 → 12.0.109-alpha.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/lib/compute.js +57 -1
- package/lib/compute.js.map +1 -1
- package/lib/config/env-config.js +8 -0
- package/lib/config/env-config.js.map +1 -1
- package/lib/features/apps/AppsCatalog.js +10 -0
- package/lib/features/apps/AppsCatalog.js.map +1 -1
- package/lib/features/apps/appArt.js +2 -1
- package/lib/features/apps/appArt.js.map +1 -1
- package/lib/features/apps/mobileAppCatalog.js +11 -0
- package/lib/features/apps/mobileAppCatalog.js.map +1 -1
- package/lib/features/apps/nativeAppHandoff.js +2 -1
- package/lib/features/apps/nativeAppHandoff.js.map +1 -1
- package/lib/features/health/healthSyncStore.js +7 -1
- package/lib/features/health/healthSyncStore.js.map +1 -1
- package/lib/features/messaging/useChatViewer.js +3 -2
- package/lib/features/messaging/useChatViewer.js.map +1 -1
- package/lib/features/webbuilder/WebBuilderExperience.js +474 -0
- package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -0
- package/lib/features/webbuilder/brandKitStorage.js +69 -0
- package/lib/features/webbuilder/brandKitStorage.js.map +1 -0
- package/lib/features/webbuilder/buildFragments.js +360 -0
- package/lib/features/webbuilder/buildFragments.js.map +1 -0
- package/lib/features/webbuilder/components/BottomTabs.js +65 -0
- package/lib/features/webbuilder/components/BottomTabs.js.map +1 -0
- package/lib/features/webbuilder/components/BrandKitSheet.js +197 -0
- package/lib/features/webbuilder/components/BrandKitSheet.js.map +1 -0
- package/lib/features/webbuilder/components/CodeView.js +99 -0
- package/lib/features/webbuilder/components/CodeView.js.map +1 -0
- package/lib/features/webbuilder/components/Composer.js +217 -0
- package/lib/features/webbuilder/components/Composer.js.map +1 -0
- package/lib/features/webbuilder/components/PreviewFrame.js +72 -0
- package/lib/features/webbuilder/components/PreviewFrame.js.map +1 -0
- package/lib/features/webbuilder/components/PreviewPlaceholder.js +107 -0
- package/lib/features/webbuilder/components/PreviewPlaceholder.js.map +1 -0
- package/lib/features/webbuilder/components/PreviewScreen.js +200 -0
- package/lib/features/webbuilder/components/PreviewScreen.js.map +1 -0
- package/lib/features/webbuilder/components/ProjectChat.js +580 -0
- package/lib/features/webbuilder/components/ProjectChat.js.map +1 -0
- package/lib/features/webbuilder/components/ProjectsScreen.js +339 -0
- package/lib/features/webbuilder/components/ProjectsScreen.js.map +1 -0
- package/lib/features/webbuilder/components/PublishSheet.js +143 -0
- package/lib/features/webbuilder/components/PublishSheet.js.map +1 -0
- package/lib/features/webbuilder/components/SiteScoreSheet.js +73 -0
- package/lib/features/webbuilder/components/SiteScoreSheet.js.map +1 -0
- package/lib/features/webbuilder/components/StudioHome.js +367 -0
- package/lib/features/webbuilder/components/StudioHome.js.map +1 -0
- package/lib/features/webbuilder/components/TemplateCard.js +73 -0
- package/lib/features/webbuilder/components/TemplateCard.js.map +1 -0
- package/lib/features/webbuilder/components/TemplatesSheet.js +178 -0
- package/lib/features/webbuilder/components/TemplatesSheet.js.map +1 -0
- package/lib/features/webbuilder/components/VersionsSheet.js +57 -0
- package/lib/features/webbuilder/components/VersionsSheet.js.map +1 -0
- package/lib/features/webbuilder/components/ui.js +291 -0
- package/lib/features/webbuilder/components/ui.js.map +1 -0
- package/lib/features/webbuilder/nativeWebBuilderRegistry.js +15 -0
- package/lib/features/webbuilder/nativeWebBuilderRegistry.js.map +1 -0
- package/lib/features/webbuilder/studioCatalog.js +147 -0
- package/lib/features/webbuilder/studioCatalog.js.map +1 -0
- package/lib/features/webbuilder/webbuilderPrompts.js +42 -0
- package/lib/features/webbuilder/webbuilderPrompts.js.map +1 -0
- package/lib/features/webbuilder/webbuilderTheme.js +63 -0
- package/lib/features/webbuilder/webbuilderTheme.js.map +1 -0
- package/lib/features/webbuilder/workflow.js +540 -0
- package/lib/features/webbuilder/workflow.js.map +1 -0
- package/lib/hooks/useChatApi.js +7 -2
- package/lib/hooks/useChatApi.js.map +1 -1
- package/lib/hooks/useChatStream.js +1 -1
- package/lib/hooks/useChatStream.js.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/routes.json +106 -0
- package/lib/screens/WebBuilderNative/index.js +71 -0
- package/lib/screens/WebBuilderNative/index.js.map +1 -0
- package/lib/screens/WebBuilderNative/useCodeAssistantCatalog.js +45 -0
- package/lib/screens/WebBuilderNative/useCodeAssistantCatalog.js.map +1 -0
- package/lib/screens/WebBuilderNative/useWebBuilderGallery.js +125 -0
- package/lib/screens/WebBuilderNative/useWebBuilderGallery.js.map +1 -0
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js +408 -0
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -0
- package/lib/screens/WebBuilderNative/webbuilderTransport.js +88 -0
- package/lib/screens/WebBuilderNative/webbuilderTransport.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import {useState,useEffect}from'react';import {StyleSheet,ScrollView,Text,View,TextInput}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {Tap,DIM}from'../../inbox/components/Tap.js';import {BRAND_MAX_COLORS,normalizeHex,sanitizeBrandKit,BRAND_MAX_FONTS}from'../studioCatalog.js';import {Sheet,PrimaryButton}from'./ui.js';function Field({
|
|
2
|
+
label,
|
|
3
|
+
value,
|
|
4
|
+
onChangeText,
|
|
5
|
+
placeholder,
|
|
6
|
+
theme,
|
|
7
|
+
testID,
|
|
8
|
+
autoCapitalize = "sentences"
|
|
9
|
+
}) {
|
|
10
|
+
return /* @__PURE__ */ jsxs(View, { style: styles.field, children: [
|
|
11
|
+
/* @__PURE__ */ jsx(Text, { style: [styles.label, {
|
|
12
|
+
color: theme.muted
|
|
13
|
+
}], children: label }),
|
|
14
|
+
/* @__PURE__ */ jsx(TextInput, { value, onChangeText, placeholder, placeholderTextColor: theme.faint, autoCapitalize, style: [styles.input, {
|
|
15
|
+
color: theme.ink,
|
|
16
|
+
backgroundColor: theme.chip,
|
|
17
|
+
borderColor: theme.border
|
|
18
|
+
}], accessibilityLabel: label, testID })
|
|
19
|
+
] });
|
|
20
|
+
}
|
|
21
|
+
function BrandKitSheet({
|
|
22
|
+
visible,
|
|
23
|
+
brand,
|
|
24
|
+
onSave,
|
|
25
|
+
onClose,
|
|
26
|
+
theme
|
|
27
|
+
}) {
|
|
28
|
+
const [name, setName] = useState("");
|
|
29
|
+
const [description, setDescription] = useState("");
|
|
30
|
+
const [colors, setColors] = useState([]);
|
|
31
|
+
const [colorDraft, setColorDraft] = useState("");
|
|
32
|
+
const [fonts, setFonts] = useState("");
|
|
33
|
+
const [voice, setVoice] = useState("");
|
|
34
|
+
const [error, setError] = useState(null);
|
|
35
|
+
const [saving, setSaving] = useState(false);
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
var _a, _b, _c, _d, _e;
|
|
38
|
+
if (!visible) return;
|
|
39
|
+
setName((_a = brand == null ? void 0 : brand.name) != null ? _a : "");
|
|
40
|
+
setDescription((_b = brand == null ? void 0 : brand.description) != null ? _b : "");
|
|
41
|
+
setColors((_c = brand == null ? void 0 : brand.colors) != null ? _c : []);
|
|
42
|
+
setColorDraft("");
|
|
43
|
+
setFonts(((_d = brand == null ? void 0 : brand.fonts) != null ? _d : []).join(", "));
|
|
44
|
+
setVoice((_e = brand == null ? void 0 : brand.voice) != null ? _e : "");
|
|
45
|
+
setError(null);
|
|
46
|
+
}, [visible, brand]);
|
|
47
|
+
const addColor = () => {
|
|
48
|
+
const hex = normalizeHex(colorDraft);
|
|
49
|
+
if (!hex) {
|
|
50
|
+
setError("Colours are hex codes, like #ea580c.");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
setError(null);
|
|
54
|
+
setColors((prev) => prev.includes(hex) ? prev : [...prev, hex].slice(0, BRAND_MAX_COLORS));
|
|
55
|
+
setColorDraft("");
|
|
56
|
+
};
|
|
57
|
+
const save = async () => {
|
|
58
|
+
const kit = sanitizeBrandKit({
|
|
59
|
+
name,
|
|
60
|
+
description,
|
|
61
|
+
colors,
|
|
62
|
+
fonts: fonts.split(",").map((f) => f.trim()).filter(Boolean).slice(0, BRAND_MAX_FONTS),
|
|
63
|
+
voice
|
|
64
|
+
});
|
|
65
|
+
if (!kit) {
|
|
66
|
+
setError("Give your brand a name or at least one colour.");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
setSaving(true);
|
|
70
|
+
const ok = await onSave(kit);
|
|
71
|
+
setSaving(false);
|
|
72
|
+
if (ok) onClose();
|
|
73
|
+
else setError("Couldn't save the brand kit on this device. Try again.");
|
|
74
|
+
};
|
|
75
|
+
return /* @__PURE__ */ jsx(Sheet, { visible, title: "Brand kit", onClose, theme, testID: "webbuilder-brand-sheet", children: /* @__PURE__ */ jsxs(ScrollView, { style: styles.scroll, contentContainerStyle: styles.body, keyboardShouldPersistTaps: "handled", children: [
|
|
76
|
+
/* @__PURE__ */ jsx(Text, { style: [styles.intro, {
|
|
77
|
+
color: theme.muted
|
|
78
|
+
}], children: "New builds follow your brand: its name, colours, fonts and voice." }),
|
|
79
|
+
/* @__PURE__ */ jsx(Field, { label: "Brand name", value: name, onChangeText: setName, placeholder: "Sweet Crumbs", theme, testID: "webbuilder-brand-name" }),
|
|
80
|
+
/* @__PURE__ */ jsx(Field, { label: "What it is", value: description, onChangeText: setDescription, placeholder: "A neighbourhood bakery in Austin", theme }),
|
|
81
|
+
/* @__PURE__ */ jsxs(View, { style: styles.field, children: [
|
|
82
|
+
/* @__PURE__ */ jsx(Text, { style: [styles.label, {
|
|
83
|
+
color: theme.muted
|
|
84
|
+
}], children: "Colours (primary first)" }),
|
|
85
|
+
/* @__PURE__ */ jsx(View, { style: styles.swatches, children: colors.map((color, index) => /* @__PURE__ */ jsxs(Tap, { onPress: () => setColors((prev) => prev.filter((c) => c !== color)), accessibilityLabel: `Remove ${color}`, style: [styles.swatchChip, {
|
|
86
|
+
borderColor: theme.border,
|
|
87
|
+
backgroundColor: theme.card
|
|
88
|
+
}], pressedStyle: DIM, children: [
|
|
89
|
+
/* @__PURE__ */ jsx(View, { style: [styles.swatch, {
|
|
90
|
+
backgroundColor: color
|
|
91
|
+
}] }),
|
|
92
|
+
/* @__PURE__ */ jsx(Text, { style: [styles.swatchLabel, {
|
|
93
|
+
color: theme.ink
|
|
94
|
+
}], children: index === 0 ? `${color} \xB7 primary` : color }),
|
|
95
|
+
/* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "close", size: 14, color: theme.muted })
|
|
96
|
+
] }, color)) }),
|
|
97
|
+
colors.length < BRAND_MAX_COLORS ? /* @__PURE__ */ jsxs(View, { style: styles.colorRow, children: [
|
|
98
|
+
/* @__PURE__ */ jsx(TextInput, { value: colorDraft, onChangeText: setColorDraft, onSubmitEditing: addColor, placeholder: "#ea580c", placeholderTextColor: theme.faint, autoCapitalize: "none", autoCorrect: false, style: [styles.input, styles.colorInput, {
|
|
99
|
+
color: theme.ink,
|
|
100
|
+
backgroundColor: theme.chip,
|
|
101
|
+
borderColor: theme.border
|
|
102
|
+
}], accessibilityLabel: "Add a colour", testID: "webbuilder-brand-color" }),
|
|
103
|
+
/* @__PURE__ */ jsx(Tap, { onPress: addColor, accessibilityRole: "button", accessibilityLabel: "Add colour", style: [styles.add, {
|
|
104
|
+
backgroundColor: theme.accentSoft
|
|
105
|
+
}], pressedStyle: DIM, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "plus", size: 20, color: theme.accent }) })
|
|
106
|
+
] }) : null
|
|
107
|
+
] }),
|
|
108
|
+
/* @__PURE__ */ jsx(Field, { label: "Fonts", value: fonts, onChangeText: setFonts, placeholder: "Fraunces, Inter", theme, autoCapitalize: "words" }),
|
|
109
|
+
/* @__PURE__ */ jsx(Field, { label: "Voice", value: voice, onChangeText: setVoice, placeholder: "Warm, plain-spoken", theme }),
|
|
110
|
+
error ? /* @__PURE__ */ jsx(Text, { style: [styles.error, {
|
|
111
|
+
color: theme.crit
|
|
112
|
+
}], children: error }) : null,
|
|
113
|
+
/* @__PURE__ */ jsx(PrimaryButton, { label: "Save brand kit", onPress: () => {
|
|
114
|
+
save().catch(() => void 0);
|
|
115
|
+
}, theme, busy: saving, testID: "webbuilder-brand-save" }),
|
|
116
|
+
brand ? /* @__PURE__ */ jsx(Tap, { onPress: () => {
|
|
117
|
+
onSave(null).then((ok) => ok ? onClose() : void 0).catch(() => void 0);
|
|
118
|
+
}, accessibilityRole: "button", style: styles.clear, pressedStyle: DIM, children: /* @__PURE__ */ jsx(Text, { style: [styles.clearLabel, {
|
|
119
|
+
color: theme.crit
|
|
120
|
+
}], children: "Remove brand kit" }) }) : null
|
|
121
|
+
] }) });
|
|
122
|
+
}
|
|
123
|
+
const styles = StyleSheet.create({
|
|
124
|
+
scroll: {
|
|
125
|
+
maxHeight: 560
|
|
126
|
+
},
|
|
127
|
+
body: {
|
|
128
|
+
gap: 12,
|
|
129
|
+
paddingBottom: 8
|
|
130
|
+
},
|
|
131
|
+
intro: {
|
|
132
|
+
fontSize: 14,
|
|
133
|
+
lineHeight: 20
|
|
134
|
+
},
|
|
135
|
+
field: {
|
|
136
|
+
gap: 6
|
|
137
|
+
},
|
|
138
|
+
label: {
|
|
139
|
+
fontSize: 13,
|
|
140
|
+
fontWeight: "600"
|
|
141
|
+
},
|
|
142
|
+
input: {
|
|
143
|
+
borderRadius: 12,
|
|
144
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
145
|
+
paddingHorizontal: 14,
|
|
146
|
+
paddingVertical: 11,
|
|
147
|
+
fontSize: 15
|
|
148
|
+
},
|
|
149
|
+
swatches: {
|
|
150
|
+
flexDirection: "row",
|
|
151
|
+
flexWrap: "wrap",
|
|
152
|
+
gap: 6
|
|
153
|
+
},
|
|
154
|
+
swatchChip: {
|
|
155
|
+
flexDirection: "row",
|
|
156
|
+
alignItems: "center",
|
|
157
|
+
gap: 6,
|
|
158
|
+
paddingHorizontal: 8,
|
|
159
|
+
paddingVertical: 6,
|
|
160
|
+
borderRadius: 999,
|
|
161
|
+
borderWidth: StyleSheet.hairlineWidth
|
|
162
|
+
},
|
|
163
|
+
swatch: {
|
|
164
|
+
width: 16,
|
|
165
|
+
height: 16,
|
|
166
|
+
borderRadius: 8
|
|
167
|
+
},
|
|
168
|
+
swatchLabel: {
|
|
169
|
+
fontSize: 13
|
|
170
|
+
},
|
|
171
|
+
colorRow: {
|
|
172
|
+
flexDirection: "row",
|
|
173
|
+
gap: 8,
|
|
174
|
+
alignItems: "center"
|
|
175
|
+
},
|
|
176
|
+
colorInput: {
|
|
177
|
+
flex: 1
|
|
178
|
+
},
|
|
179
|
+
add: {
|
|
180
|
+
width: 44,
|
|
181
|
+
height: 44,
|
|
182
|
+
borderRadius: 12,
|
|
183
|
+
alignItems: "center",
|
|
184
|
+
justifyContent: "center"
|
|
185
|
+
},
|
|
186
|
+
error: {
|
|
187
|
+
fontSize: 13
|
|
188
|
+
},
|
|
189
|
+
clear: {
|
|
190
|
+
alignSelf: "center",
|
|
191
|
+
padding: 8
|
|
192
|
+
},
|
|
193
|
+
clearLabel: {
|
|
194
|
+
fontSize: 14,
|
|
195
|
+
fontWeight: "600"
|
|
196
|
+
}
|
|
197
|
+
});export{BrandKitSheet};//# sourceMappingURL=BrandKitSheet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrandKitSheet.js","sources":["../../../../src/features/webbuilder/components/BrandKitSheet.tsx"],"sourcesContent":["/**\n * Brand kit editor - the web BrandKitDialog's manual entry: name, what it is,\n * colours (primary first), fonts and voice. Every new build's brief carries\n * it. Kept on this device, like the web keeps it per browser.\n */\nimport React, { useEffect, useState } from 'react';\nimport { ScrollView, StyleSheet, Text, TextInput, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { DIM, Tap } from '../../inbox/components/Tap';\nimport { BRAND_MAX_COLORS, BRAND_MAX_FONTS, normalizeHex, sanitizeBrandKit, type BrandKit } from '../studioCatalog';\nimport type { WebBuilderTheme } from '../webbuilderTheme';\nimport { PrimaryButton, Sheet } from './ui';\n\nfunction Field({\n label,\n value,\n onChangeText,\n placeholder,\n theme,\n testID,\n autoCapitalize = 'sentences',\n}: {\n label: string;\n value: string;\n onChangeText: (text: string) => void;\n placeholder: string;\n theme: WebBuilderTheme;\n testID?: string;\n autoCapitalize?: 'none' | 'sentences' | 'words';\n}) {\n return (\n <View style={styles.field}>\n <Text style={[styles.label, { color: theme.muted }]}>{label}</Text>\n <TextInput\n value={value}\n onChangeText={onChangeText}\n placeholder={placeholder}\n placeholderTextColor={theme.faint}\n autoCapitalize={autoCapitalize}\n style={[styles.input, { color: theme.ink, backgroundColor: theme.chip, borderColor: theme.border }]}\n accessibilityLabel={label}\n testID={testID}\n />\n </View>\n );\n}\n\nexport function BrandKitSheet({\n visible,\n brand,\n onSave,\n onClose,\n theme,\n}: {\n visible: boolean;\n brand: BrandKit | null;\n onSave: (kit: BrandKit | null) => Promise<boolean>;\n onClose: () => void;\n theme: WebBuilderTheme;\n}) {\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [colors, setColors] = useState<string[]>([]);\n const [colorDraft, setColorDraft] = useState('');\n const [fonts, setFonts] = useState('');\n const [voice, setVoice] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [saving, setSaving] = useState(false);\n\n useEffect(() => {\n if (!visible) return;\n setName(brand?.name ?? '');\n setDescription(brand?.description ?? '');\n setColors(brand?.colors ?? []);\n setColorDraft('');\n setFonts((brand?.fonts ?? []).join(', '));\n setVoice(brand?.voice ?? '');\n setError(null);\n }, [visible, brand]);\n\n const addColor = () => {\n const hex = normalizeHex(colorDraft);\n if (!hex) {\n setError('Colours are hex codes, like #ea580c.');\n return;\n }\n setError(null);\n setColors((prev) => (prev.includes(hex) ? prev : [...prev, hex].slice(0, BRAND_MAX_COLORS)));\n setColorDraft('');\n };\n\n const save = async () => {\n const kit = sanitizeBrandKit({\n name,\n description,\n colors,\n fonts: fonts\n .split(',')\n .map((f) => f.trim())\n .filter(Boolean)\n .slice(0, BRAND_MAX_FONTS),\n voice,\n });\n if (!kit) {\n setError('Give your brand a name or at least one colour.');\n return;\n }\n setSaving(true);\n const ok = await onSave(kit);\n setSaving(false);\n if (ok) onClose();\n else setError(\"Couldn't save the brand kit on this device. Try again.\");\n };\n\n return (\n <Sheet visible={visible} title=\"Brand kit\" onClose={onClose} theme={theme} testID=\"webbuilder-brand-sheet\">\n <ScrollView style={styles.scroll} contentContainerStyle={styles.body} keyboardShouldPersistTaps=\"handled\">\n <Text style={[styles.intro, { color: theme.muted }]}>\n New builds follow your brand: its name, colours, fonts and voice.\n </Text>\n <Field\n label=\"Brand name\"\n value={name}\n onChangeText={setName}\n placeholder=\"Sweet Crumbs\"\n theme={theme}\n testID=\"webbuilder-brand-name\"\n />\n <Field\n label=\"What it is\"\n value={description}\n onChangeText={setDescription}\n placeholder=\"A neighbourhood bakery in Austin\"\n theme={theme}\n />\n <View style={styles.field}>\n <Text style={[styles.label, { color: theme.muted }]}>Colours (primary first)</Text>\n <View style={styles.swatches}>\n {colors.map((color, index) => (\n <Tap\n key={color}\n onPress={() => setColors((prev) => prev.filter((c) => c !== color))}\n accessibilityLabel={`Remove ${color}`}\n style={[styles.swatchChip, { borderColor: theme.border, backgroundColor: theme.card }]}\n pressedStyle={DIM}\n >\n <View style={[styles.swatch, { backgroundColor: color }]} />\n <Text style={[styles.swatchLabel, { color: theme.ink }]}>\n {index === 0 ? `${color} · primary` : color}\n </Text>\n <MaterialCommunityIcons name=\"close\" size={14} color={theme.muted} />\n </Tap>\n ))}\n </View>\n {colors.length < BRAND_MAX_COLORS ? (\n <View style={styles.colorRow}>\n <TextInput\n value={colorDraft}\n onChangeText={setColorDraft}\n onSubmitEditing={addColor}\n placeholder=\"#ea580c\"\n placeholderTextColor={theme.faint}\n autoCapitalize=\"none\"\n autoCorrect={false}\n style={[\n styles.input,\n styles.colorInput,\n { color: theme.ink, backgroundColor: theme.chip, borderColor: theme.border },\n ]}\n accessibilityLabel=\"Add a colour\"\n testID=\"webbuilder-brand-color\"\n />\n <Tap\n onPress={addColor}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Add colour\"\n style={[styles.add, { backgroundColor: theme.accentSoft }]}\n pressedStyle={DIM}\n >\n <MaterialCommunityIcons name=\"plus\" size={20} color={theme.accent} />\n </Tap>\n </View>\n ) : null}\n </View>\n <Field\n label=\"Fonts\"\n value={fonts}\n onChangeText={setFonts}\n placeholder=\"Fraunces, Inter\"\n theme={theme}\n autoCapitalize=\"words\"\n />\n <Field\n label=\"Voice\"\n value={voice}\n onChangeText={setVoice}\n placeholder=\"Warm, plain-spoken\"\n theme={theme}\n />\n {error ? <Text style={[styles.error, { color: theme.crit }]}>{error}</Text> : null}\n <PrimaryButton\n label=\"Save brand kit\"\n onPress={() => {\n save().catch(() => undefined);\n }}\n theme={theme}\n busy={saving}\n testID=\"webbuilder-brand-save\"\n />\n {brand ? (\n <Tap\n onPress={() => {\n onSave(null)\n .then((ok) => (ok ? onClose() : undefined))\n .catch(() => undefined);\n }}\n accessibilityRole=\"button\"\n style={styles.clear}\n pressedStyle={DIM}\n >\n <Text style={[styles.clearLabel, { color: theme.crit }]}>Remove brand kit</Text>\n </Tap>\n ) : null}\n </ScrollView>\n </Sheet>\n );\n}\n\nconst styles = StyleSheet.create({\n scroll: { maxHeight: 560 },\n body: { gap: 12, paddingBottom: 8 },\n intro: { fontSize: 14, lineHeight: 20 },\n field: { gap: 6 },\n label: { fontSize: 13, fontWeight: '600' },\n input: {\n borderRadius: 12,\n borderWidth: StyleSheet.hairlineWidth,\n paddingHorizontal: 14,\n paddingVertical: 11,\n fontSize: 15,\n },\n swatches: { flexDirection: 'row', flexWrap: 'wrap', gap: 6 },\n swatchChip: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n paddingHorizontal: 8,\n paddingVertical: 6,\n borderRadius: 999,\n borderWidth: StyleSheet.hairlineWidth,\n },\n swatch: { width: 16, height: 16, borderRadius: 8 },\n swatchLabel: { fontSize: 13 },\n colorRow: { flexDirection: 'row', gap: 8, alignItems: 'center' },\n colorInput: { flex: 1 },\n add: { width: 44, height: 44, borderRadius: 12, alignItems: 'center', justifyContent: 'center' },\n error: { fontSize: 13 },\n clear: { alignSelf: 'center', padding: 8 },\n clearLabel: { fontSize: 14, fontWeight: '600' },\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import {useMemo,useState,useEffect}from'react';import {Platform,StyleSheet,View,ScrollView,Text}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {Tap,DIM}from'../../inbox/components/Tap.js';import {CenteredState}from'./ui.js';const MAX_CHARS = 6e4;
|
|
2
|
+
const MONO = Platform.select({
|
|
3
|
+
ios: "Menlo",
|
|
4
|
+
android: "monospace",
|
|
5
|
+
default: "monospace"
|
|
6
|
+
});
|
|
7
|
+
function orderedFiles(files) {
|
|
8
|
+
const rank = (path) => {
|
|
9
|
+
if (/(^|\/)src\//.test(path) || /(^|\/)(app|pages|components)\//.test(path)) return 0;
|
|
10
|
+
if (/\.(tsx?|jsx?|vue|svelte|css|html)$/.test(path)) return 1;
|
|
11
|
+
return 2;
|
|
12
|
+
};
|
|
13
|
+
return Object.keys(files).filter((path) => !/(^|\/)(package-lock\.json|yarn\.lock|pnpm-lock\.yaml)$/.test(path)).sort((a, b) => rank(a) - rank(b) || a.localeCompare(b));
|
|
14
|
+
}
|
|
15
|
+
function CodeView({
|
|
16
|
+
files,
|
|
17
|
+
theme,
|
|
18
|
+
onAsk
|
|
19
|
+
}) {
|
|
20
|
+
var _a;
|
|
21
|
+
const paths = useMemo(() => files ? orderedFiles(files) : [], [files]);
|
|
22
|
+
const [path, setPath] = useState(null);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
var _a2;
|
|
25
|
+
if (!path || !paths.includes(path)) setPath((_a2 = paths[0]) != null ? _a2 : null);
|
|
26
|
+
}, [paths, path]);
|
|
27
|
+
if (!files || paths.length === 0) {
|
|
28
|
+
return /* @__PURE__ */ jsx(CenteredState, { icon: "code-tags", title: "No code to show yet", body: "The source appears here once a build finishes.", theme, primary: {
|
|
29
|
+
label: "Ask the agent",
|
|
30
|
+
icon: "creation",
|
|
31
|
+
onPress: onAsk
|
|
32
|
+
}, testID: "webbuilder-code-empty" });
|
|
33
|
+
}
|
|
34
|
+
const source = path ? (_a = files[path]) != null ? _a : "" : "";
|
|
35
|
+
const shown = source.length > MAX_CHARS ? `${source.slice(0, MAX_CHARS)}
|
|
36
|
+
|
|
37
|
+
\u2026 (cut for the phone)` : source;
|
|
38
|
+
return /* @__PURE__ */ jsxs(View, { style: styles.fill, testID: "webbuilder-code", children: [
|
|
39
|
+
/* @__PURE__ */ jsx(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: [styles.tabs, {
|
|
40
|
+
borderBottomColor: theme.border,
|
|
41
|
+
backgroundColor: theme.card
|
|
42
|
+
}], contentContainerStyle: styles.tabsContent, children: paths.map((p) => {
|
|
43
|
+
const active = p === path;
|
|
44
|
+
return /* @__PURE__ */ jsxs(Tap, { onPress: () => setPath(p), accessibilityRole: "tab", accessibilityState: {
|
|
45
|
+
selected: active
|
|
46
|
+
}, style: [styles.tab, {
|
|
47
|
+
borderColor: active ? theme.accent : theme.border
|
|
48
|
+
}, active && {
|
|
49
|
+
backgroundColor: theme.accentSoft
|
|
50
|
+
}], pressedStyle: DIM, children: [
|
|
51
|
+
/* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "file-code-outline", size: 14, color: active ? theme.accent : theme.muted }),
|
|
52
|
+
/* @__PURE__ */ jsx(Text, { style: [styles.tabLabel, {
|
|
53
|
+
color: active ? theme.accent : theme.muted
|
|
54
|
+
}], numberOfLines: 1, children: p })
|
|
55
|
+
] }, p);
|
|
56
|
+
}) }),
|
|
57
|
+
/* @__PURE__ */ jsx(ScrollView, { style: [styles.fill, {
|
|
58
|
+
backgroundColor: theme.code
|
|
59
|
+
}], children: /* @__PURE__ */ jsx(ScrollView, { horizontal: true, contentContainerStyle: styles.codePad, children: /* @__PURE__ */ jsx(Text, { selectable: true, style: [styles.code, {
|
|
60
|
+
color: theme.codeInk,
|
|
61
|
+
fontFamily: MONO
|
|
62
|
+
}], children: shown }) }) })
|
|
63
|
+
] });
|
|
64
|
+
}
|
|
65
|
+
const styles = StyleSheet.create({
|
|
66
|
+
fill: {
|
|
67
|
+
flex: 1
|
|
68
|
+
},
|
|
69
|
+
tabs: {
|
|
70
|
+
flexGrow: 0,
|
|
71
|
+
borderBottomWidth: StyleSheet.hairlineWidth
|
|
72
|
+
},
|
|
73
|
+
tabsContent: {
|
|
74
|
+
gap: 6,
|
|
75
|
+
paddingHorizontal: 10,
|
|
76
|
+
paddingVertical: 8
|
|
77
|
+
},
|
|
78
|
+
tab: {
|
|
79
|
+
flexDirection: "row",
|
|
80
|
+
alignItems: "center",
|
|
81
|
+
gap: 5,
|
|
82
|
+
maxWidth: 220,
|
|
83
|
+
paddingHorizontal: 10,
|
|
84
|
+
paddingVertical: 6,
|
|
85
|
+
borderRadius: 8,
|
|
86
|
+
borderWidth: StyleSheet.hairlineWidth
|
|
87
|
+
},
|
|
88
|
+
tabLabel: {
|
|
89
|
+
fontSize: 12,
|
|
90
|
+
fontWeight: "600"
|
|
91
|
+
},
|
|
92
|
+
codePad: {
|
|
93
|
+
padding: 14
|
|
94
|
+
},
|
|
95
|
+
code: {
|
|
96
|
+
fontSize: 12,
|
|
97
|
+
lineHeight: 18
|
|
98
|
+
}
|
|
99
|
+
});export{CodeView,orderedFiles};//# sourceMappingURL=CodeView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeView.js","sources":["../../../../src/features/webbuilder/components/CodeView.tsx"],"sourcesContent":["/**\n * The Code tab - the source the build posted (web CreationView `view='code'`),\n * read-only on a phone: the files as a list, one file at a time in a\n * monospace pane that scrolls both ways. Changes go through the agent.\n */\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { Platform, ScrollView, StyleSheet, Text, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { DIM, Tap } from '../../inbox/components/Tap';\nimport type { WebBuilderTheme } from '../webbuilderTheme';\nimport { CenteredState } from './ui';\n\n/** Very long files are cut so the pane stays responsive. */\nconst MAX_CHARS = 60_000;\nconst MONO = Platform.select({ ios: 'Menlo', android: 'monospace', default: 'monospace' });\n\n/** Source first (src/, app/, pages/), config after, lockfiles never. */\nexport function orderedFiles(files: Record<string, string>): string[] {\n const rank = (path: string) => {\n if (/(^|\\/)src\\//.test(path) || /(^|\\/)(app|pages|components)\\//.test(path)) return 0;\n if (/\\.(tsx?|jsx?|vue|svelte|css|html)$/.test(path)) return 1;\n return 2;\n };\n return Object.keys(files)\n .filter((path) => !/(^|\\/)(package-lock\\.json|yarn\\.lock|pnpm-lock\\.yaml)$/.test(path))\n .sort((a, b) => rank(a) - rank(b) || a.localeCompare(b));\n}\n\nexport function CodeView({\n files,\n theme,\n onAsk,\n}: {\n files: Record<string, string> | null;\n theme: WebBuilderTheme;\n onAsk: () => void;\n}) {\n const paths = useMemo(() => (files ? orderedFiles(files) : []), [files]);\n const [path, setPath] = useState<string | null>(null);\n useEffect(() => {\n if (!path || !paths.includes(path)) setPath(paths[0] ?? null);\n }, [paths, path]);\n\n if (!files || paths.length === 0) {\n return (\n <CenteredState\n icon=\"code-tags\"\n title=\"No code to show yet\"\n body=\"The source appears here once a build finishes.\"\n theme={theme}\n primary={{ label: 'Ask the agent', icon: 'creation', onPress: onAsk }}\n testID=\"webbuilder-code-empty\"\n />\n );\n }\n\n const source = path ? (files[path] ?? '') : '';\n const shown = source.length > MAX_CHARS ? `${source.slice(0, MAX_CHARS)}\\n\\n… (cut for the phone)` : source;\n\n return (\n <View style={styles.fill} testID=\"webbuilder-code\">\n <ScrollView\n horizontal\n showsHorizontalScrollIndicator={false}\n style={[styles.tabs, { borderBottomColor: theme.border, backgroundColor: theme.card }]}\n contentContainerStyle={styles.tabsContent}\n >\n {paths.map((p) => {\n const active = p === path;\n return (\n <Tap\n key={p}\n onPress={() => setPath(p)}\n accessibilityRole=\"tab\"\n accessibilityState={{ selected: active }}\n style={[\n styles.tab,\n { borderColor: active ? theme.accent : theme.border },\n active && { backgroundColor: theme.accentSoft },\n ]}\n pressedStyle={DIM}\n >\n <MaterialCommunityIcons\n name=\"file-code-outline\"\n size={14}\n color={active ? theme.accent : theme.muted}\n />\n <Text\n style={[styles.tabLabel, { color: active ? theme.accent : theme.muted }]}\n numberOfLines={1}\n >\n {p}\n </Text>\n </Tap>\n );\n })}\n </ScrollView>\n <ScrollView style={[styles.fill, { backgroundColor: theme.code }]}>\n <ScrollView horizontal contentContainerStyle={styles.codePad}>\n <Text selectable style={[styles.code, { color: theme.codeInk, fontFamily: MONO }]}>\n {shown}\n </Text>\n </ScrollView>\n </ScrollView>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n tabs: { flexGrow: 0, borderBottomWidth: StyleSheet.hairlineWidth },\n tabsContent: { gap: 6, paddingHorizontal: 10, paddingVertical: 8 },\n tab: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 5,\n maxWidth: 220,\n paddingHorizontal: 10,\n paddingVertical: 6,\n borderRadius: 8,\n borderWidth: StyleSheet.hairlineWidth,\n },\n tabLabel: { fontSize: 12, fontWeight: '600' },\n codePad: { padding: 14 },\n code: { fontSize: 12, lineHeight: 18 },\n});\n"],"names":["_a"],"mappings":"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"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import {jsxs,jsx}from'react/jsx-runtime';import {forwardRef}from'react';import {View,StyleSheet,TextInput,Text,ScrollView}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {Tap,DIM}from'../../inbox/components/Tap.js';import {hostLabel}from'../studioCatalog.js';function Tool({
|
|
2
|
+
icon,
|
|
3
|
+
label,
|
|
4
|
+
value,
|
|
5
|
+
onPress,
|
|
6
|
+
onClear,
|
|
7
|
+
theme,
|
|
8
|
+
leading,
|
|
9
|
+
testID
|
|
10
|
+
}) {
|
|
11
|
+
if (!value) {
|
|
12
|
+
return /* @__PURE__ */ jsx(Tap, { onPress, accessibilityRole: "button", accessibilityLabel: label, hitSlop: 4, style: [styles.toolIcon, {
|
|
13
|
+
borderColor: theme.border
|
|
14
|
+
}], pressedStyle: DIM, testID, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: icon, size: 19, color: theme.muted }) });
|
|
15
|
+
}
|
|
16
|
+
return /* @__PURE__ */ jsxs(View, { style: [styles.toolChip, {
|
|
17
|
+
backgroundColor: theme.accentSoft,
|
|
18
|
+
borderColor: theme.accentBorder
|
|
19
|
+
}], children: [
|
|
20
|
+
/* @__PURE__ */ jsxs(Tap, { onPress, accessibilityRole: "button", accessibilityLabel: `${label}: ${value}`, style: styles.toolChipMain, pressedStyle: DIM, testID, children: [
|
|
21
|
+
leading != null ? leading : /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: icon, size: 16, color: theme.accent }),
|
|
22
|
+
/* @__PURE__ */ jsx(Text, { style: [styles.toolChipLabel, {
|
|
23
|
+
color: theme.accent
|
|
24
|
+
}], numberOfLines: 1, children: value })
|
|
25
|
+
] }),
|
|
26
|
+
onClear ? /* @__PURE__ */ jsx(Tap, { onPress: onClear, accessibilityRole: "button", accessibilityLabel: `Remove ${label.toLowerCase()}`, hitSlop: 8, style: styles.toolChipClear, pressedStyle: DIM, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "close-circle", size: 16, color: theme.accent }) }) : /* @__PURE__ */ jsx(View, { style: styles.toolChipEnd })
|
|
27
|
+
] });
|
|
28
|
+
}
|
|
29
|
+
const Composer = forwardRef(function Composer2({
|
|
30
|
+
value,
|
|
31
|
+
onChangeText,
|
|
32
|
+
onSubmit,
|
|
33
|
+
template,
|
|
34
|
+
onTemplate,
|
|
35
|
+
onClearTemplate,
|
|
36
|
+
lookUrl,
|
|
37
|
+
onLookUrl,
|
|
38
|
+
lookInvalid,
|
|
39
|
+
lookOpen,
|
|
40
|
+
onLookOpen,
|
|
41
|
+
brand,
|
|
42
|
+
onBrand,
|
|
43
|
+
connecting = null,
|
|
44
|
+
canSubmit,
|
|
45
|
+
theme
|
|
46
|
+
}, ref) {
|
|
47
|
+
const lookHost = lookUrl && !lookInvalid ? hostLabel(lookUrl) : null;
|
|
48
|
+
const ready = canSubmit && !connecting;
|
|
49
|
+
return /* @__PURE__ */ jsxs(View, { style: [styles.box, {
|
|
50
|
+
backgroundColor: theme.card,
|
|
51
|
+
borderColor: theme.border,
|
|
52
|
+
shadowColor: theme.isDark ? "#000" : "#7c2d12"
|
|
53
|
+
}], children: [
|
|
54
|
+
/* @__PURE__ */ jsx(TextInput, { ref, value, onChangeText, placeholder: "Describe the site you want to build\u2026", placeholderTextColor: theme.faint, multiline: true, style: [styles.input, {
|
|
55
|
+
color: theme.ink
|
|
56
|
+
}], accessibilityLabel: "Describe what you want to build", testID: "webbuilder-brief" }),
|
|
57
|
+
lookOpen ? /* @__PURE__ */ jsxs(View, { style: [styles.look, {
|
|
58
|
+
backgroundColor: theme.chip,
|
|
59
|
+
borderColor: lookInvalid ? theme.crit : "transparent"
|
|
60
|
+
}], children: [
|
|
61
|
+
/* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "web", size: 16, color: theme.muted }),
|
|
62
|
+
/* @__PURE__ */ jsx(TextInput, { value: lookUrl, onChangeText: onLookUrl, placeholder: "Look like\u2026 https://stripe.com", placeholderTextColor: theme.faint, autoCapitalize: "none", autoCorrect: false, keyboardType: "url", autoFocus: !lookUrl, onSubmitEditing: () => onLookOpen(false), style: [styles.lookInput, {
|
|
63
|
+
color: theme.ink
|
|
64
|
+
}], accessibilityLabel: "Make it look like this site", testID: "webbuilder-look" }),
|
|
65
|
+
/* @__PURE__ */ jsx(Tap, { onPress: () => {
|
|
66
|
+
onLookUrl("");
|
|
67
|
+
onLookOpen(false);
|
|
68
|
+
}, accessibilityRole: "button", accessibilityLabel: "Remove the look-alike site", hitSlop: 8, pressedStyle: DIM, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "close", size: 16, color: theme.muted }) })
|
|
69
|
+
] }) : null,
|
|
70
|
+
connecting ? /* @__PURE__ */ jsxs(View, { style: styles.status, accessibilityLiveRegion: "polite", children: [
|
|
71
|
+
/* @__PURE__ */ jsx(View, { style: [styles.statusDot, {
|
|
72
|
+
backgroundColor: theme.warn
|
|
73
|
+
}] }),
|
|
74
|
+
/* @__PURE__ */ jsx(Text, { style: [styles.statusText, {
|
|
75
|
+
color: theme.muted
|
|
76
|
+
}], numberOfLines: 1, children: connecting })
|
|
77
|
+
] }) : null,
|
|
78
|
+
/* @__PURE__ */ jsxs(View, { style: [styles.toolbar, {
|
|
79
|
+
borderTopColor: theme.border
|
|
80
|
+
}], children: [
|
|
81
|
+
/* @__PURE__ */ jsxs(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, keyboardShouldPersistTaps: "handled", style: styles.tools, contentContainerStyle: styles.toolsContent, children: [
|
|
82
|
+
/* @__PURE__ */ jsx(Tool, { icon: "view-grid-plus-outline", label: "Template", value: template == null ? void 0 : template.title, onPress: onTemplate, onClear: onClearTemplate, theme, testID: "webbuilder-composer-template" }),
|
|
83
|
+
/* @__PURE__ */ jsx(Tool, { icon: "web", label: "Look like", value: lookOpen ? null : lookHost, onPress: () => onLookOpen(true), onClear: () => onLookUrl(""), theme, testID: "webbuilder-composer-look" }),
|
|
84
|
+
/* @__PURE__ */ jsx(Tool, { icon: "palette-outline", label: "Brand kit", value: brand ? brand.name || "Brand" : null, onPress: onBrand, theme, leading: (brand == null ? void 0 : brand.colors.length) ? /* @__PURE__ */ jsx(View, { style: styles.dots, children: brand.colors.slice(0, 3).map((c) => /* @__PURE__ */ jsx(View, { style: [styles.dot, {
|
|
85
|
+
backgroundColor: c,
|
|
86
|
+
borderColor: theme.card
|
|
87
|
+
}] }, c)) }) : void 0, testID: "webbuilder-composer-brand" })
|
|
88
|
+
] }),
|
|
89
|
+
/* @__PURE__ */ jsx(Tap, { onPress: onSubmit, disabled: !ready, accessibilityRole: "button", accessibilityLabel: "Start building", accessibilityState: {
|
|
90
|
+
disabled: !ready
|
|
91
|
+
}, style: [styles.send, {
|
|
92
|
+
backgroundColor: ready ? theme.accent : theme.chip
|
|
93
|
+
}], pressedStyle: DIM, testID: "webbuilder-start", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "arrow-up", size: 21, color: ready ? theme.accentInk : theme.faint }) })
|
|
94
|
+
] })
|
|
95
|
+
] });
|
|
96
|
+
});
|
|
97
|
+
const styles = StyleSheet.create({
|
|
98
|
+
box: {
|
|
99
|
+
borderRadius: 22,
|
|
100
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
101
|
+
paddingTop: 14,
|
|
102
|
+
paddingHorizontal: 14,
|
|
103
|
+
paddingBottom: 10,
|
|
104
|
+
gap: 10,
|
|
105
|
+
shadowOpacity: 0.07,
|
|
106
|
+
shadowRadius: 16,
|
|
107
|
+
shadowOffset: {
|
|
108
|
+
width: 0,
|
|
109
|
+
height: 6
|
|
110
|
+
},
|
|
111
|
+
elevation: 3
|
|
112
|
+
},
|
|
113
|
+
input: {
|
|
114
|
+
minHeight: 64,
|
|
115
|
+
maxHeight: 160,
|
|
116
|
+
fontSize: 17,
|
|
117
|
+
lineHeight: 24,
|
|
118
|
+
padding: 0,
|
|
119
|
+
textAlignVertical: "top"
|
|
120
|
+
},
|
|
121
|
+
look: {
|
|
122
|
+
flexDirection: "row",
|
|
123
|
+
alignItems: "center",
|
|
124
|
+
gap: 8,
|
|
125
|
+
borderRadius: 12,
|
|
126
|
+
borderWidth: 1,
|
|
127
|
+
paddingHorizontal: 10
|
|
128
|
+
},
|
|
129
|
+
lookInput: {
|
|
130
|
+
flex: 1,
|
|
131
|
+
fontSize: 15,
|
|
132
|
+
paddingVertical: 9
|
|
133
|
+
},
|
|
134
|
+
status: {
|
|
135
|
+
flexDirection: "row",
|
|
136
|
+
alignItems: "center",
|
|
137
|
+
gap: 8
|
|
138
|
+
},
|
|
139
|
+
statusDot: {
|
|
140
|
+
width: 7,
|
|
141
|
+
height: 7,
|
|
142
|
+
borderRadius: 4
|
|
143
|
+
},
|
|
144
|
+
statusText: {
|
|
145
|
+
flex: 1,
|
|
146
|
+
fontSize: 13
|
|
147
|
+
},
|
|
148
|
+
toolbar: {
|
|
149
|
+
flexDirection: "row",
|
|
150
|
+
alignItems: "center",
|
|
151
|
+
gap: 10,
|
|
152
|
+
paddingTop: 10,
|
|
153
|
+
borderTopWidth: StyleSheet.hairlineWidth
|
|
154
|
+
},
|
|
155
|
+
tools: {
|
|
156
|
+
flex: 1
|
|
157
|
+
},
|
|
158
|
+
toolsContent: {
|
|
159
|
+
gap: 8,
|
|
160
|
+
alignItems: "center"
|
|
161
|
+
},
|
|
162
|
+
toolIcon: {
|
|
163
|
+
width: 38,
|
|
164
|
+
height: 38,
|
|
165
|
+
borderRadius: 19,
|
|
166
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
167
|
+
alignItems: "center",
|
|
168
|
+
justifyContent: "center"
|
|
169
|
+
},
|
|
170
|
+
toolChip: {
|
|
171
|
+
flexDirection: "row",
|
|
172
|
+
alignItems: "center",
|
|
173
|
+
height: 38,
|
|
174
|
+
maxWidth: 200,
|
|
175
|
+
borderRadius: 19,
|
|
176
|
+
borderWidth: StyleSheet.hairlineWidth
|
|
177
|
+
},
|
|
178
|
+
toolChipMain: {
|
|
179
|
+
flexDirection: "row",
|
|
180
|
+
alignItems: "center",
|
|
181
|
+
gap: 6,
|
|
182
|
+
paddingLeft: 12,
|
|
183
|
+
flexShrink: 1
|
|
184
|
+
},
|
|
185
|
+
toolChipLabel: {
|
|
186
|
+
fontSize: 14,
|
|
187
|
+
fontWeight: "600",
|
|
188
|
+
flexShrink: 1
|
|
189
|
+
},
|
|
190
|
+
toolChipClear: {
|
|
191
|
+
paddingLeft: 6,
|
|
192
|
+
paddingRight: 10,
|
|
193
|
+
height: 38,
|
|
194
|
+
justifyContent: "center"
|
|
195
|
+
},
|
|
196
|
+
toolChipEnd: {
|
|
197
|
+
width: 12
|
|
198
|
+
},
|
|
199
|
+
dots: {
|
|
200
|
+
flexDirection: "row",
|
|
201
|
+
marginRight: 4
|
|
202
|
+
},
|
|
203
|
+
dot: {
|
|
204
|
+
width: 12,
|
|
205
|
+
height: 12,
|
|
206
|
+
borderRadius: 6,
|
|
207
|
+
borderWidth: 1.5,
|
|
208
|
+
marginRight: -4
|
|
209
|
+
},
|
|
210
|
+
send: {
|
|
211
|
+
width: 42,
|
|
212
|
+
height: 42,
|
|
213
|
+
borderRadius: 21,
|
|
214
|
+
alignItems: "center",
|
|
215
|
+
justifyContent: "center"
|
|
216
|
+
}
|
|
217
|
+
});export{Composer};//# sourceMappingURL=Composer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Composer.js","sources":["../../../../src/features/webbuilder/components/Composer.tsx"],"sourcesContent":["/**\n * The prompt box - what to build, and in one toolbar row the three ways the web\n * studio lets you shape it: a starter template, a site to look like, the brand\n * kit. A tool shows as a small icon until it is set, then as a chip naming the\n * choice, with a way to remove it. Send is the only filled control; while the\n * builder is still connecting it rests disabled and the box says so.\n */\nimport React, { forwardRef } from 'react';\nimport { ScrollView, StyleSheet, Text, TextInput, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { DIM, Tap } from '../../inbox/components/Tap';\nimport { hostLabel, type BrandKit } from '../studioCatalog';\nimport type { WebBuilderTemplate } from '../workflow';\nimport type { WebBuilderTheme } from '../webbuilderTheme';\nimport type { IconName } from './ui';\n\nfunction Tool({\n icon,\n label,\n value,\n onPress,\n onClear,\n theme,\n leading,\n testID,\n}: {\n icon: IconName;\n /** What the tool does, for screen readers. */\n label: string;\n /** The choice once made (a template name, a host, a brand); unset when empty. */\n value?: string | null;\n onPress: () => void;\n onClear?: () => void;\n theme: WebBuilderTheme;\n leading?: React.ReactNode;\n testID?: string;\n}) {\n if (!value) {\n return (\n <Tap\n onPress={onPress}\n accessibilityRole=\"button\"\n accessibilityLabel={label}\n hitSlop={4}\n style={[styles.toolIcon, { borderColor: theme.border }]}\n pressedStyle={DIM}\n testID={testID}\n >\n <MaterialCommunityIcons name={icon} size={19} color={theme.muted} />\n </Tap>\n );\n }\n return (\n <View style={[styles.toolChip, { backgroundColor: theme.accentSoft, borderColor: theme.accentBorder }]}>\n <Tap\n onPress={onPress}\n accessibilityRole=\"button\"\n accessibilityLabel={`${label}: ${value}`}\n style={styles.toolChipMain}\n pressedStyle={DIM}\n testID={testID}\n >\n {leading ?? <MaterialCommunityIcons name={icon} size={16} color={theme.accent} />}\n <Text style={[styles.toolChipLabel, { color: theme.accent }]} numberOfLines={1}>\n {value}\n </Text>\n </Tap>\n {onClear ? (\n <Tap\n onPress={onClear}\n accessibilityRole=\"button\"\n accessibilityLabel={`Remove ${label.toLowerCase()}`}\n hitSlop={8}\n style={styles.toolChipClear}\n pressedStyle={DIM}\n >\n <MaterialCommunityIcons name=\"close-circle\" size={16} color={theme.accent} />\n </Tap>\n ) : (\n <View style={styles.toolChipEnd} />\n )}\n </View>\n );\n}\n\nexport interface ComposerProps {\n value: string;\n onChangeText: (text: string) => void;\n onSubmit: () => void;\n template: WebBuilderTemplate | null;\n onTemplate: () => void;\n onClearTemplate: () => void;\n lookUrl: string;\n onLookUrl: (url: string) => void;\n lookInvalid: boolean;\n /** The look-alike field is open (the home's \"A site you love\" card opens it too). */\n lookOpen: boolean;\n onLookOpen: (open: boolean) => void;\n brand: BrandKit | null;\n onBrand: () => void;\n /** The builder is still connecting: send waits, and this sentence says why. */\n connecting?: string | null;\n canSubmit: boolean;\n theme: WebBuilderTheme;\n}\n\nexport const Composer = forwardRef<TextInput, ComposerProps>(function Composer(\n {\n value,\n onChangeText,\n onSubmit,\n template,\n onTemplate,\n onClearTemplate,\n lookUrl,\n onLookUrl,\n lookInvalid,\n lookOpen,\n onLookOpen,\n brand,\n onBrand,\n connecting = null,\n canSubmit,\n theme,\n },\n ref,\n) {\n const lookHost = lookUrl && !lookInvalid ? hostLabel(lookUrl) : null;\n const ready = canSubmit && !connecting;\n return (\n <View\n style={[\n styles.box,\n {\n backgroundColor: theme.card,\n borderColor: theme.border,\n shadowColor: theme.isDark ? '#000' : '#7c2d12',\n },\n ]}\n >\n <TextInput\n ref={ref}\n value={value}\n onChangeText={onChangeText}\n placeholder=\"Describe the site you want to build…\"\n placeholderTextColor={theme.faint}\n multiline\n style={[styles.input, { color: theme.ink }]}\n accessibilityLabel=\"Describe what you want to build\"\n testID=\"webbuilder-brief\"\n />\n\n {lookOpen ? (\n <View\n style={[\n styles.look,\n { backgroundColor: theme.chip, borderColor: lookInvalid ? theme.crit : 'transparent' },\n ]}\n >\n <MaterialCommunityIcons name=\"web\" size={16} color={theme.muted} />\n <TextInput\n value={lookUrl}\n onChangeText={onLookUrl}\n placeholder=\"Look like… https://stripe.com\"\n placeholderTextColor={theme.faint}\n autoCapitalize=\"none\"\n autoCorrect={false}\n keyboardType=\"url\"\n autoFocus={!lookUrl}\n onSubmitEditing={() => onLookOpen(false)}\n style={[styles.lookInput, { color: theme.ink }]}\n accessibilityLabel=\"Make it look like this site\"\n testID=\"webbuilder-look\"\n />\n <Tap\n onPress={() => {\n onLookUrl('');\n onLookOpen(false);\n }}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Remove the look-alike site\"\n hitSlop={8}\n pressedStyle={DIM}\n >\n <MaterialCommunityIcons name=\"close\" size={16} color={theme.muted} />\n </Tap>\n </View>\n ) : null}\n\n {connecting ? (\n <View style={styles.status} accessibilityLiveRegion=\"polite\">\n <View style={[styles.statusDot, { backgroundColor: theme.warn }]} />\n <Text style={[styles.statusText, { color: theme.muted }]} numberOfLines={1}>\n {connecting}\n </Text>\n </View>\n ) : null}\n\n <View style={[styles.toolbar, { borderTopColor: theme.border }]}>\n <ScrollView\n horizontal\n showsHorizontalScrollIndicator={false}\n keyboardShouldPersistTaps=\"handled\"\n style={styles.tools}\n contentContainerStyle={styles.toolsContent}\n >\n <Tool\n icon=\"view-grid-plus-outline\"\n label=\"Template\"\n value={template?.title}\n onPress={onTemplate}\n onClear={onClearTemplate}\n theme={theme}\n testID=\"webbuilder-composer-template\"\n />\n <Tool\n icon=\"web\"\n label=\"Look like\"\n value={lookOpen ? null : lookHost}\n onPress={() => onLookOpen(true)}\n onClear={() => onLookUrl('')}\n theme={theme}\n testID=\"webbuilder-composer-look\"\n />\n <Tool\n icon=\"palette-outline\"\n label=\"Brand kit\"\n value={brand ? brand.name || 'Brand' : null}\n onPress={onBrand}\n theme={theme}\n leading={\n brand?.colors.length ? (\n <View style={styles.dots}>\n {brand.colors.slice(0, 3).map((c) => (\n <View\n key={c}\n style={[styles.dot, { backgroundColor: c, borderColor: theme.card }]}\n />\n ))}\n </View>\n ) : undefined\n }\n testID=\"webbuilder-composer-brand\"\n />\n </ScrollView>\n <Tap\n onPress={onSubmit}\n disabled={!ready}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Start building\"\n accessibilityState={{ disabled: !ready }}\n style={[styles.send, { backgroundColor: ready ? theme.accent : theme.chip }]}\n pressedStyle={DIM}\n testID=\"webbuilder-start\"\n >\n <MaterialCommunityIcons name=\"arrow-up\" size={21} color={ready ? theme.accentInk : theme.faint} />\n </Tap>\n </View>\n </View>\n );\n});\n\nconst styles = StyleSheet.create({\n box: {\n borderRadius: 22,\n borderWidth: StyleSheet.hairlineWidth,\n paddingTop: 14,\n paddingHorizontal: 14,\n paddingBottom: 10,\n gap: 10,\n shadowOpacity: 0.07,\n shadowRadius: 16,\n shadowOffset: { width: 0, height: 6 },\n elevation: 3,\n },\n input: {\n minHeight: 64,\n maxHeight: 160,\n fontSize: 17,\n lineHeight: 24,\n padding: 0,\n textAlignVertical: 'top',\n },\n look: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n borderRadius: 12,\n borderWidth: 1,\n paddingHorizontal: 10,\n },\n lookInput: { flex: 1, fontSize: 15, paddingVertical: 9 },\n status: { flexDirection: 'row', alignItems: 'center', gap: 8 },\n statusDot: { width: 7, height: 7, borderRadius: 4 },\n statusText: { flex: 1, fontSize: 13 },\n toolbar: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 10,\n paddingTop: 10,\n borderTopWidth: StyleSheet.hairlineWidth,\n },\n tools: { flex: 1 },\n toolsContent: { gap: 8, alignItems: 'center' },\n toolIcon: {\n width: 38,\n height: 38,\n borderRadius: 19,\n borderWidth: StyleSheet.hairlineWidth,\n alignItems: 'center',\n justifyContent: 'center',\n },\n toolChip: {\n flexDirection: 'row',\n alignItems: 'center',\n height: 38,\n maxWidth: 200,\n borderRadius: 19,\n borderWidth: StyleSheet.hairlineWidth,\n },\n toolChipMain: { flexDirection: 'row', alignItems: 'center', gap: 6, paddingLeft: 12, flexShrink: 1 },\n toolChipLabel: { fontSize: 14, fontWeight: '600', flexShrink: 1 },\n toolChipClear: { paddingLeft: 6, paddingRight: 10, height: 38, justifyContent: 'center' },\n toolChipEnd: { width: 12 },\n dots: { flexDirection: 'row', marginRight: 4 },\n dot: { width: 12, height: 12, borderRadius: 6, borderWidth: 1.5, marginRight: -4 },\n send: { width: 42, height: 42, borderRadius: 21, alignItems: 'center', justifyContent: 'center' },\n});\n"],"names":["Composer"],"mappings":"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"}
|