@lotics/cli 0.21.0 → 0.23.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/src/starter_template.js +139 -14
- package/package.json +1 -1
|
@@ -94,11 +94,13 @@ export function buildStarterTemplate(args) {
|
|
|
94
94
|
noEmit: true,
|
|
95
95
|
jsx: "react-jsx",
|
|
96
96
|
strict: true,
|
|
97
|
-
noUnusedLocals: true,
|
|
98
|
-
noUnusedParameters: true,
|
|
99
97
|
noFallthroughCasesInSwitch: true,
|
|
100
98
|
},
|
|
99
|
+
// Restrict tsc to the project's own sources. tsgo follows
|
|
100
|
+
// transitive imports into node_modules — strict rules
|
|
101
|
+
// (noUnusedLocals etc.) would fire on @lotics/ui's source.
|
|
101
102
|
include: ["src", ".lotics"],
|
|
103
|
+
exclude: ["node_modules"],
|
|
102
104
|
}, null, 2) + "\n",
|
|
103
105
|
},
|
|
104
106
|
{
|
|
@@ -116,18 +118,35 @@ import react from "@vitejs/plugin-react";
|
|
|
116
118
|
// (View, Text, Pressable, StyleSheet, etc.) render in a pure-web environment.
|
|
117
119
|
// .web.tsx is prioritized in resolve.extensions so per-target variants
|
|
118
120
|
// (avatar.web.tsx, wave_avatar.web.tsx) win over the native .tsx file.
|
|
121
|
+
//
|
|
122
|
+
// @lotics/ui/icon.tsx imports from \`lucide-react-native/dist/esm/icons/<name>\`
|
|
123
|
+
// — deep paths that lucide-react-native's package \`exports\` map blocks under
|
|
124
|
+
// Vite's strict resolution. lucide-react has the same per-icon files with no
|
|
125
|
+
// exports map, so we alias the deep path to use it. Web rendering of <svg>
|
|
126
|
+
// is identical to RN-SVG when running under RN-Web.
|
|
119
127
|
export default defineConfig({
|
|
120
128
|
plugins: [react()],
|
|
121
129
|
resolve: {
|
|
122
|
-
alias:
|
|
123
|
-
|
|
124
|
-
|
|
130
|
+
alias: [
|
|
131
|
+
{
|
|
132
|
+
find: /^lucide-react-native\\/dist\\/esm\\/icons\\/(.+)$/,
|
|
133
|
+
replacement: "lucide-react/dist/esm/icons/$1",
|
|
134
|
+
},
|
|
135
|
+
{ find: "react-native", replacement: "react-native-web" },
|
|
136
|
+
],
|
|
125
137
|
extensions: [".web.tsx", ".web.ts", ".tsx", ".ts", ".jsx", ".js"],
|
|
126
138
|
},
|
|
127
139
|
build: {
|
|
128
140
|
outDir: "dist",
|
|
129
141
|
sourcemap: true,
|
|
130
142
|
},
|
|
143
|
+
server: {
|
|
144
|
+
// Allow the sandboxed null-origin iframe used by \`lotics app dev\` to
|
|
145
|
+
// fetch HMR client + source modules from the dev server. Production
|
|
146
|
+
// iframe loads modules from api.lotics.ai which already permits null
|
|
147
|
+
// origin via CORS.
|
|
148
|
+
cors: { origin: "*" },
|
|
149
|
+
},
|
|
131
150
|
test: {
|
|
132
151
|
environment: "jsdom",
|
|
133
152
|
},
|
|
@@ -142,6 +161,20 @@ export default defineConfig({
|
|
|
142
161
|
<meta charset="UTF-8" />
|
|
143
162
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
144
163
|
<title>${escapeHtml(args.app_name)}</title>
|
|
164
|
+
<style>
|
|
165
|
+
/*
|
|
166
|
+
* Full-viewport container chain for iframe apps. @lotics/ui's DataGrid
|
|
167
|
+
* (and any layout that uses \`flex: 1\` to fill available space) relies
|
|
168
|
+
* on a measured parent height. The browser default of html/body being
|
|
169
|
+
* content-sized collapses every \`flex: 1\` to 0 and the surface shrinks
|
|
170
|
+
* to fit only its rendered content.
|
|
171
|
+
*
|
|
172
|
+
* Also: #root is made a flex column so the outermost RN \`<View flex:1>\`
|
|
173
|
+
* inside App.tsx claims the full iframe height.
|
|
174
|
+
*/
|
|
175
|
+
html, body, #root { height: 100%; margin: 0; }
|
|
176
|
+
#root { display: flex; flex-direction: column; }
|
|
177
|
+
</style>
|
|
145
178
|
</head>
|
|
146
179
|
<body>
|
|
147
180
|
<div id="root"></div>
|
|
@@ -161,37 +194,129 @@ mount(<App />);
|
|
|
161
194
|
},
|
|
162
195
|
{
|
|
163
196
|
path: "src/App.tsx",
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
//
|
|
197
|
+
// Welcome screen demonstrates the full-container layout pattern that
|
|
198
|
+
// real apps (data grids, dashboards, full-page surfaces) rely on:
|
|
199
|
+
// - Outer <View flex:1> claims the full iframe height (works because
|
|
200
|
+
// index.html sets html/body/#root to 100% + #root is a flex column).
|
|
201
|
+
// - Inner View is content-sized + centered for a card layout.
|
|
202
|
+
//
|
|
203
|
+
// We deliberately do NOT use @lotics/ui/stack for the outer chain.
|
|
204
|
+
// Stack wraps each child in an unstyled <View>, which breaks `flex: 1`
|
|
205
|
+
// propagation to children that need to claim flexible height (e.g., a
|
|
206
|
+
// DataGrid that fills the remaining space below a header + search).
|
|
207
|
+
// Use plain <View> with `flexDirection` + `gap` for any outer layout
|
|
208
|
+
// that hosts a flex-filling child; Stack is fine for content-sized
|
|
209
|
+
// groupings inside such a chain.
|
|
167
210
|
content: `import { View } from "react-native";
|
|
168
|
-
import { Stack } from "@lotics/ui/stack";
|
|
169
211
|
import { Card } from "@lotics/ui/card";
|
|
170
212
|
import { Text } from "@lotics/ui/text";
|
|
171
213
|
import { Button } from "@lotics/ui/button";
|
|
172
214
|
|
|
215
|
+
// Outer <View flex:1> claims the full iframe height — works because
|
|
216
|
+
// index.html sets html/body/#root to 100% and #root is a flex column.
|
|
217
|
+
// For real layouts with a fill-remaining-space child (DataGrid etc.),
|
|
218
|
+
// keep this flex chain plain — @lotics/ui/stack wraps each child in an
|
|
219
|
+
// unstyled <View> that breaks \`flex: 1\` propagation.
|
|
173
220
|
export default function App() {
|
|
174
221
|
return (
|
|
175
|
-
<View
|
|
176
|
-
|
|
222
|
+
<View
|
|
223
|
+
style={{
|
|
224
|
+
flex: 1,
|
|
225
|
+
padding: 24,
|
|
226
|
+
justifyContent: "center",
|
|
227
|
+
alignItems: "center",
|
|
228
|
+
}}
|
|
229
|
+
>
|
|
230
|
+
<View style={{ maxWidth: 640, width: "100%", gap: 16 }}>
|
|
177
231
|
<Text size="xl" weight="semibold">${escapeHtml(args.app_name)}</Text>
|
|
178
232
|
<Card>
|
|
179
|
-
<
|
|
233
|
+
<View style={{ padding: 16, gap: 8 }}>
|
|
180
234
|
<Text>This is your new Lotics app.</Text>
|
|
181
235
|
<Text color="muted">
|
|
182
236
|
Edit <Text weight="medium">src/App.tsx</Text> and run{" "}
|
|
183
237
|
<Text weight="medium">lotics app deploy</Text> to publish.
|
|
184
238
|
</Text>
|
|
185
|
-
</
|
|
239
|
+
</View>
|
|
186
240
|
</Card>
|
|
187
241
|
<Text color="muted" size="sm">
|
|
188
242
|
Hooks from @lotics/app-sdk: useTable, useMutate, useAction, useQuery, useWorkflow.
|
|
189
243
|
</Text>
|
|
190
244
|
<Button title="Get started" onPress={() => {}} color="primary" />
|
|
191
|
-
</
|
|
245
|
+
</View>
|
|
192
246
|
</View>
|
|
193
247
|
);
|
|
194
248
|
}
|
|
249
|
+
`,
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
path: "src/lucide-react-native.d.ts",
|
|
253
|
+
content: `// Type shim for lucide-react-native's deep-icon imports
|
|
254
|
+
// (\`lucide-react-native/dist/esm/icons/<name>\`). The package ships JS-only
|
|
255
|
+
// files without per-file .d.ts. The Vite alias in vite.config.ts rewrites
|
|
256
|
+
// these to lucide-react at bundle time; this declaration covers the
|
|
257
|
+
// TypeScript compile-time gap.
|
|
258
|
+
declare module "lucide-react-native/dist/esm/icons/*" {
|
|
259
|
+
import type { ComponentType } from "react";
|
|
260
|
+
const Icon: ComponentType<{
|
|
261
|
+
size: number;
|
|
262
|
+
color: string;
|
|
263
|
+
fill?: string;
|
|
264
|
+
strokeWidth?: number;
|
|
265
|
+
}>;
|
|
266
|
+
export default Icon;
|
|
267
|
+
}
|
|
268
|
+
`,
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
path: "src/css_modules.d.ts",
|
|
272
|
+
content: `declare module "*.module.css" {
|
|
273
|
+
const classes: { [key: string]: string };
|
|
274
|
+
export default classes;
|
|
275
|
+
}
|
|
276
|
+
`,
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
path: "src/react_native.d.ts",
|
|
280
|
+
content: `import "react-native";
|
|
281
|
+
|
|
282
|
+
// Augments react-native's types with the web-only fields @lotics/ui consumes:
|
|
283
|
+
// Pressable's \`hovered\` callback state, plus web-only ViewStyle / TextStyle
|
|
284
|
+
// properties (cursor, outline, boxShadow, etc.) used by the grid + primitives.
|
|
285
|
+
// Each iframe app needs its own copy — TypeScript doesn't auto-pick-up
|
|
286
|
+
// \`.d.ts\` files inside dependencies. \`@lotics/ui\`'s grid sources include a
|
|
287
|
+
// triple-slash reference to its own copy of this file so the augmentation
|
|
288
|
+
// kicks in transitively.
|
|
289
|
+
declare module "react-native" {
|
|
290
|
+
interface PressableStateCallbackType {
|
|
291
|
+
hovered: boolean;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
interface ViewStyle {
|
|
295
|
+
backdropFilter?: string;
|
|
296
|
+
backgroundImage?: string;
|
|
297
|
+
boxShadow?: string;
|
|
298
|
+
boxSizing?: string;
|
|
299
|
+
cursor?: string;
|
|
300
|
+
touchAction?: string;
|
|
301
|
+
transitionDuration?: string;
|
|
302
|
+
transitionProperty?: string;
|
|
303
|
+
appearance?: string;
|
|
304
|
+
outline?: string;
|
|
305
|
+
outlineColor?: string;
|
|
306
|
+
outlineStyle?: string;
|
|
307
|
+
outlineWidth?: number;
|
|
308
|
+
outlineOffset?: number;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
interface TextStyle {
|
|
312
|
+
outline?: string;
|
|
313
|
+
outlineColor?: string;
|
|
314
|
+
outlineStyle?: string;
|
|
315
|
+
outlineWidth?: number;
|
|
316
|
+
outlineOffset?: number;
|
|
317
|
+
appearance?: string;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
195
320
|
`,
|
|
196
321
|
},
|
|
197
322
|
{
|