create-foldkit-app 0.29.0 → 0.29.1

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 (68) hide show
  1. package/dist/templates/base/AGENTS.md +5 -112
  2. package/dist/templates/base/FOLDKIT.md +144 -0
  3. package/dist/templates/examples/api-cache/src/main.ts +36 -40
  4. package/dist/templates/examples/auth/src/main.ts +16 -15
  5. package/dist/templates/examples/auth/src/page/loggedIn/update.ts +10 -11
  6. package/dist/templates/examples/auth/src/page/loggedOut/page/login.ts +44 -55
  7. package/dist/templates/examples/auth/src/page/loggedOut/update.ts +8 -12
  8. package/dist/templates/examples/auth/src/update.ts +67 -73
  9. package/dist/templates/examples/canvas-art/src/main.ts +32 -31
  10. package/dist/templates/examples/charting/src/init.test.ts +6 -3
  11. package/dist/templates/examples/charting/src/init.ts +4 -4
  12. package/dist/templates/examples/charting/src/update.ts +34 -38
  13. package/dist/templates/examples/counter/src/main.ts +13 -13
  14. package/dist/templates/examples/counters/src/counter.ts +9 -8
  15. package/dist/templates/examples/counters/src/main.ts +20 -26
  16. package/dist/templates/examples/crash-view/src/main.ts +5 -3
  17. package/dist/templates/examples/embedding/src/main.ts +11 -9
  18. package/dist/templates/examples/form/src/main.ts +79 -89
  19. package/dist/templates/examples/generative-art/src/main.ts +6 -4
  20. package/dist/templates/examples/generative-art/src/update.ts +26 -23
  21. package/dist/templates/examples/interrupting-commands/src/main.ts +68 -66
  22. package/dist/templates/examples/job-application/src/main.ts +3 -4
  23. package/dist/templates/examples/job-application/src/step/attachments.ts +16 -19
  24. package/dist/templates/examples/job-application/src/step/coverLetter.ts +5 -5
  25. package/dist/templates/examples/job-application/src/step/education/education.ts +12 -17
  26. package/dist/templates/examples/job-application/src/step/education/entry.ts +29 -42
  27. package/dist/templates/examples/job-application/src/step/personalInfo.ts +35 -44
  28. package/dist/templates/examples/job-application/src/step/skills/entry.ts +15 -21
  29. package/dist/templates/examples/job-application/src/step/skills/skills.ts +12 -17
  30. package/dist/templates/examples/job-application/src/step/workHistory/entry.ts +41 -58
  31. package/dist/templates/examples/job-application/src/step/workHistory/workHistory.ts +12 -17
  32. package/dist/templates/examples/job-application/src/update.ts +26 -29
  33. package/dist/templates/examples/kanban/src/main.ts +3 -4
  34. package/dist/templates/examples/kanban/src/update.ts +31 -31
  35. package/dist/templates/examples/managed-resource-layer/src/main.ts +30 -34
  36. package/dist/templates/examples/map/src/main.ts +48 -56
  37. package/dist/templates/examples/pixel-art/src/comparison.bench.test.ts +34 -13
  38. package/dist/templates/examples/pixel-art/src/main.bench.ts +3 -3
  39. package/dist/templates/examples/pixel-art/src/main.ts +3 -4
  40. package/dist/templates/examples/pixel-art/src/update.ts +109 -100
  41. package/dist/templates/examples/query-sync/src/main.ts +27 -25
  42. package/dist/templates/examples/route-transitions/src/main.ts +46 -43
  43. package/dist/templates/examples/route-transitions/src/story.test.ts +11 -11
  44. package/dist/templates/examples/routing/src/main.ts +16 -14
  45. package/dist/templates/examples/routing/src/page/people.ts +23 -28
  46. package/dist/templates/examples/shopping-cart/src/main.ts +41 -42
  47. package/dist/templates/examples/shopping-cart/src/page/products.ts +28 -35
  48. package/dist/templates/examples/slow-warnings/src/main.ts +23 -32
  49. package/dist/templates/examples/snake/src/main.ts +135 -143
  50. package/dist/templates/examples/ssg/src/main.ts +20 -17
  51. package/dist/templates/examples/ssr/src/main.ts +20 -24
  52. package/dist/templates/examples/state-machine/src/main.ts +24 -11
  53. package/dist/templates/examples/state-machine/src/story.test.ts +2 -2
  54. package/dist/templates/examples/stopwatch/src/main.ts +42 -50
  55. package/dist/templates/examples/todo/src/main.ts +152 -160
  56. package/dist/templates/examples/ui-showcase/src/main.ts +53 -54
  57. package/dist/templates/examples/ui-showcase/src/scene.test.ts +2 -2
  58. package/dist/templates/examples/ui-showcase/src/story.test.ts +2 -2
  59. package/dist/templates/examples/ui-showcase/src/ui/init.ts +6 -7
  60. package/dist/templates/examples/ui-showcase/src/ui/update.ts +265 -336
  61. package/dist/templates/examples/view-transitions/src/main.ts +18 -17
  62. package/dist/templates/examples/weather/src/main.ts +33 -40
  63. package/dist/templates/examples/web-components/src/main.ts +14 -17
  64. package/dist/templates/examples/websocket-chat/src/main.ts +44 -50
  65. package/dist/templates/release.json +8 -8
  66. package/dist/templates/rendering/ssg/src/main.ts +20 -17
  67. package/dist/templates/rendering/ssr/src/main.ts +20 -24
  68. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { Array, Match as M, Number, Option, pipe } from 'effect'
2
- import { Command, Update } from 'foldkit'
2
+ import { Update } from 'foldkit'
3
3
  import { evo } from 'foldkit/struct'
4
4
 
5
5
  import {
@@ -80,48 +80,43 @@ const reorderColumns = (
80
80
  })
81
81
  }
82
82
 
83
- export type UiUpdateReturn = readonly [
84
- UiModel,
85
- ReadonlyArray<Command.Command<UiMessage>>,
86
- ]
87
-
88
83
  const DemoMenu = Menu.create<string>()
89
84
 
