create-foldkit-app 0.32.1 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/templates/base/.oxfmtrc.json +28 -0
- package/dist/templates/base/.oxlintrc.json +4 -0
- package/dist/templates/base/FOLDKIT.md +1 -1
- package/dist/templates/base/package.json +1 -1
- package/dist/templates/examples/api-cache/package.json +0 -2
- package/dist/templates/examples/api-cache/src/scene.test.ts +1 -2
- package/dist/templates/examples/api-cache/src/story.test.ts +3 -4
- package/dist/templates/examples/auth/package.json +0 -2
- package/dist/templates/examples/canvas-art/package.json +0 -2
- package/dist/templates/examples/charting/package.json +0 -2
- package/dist/templates/examples/charting/src/scene.test.ts +1 -2
- package/dist/templates/examples/charting/src/story.test.ts +3 -4
- package/dist/templates/examples/counter/package.json +0 -2
- package/dist/templates/examples/counters/package.json +0 -2
- package/dist/templates/examples/crash-view/package.json +0 -2
- package/dist/templates/examples/embedding/package.json +0 -2
- package/dist/templates/examples/form/package.json +0 -2
- package/dist/templates/examples/generative-art/package.json +0 -2
- package/dist/templates/examples/interrupting-commands/package.json +0 -2
- package/dist/templates/examples/job-application/package.json +0 -2
- package/dist/templates/examples/job-application/src/main.fixture.ts +69 -0
- package/dist/templates/examples/job-application/src/main.ts +1 -1
- package/dist/templates/examples/job-application/src/scene.test.ts +6 -66
- package/dist/templates/examples/job-application/src/step/attachments/index.ts +2 -0
- package/dist/templates/examples/job-application/src/step/attachments/scene.test.ts +19 -0
- package/dist/templates/examples/job-application/src/step/attachments/story.test.ts +46 -0
- package/dist/templates/examples/job-application/src/{view/attachments.ts → step/attachments/view.ts} +4 -11
- package/dist/templates/examples/job-application/src/{view → step/coverLetter}/coverLetter.ts +36 -7
- package/dist/templates/examples/job-application/src/step/coverLetter/index.ts +1 -0
- package/dist/templates/examples/job-application/src/step/coverLetter/scene.test.ts +24 -0
- package/dist/templates/examples/job-application/src/step/coverLetter/story.test.ts +19 -0
- package/dist/templates/examples/job-application/src/step/education/{entry.ts → entry/entry.ts} +2 -2
- package/dist/templates/examples/job-application/src/step/education/entry/index.ts +11 -0
- package/dist/templates/examples/job-application/src/step/education/entry/story.test.ts +39 -0
- package/dist/templates/examples/job-application/src/step/education/entry/view.ts +160 -0
- package/dist/templates/examples/job-application/src/step/education/index.ts +11 -1
- package/dist/templates/examples/job-application/src/step/education/scene.test.ts +20 -0
- package/dist/templates/examples/job-application/src/step/education/story.test.ts +87 -0
- package/dist/templates/examples/job-application/src/{view/education.ts → step/education/view.ts} +6 -10
- package/dist/templates/examples/job-application/src/step/personalInfo/index.ts +11 -0
- package/dist/templates/examples/job-application/src/step/{personalInfo.ts → personalInfo/personalInfo.ts} +2 -2
- package/dist/templates/examples/job-application/src/step/personalInfo/scene.test.ts +38 -0
- package/dist/templates/examples/job-application/src/step/personalInfo/story.test.ts +87 -0
- package/dist/templates/examples/job-application/src/{view/personalInfo.ts → step/personalInfo/view.ts} +24 -34
- package/dist/templates/examples/job-application/src/step/skills/{entry.ts → entry/entry.ts} +2 -2
- package/dist/templates/examples/job-application/src/step/skills/entry/index.ts +11 -0
- package/dist/templates/examples/job-application/src/step/skills/entry/story.test.ts +27 -0
- package/dist/templates/examples/job-application/src/{view/skillEntry.ts → step/skills/entry/view.ts} +9 -12
- package/dist/templates/examples/job-application/src/step/skills/index.ts +11 -1
- package/dist/templates/examples/job-application/src/step/skills/scene.test.ts +16 -0
- package/dist/templates/examples/job-application/src/step/skills/story.test.ts +85 -0
- package/dist/templates/examples/job-application/src/step/skills/view.ts +47 -0
- package/dist/templates/examples/job-application/src/step/workHistory/{entry.ts → entry/entry.ts} +1 -1
- package/dist/templates/examples/job-application/src/step/workHistory/entry/index.ts +11 -0
- package/dist/templates/examples/job-application/src/step/workHistory/entry/story.test.ts +42 -0
- package/dist/templates/examples/job-application/src/{view/workEntry.ts → step/workHistory/entry/view.ts} +27 -42
- package/dist/templates/examples/job-application/src/step/workHistory/index.ts +11 -1
- package/dist/templates/examples/job-application/src/step/workHistory/scene.test.ts +20 -0
- package/dist/templates/examples/job-application/src/step/workHistory/story.test.ts +87 -0
- package/dist/templates/examples/job-application/src/{view/workHistory.ts → step/workHistory/view.ts} +4 -8
- package/dist/templates/examples/job-application/src/story.test.ts +28 -419
- package/dist/templates/examples/job-application/src/view/datePicker.ts +4 -4
- package/dist/templates/examples/job-application/src/view/field.ts +3 -3
- package/dist/templates/examples/job-application/src/view/index.ts +3 -358
- package/dist/templates/examples/job-application/src/view/stepNav.ts +2 -2
- package/dist/templates/examples/job-application/src/view/view.ts +359 -0
- package/dist/templates/examples/kanban/package.json +0 -2
- package/dist/templates/examples/kanban/src/scene.test.ts +1 -1
- package/dist/templates/examples/kanban/src/story.test.ts +22 -23
- package/dist/templates/examples/kanban/src/view/index.ts +1 -71
- package/dist/templates/examples/kanban/src/view/view.ts +71 -0
- package/dist/templates/examples/managed-resource-layer/package.json +0 -2
- package/dist/templates/examples/map/package.json +0 -2
- package/dist/templates/examples/pixel-art/package.json +0 -2
- package/dist/templates/examples/pixel-art/src/scene.test.ts +16 -9
- package/dist/templates/examples/pixel-art/src/story.test.ts +12 -7
- package/dist/templates/examples/query-sync/package.json +0 -2
- package/dist/templates/examples/query-sync/src/story.test.ts +4 -5
- package/dist/templates/examples/route-transitions/package.json +0 -2
- package/dist/templates/examples/routing/package.json +0 -2
- package/dist/templates/examples/routing/src/page/people.scene.test.ts +41 -0
- package/dist/templates/examples/routing/src/page/people.story.test.ts +73 -0
- package/dist/templates/examples/routing/src/scene.test.ts +2 -17
- package/dist/templates/examples/routing/src/story.test.ts +4 -34
- package/dist/templates/examples/shopping-cart/package.json +0 -2
- package/dist/templates/examples/shopping-cart/src/page/products.scene.test.ts +20 -0
- package/dist/templates/examples/shopping-cart/src/page/products.story.test.ts +56 -0
- package/dist/templates/examples/shopping-cart/src/page/products.ts +1 -1
- package/dist/templates/examples/shopping-cart/src/scene.test.ts +1 -4
- package/dist/templates/examples/shopping-cart/src/story.test.ts +3 -4
- package/dist/templates/examples/slow-warnings/package.json +0 -2
- package/dist/templates/examples/snake/package.json +0 -2
- package/dist/templates/examples/ssg/package.json +0 -2
- package/dist/templates/examples/ssr/package.json +0 -2
- package/dist/templates/examples/state-machine/package.json +0 -2
- package/dist/templates/examples/state-machine/src/main.ts +79 -87
- package/dist/templates/examples/state-machine/src/scene.test.ts +1 -2
- package/dist/templates/examples/stopwatch/package.json +0 -2
- package/dist/templates/examples/todo/package.json +0 -2
- package/dist/templates/examples/ui-showcase/package.json +0 -2
- package/dist/templates/examples/ui-showcase/src/story.test.ts +1 -2
- package/dist/templates/examples/view-transitions/package.json +0 -2
- package/dist/templates/examples/view-transitions/src/styles.css +3 -3
- package/dist/templates/examples/weather/package.json +0 -2
- package/dist/templates/examples/web-components/package.json +0 -2
- package/dist/templates/examples/websocket-chat/package.json +0 -2
- package/dist/templates/release.json +9 -10
- package/dist/templates/rendering/ssg/package.json +1 -1
- package/dist/templates/rendering/ssr/package.json +1 -1
- package/dist/utils/packages.js +1 -2
- package/package.json +3 -3
- package/dist/templates/base/.prettierignore +0 -5
- package/dist/templates/base/.prettierrc +0 -13
- package/dist/templates/examples/job-application/src/step/coverLetter.ts +0 -34
- package/dist/templates/examples/job-application/src/view/educationEntry.ts +0 -165
- package/dist/templates/examples/job-application/src/view/skills.ts +0 -49
- /package/dist/templates/examples/job-application/src/step/{attachments.ts → attachments/attachments.ts} +0 -0
|
@@ -5,7 +5,7 @@ import { type Html, inertHtml as ih } from 'foldkit/html'
|
|
|
5
5
|
import { Calendar } from '@foldkit/ui'
|
|
6
6
|
|
|
7
7
|
import { fullDate } from './format'
|
|
8
|
-
import
|
|
8
|
+
import * as Icon from './icon'
|
|
9
9
|
|
|
10
10
|
export const triggerClassName =
|
|
11
11
|
'w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm text-left cursor-pointer focus:outline-none focus:ring-2 focus:ring-indigo-500'
|
|
@@ -26,7 +26,7 @@ export const triggerContent = (
|
|
|
26
26
|
onNone: () => ih.span([ih.Class('text-gray-400')], [placeholder]),
|
|
27
27
|
onSome: date => ih.span([], [fullDate(date)]),
|
|
28
28
|
}),
|
|
29
|
-
ih.span([ih.Class('text-gray-400 shrink-0')], [chevronDown()]),
|
|
29
|
+
ih.span([ih.Class('text-gray-400 shrink-0')], [Icon.chevronDown()]),
|
|
30
30
|
],
|
|
31
31
|
)
|
|
32
32
|
|
|
@@ -70,7 +70,7 @@ export const calendarView = (attributes: Calendar.CalendarAttributes): Html =>
|
|
|
70
70
|
...days.headingButton,
|
|
71
71
|
ih.Class(headingButtonClassName),
|
|
72
72
|
],
|
|
73
|
-
[days.heading.text, chevronDown('w-3 h-3')],
|
|
73
|
+
[days.heading.text, Icon.chevronDown('w-3 h-3')],
|
|
74
74
|
),
|
|
75
75
|
ih.button(
|
|
76
76
|
[...days.nextMonthButton, ih.Class(navButtonClassName)],
|
|
@@ -134,7 +134,7 @@ export const calendarView = (attributes: Calendar.CalendarAttributes): Html =>
|
|
|
134
134
|
...months.headingButton,
|
|
135
135
|
ih.Class(headingButtonClassName),
|
|
136
136
|
],
|
|
137
|
-
[months.heading.text, chevronDown('w-3 h-3')],
|
|
137
|
+
[months.heading.text, Icon.chevronDown('w-3 h-3')],
|
|
138
138
|
),
|
|
139
139
|
],
|
|
140
140
|
),
|
|
@@ -14,7 +14,7 @@ const borderClass = (field: Field<string>): string =>
|
|
|
14
14
|
onInvalid: () => 'border-red-500',
|
|
15
15
|
})
|
|
16
16
|
|
|
17
|
-
export const
|
|
17
|
+
export const input = <ParentMessage>(
|
|
18
18
|
config: Readonly<{
|
|
19
19
|
id: string
|
|
20
20
|
label: string
|
|
@@ -90,7 +90,7 @@ export const inputField = <ParentMessage>(
|
|
|
90
90
|
h,
|
|
91
91
|
)
|
|
92
92
|
|
|
93
|
-
export const
|
|
93
|
+
export const checkbox = <ParentMessage>(
|
|
94
94
|
config: Readonly<{
|
|
95
95
|
id: string
|
|
96
96
|
label: string
|
|
@@ -138,7 +138,7 @@ export const checkboxField = <ParentMessage>(
|
|
|
138
138
|
h,
|
|
139
139
|
)
|
|
140
140
|
|
|
141
|
-
export const
|
|
141
|
+
export const textarea = <ParentMessage>(
|
|
142
142
|
config: Readonly<{
|
|
143
143
|
id: string
|
|
144
144
|
label: string
|
|
@@ -1,358 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { Button, Tabs } from '@foldkit/ui'
|
|
6
|
-
|
|
7
|
-
import { Step } from '../domain'
|
|
8
|
-
import { Message } from '../message'
|
|
9
|
-
import { type Model } from '../model'
|
|
10
|
-
import { Education, PersonalInfo, Skills, WorkHistory } from '../step'
|
|
11
|
-
import { attachmentsView } from './attachments'
|
|
12
|
-
import { coverLetterView } from './coverLetter'
|
|
13
|
-
import { educationView } from './education'
|
|
14
|
-
import { personalInfoView } from './personalInfo'
|
|
15
|
-
import { preview } from './preview'
|
|
16
|
-
import { review } from './review'
|
|
17
|
-
import { skillsView } from './skills'
|
|
18
|
-
import { stepMenu, stepTabButton } from './stepNav'
|
|
19
|
-
import { workHistoryView } from './workHistory'
|
|
20
|
-
|
|
21
|
-
const StepTabs = Tabs.create<Step.Step>()
|
|
22
|
-
|
|
23
|
-
const stepHasErrors =
|
|
24
|
-
(model: Model) =>
|
|
25
|
-
(step: Step.Step): boolean =>
|
|
26
|
-
Match.value(step).pipe(
|
|
27
|
-
Match.when('PersonalInfo', () =>
|
|
28
|
-
PersonalInfo.hasErrors(model.personalInfo),
|
|
29
|
-
),
|
|
30
|
-
Match.when('WorkHistory', () => WorkHistory.hasErrors(model.workHistory)),
|
|
31
|
-
Match.when('Education', () => Education.hasErrors(model.education)),
|
|
32
|
-
Match.when('Skills', () => Skills.hasErrors(model.skills)),
|
|
33
|
-
Match.orElse(() => false),
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
const stepIsComplete =
|
|
37
|
-
(model: Model) =>
|
|
38
|
-
(step: Step.Step): boolean =>
|
|
39
|
-
Match.value(step).pipe(
|
|
40
|
-
Match.when('PersonalInfo', () =>
|
|
41
|
-
PersonalInfo.isComplete(model.personalInfo),
|
|
42
|
-
),
|
|
43
|
-
Match.when('WorkHistory', () =>
|
|
44
|
-
WorkHistory.isComplete(model.workHistory),
|
|
45
|
-
),
|
|
46
|
-
Match.when('Education', () => Education.isComplete(model.education)),
|
|
47
|
-
Match.when('Skills', () => Skills.isComplete(model.skills)),
|
|
48
|
-
Match.orElse(() => true),
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
const stepNeedsAttention =
|
|
52
|
-
(model: Model) =>
|
|
53
|
-
(step: Step.Step): boolean =>
|
|
54
|
-
stepHasErrors(model)(step) ||
|
|
55
|
-
(model.isSubmitAttempted && !stepIsComplete(model)(step))
|
|
56
|
-
|
|
57
|
-
const stepsNeedingAttention = (model: Model): ReadonlyArray<Step.Step> =>
|
|
58
|
-
Array.filter(Step.all, stepNeedsAttention(model))
|
|
59
|
-
|
|
60
|
-
const stepContent = (
|
|
61
|
-
model: Model,
|
|
62
|
-
attentionSteps: ReadonlyArray<Step.Step>,
|
|
63
|
-
h: HtmlBuilder<Message>,
|
|
64
|
-
): Html =>
|
|
65
|
-
Match.value(model.currentStep).pipe(
|
|
66
|
-
Match.when('PersonalInfo', () =>
|
|
67
|
-
h.submodel({
|
|
68
|
-
slotId: 'personal-info',
|
|
69
|
-
model: model.personalInfo,
|
|
70
|
-
view: personalInfoView,
|
|
71
|
-
toParentMessage: message => Message.GotPersonalInfoMessage({ message }),
|
|
72
|
-
}),
|
|
73
|
-
),
|
|
74
|
-
Match.when('WorkHistory', () =>
|
|
75
|
-
h.submodel({
|
|
76
|
-
slotId: 'work-history',
|
|
77
|
-
model: model.workHistory,
|
|
78
|
-
view: workHistoryView,
|
|
79
|
-
toParentMessage: message => Message.GotWorkHistoryMessage({ message }),
|
|
80
|
-
}),
|
|
81
|
-
),
|
|
82
|
-
Match.when('Education', () =>
|
|
83
|
-
h.submodel({
|
|
84
|
-
slotId: 'education',
|
|
85
|
-
model: model.education,
|
|
86
|
-
view: educationView,
|
|
87
|
-
toParentMessage: message => Message.GotEducationMessage({ message }),
|
|
88
|
-
}),
|
|
89
|
-
),
|
|
90
|
-
Match.when('Skills', () =>
|
|
91
|
-
h.submodel({
|
|
92
|
-
slotId: 'skills',
|
|
93
|
-
model: model.skills,
|
|
94
|
-
view: skillsView,
|
|
95
|
-
toParentMessage: message => Message.GotSkillsMessage({ message }),
|
|
96
|
-
}),
|
|
97
|
-
),
|
|
98
|
-
Match.when('CoverLetter', () =>
|
|
99
|
-
h.submodel({
|
|
100
|
-
slotId: 'cover-letter',
|
|
101
|
-
model: model.coverLetter,
|
|
102
|
-
view: coverLetterView,
|
|
103
|
-
toParentMessage: message => Message.GotCoverLetterMessage({ message }),
|
|
104
|
-
}),
|
|
105
|
-
),
|
|
106
|
-
Match.when('Attachments', () =>
|
|
107
|
-
h.submodel({
|
|
108
|
-
slotId: 'attachments',
|
|
109
|
-
model: model.attachments,
|
|
110
|
-
view: attachmentsView,
|
|
111
|
-
toParentMessage: message => Message.GotAttachmentsMessage({ message }),
|
|
112
|
-
}),
|
|
113
|
-
),
|
|
114
|
-
Match.when('Review', () => review(model, attentionSteps, h)),
|
|
115
|
-
Match.exhaustive,
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
const isFirstStep = (model: Model): boolean =>
|
|
119
|
-
pipe(Step.all, Array.head, Option.exists(Equal.equals(model.currentStep)))
|
|
120
|
-
|
|
121
|
-
const isLastStep = (model: Model): boolean =>
|
|
122
|
-
pipe(Step.all, Array.last, Option.exists(Equal.equals(model.currentStep)))
|
|
123
|
-
|
|
124
|
-
const navigationButtons = (model: Model, h: HtmlBuilder<Message>): Html =>
|
|
125
|
-
h.div(
|
|
126
|
-
[h.Class('flex justify-between pt-6 mt-8 border-t border-gray-200')],
|
|
127
|
-
[
|
|
128
|
-
...(isFirstStep(model)
|
|
129
|
-
? [h.empty]
|
|
130
|
-
: [
|
|
131
|
-
Button.view(
|
|
132
|
-
{
|
|
133
|
-
onClick: Message.ClickedPrevious(),
|
|
134
|
-
toView: attributes =>
|
|
135
|
-
h.button(
|
|
136
|
-
[
|
|
137
|
-
...attributes.button,
|
|
138
|
-
h.Class(
|
|
139
|
-
'rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 transition cursor-pointer',
|
|
140
|
-
),
|
|
141
|
-
],
|
|
142
|
-
['← Previous'],
|
|
143
|
-
),
|
|
144
|
-
},
|
|
145
|
-
h,
|
|
146
|
-
),
|
|
147
|
-
]),
|
|
148
|
-
...(isLastStep(model)
|
|
149
|
-
? []
|
|
150
|
-
: [
|
|
151
|
-
Button.view(
|
|
152
|
-
{
|
|
153
|
-
onClick: Message.ClickedNext(),
|
|
154
|
-
toView: attributes =>
|
|
155
|
-
h.button(
|
|
156
|
-
[
|
|
157
|
-
...attributes.button,
|
|
158
|
-
h.Class(
|
|
159
|
-
'rounded-lg bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700 transition cursor-pointer',
|
|
160
|
-
),
|
|
161
|
-
],
|
|
162
|
-
['Next →'],
|
|
163
|
-
),
|
|
164
|
-
},
|
|
165
|
-
h,
|
|
166
|
-
),
|
|
167
|
-
]),
|
|
168
|
-
],
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
const pageHeader = (h: HtmlBuilder<Message>): Html =>
|
|
172
|
-
h.div(
|
|
173
|
-
[h.Class('mb-6')],
|
|
174
|
-
[
|
|
175
|
-
h.h1(
|
|
176
|
-
[h.Class('text-2xl font-bold text-gray-900')],
|
|
177
|
-
['Apply to Work on Foldkit'],
|
|
178
|
-
),
|
|
179
|
-
h.p(
|
|
180
|
-
[h.Class('text-sm text-gray-500 mt-1')],
|
|
181
|
-
['Fill out the form below and watch your resume build in real time.'],
|
|
182
|
-
),
|
|
183
|
-
],
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
const stepContentPanel = (
|
|
187
|
-
model: Model,
|
|
188
|
-
attentionSteps: ReadonlyArray<Step.Step>,
|
|
189
|
-
panelAttributes: ReadonlyArray<ChildAttribute>,
|
|
190
|
-
h: HtmlBuilder<Message>,
|
|
191
|
-
): Html =>
|
|
192
|
-
h.div(
|
|
193
|
-
[...panelAttributes, h.Class('flex-1 min-w-0')],
|
|
194
|
-
[
|
|
195
|
-
h.h2(
|
|
196
|
-
[h.Class('text-lg font-semibold text-gray-900 mb-6')],
|
|
197
|
-
[Step.show(model.currentStep)],
|
|
198
|
-
),
|
|
199
|
-
h.div(
|
|
200
|
-
[h.Class('min-h-[400px]')],
|
|
201
|
-
[stepContent(model, attentionSteps, h)],
|
|
202
|
-
),
|
|
203
|
-
...(model.currentStep !== 'Review' ? [navigationButtons(model, h)] : []),
|
|
204
|
-
],
|
|
205
|
-
)
|
|
206
|
-
|
|
207
|
-
const stepTabsLayout = (
|
|
208
|
-
model: Model,
|
|
209
|
-
attentionSteps: ReadonlyArray<Step.Step>,
|
|
210
|
-
attentionStepSet: HashSet.HashSet<Step.Step>,
|
|
211
|
-
h: HtmlBuilder<Message>,
|
|
212
|
-
): Html =>
|
|
213
|
-
h.submodel({
|
|
214
|
-
slotId: model.stepTabs.id,
|
|
215
|
-
model: model.stepTabs,
|
|
216
|
-
view: StepTabs.view,
|
|
217
|
-
viewInputs: {
|
|
218
|
-
tabs: Step.all,
|
|
219
|
-
selectedValue: model.currentStep,
|
|
220
|
-
ariaLabel: 'Application steps',
|
|
221
|
-
orientation: 'Vertical',
|
|
222
|
-
toView: ({ tablist, tabs, activeIndex }) =>
|
|
223
|
-
h.div(
|
|
224
|
-
[h.Class('lg:flex lg:gap-8')],
|
|
225
|
-
[
|
|
226
|
-
h.div(
|
|
227
|
-
[h.Class('hidden w-60 shrink-0 lg:block')],
|
|
228
|
-
[
|
|
229
|
-
h.div(
|
|
230
|
-
[h.Class('sticky top-8')],
|
|
231
|
-
[
|
|
232
|
-
h.div(
|
|
233
|
-
[...tablist, h.Class('space-y-0.5')],
|
|
234
|
-
Array.map(tabs, tab =>
|
|
235
|
-
stepTabButton(
|
|
236
|
-
tab,
|
|
237
|
-
model.currentStep,
|
|
238
|
-
attentionStepSet,
|
|
239
|
-
h,
|
|
240
|
-
),
|
|
241
|
-
),
|
|
242
|
-
),
|
|
243
|
-
],
|
|
244
|
-
),
|
|
245
|
-
],
|
|
246
|
-
),
|
|
247
|
-
...pipe(
|
|
248
|
-
tabs,
|
|
249
|
-
Array.filter(tab => tab.index === activeIndex),
|
|
250
|
-
Array.map(tab =>
|
|
251
|
-
stepContentPanel(model, attentionSteps, tab.panel, h),
|
|
252
|
-
),
|
|
253
|
-
),
|
|
254
|
-
desktopPreviewSidebar(model, h),
|
|
255
|
-
mobilePreviewToggle(model, h),
|
|
256
|
-
...(model.isPreviewVisible ? [mobilePreviewOverlay(model, h)] : []),
|
|
257
|
-
],
|
|
258
|
-
),
|
|
259
|
-
},
|
|
260
|
-
toParentMessage: message => Message.GotStepTabsMessage({ message }),
|
|
261
|
-
})
|
|
262
|
-
|
|
263
|
-
const desktopPreviewSidebar = (model: Model, h: HtmlBuilder<Message>): Html =>
|
|
264
|
-
h.div(
|
|
265
|
-
[h.Class('hidden w-80 shrink-0 xl:block')],
|
|
266
|
-
[
|
|
267
|
-
h.div(
|
|
268
|
-
[h.Class('sticky top-8')],
|
|
269
|
-
[
|
|
270
|
-
h.div(
|
|
271
|
-
[h.Class('mb-2 flex items-center justify-between')],
|
|
272
|
-
[
|
|
273
|
-
h.h2(
|
|
274
|
-
[h.Class('text-sm font-semibold text-gray-700')],
|
|
275
|
-
['Live Preview'],
|
|
276
|
-
),
|
|
277
|
-
],
|
|
278
|
-
),
|
|
279
|
-
h.div(
|
|
280
|
-
[
|
|
281
|
-
h.Class(
|
|
282
|
-
'rounded-xl border border-gray-200 bg-white p-6 shadow-sm',
|
|
283
|
-
),
|
|
284
|
-
],
|
|
285
|
-
[preview(model)],
|
|
286
|
-
),
|
|
287
|
-
],
|
|
288
|
-
),
|
|
289
|
-
],
|
|
290
|
-
)
|
|
291
|
-
|
|
292
|
-
const mobilePreviewToggle = (model: Model, h: HtmlBuilder<Message>): Html =>
|
|
293
|
-
h.div(
|
|
294
|
-
[h.Class('fixed top-4 right-4 xl:hidden')],
|
|
295
|
-
[
|
|
296
|
-
Button.view(
|
|
297
|
-
{
|
|
298
|
-
onClick: Message.ToggledPreview(),
|
|
299
|
-
toView: attributes =>
|
|
300
|
-
h.button(
|
|
301
|
-
[
|
|
302
|
-
...attributes.button,
|
|
303
|
-
h.Class(
|
|
304
|
-
clsx(
|
|
305
|
-
'rounded-full px-4 py-2 text-sm font-medium shadow-lg transition cursor-pointer',
|
|
306
|
-
model.isPreviewVisible
|
|
307
|
-
? 'bg-gray-800 text-white'
|
|
308
|
-
: 'bg-indigo-600 text-white',
|
|
309
|
-
),
|
|
310
|
-
),
|
|
311
|
-
],
|
|
312
|
-
[model.isPreviewVisible ? 'Hide Preview' : 'Preview'],
|
|
313
|
-
),
|
|
314
|
-
},
|
|
315
|
-
h,
|
|
316
|
-
),
|
|
317
|
-
],
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
const mobilePreviewOverlay = (model: Model, h: HtmlBuilder<Message>): Html =>
|
|
321
|
-
h.div(
|
|
322
|
-
[
|
|
323
|
-
h.Class(
|
|
324
|
-
'fixed inset-x-4 top-16 bottom-4 overflow-y-auto rounded-xl border border-gray-200 bg-white p-6 shadow-2xl xl:hidden',
|
|
325
|
-
),
|
|
326
|
-
],
|
|
327
|
-
[preview(model)],
|
|
328
|
-
)
|
|
329
|
-
|
|
330
|
-
export const view = (model: Model, h: HtmlBuilder<Message>): Document => {
|
|
331
|
-
const attentionSteps = stepsNeedingAttention(model)
|
|
332
|
-
const attentionStepSet = HashSet.fromIterable(attentionSteps)
|
|
333
|
-
const body = h.div(
|
|
334
|
-
[h.Class('min-h-screen bg-gray-50')],
|
|
335
|
-
[
|
|
336
|
-
h.div(
|
|
337
|
-
[h.Class('mx-auto max-w-7xl px-4 py-8 sm:px-6 lg:px-8')],
|
|
338
|
-
[
|
|
339
|
-
pageHeader(h),
|
|
340
|
-
h.div(
|
|
341
|
-
[h.Class('mb-6 lg:hidden')],
|
|
342
|
-
[
|
|
343
|
-
stepMenu(
|
|
344
|
-
model,
|
|
345
|
-
attentionStepSet,
|
|
346
|
-
message => Message.GotStepMenuMessage({ message }),
|
|
347
|
-
h,
|
|
348
|
-
),
|
|
349
|
-
],
|
|
350
|
-
),
|
|
351
|
-
stepTabsLayout(model, attentionSteps, attentionStepSet, h),
|
|
352
|
-
],
|
|
353
|
-
),
|
|
354
|
-
],
|
|
355
|
-
)
|
|
356
|
-
|
|
357
|
-
return { title: 'Job Application', body }
|
|
358
|
-
}
|
|
1
|
+
export * as DatePicker from './datePicker'
|
|
2
|
+
export * as Field from './field'
|
|
3
|
+
export * as Icon from './icon'
|
|
@@ -7,7 +7,7 @@ import { Menu, Tabs } from '@foldkit/ui'
|
|
|
7
7
|
import { Step } from '../domain'
|
|
8
8
|
import type { Message } from '../message'
|
|
9
9
|
import { type Model } from '../model'
|
|
10
|
-
import
|
|
10
|
+
import * as Icon from './icon'
|
|
11
11
|
|
|
12
12
|
const StepMenu = Menu.create<Step.Step>()
|
|
13
13
|
|
|
@@ -125,7 +125,7 @@ const stepMenuTrigger = (
|
|
|
125
125
|
),
|
|
126
126
|
],
|
|
127
127
|
),
|
|
128
|
-
h.span([h.Class('text-gray-400 shrink-0')], [chevronDown()]),
|
|
128
|
+
h.span([h.Class('text-gray-400 shrink-0')], [Icon.chevronDown()]),
|
|
129
129
|
],
|
|
130
130
|
)
|
|
131
131
|
|