@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, AlertDialog) over raw HTML.
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,CAqQlD;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,CA0LzC"}
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"}
@@ -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, queryMatch, globalCss, ThemeProvider, variants } from 'vertz/ui';
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
- ### \`queryMatch()\` — Pattern matching for query states
309
+ ### Rendering query states
310
+
311
+ Use direct conditional rendering for loading, error, and data states:
310
312
 
311
313
  \`\`\`tsx
312
- {queryMatch(tasksQuery, {
313
- loading: () => <div>Loading...</div>,
314
- error: (err) => <div>Error: {err.message}</div>,
315
- data: (response) => (
316
- <div>
317
- {response.items.map((item) => (
318
- <div key={item.id}>{item.title}</div>
319
- ))}
320
- </div>
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, AlertDialog } from '@vertz/ui/components';
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**: \`AlertDialog\`, \`Dialog\`, \`Tabs\`,
357
+ **Primitives**: \`Dialog\`, \`Tabs\`,
358
358
  \`Select\`, \`DropdownMenu\`, \`Popover\`, \`Sheet\`, \`Tooltip\`, \`Accordion\`
359
- — all with sub-components (\`.Trigger\`, \`.Content\`, \`.Footer\`, etc.)
359
+ — all with sub-components (\`.Title\`, \`.Content\`, \`.Footer\`, etc.)
360
360
 
361
361
  ## Dialogs
362
362
 
363
- ### Composable \`<AlertDialog>\` for inline confirmations
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 { Button, AlertDialog } from '@vertz/ui/components';
367
-
368
- <AlertDialog>
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
- ### \`useDialogStack()\` for imperative/stacked dialogs
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
- Use when you need promise-based results or dialogs opened from event handlers:
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
- const dialogs = useDialogStack();
391
- const confirmed = await dialogs.open(ConfirmDialog, { message: 'Delete?' });
392
- if (confirmed) handleDelete();
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, AlertDialog) over raw HTML.
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 api.tasks.delete(id);
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
- <AlertDialog onAction={handleDelete}>
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
- {queryMatch(tasksQuery, {
951
- loading: () => (
952
- <div className={styles.loading}>Loading tasks...</div>
953
- ),
954
- error: (err) => (
955
- <div className={styles.error}>
956
- {err instanceof Error ? err.message : String(err)}
957
- </div>
958
- ),
959
- data: (response) => (
960
- <>
961
- {response.items.length === 0 && (
962
- <div className={styles.empty}>
963
- No tasks yet. Add one above!
964
- </div>
965
- )}
966
- <div data-testid="task-list" className={styles.list}>
967
- <ListTransition
968
- each={response.items}
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
- {response.items.length > 0 && (
980
- <div className={styles.count}>
981
- {response.items.filter((t) => !t.completed).length} remaining
982
- </div>
983
- )}
984
- </>
985
- ),
986
- })}
992
+ )}
993
+ </>
994
+ )}
987
995
  </div>
988
996
  );
989
997
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertz/create-vertz-app",
3
- "version": "0.2.23",
3
+ "version": "0.2.25",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Create a new Vertz application",