90
85
  const foldDialogOutMessage = M.type<Dialog.OutMessage>().pipe(
91
86
  M.withReturnType<Update.Step<UiModel, UiMessage>>(),
92
87
  M.tagsExhaustive({
93
- Opened: () => model => [model, []],
94
- Closed: () => model => [model, []],
88
+ Opened: () => model => ({ model }),
89
+ Closed: () => model => ({ model }),
95
90
  }),
96
91
  )
97
92
 
98
93
  const foldMenuOutMessage = M.type<Menu.OutMessage<string>>().pipe(
99
94
  M.withReturnType<Update.Step<UiModel, UiMessage>>(),
100
95
  M.tagsExhaustive({
101
- Selected: () => model => [model, []],
96
+ Selected: () => model => ({ model }),
102
97
  }),
103
98
  )
104
99
 
105
100
  const foldPopoverOutMessage = M.type<Popover.OutMessage>().pipe(
106
101
  M.withReturnType<Update.Step<UiModel, UiMessage>>(),
107
102
  M.tagsExhaustive({
108
- Opened: () => model => [model, []],
109
- Closed: () => model => [model, []],
103
+ Opened: () => model => ({ model }),
104
+ Closed: () => model => ({ model }),
110
105
  }),
111
106
  )
112
107
 
113
108
  const foldToastOutMessage = M.type<typeof Toast.OutMessage.Type>().pipe(
114
109
  M.withReturnType<Update.Step<UiModel, UiMessage>>(),
115
110
  M.tagsExhaustive({
116
- DismissedToast: () => model => [model, []],
111
+ DismissedToast: () => model => ({ model }),
117
112
  }),
118
113
  )
119
114
 
120
115
  const foldTooltipOutMessage = M.type<Tooltip.OutMessage>().pipe(
121
116
  M.withReturnType<Update.Step<UiModel, UiMessage>>(),
122
117
  M.tagsExhaustive({
123
- Shown: () => model => [model, []],
124
- Hidden: () => model => [model, []],
118
+ Shown: () => model => ({ model }),
119
+ Hidden: () => model => ({ model }),
125
120
  }),
126
121
  )
127
122
 
@@ -134,18 +129,26 @@ const foldMobileMenuDialog = Update.foldChild({
134
129
  foldOutMessage: foldDialogOutMessage,
135
130
  })
136
131
 
