create-foldkit-app 0.32.0 → 0.32.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.
- package/dist/commands/create.js +9 -7
- package/dist/templates/base/FOLDKIT.md +22 -6
- package/dist/templates/examples/api-cache/src/data.ts +14 -14
- package/dist/templates/examples/api-cache/src/main.ts +42 -39
- package/dist/templates/examples/auth/src/command.ts +3 -3
- package/dist/templates/examples/auth/src/domain/session.ts +8 -6
- package/dist/templates/examples/auth/src/main.ts +11 -11
- package/dist/templates/examples/auth/src/message.ts +3 -3
- package/dist/templates/examples/auth/src/model.ts +2 -2
- package/dist/templates/examples/auth/src/page/loggedIn/index.ts +1 -1
- package/dist/templates/examples/auth/src/page/loggedIn/view.ts +3 -3
- package/dist/templates/examples/auth/src/page/loggedOut/index.ts +1 -1
- package/dist/templates/examples/auth/src/page/loggedOut/page/login.ts +9 -17
- package/dist/templates/examples/auth/src/page/loggedOut/update.ts +4 -6
- package/dist/templates/examples/auth/src/page/loggedOut/view.ts +3 -3
- package/dist/templates/examples/auth/src/route.ts +2 -2
- package/dist/templates/examples/auth/src/update.ts +37 -40
- package/dist/templates/examples/auth/src/view.ts +6 -6
- package/dist/templates/examples/canvas-art/src/main.ts +22 -30
- package/dist/templates/examples/charting/src/command.ts +3 -3
- package/dist/templates/examples/charting/src/domain.ts +53 -48
- package/dist/templates/examples/charting/src/echarts.ts +6 -6
- package/dist/templates/examples/charting/src/githubApi.ts +33 -34
- package/dist/templates/examples/charting/src/http.ts +7 -7
- package/dist/templates/examples/charting/src/message.ts +6 -6
- package/dist/templates/examples/charting/src/model.ts +6 -6
- package/dist/templates/examples/charting/src/npmApi.ts +19 -15
- package/dist/templates/examples/charting/src/subscription.ts +5 -5
- package/dist/templates/examples/charting/src/telemetry.test.ts +18 -12
- package/dist/templates/examples/charting/src/telemetry.ts +11 -18
- package/dist/templates/examples/charting/src/update.ts +17 -23
- package/dist/templates/examples/charting/src/view/chart.ts +2 -2
- package/dist/templates/examples/counter/src/main.ts +2 -2
- package/dist/templates/examples/counters/src/counter.ts +2 -2
- package/dist/templates/examples/counters/src/main.ts +8 -8
- package/dist/templates/examples/embedding/src/main.ts +10 -7
- package/dist/templates/examples/form/src/main.ts +18 -14
- package/dist/templates/examples/generative-art/src/command.ts +7 -2
- package/dist/templates/examples/generative-art/src/message.ts +14 -14
- package/dist/templates/examples/generative-art/src/model.ts +21 -21
- package/dist/templates/examples/generative-art/src/update.ts +15 -17
- package/dist/templates/examples/interrupting-commands/src/main.ts +30 -27
- package/dist/templates/examples/job-application/src/domain/proficiencyLevel.ts +2 -2
- package/dist/templates/examples/job-application/src/domain/pronounOption.ts +2 -2
- package/dist/templates/examples/job-application/src/domain/step.ts +11 -11
- package/dist/templates/examples/job-application/src/main.ts +5 -5
- package/dist/templates/examples/job-application/src/message.ts +2 -2
- package/dist/templates/examples/job-application/src/model.ts +5 -5
- package/dist/templates/examples/job-application/src/step/attachments.ts +32 -34
- package/dist/templates/examples/job-application/src/step/coverLetter.ts +4 -4
- package/dist/templates/examples/job-application/src/step/education/education.ts +11 -14
- package/dist/templates/examples/job-application/src/step/education/entry.ts +21 -22
- package/dist/templates/examples/job-application/src/step/personalInfo.ts +44 -54
- package/dist/templates/examples/job-application/src/step/skills/entry.ts +12 -14
- package/dist/templates/examples/job-application/src/step/skills/skills.ts +11 -14
- package/dist/templates/examples/job-application/src/step/workHistory/entry.ts +43 -45
- package/dist/templates/examples/job-application/src/step/workHistory/workHistory.ts +11 -14
- package/dist/templates/examples/job-application/src/update.ts +17 -17
- package/dist/templates/examples/job-application/src/view/attachments.ts +5 -5
- package/dist/templates/examples/job-application/src/view/datePicker.ts +3 -3
- package/dist/templates/examples/job-application/src/view/field.ts +5 -5
- package/dist/templates/examples/job-application/src/view/index.ts +28 -22
- package/dist/templates/examples/kanban/src/command.ts +4 -4
- package/dist/templates/examples/kanban/src/domain/card.ts +6 -6
- package/dist/templates/examples/kanban/src/domain/column.ts +9 -9
- package/dist/templates/examples/kanban/src/main.ts +4 -4
- package/dist/templates/examples/kanban/src/message.ts +6 -6
- package/dist/templates/examples/kanban/src/model.ts +11 -9
- package/dist/templates/examples/kanban/src/update.ts +5 -5
- package/dist/templates/examples/managed-resource-layer/src/main.ts +20 -20
- package/dist/templates/examples/map/src/locations.ts +7 -7
- package/dist/templates/examples/map/src/main.ts +83 -44
- package/dist/templates/examples/map/src/mount.test.ts +127 -0
- package/dist/templates/examples/pixel-art/src/command.ts +12 -5
- package/dist/templates/examples/pixel-art/src/main.ts +4 -4
- package/dist/templates/examples/pixel-art/src/message.ts +7 -7
- package/dist/templates/examples/pixel-art/src/model.ts +34 -29
- package/dist/templates/examples/pixel-art/src/subscription.ts +2 -2
- package/dist/templates/examples/pixel-art/src/update.ts +79 -86
- package/dist/templates/examples/query-sync/src/main.ts +106 -102
- package/dist/templates/examples/route-transitions/src/data.ts +6 -6
- package/dist/templates/examples/route-transitions/src/main.ts +23 -29
- package/dist/templates/examples/route-transitions/src/route.ts +3 -3
- package/dist/templates/examples/routing/src/fileTree.ts +10 -8
- package/dist/templates/examples/routing/src/main.ts +23 -21
- package/dist/templates/examples/routing/src/page/people.ts +14 -22
- package/dist/templates/examples/routing/src/route.ts +7 -7
- package/dist/templates/examples/shopping-cart/src/main.ts +30 -31
- package/dist/templates/examples/shopping-cart/src/page/products.ts +10 -10
- package/dist/templates/examples/shopping-cart/src/route.ts +6 -4
- package/dist/templates/examples/slow-warnings/src/main.ts +35 -43
- package/dist/templates/examples/snake/src/domain/snake.ts +2 -2
- package/dist/templates/examples/snake/src/main.ts +39 -47
- package/dist/templates/examples/ssg/src/main.ts +5 -5
- package/dist/templates/examples/ssg/src/route.ts +2 -2
- package/dist/templates/examples/ssr/src/cookie.ts +3 -3
- package/dist/templates/examples/ssr/src/main.ts +10 -10
- package/dist/templates/examples/state-machine/src/main.ts +55 -53
- package/dist/templates/examples/state-machine/src/view.ts +7 -7
- package/dist/templates/examples/stopwatch/src/main.ts +10 -10
- package/dist/templates/examples/todo/src/main.ts +41 -34
- package/dist/templates/examples/ui-showcase/src/main.ts +54 -42
- package/dist/templates/examples/ui-showcase/src/scene.test.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/init.ts +1 -2
- package/dist/templates/examples/ui-showcase/src/ui/message.ts +17 -18
- package/dist/templates/examples/ui-showcase/src/ui/model.ts +47 -44
- package/dist/templates/examples/ui-showcase/src/ui/subscriptions.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/toast.ts +4 -4
- package/dist/templates/examples/ui-showcase/src/ui/update.ts +287 -298
- package/dist/templates/examples/ui-showcase/src/ui/view/animation.ts +2 -2
- package/dist/templates/examples/ui-showcase/src/ui/view/button.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/calendar.ts +4 -4
- package/dist/templates/examples/ui-showcase/src/ui/view/checkbox.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/combobox.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/datePicker.ts +4 -4
- package/dist/templates/examples/ui-showcase/src/ui/view/dialog.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/disclosure.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/dragAndDrop.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/fieldset.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/fileDrop.ts +6 -6
- package/dist/templates/examples/ui-showcase/src/ui/view/hoverIntent.ts +9 -20
- package/dist/templates/examples/ui-showcase/src/ui/view/input.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/listbox.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/menu.ts +15 -15
- package/dist/templates/examples/ui-showcase/src/ui/view/popover.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/radioGroup.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/select.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/slider.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/switch.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/tabs.ts +7 -7
- package/dist/templates/examples/ui-showcase/src/ui/view/textarea.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/toast.ts +8 -8
- package/dist/templates/examples/ui-showcase/src/ui/view/tooltip.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/virtualList.ts +7 -7
- package/dist/templates/examples/view-transitions/src/artwork.ts +7 -7
- package/dist/templates/examples/view-transitions/src/main.ts +6 -6
- package/dist/templates/examples/view-transitions/src/route.ts +3 -3
- package/dist/templates/examples/weather/src/main.ts +42 -42
- package/dist/templates/examples/weather/src/story.test.ts +5 -5
- package/dist/templates/examples/web-components/src/main.ts +16 -16
- package/dist/templates/examples/websocket-chat/src/main.ts +30 -30
- package/dist/templates/release.json +13 -13
- package/dist/templates/rendering/ssg/src/main.ts +5 -5
- package/dist/templates/rendering/ssg/src/route.ts +2 -2
- package/dist/templates/rendering/ssr/server/main.ts +15 -15
- package/dist/templates/rendering/ssr/src/cookie.ts +3 -3
- package/dist/templates/rendering/ssr/src/main.ts +10 -10
- package/dist/utils/packages.js +17 -0
- package/package.json +1 -1
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Array,
|
|
3
|
-
Duration,
|
|
4
|
-
Effect,
|
|
5
|
-
Match as M,
|
|
6
|
-
Number,
|
|
7
|
-
Option,
|
|
8
|
-
Schema as S,
|
|
9
|
-
} from 'effect'
|
|
1
|
+
import { Array, Duration, Effect, Match, Number, Option, Schema } from 'effect'
|
|
10
2
|
import { Command, Update } from 'foldkit'
|
|
11
3
|
import { CalendarDate } from 'foldkit/calendar'
|
|
12
4
|
import {
|
|
@@ -32,35 +24,35 @@ import { revealFieldErrors } from './validation'
|
|
|
32
24
|
|
|
33
25
|
const PronounsListbox = Listbox.create<string>()
|
|
34
26
|
|
|
35
|
-
export const Model =
|
|
36
|
-
firstName: Field(
|
|
37
|
-
lastName: Field(
|
|
38
|
-
email: Field(
|
|
39
|
-
emailValidationId:
|
|
40
|
-
phone: Field(
|
|
27
|
+
export const Model = Schema.Struct({
|
|
28
|
+
firstName: Field(Schema.String),
|
|
29
|
+
lastName: Field(Schema.String),
|
|
30
|
+
email: Field(Schema.String),
|
|
31
|
+
emailValidationId: Schema.Number,
|
|
32
|
+
phone: Field(Schema.String),
|
|
41
33
|
pronouns: Listbox.Model,
|
|
42
|
-
maybeSelectedPronoun:
|
|
43
|
-
customPronouns:
|
|
44
|
-
portfolioUrl: Field(
|
|
34
|
+
maybeSelectedPronoun: Schema.Option(Schema.String),
|
|
35
|
+
customPronouns: Schema.String,
|
|
36
|
+
portfolioUrl: Field(Schema.String),
|
|
45
37
|
availableDate: DatePicker.Model,
|
|
46
|
-
maybeAvailableDate:
|
|
38
|
+
maybeAvailableDate: Schema.Option(CalendarDate),
|
|
47
39
|
})
|
|
48
40
|
export type Model = typeof Model.Type
|
|
49
41
|
|
|
50
42
|
// MESSAGE
|
|
51
43
|
|
|
52
44
|
export const Message = defineMessageUnion({
|
|
53
|
-
UpdatedFirstName: { value:
|
|
54
|
-
UpdatedLastName: { value:
|
|
55
|
-
UpdatedEmail: { value:
|
|
45
|
+
UpdatedFirstName: { value: Schema.String },
|
|
46
|
+
UpdatedLastName: { value: Schema.String },
|
|
47
|
+
UpdatedEmail: { value: Schema.String },
|
|
56
48
|
CompletedValidateEmailAsync: {
|
|
57
|
-
validationId:
|
|
58
|
-
field: Field(
|
|
49
|
+
validationId: Schema.Number,
|
|
50
|
+
field: Field(Schema.String),
|
|
59
51
|
},
|
|
60
|
-
UpdatedPhone: { value:
|
|
52
|
+
UpdatedPhone: { value: Schema.String },
|
|
61
53
|
GotPronounsMessage: { message: Listbox.Message },
|
|
62
|
-
UpdatedCustomPronouns: { value:
|
|
63
|
-
UpdatedPortfolioUrl: { value:
|
|
54
|
+
UpdatedCustomPronouns: { value: Schema.String },
|
|
55
|
+
UpdatedPortfolioUrl: { value: Schema.String },
|
|
64
56
|
GotAvailableDateMessage: { message: DatePicker.Message },
|
|
65
57
|
})
|
|
66
58
|
|
|
@@ -140,7 +132,7 @@ const isEmailTaken = (emailInput: string): Effect.Effect<boolean> =>
|
|
|
140
132
|
})
|
|
141
133
|
|
|
142
134
|
export const ValidateEmailAsync = Command.define('ValidateEmailAsync', {
|
|
143
|
-
args: { emailInput:
|
|
135
|
+
args: { emailInput: Schema.String, validationId: Schema.Number },
|
|
144
136
|
messages: [Message.CompletedValidateEmailAsync],
|
|
145
137
|
execute: ({ emailInput, validationId }) =>
|
|
146
138
|
Effect.gen(function* () {
|
|
@@ -164,16 +156,15 @@ export const ValidateEmailAsync = Command.define('ValidateEmailAsync', {
|
|
|
164
156
|
|
|
165
157
|
type UpdateReturn = Update.Return<Model, Message>
|
|
166
158
|
|
|
167
|
-
const foldPronounsOutMessage =
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
)
|
|
159
|
+
const foldPronounsOutMessage = Listbox.OutMessage.match<
|
|
160
|
+
Update.Step<Model, Message>
|
|
161
|
+
>({
|
|
162
|
+
Selected:
|
|
163
|
+
({ value }) =>
|
|
164
|
+
model => ({
|
|
165
|
+
model: evo(model, { maybeSelectedPronoun: () => Option.some(value) }),
|
|
166
|
+
}),
|
|
167
|
+
})
|
|
177
168
|
|
|
178
169
|
const foldPronouns = Update.foldChild({
|
|
179
170
|
update: PronounsListbox.update,
|
|
@@ -183,20 +174,19 @@ const foldPronouns = Update.foldChild({
|
|
|
183
174
|
foldOutMessage: foldPronounsOutMessage,
|
|
184
175
|
})
|
|
185
176
|
|
|
186
|
-
const foldAvailableDateOutMessage =
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}),
|
|
194
|
-
ClearedDate: () => model => ({
|
|
195
|
-
model: evo(model, { maybeAvailableDate: () => Option.none() }),
|
|
177
|
+
const foldAvailableDateOutMessage = DatePicker.OutMessage.match<
|
|
178
|
+
Update.Step<Model, Message>
|
|
179
|
+
>({
|
|
180
|
+
SelectedDate:
|
|
181
|
+
({ date }) =>
|
|
182
|
+
model => ({
|
|
183
|
+
model: evo(model, { maybeAvailableDate: () => Option.some(date) }),
|
|
196
184
|
}),
|
|
197
|
-
|
|
185
|
+
ClearedDate: () => model => ({
|
|
186
|
+
model: evo(model, { maybeAvailableDate: () => Option.none() }),
|
|
198
187
|
}),
|
|
199
|
-
)
|
|
188
|
+
ChangedViewMonth: () => model => ({ model }),
|
|
189
|
+
})
|
|
200
190
|
|
|
201
191
|
const foldAvailableDate = Update.foldChild({
|
|
202
192
|
update: DatePicker.update,
|
|
@@ -219,16 +209,16 @@ export const update = (model: Model, message: Message) =>
|
|
|
219
209
|
|
|
220
210
|
UpdatedEmail: ({ value }) => {
|
|
221
211
|
const validationId = Number.increment(model.emailValidationId)
|
|
222
|
-
return
|
|
223
|
-
|
|
224
|
-
|
|
212
|
+
return Match.value(validateEmail(value)).pipe(
|
|
213
|
+
Match.withReturnType<UpdateReturn>(),
|
|
214
|
+
Match.tag('Valid', () => ({
|
|
225
215
|
model: evo(model, {
|
|
226
216
|
email: () => Validating({ value }),
|
|
227
217
|
emailValidationId: () => validationId,
|
|
228
218
|
}),
|
|
229
219
|
commands: [ValidateEmailAsync({ emailInput: value, validationId })],
|
|
230
220
|
})),
|
|
231
|
-
|
|
221
|
+
Match.orElse(syncResult => ({
|
|
232
222
|
model: evo(model, {
|
|
233
223
|
email: () => syncResult,
|
|
234
224
|
emailValidationId: () => validationId,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Option, Schema } from 'effect'
|
|
2
2
|
import { Update } from 'foldkit'
|
|
3
3
|
import {
|
|
4
4
|
Field,
|
|
@@ -32,9 +32,9 @@ export const proficiencyRadioGroupId = (entryId: string): string =>
|
|
|
32
32
|
export const ProficiencyRadioGroup =
|
|
33
33
|
RadioGroup.create<ProficiencyLevel.ProficiencyLevel>()
|
|
34
34
|
|
|
35
|
-
export const Model =
|
|
36
|
-
id:
|
|
37
|
-
name: Field(
|
|
35
|
+
export const Model = Schema.Struct({
|
|
36
|
+
id: Schema.String,
|
|
37
|
+
name: Field(Schema.String),
|
|
38
38
|
proficiency: ProficiencyLevel.ProficiencyLevel,
|
|
39
39
|
proficiencyRadioGroup: RadioGroup.Model,
|
|
40
40
|
})
|
|
@@ -43,7 +43,7 @@ export type Model = typeof Model.Type
|
|
|
43
43
|
// MESSAGE
|
|
44
44
|
|
|
45
45
|
export const Message = defineMessageUnion({
|
|
46
|
-
UpdatedName: { value:
|
|
46
|
+
UpdatedName: { value: Schema.String },
|
|
47
47
|
GotProficiencyRadioGroupMessage: { message: RadioGroup.Message },
|
|
48
48
|
ClickedRemoveSelf: {},
|
|
49
49
|
})
|
|
@@ -73,16 +73,14 @@ export const init = (entryId: string): Model => ({
|
|
|
73
73
|
|
|
74
74
|
// UPDATE
|
|
75
75
|
|
|
76
|
-
const foldProficiencyRadioGroupOutMessage =
|
|
76
|
+
const foldProficiencyRadioGroupOutMessage = RadioGroup.OutMessage.match<
|
|
77
|
+
Update.Step<Model, Message>,
|
|
77
78
|
RadioGroup.OutMessage<ProficiencyLevel.ProficiencyLevel>
|
|
78
|
-
>(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
model => ({ model: evo(model, { proficiency: () => value }) }),
|
|
84
|
-
}),
|
|
85
|
-
)
|
|
79
|
+
>({
|
|
80
|
+
Selected:
|
|
81
|
+
({ value }) =>
|
|
82
|
+
model => ({ model: evo(model, { proficiency: () => value }) }),
|
|
83
|
+
})
|
|
86
84
|
|
|
87
85
|
const foldProficiencyRadioGroup = Update.foldChild({
|
|
88
86
|
update: ProficiencyRadioGroup.update,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Array, Crypto, Effect,
|
|
1
|
+
import { Array, Crypto, Effect, Schema } from 'effect'
|
|
2
2
|
import { Command, Update } from 'foldkit'
|
|
3
3
|
import { defineMessageUnion } from 'foldkit/message'
|
|
4
4
|
import { evo } from 'foldkit/struct'
|
|
@@ -9,8 +9,8 @@ import * as Entry from './entry'
|
|
|
9
9
|
|
|
10
10
|
// MODEL
|
|
11
11
|
|
|
12
|
-
export const Model =
|
|
13
|
-
entries:
|
|
12
|
+
export const Model = Schema.Struct({
|
|
13
|
+
entries: Schema.Array(Entry.Model),
|
|
14
14
|
})
|
|
15
15
|
export type Model = typeof Model.Type
|
|
16
16
|
|
|
@@ -18,11 +18,11 @@ export type Model = typeof Model.Type
|
|
|
18
18
|
|
|
19
19
|
export const Message = defineMessageUnion({
|
|
20
20
|
ClickedAddEntry: {},
|
|
21
|
-
SucceededGenerateEntryId: { entryId:
|
|
21
|
+
SucceededGenerateEntryId: { entryId: Schema.String },
|
|
22
22
|
FailedGenerateEntryId: {},
|
|
23
|
-
RemovedEntry: { entryId:
|
|
23
|
+
RemovedEntry: { entryId: Schema.String },
|
|
24
24
|
GotEntryMessage: {
|
|
25
|
-
entryId:
|
|
25
|
+
entryId: Schema.String,
|
|
26
26
|
message: Entry.Message,
|
|
27
27
|
},
|
|
28
28
|
})
|
|
@@ -54,16 +54,13 @@ export const GenerateEntryId = Command.define('GenerateEntryId', {
|
|
|
54
54
|
const foldEntryOutMessage: (
|
|
55
55
|
entryId: string,
|
|
56
56
|
) => (outMessage: Entry.OutMessage) => Update.Step<Model, Message> = entryId =>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
model: evo(model, {
|
|
62
|
-
entries: Array.filter(entry => entry.id !== entryId),
|
|
63
|
-
}),
|
|
57
|
+
Entry.OutMessage.match<Update.Step<Model, Message>>({
|
|
58
|
+
Removed: () => model => ({
|
|
59
|
+
model: evo(model, {
|
|
60
|
+
entries: Array.filter(entry => entry.id !== entryId),
|
|
64
61
|
}),
|
|
65
62
|
}),
|
|
66
|
-
)
|
|
63
|
+
})
|
|
67
64
|
|
|
68
65
|
const foldEntry = (entryId: string) =>
|
|
69
66
|
Update.foldChild({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Option, Schema } from 'effect'
|
|
2
2
|
import { Update } from 'foldkit'
|
|
3
3
|
import { CalendarDate } from 'foldkit/calendar'
|
|
4
4
|
import {
|
|
@@ -31,28 +31,28 @@ const validateTitle = validate(titleRules)
|
|
|
31
31
|
|
|
32
32
|
// MODEL
|
|
33
33
|
|
|
34
|
-
export const Model =
|
|
35
|
-
id:
|
|
36
|
-
company: Field(
|
|
37
|
-
title: Field(
|
|
34
|
+
export const Model = Schema.Struct({
|
|
35
|
+
id: Schema.String,
|
|
36
|
+
company: Field(Schema.String),
|
|
37
|
+
title: Field(Schema.String),
|
|
38
38
|
startDate: DatePicker.Model,
|
|
39
|
-
maybeStartDate:
|
|
39
|
+
maybeStartDate: Schema.Option(CalendarDate),
|
|
40
40
|
endDate: DatePicker.Model,
|
|
41
|
-
maybeEndDate:
|
|
42
|
-
isCurrentlyEmployed:
|
|
43
|
-
description:
|
|
41
|
+
maybeEndDate: Schema.Option(CalendarDate),
|
|
42
|
+
isCurrentlyEmployed: Schema.Boolean,
|
|
43
|
+
description: Schema.String,
|
|
44
44
|
})
|
|
45
45
|
export type Model = typeof Model.Type
|
|
46
46
|
|
|
47
47
|
// MESSAGE
|
|
48
48
|
|
|
49
49
|
export const Message = defineMessageUnion({
|
|
50
|
-
UpdatedCompany: { value:
|
|
51
|
-
UpdatedTitle: { value:
|
|
50
|
+
UpdatedCompany: { value: Schema.String },
|
|
51
|
+
UpdatedTitle: { value: Schema.String },
|
|
52
52
|
GotStartDateMessage: { message: DatePicker.Message },
|
|
53
53
|
GotEndDateMessage: { message: DatePicker.Message },
|
|
54
|
-
ToggledCurrentlyEmployed: { isChecked:
|
|
55
|
-
UpdatedDescription: { value:
|
|
54
|
+
ToggledCurrentlyEmployed: { isChecked: Schema.Boolean },
|
|
55
|
+
UpdatedDescription: { value: Schema.String },
|
|
56
56
|
ClickedRemoveSelf: {},
|
|
57
57
|
})
|
|
58
58
|
|
|
@@ -84,26 +84,25 @@ export const init = (entryId: string, today: CalendarDate): Model => ({
|
|
|
84
84
|
|
|
85
85
|
// UPDATE
|
|
86
86
|
|
|
87
|
-
const foldStartDateOutMessage =
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
model: evo(model, {
|
|
95
|
-
maybeStartDate: () => Option.some(date),
|
|
96
|
-
endDate: DatePicker.reflectMinDate(Option.some(date)),
|
|
97
|
-
}),
|
|
98
|
-
}),
|
|
99
|
-
ClearedDate: () => model => ({
|
|
87
|
+
const foldStartDateOutMessage = DatePicker.OutMessage.match<
|
|
88
|
+
Update.Step<Model, Message>
|
|
89
|
+
>({
|
|
90
|
+
ChangedViewMonth: () => model => ({ model }),
|
|
91
|
+
SelectedDate:
|
|
92
|
+
({ date }) =>
|
|
93
|
+
model => ({
|
|
100
94
|
model: evo(model, {
|
|
101
|
-
maybeStartDate: () => Option.
|
|
102
|
-
endDate: DatePicker.reflectMinDate(Option.
|
|
95
|
+
maybeStartDate: () => Option.some(date),
|
|
96
|
+
endDate: DatePicker.reflectMinDate(Option.some(date)),
|
|
103
97
|
}),
|
|
104
98
|
}),
|
|
99
|
+
ClearedDate: () => model => ({
|
|
100
|
+
model: evo(model, {
|
|
101
|
+
maybeStartDate: () => Option.none(),
|
|
102
|
+
endDate: DatePicker.reflectMinDate(Option.none()),
|
|
103
|
+
}),
|
|
105
104
|
}),
|
|
106
|
-
)
|
|
105
|
+
})
|
|
107
106
|
|
|
108
107
|
const foldStartDate = Update.foldChild({
|
|
109
108
|
update: DatePicker.update,
|
|
@@ -114,26 +113,25 @@ const foldStartDate = Update.foldChild({
|
|
|
114
113
|
foldOutMessage: foldStartDateOutMessage,
|
|
115
114
|
})
|
|
116
115
|
|
|
117
|
-
const foldEndDateOutMessage =
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
model: evo(model, {
|
|
125
|
-
maybeEndDate: () => Option.some(date),
|
|
126
|
-
startDate: DatePicker.reflectMaxDate(Option.some(date)),
|
|
127
|
-
}),
|
|
128
|
-
}),
|
|
129
|
-
ClearedDate: () => model => ({
|
|
116
|
+
const foldEndDateOutMessage = DatePicker.OutMessage.match<
|
|
117
|
+
Update.Step<Model, Message>
|
|
118
|
+
>({
|
|
119
|
+
ChangedViewMonth: () => model => ({ model }),
|
|
120
|
+
SelectedDate:
|
|
121
|
+
({ date }) =>
|
|
122
|
+
model => ({
|
|
130
123
|
model: evo(model, {
|
|
131
|
-
maybeEndDate: () => Option.
|
|
132
|
-
startDate: DatePicker.reflectMaxDate(Option.
|
|
124
|
+
maybeEndDate: () => Option.some(date),
|
|
125
|
+
startDate: DatePicker.reflectMaxDate(Option.some(date)),
|
|
133
126
|
}),
|
|
134
127
|
}),
|
|
128
|
+
ClearedDate: () => model => ({
|
|
129
|
+
model: evo(model, {
|
|
130
|
+
maybeEndDate: () => Option.none(),
|
|
131
|
+
startDate: DatePicker.reflectMaxDate(Option.none()),
|
|
132
|
+
}),
|
|
135
133
|
}),
|
|
136
|
-
)
|
|
134
|
+
})
|
|
137
135
|
|
|
138
136
|
const foldEndDate = Update.foldChild({
|
|
139
137
|
update: DatePicker.update,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Array, Crypto, Effect,
|
|
1
|
+
import { Array, Crypto, Effect, Schema } from 'effect'
|
|
2
2
|
import { Calendar, Command, Update } from 'foldkit'
|
|
3
3
|
import { type CalendarDate } from 'foldkit/calendar'
|
|
4
4
|
import { defineMessageUnion } from 'foldkit/message'
|
|
@@ -10,8 +10,8 @@ import * as Entry from './entry'
|
|
|
10
10
|
|
|
11
11
|
// MODEL
|
|
12
12
|
|
|
13
|
-
export const Model =
|
|
14
|
-
entries:
|
|
13
|
+
export const Model = Schema.Struct({
|
|
14
|
+
entries: Schema.Array(Entry.Model),
|
|
15
15
|
today: Calendar.CalendarDate,
|
|
16
16
|
})
|
|
17
17
|
export type Model = typeof Model.Type
|
|
@@ -20,11 +20,11 @@ export type Model = typeof Model.Type
|
|
|
20
20
|
|
|
21
21
|
export const Message = defineMessageUnion({
|
|
22
22
|
ClickedAddEntry: {},
|
|
23
|
-
SucceededGenerateEntryId: { entryId:
|
|
23
|
+
SucceededGenerateEntryId: { entryId: Schema.String },
|
|
24
24
|
FailedGenerateEntryId: {},
|
|
25
|
-
RemovedEntry: { entryId:
|
|
25
|
+
RemovedEntry: { entryId: Schema.String },
|
|
26
26
|
GotEntryMessage: {
|
|
27
|
-
entryId:
|
|
27
|
+
entryId: Schema.String,
|
|
28
28
|
message: Entry.Message,
|
|
29
29
|
},
|
|
30
30
|
})
|
|
@@ -57,16 +57,13 @@ export const GenerateEntryId = Command.define('GenerateEntryId', {
|
|
|
57
57
|
const foldEntryOutMessage: (
|
|
58
58
|
entryId: string,
|
|
59
59
|
) => (outMessage: Entry.OutMessage) => Update.Step<Model, Message> = entryId =>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
model: evo(model, {
|
|
65
|
-
entries: Array.filter(entry => entry.id !== entryId),
|
|
66
|
-
}),
|
|
60
|
+
Entry.OutMessage.match<Update.Step<Model, Message>>({
|
|
61
|
+
Removed: () => model => ({
|
|
62
|
+
model: evo(model, {
|
|
63
|
+
entries: Array.filter(entry => entry.id !== entryId),
|
|
67
64
|
}),
|
|
68
65
|
}),
|
|
69
|
-
)
|
|
66
|
+
})
|
|
70
67
|
|
|
71
68
|
const foldEntry = (entryId: string) =>
|
|
72
69
|
Update.foldChild({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Array,
|
|
1
|
+
import { Array, Option, pipe } from 'effect'
|
|
2
2
|
import { Update } from 'foldkit'
|
|
3
3
|
import { evo } from 'foldkit/struct'
|
|
4
4
|
|
|
@@ -87,14 +87,14 @@ const foldAttachments = Update.foldChild({
|
|
|
87
87
|
toParentMessage: message => Message.GotAttachmentsMessage({ message }),
|
|
88
88
|
})
|
|
89
89
|
|
|
90
|
-
const foldStepMenuOutMessage =
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
)
|
|
90
|
+
const foldStepMenuOutMessage = Menu.OutMessage.match<
|
|
91
|
+
Update.Step<Model, Message>,
|
|
92
|
+
Menu.OutMessage<Step.Step>
|
|
93
|
+
>({
|
|
94
|
+
Selected:
|
|
95
|
+
({ value }) =>
|
|
96
|
+
model => ({ model: evo(model, { currentStep: () => value }) }),
|
|
97
|
+
})
|
|
98
98
|
|
|
99
99
|
const foldStepMenu = Update.foldChild({
|
|
100
100
|
update: StepMenu.update,
|
|
@@ -104,14 +104,14 @@ const foldStepMenu = Update.foldChild({
|
|
|
104
104
|
foldOutMessage: foldStepMenuOutMessage,
|
|
105
105
|
})
|
|
106
106
|
|
|
107
|
-
const foldStepTabsOutMessage =
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
)
|
|
107
|
+
const foldStepTabsOutMessage = Tabs.OutMessage.match<
|
|
108
|
+
Update.Step<Model, Message>,
|
|
109
|
+
Tabs.OutMessage<Step.Step>
|
|
110
|
+
>({
|
|
111
|
+
Selected:
|
|
112
|
+
({ value }) =>
|
|
113
|
+
model => ({ model: evo(model, { currentStep: () => value }) }),
|
|
114
|
+
})
|
|
115
115
|
|
|
116
116
|
const foldStepTabs = Update.foldChild({
|
|
117
117
|
update: StepTabs.update,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import clsx from 'clsx'
|
|
2
|
-
import { Array, Match
|
|
2
|
+
import { Array, Match, Number, Option } from 'effect'
|
|
3
3
|
import { File, Submodel } from 'foldkit'
|
|
4
4
|
import type { Html, HtmlBuilder } from 'foldkit/html'
|
|
5
5
|
|
|
@@ -12,13 +12,13 @@ const BYTES_PER_KB = 1024
|
|
|
12
12
|
const BYTES_PER_MB = BYTES_PER_KB * BYTES_PER_KB
|
|
13
13
|
|
|
14
14
|
const formatFileSize = (bytes: number): string =>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
Match.value(bytes).pipe(
|
|
16
|
+
Match.when(Number.isLessThan(BYTES_PER_KB), () => `${bytes} B`),
|
|
17
|
+
Match.when(
|
|
18
18
|
Number.isLessThan(BYTES_PER_MB),
|
|
19
19
|
() => `${(bytes / BYTES_PER_KB).toFixed(1)} KB`,
|
|
20
20
|
),
|
|
21
|
-
|
|
21
|
+
Match.orElse(() => `${(bytes / BYTES_PER_MB).toFixed(1)} MB`),
|
|
22
22
|
)
|
|
23
23
|
|
|
24
24
|
const dropZoneClassName =
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Match
|
|
1
|
+
import { Match, Option } from 'effect'
|
|
2
2
|
import { type CalendarDate } from 'foldkit/calendar'
|
|
3
3
|
import { type Html, inertHtml as ih } from 'foldkit/html'
|
|
4
4
|
|
|
@@ -51,8 +51,8 @@ const monthYearButtonClassName =
|
|
|
51
51
|
'flex h-full w-full items-center justify-center rounded-md text-sm text-gray-900 tabular-nums cursor-pointer hover:bg-gray-100 group-data-[today]:ring-1 group-data-[today]:ring-gray-400 group-data-[selected]:bg-indigo-600 group-data-[selected]:text-white! group-data-[selected]:hover:bg-indigo-600 group-data-[focused]:outline-2 group-data-[focused]:outline-offset-2 group-data-[focused]:outline-indigo-500 group-data-[disabled]:cursor-not-allowed group-data-[disabled]:opacity-40'
|
|
52
52
|
|
|
53
53
|
export const calendarView = (attributes: Calendar.CalendarAttributes): Html =>
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
Match.value(attributes).pipe(
|
|
55
|
+
Match.tagsExhaustive({
|
|
56
56
|
Days: days =>
|
|
57
57
|
ih.div(
|
|
58
58
|
[...days.root, ih.Class(calendarWrapperClassName)],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import clsx from 'clsx'
|
|
2
|
-
import { Match
|
|
2
|
+
import { Match } from 'effect'
|
|
3
3
|
import { FieldValidation } from 'foldkit'
|
|
4
4
|
import { type Field } from 'foldkit/fieldValidation'
|
|
5
5
|
import type { Html, HtmlBuilder } from 'foldkit/html'
|
|
@@ -50,17 +50,17 @@ export const inputField = <ParentMessage>(
|
|
|
50
50
|
],
|
|
51
51
|
[config.label],
|
|
52
52
|
),
|
|
53
|
-
...
|
|
54
|
-
|
|
53
|
+
...Match.value(config.field).pipe(
|
|
54
|
+
Match.tag('Validating', () => [
|
|
55
55
|
h.span(
|
|
56
56
|
[h.Class('text-blue-600 text-sm animate-spin')],
|
|
57
57
|
['◐'],
|
|
58
58
|
),
|
|
59
59
|
]),
|
|
60
|
-
|
|
60
|
+
Match.tag('Valid', () => [
|
|
61
61
|
h.span([h.Class('text-green-600 text-sm')], ['✓']),
|
|
62
62
|
]),
|
|
63
|
-
|
|
63
|
+
Match.orElse(() => []),
|
|
64
64
|
),
|
|
65
65
|
],
|
|
66
66
|
),
|