@vertz/create-vertz-app 0.2.23 → 0.2.25
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.
|
@@ -85,7 +85,7 @@ export declare function themeTemplate(): string;
|
|
|
85
85
|
/**
|
|
86
86
|
* src/pages/home.tsx — full CRUD task list with form, checkbox toggle,
|
|
87
87
|
* delete confirmation dialog, and animated list transitions.
|
|
88
|
-
* Demonstrates theme components (Button, Input
|
|
88
|
+
* Demonstrates theme components (Button, Input) and DialogStack confirmation.
|
|
89
89
|
*/
|
|
90
90
|
export declare function homePageTemplate(): string;
|
|
91
91
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA6B5D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAyJnD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA6B5D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAyJnD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAoRlD;AAID;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAGxC;AAID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA6B/D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAoBzC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAa5C;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAIpC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAIvC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAc9C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CA6B1C;AAID;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAW1C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAoBvC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAavC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAWnC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAe5C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAOvC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAgD7C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAW5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CActC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAmLzC"}
|
package/dist/templates/index.js
CHANGED
|
@@ -201,7 +201,7 @@ You write plain-looking code and the compiler makes it reactive automatically.
|
|
|
201
201
|
## Imports
|
|
202
202
|
|
|
203
203
|
\`\`\`ts
|
|
204
|
-
import { css, query,
|
|
204
|
+
import { css, query, globalCss, ThemeProvider, variants } from 'vertz/ui';
|
|
205
205
|
import { api } from '../client';
|
|
206
206
|
\`\`\`
|
|
207
207
|
|
|
@@ -306,20 +306,20 @@ const tasks = query(api.tasks.list());
|
|
|
306
306
|
The query result has reactive properties (\`.data\`, \`.error\`, \`.loading\`) that the compiler
|
|
307
307
|
auto-unwraps everywhere — just access them directly, the compiler handles the rest.
|
|
308
308
|
|
|
309
|
-
###
|
|
309
|
+
### Rendering query states
|
|
310
|
+
|
|
311
|
+
Use direct conditional rendering for loading, error, and data states:
|
|
310
312
|
|
|
311
313
|
\`\`\`tsx
|
|
312
|
-
{
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
{
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
),
|
|
322
|
-
})}
|
|
314
|
+
{tasks.loading && <div>Loading...</div>}
|
|
315
|
+
{tasks.error && <div>Error: {tasks.error.message}</div>}
|
|
316
|
+
{tasks.data && (
|
|
317
|
+
<div>
|
|
318
|
+
{tasks.data.items.map((item) => (
|
|
319
|
+
<div key={item.id}>{item.title}</div>
|
|
320
|
+
))}
|
|
321
|
+
</div>
|
|
322
|
+
)}
|
|
323
323
|
\`\`\`
|
|
324
324
|
|
|
325
325
|
### Automatic Cache Invalidation
|
|
@@ -338,7 +338,7 @@ Theme components are pre-configured with the app's design tokens and provide con
|
|
|
338
338
|
Import components from \`@vertz/ui/components\` — the centralized entrypoint:
|
|
339
339
|
|
|
340
340
|
\`\`\`tsx
|
|
341
|
-
import { Button, Input,
|
|
341
|
+
import { Button, Input, Dialog } from '@vertz/ui/components';
|
|
342
342
|
|
|
343
343
|
// RIGHT — use theme components
|
|
344
344
|
<Button intent="primary" size="md">Submit</Button>
|
|
@@ -354,42 +354,57 @@ import { Button, Input, AlertDialog } from '@vertz/ui/components';
|
|
|
354
354
|
**Direct**: \`Button\`, \`Input\`, \`Label\`, \`Badge\`, \`Textarea\`,
|
|
355
355
|
\`Card\` suite, \`Table\` suite, \`Avatar\` suite, \`FormGroup\` suite
|
|
356
356
|
|
|
357
|
-
**Primitives**: \`
|
|
357
|
+
**Primitives**: \`Dialog\`, \`Tabs\`,
|
|
358
358
|
\`Select\`, \`DropdownMenu\`, \`Popover\`, \`Sheet\`, \`Tooltip\`, \`Accordion\`
|
|
359
|
-
— all with sub-components (\`.
|
|
359
|
+
— all with sub-components (\`.Title\`, \`.Content\`, \`.Footer\`, etc.)
|
|
360
360
|
|
|
361
361
|
## Dialogs
|
|
362
362
|
|
|
363
|
-
###
|
|
363
|
+
### \`useDialogStack()\` for all dialogs
|
|
364
|
+
|
|
365
|
+
All dialogs use the DialogStack pattern — imperative, promise-based, with automatic
|
|
366
|
+
overlay, focus trapping, and stacking via native \`<dialog>\`.
|
|
364
367
|
|
|
365
368
|
\`\`\`tsx
|
|
366
|
-
import {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
<AlertDialog.Trigger>
|
|
370
|
-
<Button intent="danger" size="sm">Delete</Button>
|
|
371
|
-
</AlertDialog.Trigger>
|
|
372
|
-
<AlertDialog.Content>
|
|
373
|
-
<AlertDialog.Title>Delete task?</AlertDialog.Title>
|
|
374
|
-
<AlertDialog.Description>This action cannot be undone.</AlertDialog.Description>
|
|
375
|
-
<AlertDialog.Footer>
|
|
376
|
-
<AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
|
|
377
|
-
<AlertDialog.Action onClick={handleDelete}>Delete</AlertDialog.Action>
|
|
378
|
-
</AlertDialog.Footer>
|
|
379
|
-
</AlertDialog.Content>
|
|
380
|
-
</AlertDialog>
|
|
381
|
-
\`\`\`
|
|
369
|
+
import { useDialogStack } from '@vertz/ui';
|
|
370
|
+
|
|
371
|
+
const dialogs = useDialogStack();
|
|
382
372
|
|
|
383
|
-
|
|
373
|
+
// Quick confirmation
|
|
374
|
+
const confirmed = await dialogs.confirm({
|
|
375
|
+
title: 'Delete task?',
|
|
376
|
+
description: 'This action cannot be undone.',
|
|
377
|
+
confirm: 'Delete',
|
|
378
|
+
cancel: 'Cancel',
|
|
379
|
+
intent: 'danger',
|
|
380
|
+
});
|
|
381
|
+
if (confirmed) handleDelete();
|
|
382
|
+
\`\`\`
|
|
384
383
|
|
|
385
|
-
|
|
384
|
+
### Custom dialog components
|
|
386
385
|
|
|
387
386
|
\`\`\`tsx
|
|
388
|
-
import { useDialogStack } from 'vertz/ui';
|
|
387
|
+
import { useDialogStack, useDialog } from '@vertz/ui';
|
|
388
|
+
import { Dialog } from '@vertz/ui/components';
|
|
389
389
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
390
|
+
function EditDialog({ task, dialog }: { task: Task; dialog: DialogHandle<Task> }) {
|
|
391
|
+
return (
|
|
392
|
+
<>
|
|
393
|
+
<Dialog.Header>
|
|
394
|
+
<Dialog.Title>Edit Task</Dialog.Title>
|
|
395
|
+
</Dialog.Header>
|
|
396
|
+
<Dialog.Body>...</Dialog.Body>
|
|
397
|
+
<Dialog.Footer>
|
|
398
|
+
<Dialog.Cancel>Cancel</Dialog.Cancel>
|
|
399
|
+
<Button onClick={() => dialog.close(updatedTask)}>Save</Button>
|
|
400
|
+
</Dialog.Footer>
|
|
401
|
+
</>
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Open it
|
|
406
|
+
const result = await dialogs.open(EditDialog, { task });
|
|
407
|
+
if (result.ok) saveTask(result.data);
|
|
393
408
|
\`\`\`
|
|
394
409
|
|
|
395
410
|
## Styling
|
|
@@ -800,23 +815,21 @@ export const themeGlobals = config.globals;
|
|
|
800
815
|
/**
|
|
801
816
|
* src/pages/home.tsx — full CRUD task list with form, checkbox toggle,
|
|
802
817
|
* delete confirmation dialog, and animated list transitions.
|
|
803
|
-
* Demonstrates theme components (Button, Input
|
|
818
|
+
* Demonstrates theme components (Button, Input) and DialogStack confirmation.
|
|
804
819
|
*/
|
|
805
820
|
export function homePageTemplate() {
|
|
806
821
|
return `import {
|
|
807
822
|
ANIMATION_DURATION,
|
|
808
823
|
ANIMATION_EASING,
|
|
809
|
-
ListTransition,
|
|
810
824
|
css,
|
|
811
825
|
fadeOut,
|
|
812
826
|
form,
|
|
813
827
|
globalCss,
|
|
814
828
|
query,
|
|
815
|
-
queryMatch,
|
|
816
829
|
slideInFromTop,
|
|
830
|
+
useDialogStack,
|
|
817
831
|
} from 'vertz/ui';
|
|
818
|
-
import { Button } from '@vertz/ui/components';
|
|
819
|
-
import { AlertDialog } from '@vertz/ui/components';
|
|
832
|
+
import { Button, List } from '@vertz/ui/components';
|
|
820
833
|
import { api } from '../client';
|
|
821
834
|
|
|
822
835
|
// Global CSS for list item enter/exit animations
|
|
@@ -877,12 +890,23 @@ interface TaskItemProps {
|
|
|
877
890
|
}
|
|
878
891
|
|
|
879
892
|
function TaskItem({ id, title, completed }: TaskItemProps) {
|
|
893
|
+
const dialogs = useDialogStack();
|
|
894
|
+
|
|
880
895
|
const handleToggle = async () => {
|
|
881
896
|
await api.tasks.update(id, { completed: !completed });
|
|
882
897
|
};
|
|
883
898
|
|
|
884
899
|
const handleDelete = async () => {
|
|
885
|
-
await
|
|
900
|
+
const confirmed = await dialogs.confirm({
|
|
901
|
+
title: 'Delete task?',
|
|
902
|
+
description: 'This action cannot be undone.',
|
|
903
|
+
confirm: 'Delete',
|
|
904
|
+
cancel: 'Cancel',
|
|
905
|
+
intent: 'danger',
|
|
906
|
+
});
|
|
907
|
+
if (confirmed) {
|
|
908
|
+
await api.tasks.delete(id);
|
|
909
|
+
}
|
|
886
910
|
};
|
|
887
911
|
|
|
888
912
|
return (
|
|
@@ -896,21 +920,7 @@ function TaskItem({ id, title, completed }: TaskItemProps) {
|
|
|
896
920
|
<span className={completed ? styles.labelDone : styles.label}>
|
|
897
921
|
{title}
|
|
898
922
|
</span>
|
|
899
|
-
<
|
|
900
|
-
<AlertDialog.Trigger>
|
|
901
|
-
<Button intent="ghost" size="sm">Delete</Button>
|
|
902
|
-
</AlertDialog.Trigger>
|
|
903
|
-
<AlertDialog.Content>
|
|
904
|
-
<AlertDialog.Title>Delete task?</AlertDialog.Title>
|
|
905
|
-
<AlertDialog.Description>
|
|
906
|
-
This action cannot be undone.
|
|
907
|
-
</AlertDialog.Description>
|
|
908
|
-
<AlertDialog.Footer>
|
|
909
|
-
<AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
|
|
910
|
-
<AlertDialog.Action>Delete</AlertDialog.Action>
|
|
911
|
-
</AlertDialog.Footer>
|
|
912
|
-
</AlertDialog.Content>
|
|
913
|
-
</AlertDialog>
|
|
923
|
+
<Button intent="ghost" size="sm" onClick={handleDelete}>Delete</Button>
|
|
914
924
|
</div>
|
|
915
925
|
);
|
|
916
926
|
}
|
|
@@ -947,43 +957,41 @@ export function HomePage() {
|
|
|
947
957
|
</Button>
|
|
948
958
|
</form>
|
|
949
959
|
|
|
950
|
-
{
|
|
951
|
-
loading
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
error
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
{
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
<
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
keyFn={(task) => task.id}
|
|
970
|
-
children={(task) => (
|
|
960
|
+
{tasksQuery.loading && (
|
|
961
|
+
<div className={styles.loading}>Loading tasks...</div>
|
|
962
|
+
)}
|
|
963
|
+
{tasksQuery.error && (
|
|
964
|
+
<div className={styles.error}>
|
|
965
|
+
{tasksQuery.error instanceof Error ? tasksQuery.error.message : String(tasksQuery.error)}
|
|
966
|
+
</div>
|
|
967
|
+
)}
|
|
968
|
+
{tasksQuery.data && (
|
|
969
|
+
<>
|
|
970
|
+
{tasksQuery.data.items.length === 0 && (
|
|
971
|
+
<div className={styles.empty}>
|
|
972
|
+
No tasks yet. Add one above!
|
|
973
|
+
</div>
|
|
974
|
+
)}
|
|
975
|
+
<div data-testid="task-list" className={styles.list}>
|
|
976
|
+
<List animate>
|
|
977
|
+
{tasksQuery.data.items.map((task) => (
|
|
978
|
+
<List.Item key={task.id}>
|
|
971
979
|
<TaskItem
|
|
972
980
|
id={task.id}
|
|
973
981
|
title={task.title}
|
|
974
982
|
completed={task.completed}
|
|
975
983
|
/>
|
|
976
|
-
|
|
977
|
-
|
|
984
|
+
</List.Item>
|
|
985
|
+
))}
|
|
986
|
+
</List>
|
|
987
|
+
</div>
|
|
988
|
+
{tasksQuery.data.items.length > 0 && (
|
|
989
|
+
<div className={styles.count}>
|
|
990
|
+
{tasksQuery.data.items.filter((t) => !t.completed).length} remaining
|
|
978
991
|
</div>
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
</div>
|
|
983
|
-
)}
|
|
984
|
-
</>
|
|
985
|
-
),
|
|
986
|
-
})}
|
|
992
|
+
)}
|
|
993
|
+
</>
|
|
994
|
+
)}
|
|
987
995
|
</div>
|
|
988
996
|
);
|
|
989
997
|
}
|