132
+ const foldMobileMenuDialogOpen = Update.foldChildStep({
133
+ update: Dialog.open,
134
+ read: (model: UiModel) => Option.some(model.mobileMenuDialog),
135
+ write: (model, nextMobileMenuDialog) =>
136
+ evo(model, { mobileMenuDialog: () => nextMobileMenuDialog }),
137
+ toParentMessage: message => UiMessage.GotMobileMenuDialogMessage({ message }),
138
+ foldOutMessage: foldDialogOutMessage,
139
+ })
140
+
137
141
  const foldComboboxDemoOutMessage = M.type<Combobox.OutMessage<City>>().pipe(
138
142
  M.withReturnType<Update.Step<UiModel, UiMessage>>(),
139
143
  M.tagsExhaustive({
140
144
  Selected:
141
145
  ({ value }) =>
142
- model => [
143
- evo(model, {
146
+ model => ({
147
+ model: evo(model, {
144
148
  maybeComboboxDemoSelectedCity: () => Option.some(value),
145
149
  }),
146
- [],
147
- ],
148
- ClearedSelection: () => model => [model, []],
150
+ }),
151
+ ClearedSelection: () => model => ({ model }),
149
152
  }),
150
153
  )
151
154
 
@@ -165,21 +168,19 @@ const foldComboboxNullableDemoOutMessage = M.type<
165
168
  M.tagsExhaustive({
166
169
  Selected:
167
170
  ({ value }) =>
168
- model => [
169
- evo(model, {
171
+ model => ({
172
+ model: evo(model, {
170
173
  maybeComboboxNullableDemoSelectedCity: () =>
171
174
  Option.contains(model.maybeComboboxNullableDemoSelectedCity, value)
172
175
  ? Option.none()
173
176
  : Option.some(value),
174
177
  }),
175
- [],
176
- ],
177
- ClearedSelection: () => model => [
178
- evo(model, {
178
+ }),
179
+ ClearedSelection: () => model => ({
180
+ model: evo(model, {
179
181
  maybeComboboxNullableDemoSelectedCity: () => Option.none(),
180
182
  }),
181
- [],
182
- ],
183
+ }),
183
184
  }),
184
185
  )
185
186
 
@@ -200,8 +201,8 @@ const foldComboboxMultiDemoOutMessage = M.type<
200
201
  M.tagsExhaustive({
201
202
  Selected:
202
203
  ({ value }) =>
203
- model => [
204
- evo(model, {
204
+ model => ({
205
+ model: evo(model, {
205
206
  comboboxMultiDemoSelectedCities: () =>
206
207
  Array.contains(model.comboboxMultiDemoSelectedCities, value)
207
208
  ? Array.filter(
@@ -210,9 +211,8 @@ const foldComboboxMultiDemoOutMessage = M.type<
210
211
  )
211
212
  : Array.append(model.comboboxMultiDemoSelectedCities, value),
212
213
  }),
213
- [],
214
- ],
215
- ClearedSelection: () => model => [model, []],
214
+ }),
215
+ ClearedSelection: () => model => ({ model }),
216
216
  }),
217
217
  )
218
218
 
@@ -233,13 +233,12 @@ const foldComboboxPlacementLockDemoOutMessage = M.type<
233
233
  M.tagsExhaustive({
234
234
  Selected:
235
235
  ({ value }) =>
236
- model => [
237
- evo(model, {
236
+ model => ({
237
+ model: evo(model, {
238
238
  maybeComboboxPlacementLockDemoSelectedCity: () => Option.some(value),
239
239
  }),
240
- [],
241
- ],
242
- ClearedSelection: () => model => [model, []],
240
+ }),
241
+ ClearedSelection: () => model => ({ model }),
243
242
  }),
244
243
  )
245
244
 
@@ -262,13 +261,12 @@ const foldComboboxSelectOnFocusDemoOutMessage = M.type<
262
261
  M.tagsExhaustive({
263
262
  Selected:
264
263
  ({ value }) =>
265
- model => [
266
- evo(model, {
264
+ model => ({
265
+ model: evo(model, {
267
266
  maybeComboboxSelectOnFocusDemoSelectedCity: () => Option.some(value),
268
267
  }),
269
- [],
270
- ],
271
- ClearedSelection: () => model => [model, []],
268
+ }),
269
+ ClearedSelection: () => model => ({ model }),
272
270
  }),
273
271
  )
274
272
 
@@ -293,6 +291,15 @@ const foldDialogDemo = Update.foldChild({
293
291
  foldOutMessage: foldDialogOutMessage,
294
292
  })
295
293
 
294
+ const foldDialogDemoOpen = Update.foldChildStep({
295
+ update: Dialog.open,
296
+ read: (model: UiModel) => Option.some(model.dialogDemo),
297
+ write: (model, nextDialogDemo) =>
298
+ evo(model, { dialogDemo: () => nextDialogDemo }),
299
+ toParentMessage: message => UiMessage.GotDialogDemoMessage({ message }),
300
+ foldOutMessage: foldDialogOutMessage,
301
+ })
302
+
296
303
  const foldDialogAnimatedDemo = Update.foldChild({
297
304
  update: Dialog.update,
298
305
  read: (model: UiModel) => Option.some(model.dialogAnimatedDemo),
@@ -303,6 +310,16 @@ const foldDialogAnimatedDemo = Update.foldChild({
303
310
  foldOutMessage: foldDialogOutMessage,
304
311
  })
305
312
 
313
+ const foldDialogAnimatedDemoOpen = Update.foldChildStep({
314
+ update: Dialog.open,
315
+ read: (model: UiModel) => Option.some(model.dialogAnimatedDemo),
316
+ write: (model, nextDialogAnimatedDemo) =>
317
+ evo(model, { dialogAnimatedDemo: () => nextDialogAnimatedDemo }),
318
+ toParentMessage: message =>
319
+ UiMessage.GotDialogAnimatedDemoMessage({ message }),
320
+ foldOutMessage: foldDialogOutMessage,
321
+ })
322
+
306
323
  const foldOverlayDialogDemo = Update.foldChild({
307
324
  update: Dialog.update,
308
325
  read: (model: UiModel) => Option.some(model.overlayDialogDemo),
@@ -313,6 +330,16 @@ const foldOverlayDialogDemo = Update.foldChild({
313
330
  foldOutMessage: foldDialogOutMessage,
314
331
  })
315
332
 
333
+ const foldOverlayDialogDemoOpen = Update.foldChildStep({
334
+ update: Dialog.open,
335
+ read: (model: UiModel) => Option.some(model.overlayDialogDemo),
336
+ write: (model, nextOverlayDialogDemo) =>
337
+ evo(model, { overlayDialogDemo: () => nextOverlayDialogDemo }),
338
+ toParentMessage: message =>
339
+ UiMessage.GotOverlayDialogDemoMessage({ message }),
340
+ foldOutMessage: foldDialogOutMessage,
341
+ })
342
+
316
343
  const foldOverlayComboboxDemoOutMessage = M.type<
317
344
  Combobox.OutMessage<City>
318
345
  >().pipe(
@@ -320,13 +347,12 @@ const foldOverlayComboboxDemoOutMessage = M.type<
320
347
  M.tagsExhaustive({
321
348
  Selected:
322
349
  ({ value }) =>
323
- model => [
324
- evo(model, {
350
+ model => ({
351
+ model: evo(model, {
325
352
  maybeOverlayComboboxDemoSelectedCity: () => Option.some(value),
326
353
  }),
327
- [],
328
- ],
329
- ClearedSelection: () => model => [model, []],
354
+ }),
355
+ ClearedSelection: () => model => ({ model }),
330
356
  }),
331
357
  )
332
358
 
@@ -350,6 +376,16 @@ const foldNestedDialogParentDemo = Update.foldChild({
350
376
  foldOutMessage: foldDialogOutMessage,
351
377
  })
352
378
 
379
+ const foldNestedDialogParentDemoOpen = Update.foldChildStep({
380
+ update: Dialog.open,
381
+ read: (model: UiModel) => Option.some(model.nestedDialogParentDemo),
382
+ write: (model, nextNestedDialogParentDemo) =>
383
+ evo(model, { nestedDialogParentDemo: () => nextNestedDialogParentDemo }),
384
+ toParentMessage: message =>
385
+ UiMessage.GotNestedDialogParentDemoMessage({ message }),
386
+ foldOutMessage: foldDialogOutMessage,
387
+ })
388
+
353
389
  const foldNestedDialogChildDemo = Update.foldChild({
354
390
  update: Dialog.update,
355
391
  read: (model: UiModel) => Option.some(model.nestedDialogChildDemo),
@@ -360,18 +396,27 @@ const foldNestedDialogChildDemo = Update.foldChild({
360
396
  foldOutMessage: foldDialogOutMessage,
361
397
  })
362
398
 
399
+ const foldNestedDialogChildDemoOpen = Update.foldChildStep({
400
+ update: Dialog.open,
401
+ read: (model: UiModel) => Option.some(model.nestedDialogChildDemo),
402
+ write: (model, nextNestedDialogChildDemo) =>
403
+ evo(model, { nestedDialogChildDemo: () => nextNestedDialogChildDemo }),
404
+ toParentMessage: message =>
405
+ UiMessage.GotNestedDialogChildDemoMessage({ message }),
406
+ foldOutMessage: foldDialogOutMessage,
407
+ })
408
+
363
409
  const foldCalendarBasicDemoOutMessage = M.type<Calendar.OutMessage>().pipe(
364
410
  M.withReturnType<Update.Step<UiModel, UiMessage>>(),
365
411
  M.tagsExhaustive({
366
412
  SelectedDate:
367
413
  ({ date }) =>
368
- model => [
369
- evo(model, {
414
+ model => ({
415
+ model: evo(model, {
370
416
  maybeCalendarBasicDemoSelectedDate: () => Option.some(date),
371
417
  }),
372
- [],
373
- ],
374
- ChangedViewMonth: () => model => [model, []],
418
+ }),
419
+ ChangedViewMonth: () => model => ({ model }),
375
420
  }),
376
421
  )
377
422
 
@@ -390,19 +435,17 @@ const foldDatePickerBasicDemoOutMessage = M.type<DatePicker.OutMessage>().pipe(
390
435
  M.tagsExhaustive({
391
436
  SelectedDate:
392
437
  ({ date }) =>
393
- model => [
394
- evo(model, {
438
+ model => ({
439
+ model: evo(model, {
395
440
  maybeDatePickerBasicDemoSelectedDate: () => Option.some(date),
396
441
  }),
397
- [],
398
- ],
399
- ClearedDate: () => model => [
400
- evo(model, {
442
+ }),
443
+ ClearedDate: () => model => ({
444
+ model: evo(model, {
401
445
  maybeDatePickerBasicDemoSelectedDate: () => Option.none(),
402
446
  }),
403
- [],
404
- ],
405
- ChangedViewMonth: () => model => [model, []],
447
+ }),
448
+ ChangedViewMonth: () => model => ({ model }),
406
449
  }),
407
450
  )
408
451
 
@@ -421,8 +464,8 @@ const foldDragAndDropDemoOutMessage = M.type<DragAndDrop.OutMessage>().pipe(
421
464
  M.tagsExhaustive({
422
465
  Reordered:
423
466
  ({ itemId, fromContainerId, toContainerId, toIndex }) =>
424
- model => [
425
- evo(model, {
467
+ model => ({
468
+ model: evo(model, {
426
469
  dragAndDropDemoColumns: () =>
427
470
  reorderColumns(
428
471
  model.dragAndDropDemoColumns,
@@ -432,9 +475,8 @@ const foldDragAndDropDemoOutMessage = M.type<DragAndDrop.OutMessage>().pipe(
432
475
  toIndex,
433
476
  ),
434
477
  }),
435
- [],
436
- ],
437
- Cancelled: () => model => [model, []],
478
+ }),
479
+ Cancelled: () => model => ({ model }),
438
480
  }),
439
481
  )
440
482
 
@@ -452,16 +494,15 @@ const foldFileDropBasicDemoOutMessage = M.type<FileDrop.OutMessage>().pipe(
452
494
  M.tagsExhaustive({
453
495
  ReceivedFiles:
454
496
  ({ files }) =>
455
- model => [
456
- evo(model, {
497
+ model => ({
498
+ model: evo(model, {
457
499
  fileDropBasicDemoFiles: () => [
458
500
  ...model.fileDropBasicDemoFiles,
459
501
  ...files,
460
502
  ],
461
503
  }),
462
- [],
463
- ],
464
- RejectedNonFiles: () => model => [model, []],
504
+ }),
505
+ RejectedNonFiles: () => model => ({ model }),
465
506
  }),
466
507
  )
467
508
 
@@ -482,12 +523,11 @@ const foldListboxDemoOutMessage = M.type<
482
523
  M.tagsExhaustive({
483
524
  Selected:
484
525
  ({ value }) =>
485
- model => [
486
- evo(model, {
526
+ model => ({
527
+ model: evo(model, {
487
528
  maybeListboxDemoSelectedItem: () => Option.some(value),
488
529
  }),
489
- [],
490
- ],
530
+ }),
491
531
  }),
492
532
  )
493
533
 
@@ -509,8 +549,8 @@ const foldListboxMultiDemoOutMessage: (
509
549
  M.tagsExhaustive({
510
550
  Selected:
511
551
  ({ value }) =>
512
- model => [
513
- evo(model, {
552
+ model => ({
553
+ model: evo(model, {
514
554
  listboxMultiDemoSelectedItems: () =>
515
555
  Array.contains(model.listboxMultiDemoSelectedItems, value)
516
556
  ? Array.filter(
@@ -519,8 +559,7 @@ const foldListboxMultiDemoOutMessage: (
519
559
  )
520
560
  : Array.append(model.listboxMultiDemoSelectedItems, value),
521
561
  }),
522
- [],
523
- ],
562
+ }),
524
563
  }),
525
564
  )
526
565
 
@@ -538,12 +577,11 @@ const foldListboxGroupedDemoOutMessage = M.type<Listbox.OutMessage>().pipe(
538
577
  M.tagsExhaustive({
539
578
  Selected:
540
579
  ({ value }) =>
541
- model => [
542
- evo(model, {
580
+ model => ({
581
+ model: evo(model, {
543
582
  maybeListboxGroupedDemoSelectedItem: () => Option.some(value),
544
583
  }),
545
- [],
546
- ],
584
+ }),
547
585
  }),
548
586
  )
549
587
 
@@ -621,10 +659,11 @@ const foldVerticalRadioGroupDemoOutMessage = M.type<
621
659
  M.tagsExhaustive({
622
660
  Selected:
623
661
  ({ value }) =>
624
- model => [
625
- evo(model, { verticalRadioGroupDemoValue: () => Option.some(value) }),
626
- [],
627
- ],
662
+ model => ({
663
+ model: evo(model, {
664
+ verticalRadioGroupDemoValue: () => Option.some(value),
665
+ }),
666
+ }),
628
667
  }),
629
668
  )
630
669
 
@@ -645,10 +684,11 @@ const foldHorizontalRadioGroupDemoOutMessage = M.type<
645
684
  M.tagsExhaustive({
646
685
  Selected:
647
686
  ({ value }) =>
648
- model => [
649
- evo(model, { horizontalRadioGroupDemoValue: () => Option.some(value) }),
650
- [],
651
- ],
687
+ model => ({
688
+ model: evo(model, {
689
+ horizontalRadioGroupDemoValue: () => Option.some(value),
690
+ }),
691
+ }),
652
692
  }),
653
693
  )
654
694
 
@@ -669,7 +709,7 @@ const foldSliderRatingDemoOutMessage = M.type<Slider.OutMessage>().pipe(
669
709
  M.tagsExhaustive({
670
710
  ChangedValue:
671
711
  ({ value }) =>
672
- model => [evo(model, { sliderRatingValue: () => value }), []],
712
+ model => ({ model: evo(model, { sliderRatingValue: () => value }) }),
673
713
  }),
674
714
  )
675
715
 
@@ -687,7 +727,7 @@ const foldSliderVolumeDemoOutMessage = M.type<Slider.OutMessage>().pipe(
687
727
  M.tagsExhaustive({
688
728
  ChangedValue:
689
729
  ({ value }) =>
690
- model => [evo(model, { sliderVolumeValue: () => value }), []],
730
+ model => ({ model: evo(model, { sliderVolumeValue: () => value }) }),
691
731
  }),
692
732
  )
693
733
 
@@ -707,7 +747,7 @@ const foldHorizontalTabsDemoOutMessage = M.type<
707
747
  M.tagsExhaustive({
708
748
  Selected:
709
749
  ({ value }) =>
710
- model => [evo(model, { horizontalTabsDemoTab: () => value }), []],
750
+ model => ({ model: evo(model, { horizontalTabsDemoTab: () => value }) }),
711
751
  }),
712
752
  )
713
753
 
@@ -726,7 +766,7 @@ const foldVerticalTabsDemoOutMessage = M.type<Tabs.OutMessage<DemoTab>>().pipe(
726
766
  M.tagsExhaustive({
727
767
  Selected:
728
768
  ({ value }) =>
729
- model => [evo(model, { verticalTabsDemoTab: () => value }), []],
769
+ model => ({ model: evo(model, { verticalTabsDemoTab: () => value }) }),
730
770
  }),
731
771
  )
732
772
 
@@ -748,6 +788,24 @@ const foldToastDemo = Update.foldChild({
748
788
  foldOutMessage: foldToastOutMessage,
749
789
  })
750
790
 
791
+ const foldToastDemoShow = Update.foldChild({
792
+ update: Toast.show,
793
+ read: (model: UiModel) => Option.some(model.toastDemo),
794
+ write: (model, nextToastDemo) =>
795
+ evo(model, { toastDemo: () => nextToastDemo }),
796
+ toParentMessage: message => UiMessage.GotToastDemoMessage({ message }),
797
+ foldOutMessage: foldToastOutMessage,
798
+ })
799
+
800
+ const foldToastDemoDismissAll = Update.foldChildStep({
801
+ update: Toast.dismissAll,
802
+ read: (model: UiModel) => Option.some(model.toastDemo),
803
+ write: (model, nextToastDemo) =>
804
+ evo(model, { toastDemo: () => nextToastDemo }),
805
+ toParentMessage: message => UiMessage.GotToastDemoMessage({ message }),
806
+ foldOutMessage: foldToastOutMessage,
807
+ })
808
+
751
809
  const foldTooltipBasicDemo = Update.foldChild({
752
810
  update: Tooltip.update,
753
811
  read: (model: UiModel) => Option.some(model.tooltipBasicDemo),
@@ -772,11 +830,13 @@ const foldAnimationDemoOutMessage: (
772
830
  context: Update.FoldContext<Animation.Message, UiMessage>,
773
831
  ) => Update.Step<UiModel, UiMessage> = (outMessage, { liftCommand }) =>
774
832
  Animation.OutMessage.match<Update.Step<UiModel, UiMessage>>(outMessage, {
775
- StartedLeaveAnimating: () => model => [
833
+ StartedLeaveAnimating: () => model => ({
776
834
  model,
777
- [liftCommand(Animation.defaultLeaveCommand(model.animationDemo))],
778
- ],
779
- TransitionedOut: () => model => [model, []],
835
+ commands: [
836
+ liftCommand(Animation.defaultLeaveCommand(model.animationDemo)),
837
+ ],
838
+ }),
839
+ TransitionedOut: () => model => ({ model }),
780
840
  })
781
841
 
782
842
  const foldAnimationDemo = Update.foldChild({
@@ -796,6 +856,14 @@ const foldVirtualListDemo = Update.foldChild({
796
856
  toParentMessage: message => UiMessage.GotVirtualListDemoMessage({ message }),
797
857
  })
798
858
 
859
+ const foldVirtualListDemoScrollToIndex = Update.foldChild({
860
+ update: VirtualList.scrollToIndex,
861
+ read: (model: UiModel) => Option.some(model.virtualListDemo),
862
+ write: (model, nextVirtualListDemo) =>
863
+ evo(model, { virtualListDemo: () => nextVirtualListDemo }),
864
+ toParentMessage: message => UiMessage.GotVirtualListDemoMessage({ message }),
865
+ })
866
+
799
867
  const foldVirtualListVariableDemo = Update.foldChild({
800
868
  update: VirtualList.update,
801
869
  read: (model: UiModel) => Option.some(model.virtualListVariableDemo),
@@ -805,93 +873,84 @@ const foldVirtualListVariableDemo = Update.foldChild({
805
873
  UiMessage.GotVirtualListVariableDemoMessage({ message }),
806
874
  })
807
875
 
808
- export const uiUpdate = (model: UiModel, message: UiMessage): UiUpdateReturn =>
809
- UiMessage.match<UiUpdateReturn>(message, {
810
- ClickedOpenMobileMenu: () => {
811
- const [nextMobileMenuDialog, mobileMenuDialogCommands] = Dialog.open(
812
- model.mobileMenuDialog,
813
- )
876
+ const foldVirtualListVariableDemoScrollToIndex = Update.foldChild({
877
+ update: (virtualList: VirtualList.Model, index: number) =>
878
+ VirtualList.scrollToIndexVariable(
879
+ virtualList,
880
+ variableActivities,
881
+ variableRowHeightPx,
882
+ index,
883
+ ),
884
+ read: (model: UiModel) => Option.some(model.virtualListVariableDemo),
885
+ write: (model, nextVirtualListVariableDemo) =>
886
+ evo(model, { virtualListVariableDemo: () => nextVirtualListVariableDemo }),
887
+ toParentMessage: message =>
888
+ UiMessage.GotVirtualListVariableDemoMessage({ message }),
889
+ })
814
890
 
815
- return [
816
- evo(model, {
817
- mobileMenuDialog: () => nextMobileMenuDialog,
818
- }),
819
- Command.mapMessages(mobileMenuDialogCommands, message =>
820
- UiMessage.GotMobileMenuDialogMessage({ message }),
821
- ),
822
- ]
823
- },
891
+ export const uiUpdate = (model: UiModel, message: UiMessage) =>
892
+ UiMessage.match<Update.Return<UiModel, UiMessage>>(message, {
893
+ ClickedOpenMobileMenu: () => foldMobileMenuDialogOpen(model),
824
894
 
825
895
  GotMobileMenuDialogMessage: ({ message }) =>
826
896
  foldMobileMenuDialog(model, message),
827
897
 
828
- UpdatedInputDemoValue: ({ value }) => [
829
- evo(model, { inputDemoValue: () => value }),
830
- [],
831
- ],
832
-
833
- UpdatedTextareaDemoValue: ({ value }) => [
834
- evo(model, { textareaDemoValue: () => value }),
835
- [],
836
- ],
837
-
838
- UpdatedFieldsetInputValue: ({ value }) => [
839
- evo(model, { fieldsetInputValue: () => value }),
840
- [],
841
- ],
842
-
843
- UpdatedFieldsetTextareaValue: ({ value }) => [
844
- evo(model, { fieldsetTextareaValue: () => value }),
845
- [],
846
- ],
847
-
848
- UpdatedSelectDemoValue: ({ value }) => [
849
- evo(model, { selectDemoValue: () => value }),
850
- [],
851
- ],
852
-
853
- ToggledFieldsetCheckboxDemo: ({ isChecked }) => [
854
- evo(model, {
898
+ UpdatedInputDemoValue: ({ value }) => ({
899
+ model: evo(model, { inputDemoValue: () => value }),
900
+ }),
901
+
902
+ UpdatedTextareaDemoValue: ({ value }) => ({
903
+ model: evo(model, { textareaDemoValue: () => value }),
904
+ }),
905
+
906
+ UpdatedFieldsetInputValue: ({ value }) => ({
907
+ model: evo(model, { fieldsetInputValue: () => value }),
908
+ }),
909
+
910
+ UpdatedFieldsetTextareaValue: ({ value }) => ({
911
+ model: evo(model, { fieldsetTextareaValue: () => value }),
912
+ }),
913
+
914
+ UpdatedSelectDemoValue: ({ value }) => ({
915
+ model: evo(model, { selectDemoValue: () => value }),
916
+ }),
917
+
918
+ ToggledFieldsetCheckboxDemo: ({ isChecked }) => ({
919
+ model: evo(model, {
855
920
  isFieldsetCheckboxDemoChecked: () => isChecked,
856
921
  }),
857
- [],
858
- ],
922
+ }),
859
923
 
860
- ClickedButtonDemo: () => [
861
- evo(model, {
924
+ ClickedButtonDemo: () => ({
925
+ model: evo(model, {
862
926
  buttonClickCount: Number.increment,
863
927
  }),
864
- [],
865
- ],
928
+ }),
866
929
 
867
- ToggledCheckboxBasicDemo: ({ isChecked }) => [
868
- evo(model, {
930
+ ToggledCheckboxBasicDemo: ({ isChecked }) => ({
931
+ model: evo(model, {
869
932
  isCheckboxBasicDemoChecked: () => isChecked,
870
933
  }),
871
- [],
872
- ],
934
+ }),
873
935
 
874
- ToggledCheckboxAllDemo: ({ isChecked }) => [
875
- evo(model, {
936
+ ToggledCheckboxAllDemo: ({ isChecked }) => ({
937
+ model: evo(model, {
876
938
  isCheckboxOptionADemoChecked: () => isChecked,
877
939
  isCheckboxOptionBDemoChecked: () => isChecked,
878
940
  }),
879
- [],
880
- ],
941
+ }),
881
942
 
882
- ToggledCheckboxOptionADemo: ({ isChecked }) => [
883
- evo(model, {
943
+ ToggledCheckboxOptionADemo: ({ isChecked }) => ({
944
+ model: evo(model, {
884
945
  isCheckboxOptionADemoChecked: () => isChecked,
885
946
  }),
886
- [],
887
- ],
947
+ }),
888
948
 
889
- ToggledCheckboxOptionBDemo: ({ isChecked }) => [
890
- evo(model, {
949
+ ToggledCheckboxOptionBDemo: ({ isChecked }) => ({
950
+ model: evo(model, {
891
951
  isCheckboxOptionBDemoChecked: () => isChecked,
892
952
  }),
893
- [],
894
- ],
953
+ }),
895
954
 
896
955
  GotComboboxDemoMessage: ({ message }) => foldComboboxDemo(model, message),
897
956
 
@@ -924,84 +983,27 @@ export const uiUpdate = (model: UiModel, message: UiMessage): UiUpdateReturn =>
924
983
  GotNestedDialogChildDemoMessage: ({ message }) =>
925
984
  foldNestedDialogChildDemo(model, message),
926
985
 
927
- ClickedDeleteProject: () => {
928
- const [nextNestedDialogChildDemo, nestedDialogChildCommands] =
929
- Dialog.open(model.nestedDialogChildDemo)
930
-
931
- return [
932
- evo(model, {
933
- nestedDialogChildDemo: () => nextNestedDialogChildDemo,
934
- }),
935
- Command.mapMessages(nestedDialogChildCommands, message =>
936
- UiMessage.GotNestedDialogChildDemoMessage({ message }),
937
- ),
938
- ]
939
- },
940
-
941
- ClickedOpenDialog: () => {
942
- const [nextDialogDemo, dialogCommands] = Dialog.open(model.dialogDemo)
943
-
944
- return [
945
- evo(model, { dialogDemo: () => nextDialogDemo }),
946
- Command.mapMessages(dialogCommands, message =>
947
- UiMessage.GotDialogDemoMessage({ message }),
948
- ),
949
- ]
950
- },
951
-
952
- ClickedOpenAnimatedDialog: () => {
953
- const [nextDialogAnimatedDemo, dialogAnimatedCommands] = Dialog.open(
954
- model.dialogAnimatedDemo,
955
- )
956
-
957
- return [
958
- evo(model, { dialogAnimatedDemo: () => nextDialogAnimatedDemo }),
959
- Command.mapMessages(dialogAnimatedCommands, message =>
960
- UiMessage.GotDialogAnimatedDemoMessage({ message }),
961
- ),
962
- ]
963
- },
986
+ ClickedDeleteProject: () => foldNestedDialogChildDemoOpen(model),
964
987
 
965
- ClickedEditFilters: () => {
966
- const [nextOverlayDialogDemo, overlayDialogCommands] = Dialog.open(
967
- model.overlayDialogDemo,
968
- )
988
+ ClickedOpenDialog: () => foldDialogDemoOpen(model),
969
989
 
970
- return [
971
- evo(model, { overlayDialogDemo: () => nextOverlayDialogDemo }),
972
- Command.mapMessages(overlayDialogCommands, message =>
973
- UiMessage.GotOverlayDialogDemoMessage({ message }),
974
- ),
975
- ]
976
- },
990
+ ClickedOpenAnimatedDialog: () => foldDialogAnimatedDemoOpen(model),
977
991
 
978
- ClickedOpenProjectSettings: () => {
979
- const [nextNestedDialogParentDemo, nestedDialogParentCommands] =
980
- Dialog.open(model.nestedDialogParentDemo)
992
+ ClickedEditFilters: () => foldOverlayDialogDemoOpen(model),
981
993
 
982
- return [
983
- evo(model, {
984
- nestedDialogParentDemo: () => nextNestedDialogParentDemo,
985
- }),
986
- Command.mapMessages(nestedDialogParentCommands, message =>
987
- UiMessage.GotNestedDialogParentDemoMessage({ message }),
988
- ),
989
- ]
990
- },
994
+ ClickedOpenProjectSettings: () => foldNestedDialogParentDemoOpen(model),
991
995
 
992
- ToggledDisclosureBasicDemo: ({ isOpen }) => [
993
- evo(model, {
996
+ ToggledDisclosureBasicDemo: ({ isOpen }) => ({
997
+ model: evo(model, {
994
998
  isDisclosureBasicDemoOpen: () => isOpen,
995
999
  }),
996
- [],
997
- ],
1000
+ }),
998
1001
 
999
- ToggledDisclosureAnimatedDemo: ({ isOpen }) => [
1000
- evo(model, {
1002
+ ToggledDisclosureAnimatedDemo: ({ isOpen }) => ({
1003
+ model: evo(model, {
1001
1004
  isDisclosureAnimatedDemoOpen: () => isOpen,
1002
1005
  }),
1003
- [],
1004
- ],
1006
+ }),
1005
1007
 
1006
1008
  GotCalendarBasicDemoMessage: ({ message }) =>
1007
1009
  foldCalendarBasicDemo(model, message),
@@ -1015,13 +1017,12 @@ export const uiUpdate = (model: UiModel, message: UiMessage): UiUpdateReturn =>
1015
1017
  GotFileDropBasicDemoMessage: ({ message }) =>
1016
1018
  foldFileDropBasicDemo(model, message),
1017
1019
 
1018
- ClickedRemoveFileDropDemoFile: ({ fileIndex }) => [
1019
- evo(model, {
1020
+ ClickedRemoveFileDropDemoFile: ({ fileIndex }) => ({
1021
+ model: evo(model, {
1020
1022
  fileDropBasicDemoFiles: () =>
1021
1023
  Array.remove(model.fileDropBasicDemoFiles, fileIndex),
1022
1024
  }),
1023
- [],
1024
- ],
1025
+ }),
1025
1026
 
1026
1027
  GotListboxDemoMessage: ({ message }) => foldListboxDemo(model, message),
1027
1028
 
@@ -1060,12 +1061,11 @@ export const uiUpdate = (model: UiModel, message: UiMessage): UiUpdateReturn =>
1060
1061
  GotSliderVolumeDemoMessage: ({ message }) =>
1061
1062
  foldSliderVolumeDemo(model, message),
1062
1063
 
1063
- ToggledSwitchDemo: ({ isChecked }) => [
1064
- evo(model, {
1064
+ ToggledSwitchDemo: ({ isChecked }) => ({
1065
+ model: evo(model, {
1065
1066
  isSwitchDemoChecked: () => isChecked,
1066
1067
  }),
1067
- [],
1068
- ],
1068
+ }),
1069
1069
 
1070
1070
  GotHorizontalTabsDemoMessage: ({ message }) =>
1071
1071
  foldHorizontalTabsDemo(model, message),
@@ -1075,42 +1075,26 @@ export const uiUpdate = (model: UiModel, message: UiMessage): UiUpdateReturn =>
1075
1075
 
1076
1076
  GotToastDemoMessage: ({ message }) => foldToastDemo(model, message),
1077
1077
 
1078
- ClickedShowInfoToast: () => {
1079
- const [nextToastDemo, toastCommands] = Toast.show(model.toastDemo, {
1078
+ ClickedShowInfoToast: () =>
1079
+ foldToastDemoShow(model, {
1080
1080
  variant: 'Info',
1081
1081
  payload: {
1082
1082
  title: 'Changes saved',
1083
1083
  maybeDescription: Option.some('Your preferences have been updated.'),
1084
1084
  },
1085
- })
1086
-
1087
- return [
1088
- evo(model, { toastDemo: () => nextToastDemo }),
1089
- Command.mapMessages(toastCommands, message =>
1090
- UiMessage.GotToastDemoMessage({ message }),
1091
- ),
1092
- ]
1093
- },
1085
+ }),
1094
1086
 
1095
- ClickedShowSuccessToast: () => {
1096
- const [nextToastDemo, toastCommands] = Toast.show(model.toastDemo, {
1087
+ ClickedShowSuccessToast: () =>
1088
+ foldToastDemoShow(model, {
1097
1089
  variant: 'Success',
1098
1090
  payload: {
1099
1091
  title: 'Uploaded successfully',
1100
1092
  maybeDescription: Option.some('kit-manual.pdf is now available.'),
1101
1093
  },
1102
- })
1103
-
1104
- return [
1105
- evo(model, { toastDemo: () => nextToastDemo }),
1106
- Command.mapMessages(toastCommands, message =>
1107
- UiMessage.GotToastDemoMessage({ message }),
1108
- ),
1109
- ]
1110
- },
1094
+ }),
1111
1095
 
1112
- ClickedShowWarningToast: () => {
1113
- const [nextToastDemo, toastCommands] = Toast.show(model.toastDemo, {
1096
+ ClickedShowWarningToast: () =>
1097
+ foldToastDemoShow(model, {
1114
1098
  variant: 'Warning',
1115
1099
  payload: {
1116
1100
  title: 'Network slow',
@@ -1118,35 +1102,19 @@ export const uiUpdate = (model: UiModel, message: UiMessage): UiUpdateReturn =>
1118
1102
  'Some assets are loading over a weak connection.',
1119
1103
  ),
1120
1104
  },
1121
- })
1122
-
1123
- return [
1124
- evo(model, { toastDemo: () => nextToastDemo }),
1125
- Command.mapMessages(toastCommands, message =>
1126
- UiMessage.GotToastDemoMessage({ message }),
1127
- ),
1128
- ]
1129
- },
1105
+ }),
1130
1106
 
1131
- ClickedShowErrorToast: () => {
1132
- const [nextToastDemo, toastCommands] = Toast.show(model.toastDemo, {
1107
+ ClickedShowErrorToast: () =>
1108
+ foldToastDemoShow(model, {
1133
1109
  variant: 'Error',
1134
1110
  payload: {
1135
1111
  title: 'Failed to save',
1136
1112
  maybeDescription: Option.some('Check your connection and try again.'),
1137
1113
  },
1138
- })
1139
-
1140
- return [
1141
- evo(model, { toastDemo: () => nextToastDemo }),
1142
- Command.mapMessages(toastCommands, message =>
1143
- UiMessage.GotToastDemoMessage({ message }),
1144
- ),
1145
- ]
1146
- },
1114
+ }),
1147
1115
 
1148
- ClickedShowStickyToast: () => {
1149
- const [nextToastDemo, toastCommands] = Toast.show(model.toastDemo, {
1116
+ ClickedShowStickyToast: () =>
1117
+ foldToastDemoShow(model, {
1150
1118
  variant: 'Info',
1151
1119
  payload: {
1152
1120
  title: 'Review pending',
@@ -1155,26 +1123,9 @@ export const uiUpdate = (model: UiModel, message: UiMessage): UiUpdateReturn =>
1155
1123
  ),
1156
1124
  },
1157
1125
  sticky: true,
1158
- })
1159
-
1160
- return [
1161
- evo(model, { toastDemo: () => nextToastDemo }),
1162
- Command.mapMessages(toastCommands, message =>
1163
- UiMessage.GotToastDemoMessage({ message }),
1164
- ),
1165
- ]
1166
- },
1167
-
1168
- ClickedDismissAllToasts: () => {
1169
- const [nextToastDemo, toastCommands] = Toast.dismissAll(model.toastDemo)
1126
+ }),
1170
1127
 
1171
- return [
1172
- evo(model, { toastDemo: () => nextToastDemo }),
1173
- Command.mapMessages(toastCommands, message =>
1174
- UiMessage.GotToastDemoMessage({ message }),
1175
- ),
1176
- ]
1177
- },
1128
+ ClickedDismissAllToasts: () => foldToastDemoDismissAll(model),
1178
1129
 
1179
1130
  GotTooltipBasicDemoMessage: ({ message }) =>
1180
1131
  foldTooltipBasicDemo(model, message),
@@ -1195,40 +1146,18 @@ export const uiUpdate = (model: UiModel, message: UiMessage): UiUpdateReturn =>
1195
1146
  GotVirtualListDemoMessage: ({ message }) =>
1196
1147
  foldVirtualListDemo(model, message),
1197
1148
 
1198
- ClickedVirtualListScrollToMiddle: () => {
1199
- const [nextVirtualListDemo, virtualListCommands] =
1200
- VirtualList.scrollToIndex(
1201
- model.virtualListDemo,
1202
- Math.floor(VIRTUAL_LIST_ROW_COUNT / 2),
1203
- )
1204
-
1205
- return [
1206
- evo(model, { virtualListDemo: () => nextVirtualListDemo }),
1207
- Command.mapMessages(virtualListCommands, message =>
1208
- UiMessage.GotVirtualListDemoMessage({ message }),
1209
- ),
1210
- ]
1211
- },
1149
+ ClickedVirtualListScrollToMiddle: () =>
1150
+ foldVirtualListDemoScrollToIndex(
1151
+ model,
1152
+ Math.floor(VIRTUAL_LIST_ROW_COUNT / 2),
1153
+ ),
1212
1154
 
1213
1155
  GotVirtualListVariableDemoMessage: ({ message }) =>
1214
1156
  foldVirtualListVariableDemo(model, message),
1215
1157
 
1216
- ClickedVirtualListVariableScrollToMiddle: () => {
1217
- const [nextVirtualListVariableDemo, virtualListCommands] =
1218
- VirtualList.scrollToIndexVariable(
1219
- model.virtualListVariableDemo,
1220
- variableActivities,
1221
- variableRowHeightPx,
1222
- Math.floor(VIRTUAL_LIST_ROW_COUNT / 2),
1223
- )
1224
-
1225
- return [
1226
- evo(model, {
1227
- virtualListVariableDemo: () => nextVirtualListVariableDemo,
1228
- }),
1229
- Command.mapMessages(virtualListCommands, message =>
1230
- UiMessage.GotVirtualListVariableDemoMessage({ message }),
1231
- ),
1232
- ]
1233
- },
1158
+ ClickedVirtualListVariableScrollToMiddle: () =>
1159
+ foldVirtualListVariableDemoScrollToIndex(
1160
+ model,
1161
+ Math.floor(VIRTUAL_LIST_ROW_COUNT / 2),
1162
+ ),
1234
1163
  })