@sealcode/sealgen 0.8.47 → 0.8.48

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 (243) hide show
  1. package/@types/index.d.ts +1 -0
  2. package/@types/page/stateful-page.d.ts +34 -0
  3. package/@types/templates/stateful-page.d.ts +1 -0
  4. package/@types/utils/base64.d.ts +2 -0
  5. package/@types/utils/utils.d.ts +3 -0
  6. package/lib/add-route.js +3 -0
  7. package/lib/cli.js +0 -0
  8. package/lib/generate-routes.js +2 -1
  9. package/lib/index.js +1 -0
  10. package/lib/page/stateful-page.js +117 -0
  11. package/lib/templates/stateful-page.js +66 -0
  12. package/lib/utils/base64.js +12 -0
  13. package/lib/utils/utils.js +6 -1
  14. package/package.json +2 -1
  15. package/.arcconfig +0 -12
  16. package/.arclint +0 -18
  17. package/.eslintrc.js +0 -38
  18. package/.mocharc.js +0 -10
  19. package/.nycrc +0 -6
  20. package/.prettierrc +0 -21
  21. package/jenkins.sanity.sh +0 -3
  22. package/lib/add-collection.js.map +0 -1
  23. package/lib/add-route.js.map +0 -1
  24. package/lib/add-route.test.js.map +0 -1
  25. package/lib/build.js.map +0 -1
  26. package/lib/cli.js.map +0 -1
  27. package/lib/components/components.js.map +0 -1
  28. package/lib/components/tabs.js.map +0 -1
  29. package/lib/components/toggle-modal.js.map +0 -1
  30. package/lib/example.test.js.map +0 -1
  31. package/lib/find-scss-includes.js.map +0 -1
  32. package/lib/forms/controls/array.js.map +0 -1
  33. package/lib/forms/controls/autocomplete.js.map +0 -1
  34. package/lib/forms/controls/big-radio-group.js.map +0 -1
  35. package/lib/forms/controls/checkbox-group.js.map +0 -1
  36. package/lib/forms/controls/checkbox.js.map +0 -1
  37. package/lib/forms/controls/checkboxed-list-input.js.map +0 -1
  38. package/lib/forms/controls/collapsible-checkbox-group.js.map +0 -1
  39. package/lib/forms/controls/collapsible-field-group.js.map +0 -1
  40. package/lib/forms/controls/controls.js.map +0 -1
  41. package/lib/forms/controls/derived-frame.js.map +0 -1
  42. package/lib/forms/controls/derived.js.map +0 -1
  43. package/lib/forms/controls/dropdown.js.map +0 -1
  44. package/lib/forms/controls/editable-collection-subset.js.map +0 -1
  45. package/lib/forms/controls/field-group.js.map +0 -1
  46. package/lib/forms/controls/file.js.map +0 -1
  47. package/lib/forms/controls/form-control.js.map +0 -1
  48. package/lib/forms/controls/form-field-control.js.map +0 -1
  49. package/lib/forms/controls/form-header.js.map +0 -1
  50. package/lib/forms/controls/form-paragraph.js.map +0 -1
  51. package/lib/forms/controls/frame.js.map +0 -1
  52. package/lib/forms/controls/hidden-input.js.map +0 -1
  53. package/lib/forms/controls/html.js.map +0 -1
  54. package/lib/forms/controls/multiple-files.js.map +0 -1
  55. package/lib/forms/controls/multiple-photos.js.map +0 -1
  56. package/lib/forms/controls/number.js.map +0 -1
  57. package/lib/forms/controls/photo.js.map +0 -1
  58. package/lib/forms/controls/radio.js.map +0 -1
  59. package/lib/forms/controls/reverse-single-reference.js.map +0 -1
  60. package/lib/forms/controls/simple-input.js.map +0 -1
  61. package/lib/forms/controls/textarea.js.map +0 -1
  62. package/lib/forms/controls/tickable.js.map +0 -1
  63. package/lib/forms/fields/boolean.js.map +0 -1
  64. package/lib/forms/fields/boolean.test.js.map +0 -1
  65. package/lib/forms/fields/checkboxed-list.js.map +0 -1
  66. package/lib/forms/fields/collection-field.js.map +0 -1
  67. package/lib/forms/fields/email.js.map +0 -1
  68. package/lib/forms/fields/email.test.js.map +0 -1
  69. package/lib/forms/fields/enum-multiple.js.map +0 -1
  70. package/lib/forms/fields/enum-multiple.test.js.map +0 -1
  71. package/lib/forms/fields/enum.js.map +0 -1
  72. package/lib/forms/fields/enum.test.js.map +0 -1
  73. package/lib/forms/fields/existing-sealious-value.js.map +0 -1
  74. package/lib/forms/fields/field.js.map +0 -1
  75. package/lib/forms/fields/file.js.map +0 -1
  76. package/lib/forms/fields/multiple-files.js.map +0 -1
  77. package/lib/forms/fields/number.js.map +0 -1
  78. package/lib/forms/fields/number.test.js.map +0 -1
  79. package/lib/forms/fields/pick-from-list.js.map +0 -1
  80. package/lib/forms/fields/pick-from-list.test.js.map +0 -1
  81. package/lib/forms/fields/proxy-field.js.map +0 -1
  82. package/lib/forms/fields/regexp.js.map +0 -1
  83. package/lib/forms/fields/regexp.test.js.map +0 -1
  84. package/lib/forms/fields/reverse-single-reference.js.map +0 -1
  85. package/lib/forms/fields/simple-form-field.js.map +0 -1
  86. package/lib/forms/fields/structured-array.js.map +0 -1
  87. package/lib/forms/form.js.map +0 -1
  88. package/lib/forms/form.test.js.map +0 -1
  89. package/lib/forms/multiform.js.map +0 -1
  90. package/lib/forms/multiform.test.js.map +0 -1
  91. package/lib/generate-collections.js.map +0 -1
  92. package/lib/generate-routes.js.map +0 -1
  93. package/lib/index.js.map +0 -1
  94. package/lib/make-env.js.map +0 -1
  95. package/lib/make-hidden-inputs.js.map +0 -1
  96. package/lib/mount.js.map +0 -1
  97. package/lib/page/access-control.js.map +0 -1
  98. package/lib/page/list.js.map +0 -1
  99. package/lib/page/mountable-with-fields.js.map +0 -1
  100. package/lib/page/mountable.js.map +0 -1
  101. package/lib/page/page.js.map +0 -1
  102. package/lib/page/props-parser.js.map +0 -1
  103. package/lib/run.js.map +0 -1
  104. package/lib/sanitize.js.map +0 -1
  105. package/lib/templates/collection.js.map +0 -1
  106. package/lib/templates/form.js.map +0 -1
  107. package/lib/templates/list.js.map +0 -1
  108. package/lib/templates/multiform.js.map +0 -1
  109. package/lib/templates/page.js.map +0 -1
  110. package/lib/templates/post.js.map +0 -1
  111. package/lib/templates/redirect.js.map +0 -1
  112. package/lib/templates/route-test.js.map +0 -1
  113. package/lib/test_utils/locator_is_visible.js.map +0 -1
  114. package/lib/utils/assert-throws.js.map +0 -1
  115. package/lib/utils/browser-creator.js.map +0 -1
  116. package/lib/utils/escape-url-params.js.map +0 -1
  117. package/lib/utils/exec.js.map +0 -1
  118. package/lib/utils/format-external-url.js.map +0 -1
  119. package/lib/utils/import-path.js.map +0 -1
  120. package/lib/utils/input-wrapper.js.map +0 -1
  121. package/lib/utils/list-collections.js.map +0 -1
  122. package/lib/utils/make-slug.js.map +0 -1
  123. package/lib/utils/natural-numbers.js.map +0 -1
  124. package/lib/utils/prettier.js.map +0 -1
  125. package/lib/utils/question.js.map +0 -1
  126. package/lib/utils/render-attributes.js.map +0 -1
  127. package/lib/utils/sleep.js.map +0 -1
  128. package/lib/utils/translate.js.map +0 -1
  129. package/lib/utils/url-with-new-params.js.map +0 -1
  130. package/lib/utils/utils.js.map +0 -1
  131. package/lib/utils/walk.js.map +0 -1
  132. package/mocha_root_hooks.js +0 -6
  133. package/src/add-collection.ts +0 -31
  134. package/src/add-route.test.ts +0 -58
  135. package/src/add-route.ts +0 -86
  136. package/src/build.ts +0 -94
  137. package/src/cli.ts +0 -36
  138. package/src/components/components.ts +0 -2
  139. package/src/components/tabs.ts +0 -95
  140. package/src/components/toggle-modal.ts +0 -52
  141. package/src/example.test.ts +0 -3
  142. package/src/find-scss-includes.ts +0 -32
  143. package/src/forms/controls/array.ts +0 -226
  144. package/src/forms/controls/autocomplete.ts +0 -33
  145. package/src/forms/controls/big-radio-group.ts +0 -48
  146. package/src/forms/controls/checkbox-group.ts +0 -71
  147. package/src/forms/controls/checkbox.ts +0 -34
  148. package/src/forms/controls/checkboxed-list-input.ts +0 -50
  149. package/src/forms/controls/collapsible-checkbox-group.ts +0 -28
  150. package/src/forms/controls/collapsible-field-group.ts +0 -94
  151. package/src/forms/controls/controls.ts +0 -30
  152. package/src/forms/controls/derived-frame.ts +0 -91
  153. package/src/forms/controls/derived.ts +0 -108
  154. package/src/forms/controls/dropdown.ts +0 -87
  155. package/src/forms/controls/editable-collection-subset.ts +0 -97
  156. package/src/forms/controls/field-group.ts +0 -69
  157. package/src/forms/controls/file.ts +0 -47
  158. package/src/forms/controls/form-control.ts +0 -24
  159. package/src/forms/controls/form-field-control.ts +0 -22
  160. package/src/forms/controls/form-header.ts +0 -19
  161. package/src/forms/controls/form-paragraph.ts +0 -11
  162. package/src/forms/controls/frame.ts +0 -26
  163. package/src/forms/controls/hidden-input.ts +0 -22
  164. package/src/forms/controls/html.ts +0 -38
  165. package/src/forms/controls/multiple-files.ts +0 -256
  166. package/src/forms/controls/multiple-photos.ts +0 -44
  167. package/src/forms/controls/number.ts +0 -38
  168. package/src/forms/controls/photo.ts +0 -74
  169. package/src/forms/controls/radio.ts +0 -43
  170. package/src/forms/controls/reverse-single-reference.ts +0 -50
  171. package/src/forms/controls/simple-input.ts +0 -148
  172. package/src/forms/controls/textarea.ts +0 -60
  173. package/src/forms/controls/tickable.ts +0 -127
  174. package/src/forms/fields/boolean.test.ts +0 -36
  175. package/src/forms/fields/boolean.ts +0 -63
  176. package/src/forms/fields/checkboxed-list.ts +0 -66
  177. package/src/forms/fields/collection-field.ts +0 -62
  178. package/src/forms/fields/email.test.ts +0 -24
  179. package/src/forms/fields/email.ts +0 -20
  180. package/src/forms/fields/enum-multiple.test.ts +0 -31
  181. package/src/forms/fields/enum-multiple.ts +0 -62
  182. package/src/forms/fields/enum.test.ts +0 -25
  183. package/src/forms/fields/enum.ts +0 -56
  184. package/src/forms/fields/existing-sealious-value.ts +0 -22
  185. package/src/forms/fields/field.ts +0 -172
  186. package/src/forms/fields/file.ts +0 -89
  187. package/src/forms/fields/multiple-files.ts +0 -20
  188. package/src/forms/fields/number.test.ts +0 -34
  189. package/src/forms/fields/number.ts +0 -70
  190. package/src/forms/fields/pick-from-list.test.ts +0 -19
  191. package/src/forms/fields/pick-from-list.ts +0 -52
  192. package/src/forms/fields/proxy-field.ts +0 -24
  193. package/src/forms/fields/regexp.test.ts +0 -25
  194. package/src/forms/fields/regexp.ts +0 -53
  195. package/src/forms/fields/reverse-single-reference.ts +0 -20
  196. package/src/forms/fields/simple-form-field.ts +0 -30
  197. package/src/forms/fields/structured-array.ts +0 -27
  198. package/src/forms/form.test.ts +0 -351
  199. package/src/forms/form.ts +0 -294
  200. package/src/forms/forms.scss +0 -85
  201. package/src/forms/multiform.test.ts +0 -540
  202. package/src/forms/multiform.ts +0 -236
  203. package/src/generate-collections.ts +0 -77
  204. package/src/generate-routes.ts +0 -120
  205. package/src/index.ts +0 -24
  206. package/src/make-env.ts +0 -15
  207. package/src/make-hidden-inputs.ts +0 -24
  208. package/src/mount.ts +0 -85
  209. package/src/page/access-control.ts +0 -18
  210. package/src/page/list.ts +0 -240
  211. package/src/page/mountable-with-fields.ts +0 -158
  212. package/src/page/mountable.ts +0 -13
  213. package/src/page/page.ts +0 -46
  214. package/src/page/props-parser.ts +0 -38
  215. package/src/run.ts +0 -0
  216. package/src/sanitize.ts +0 -9
  217. package/src/templates/collection.ts +0 -11
  218. package/src/templates/form.ts +0 -60
  219. package/src/templates/list.ts +0 -75
  220. package/src/templates/multiform.ts +0 -58
  221. package/src/templates/page.ts +0 -25
  222. package/src/templates/post.ts +0 -21
  223. package/src/templates/redirect.ts +0 -22
  224. package/src/templates/route-test.ts +0 -27
  225. package/src/test_utils/locator_is_visible.ts +0 -17
  226. package/src/utils/assert-throws.ts +0 -18
  227. package/src/utils/browser-creator.js +0 -10
  228. package/src/utils/escape-url-params.ts +0 -14
  229. package/src/utils/exec.ts +0 -30
  230. package/src/utils/format-external-url.ts +0 -13
  231. package/src/utils/import-path.ts +0 -25
  232. package/src/utils/input-wrapper.ts +0 -21
  233. package/src/utils/list-collections.ts +0 -16
  234. package/src/utils/make-slug.ts +0 -5
  235. package/src/utils/natural-numbers.ts +0 -5
  236. package/src/utils/prettier.ts +0 -13
  237. package/src/utils/question.ts +0 -23
  238. package/src/utils/render-attributes.ts +0 -17
  239. package/src/utils/sleep.ts +0 -3
  240. package/src/utils/translate.ts +0 -13
  241. package/src/utils/url-with-new-params.ts +0 -9
  242. package/src/utils/utils.ts +0 -14
  243. package/src/utils/walk.ts +0 -20
@@ -1,226 +0,0 @@
1
- import Router from "@koa/router";
2
- import { hasShape, predicates } from "@sealcode/ts-predicates";
3
- import { Context } from "koa";
4
- import qs from "qs";
5
- import { Field, FieldsetOutput } from "sealious";
6
- import { tempstream } from "tempstream";
7
- import { Controls, Fields } from "../..";
8
- import { FormField, StructuredArrayField } from "../fields/field";
9
- import { FormDataValue } from "../form";
10
- import { FormControl } from "./controls";
11
- import { FormControlContext } from "./form-control";
12
- import { FormFieldControl } from "./form-field-control";
13
-
14
- export type UnboundControlStorage<
15
- F extends { new (...args: any): FormFieldControl } = {
16
- new (...args: any): FormFieldControl;
17
- }
18
- > = [F, string, ConstructorParameters<F>];
19
-
20
- export function UnboundControl<
21
- F extends { new (...args: any): FormFieldControl }
22
- >(
23
- controlClass: F,
24
- arbitrary_field_name: string,
25
- params: ConstructorParameters<F>["1"]
26
- ): UnboundControlStorage {
27
- return [controlClass, arbitrary_field_name, params];
28
- }
29
-
30
- export class StructuredArray<
31
- Subfields extends Record<string, Field>
32
- > extends FormFieldControl {
33
- constructor(
34
- public field: StructuredArrayField<Subfields>,
35
- public item_controls: Array<FormControl | UnboundControlStorage>
36
- ) {
37
- super([field]);
38
- }
39
-
40
- getFrameID() {
41
- return `array-frame-${this.field.name}`;
42
- }
43
-
44
- getInnerFormID() {
45
- return this.getFrameID() + "-form";
46
- }
47
-
48
- getActionURL(form_id?: string, action?: Record<string, unknown>) {
49
- return `${this.getFrameID()}${
50
- form_id || action ? "?" : ""
51
- }${qs.stringify({ form_id, action })}`;
52
- }
53
-
54
- async getDefaultItemBody() {
55
- return {};
56
- }
57
-
58
- makeSubfield(_field_name: string): FormField {
59
- const fields = this;
60
- return new Fields.SimpleFormField(false);
61
- }
62
-
63
- async renderItemControl(
64
- ctx: Context,
65
- form_id: string,
66
- control: FormControl | UnboundControlStorage,
67
- item: FieldsetOutput<Subfields>,
68
- index: number
69
- ) {
70
- const fctx = {
71
- ctx,
72
- data: {},
73
- messages: [],
74
- field_name_prefix: "",
75
- form_id,
76
- validate: false,
77
- };
78
- if (Array.isArray(control)) {
79
- const [constructor, field_name, params] = control;
80
- const field = this.makeSubfield(field_name);
81
- if (!field) {
82
- console.warn(
83
- `makeSubfield returned null for field ${field_name}`
84
- );
85
- return "";
86
- }
87
- await field.init(
88
- `${this.field.name}[data][${index}][${field_name}]`
89
- );
90
- const hidden_shadow = new Controls.Derived(
91
- [field],
92
- async (
93
- values,
94
- { inner_form_id, field_name }
95
- ) => /* HTML */ `<input
96
- name="${field_name}"
97
- type="hidden"
98
- value="${values[field_name] || ""}"
99
- form="${inner_form_id}"
100
- />`,
101
- async () => ({
102
- inner_form_id: this.getInnerFormID(),
103
- field_name: field.name,
104
- })
105
- );
106
- return tempstream`${new constructor(field, params).render({
107
- ...fctx,
108
- data: { [field.name]: item[field_name] as FormDataValue },
109
- })}${hidden_shadow.render({
110
- ...fctx,
111
- data: { [field.name]: item[field_name] as FormDataValue },
112
- form_id: this.getInnerFormID(),
113
- })}`;
114
- } else {
115
- return control.render(fctx);
116
- }
117
- }
118
-
119
- async renderItem(
120
- ctx: Context,
121
- form_id: string,
122
- item: FieldsetOutput<Subfields>,
123
- index: number
124
- ) {
125
- return tempstream/* HTML */ `<div>
126
- ${this.item_controls.map((control) =>
127
- this.renderItemControl(ctx, form_id, control, item, index)
128
- )}
129
- <input
130
- type="submit"
131
- value="remove"
132
- form="${this.getInnerFormID()}"
133
- formaction="${this.getActionURL(form_id, {
134
- remove: index,
135
- })}"
136
- />
137
- </div>`;
138
- }
139
-
140
- async getItems(ctx: Context, raw_values: Record<string, FormDataValue>) {
141
- return (await this.field.getValue(ctx, raw_values)).parsed as Promise<
142
- FieldsetOutput<Subfields>[]
143
- >;
144
- }
145
-
146
- async _render(
147
- ctx: Context,
148
- form_id: string,
149
- raw_values: Record<string, FormDataValue>
150
- ) {
151
- const items = await this.getItems(ctx, raw_values);
152
-
153
- return tempstream/* HTML */ `<turbo-frame id="${this.getFrameID()}">
154
- Reverse Single Reference
155
- ${items.map((item, index) =>
156
- this.renderItem(ctx, form_id, item, index)
157
- )}
158
- <form id="${this.getInnerFormID()}" method="POST"></form>
159
- <input
160
- type="submit"
161
- value="add"
162
- form="${this.getInnerFormID()}"
163
- formaction="${this.getActionURL(form_id, {
164
- insert: { index: items.length, value: {} },
165
- })}"
166
- />
167
- </turbo-frame>`;
168
- }
169
-
170
- render(fctx: FormControlContext) {
171
- return this._render(fctx.ctx, fctx.form_id, fctx.data);
172
- }
173
-
174
- async getTargetItemID(ctx: Context): Promise<string> {
175
- return ctx.params.id;
176
- }
177
-
178
- mount(router: Router) {
179
- console.log("mounting!", this.getActionURL());
180
- router.post(this.getActionURL(), async (ctx) => {
181
- let form_id = ctx.query.form_id;
182
- if (typeof form_id != "string") {
183
- throw new Error("Missing form_id query param");
184
- }
185
-
186
- const item = await this.field.sealious_field.collection.getByID(
187
- ctx.$context,
188
- await this.getTargetItemID(ctx)
189
- );
190
-
191
- if (!hasShape({ action: predicates.object }, ctx.$body)) {
192
- throw new Error("Missing action param");
193
- }
194
-
195
- const field_data = ctx.$body[this.field.name] || { data: [] };
196
- console.log({ action: field_data });
197
- if (
198
- !hasShape(
199
- {
200
- data: predicates.array(
201
- this.field.sealious_field.value_predicate
202
- ),
203
- },
204
- field_data
205
- )
206
- ) {
207
- throw new Error("missing data atribute in action description");
208
- }
209
- item.set(this.field.name, {
210
- ...ctx.$body.action,
211
- data: field_data.data || [],
212
- });
213
- console.log("ACTION", {
214
- ...ctx.$body.action,
215
- data: field_data.data || [],
216
- });
217
- await item.save(ctx.$context);
218
- console.log(await item.getDecodedBody(ctx.$context, {}));
219
- ctx.body = this._render(
220
- ctx,
221
- form_id,
222
- await item.getDecodedBody(ctx.$context, {})
223
- );
224
- });
225
- }
226
- }
@@ -1,33 +0,0 @@
1
- import { Context } from "koa";
2
- import { PickFromListField } from "../fields/pick-from-list";
3
- import { FormDataValue } from "../form";
4
- import { FormControlContext } from "./form-control";
5
- import { SimpleInput } from "./simple-input";
6
-
7
- export class Autocomplete extends SimpleInput<string | null> {
8
- constructor(
9
- public field: PickFromListField<boolean>,
10
- public options: { id?: string; label?: string; placeholder?: string }
11
- ) {
12
- super(field);
13
- }
14
-
15
- getListID(): string {
16
- return this.getID() + "_list";
17
- }
18
-
19
- async getInputAttributes(fctx: FormControlContext) {
20
- return {
21
- ...(await super.getInputAttributes(fctx)),
22
- list: this.getListID(),
23
- };
24
- }
25
-
26
- async postInput(ctx: Context) {
27
- return /* HTML */ `<datalist id="${this.getListID()}">
28
- ${(await this.field.generateOptions(ctx)).map(
29
- ({ value }) => /* HTML */ `<option>${value}</option>`
30
- )}
31
- </datalist>`;
32
- }
33
- }
@@ -1,48 +0,0 @@
1
- import { FlatTemplatable, tempstream } from "tempstream";
2
- import { FormField } from "../fields/field";
3
- import { FormControlContext } from "./form-control";
4
- import { FormFieldControl } from "./form-field-control";
5
-
6
- export class BigRadioGroup extends FormFieldControl {
7
- constructor(
8
- public field: FormField,
9
- public options: Record<
10
- string,
11
- {
12
- description:
13
- | FlatTemplatable
14
- | ((fctx: FormControlContext) => FlatTemplatable);
15
- }
16
- >
17
- ) {
18
- super([field]);
19
- }
20
-
21
- async render(fctx: FormControlContext): Promise<FlatTemplatable> {
22
- const { raw: current_value } = await this.field.getValue(
23
- fctx.ctx,
24
- fctx.data
25
- );
26
- return tempstream/* HTML */ `<div class="bigradios">
27
- ${Object.entries(this.options).map(([key, { description }]) => {
28
- const id = `${this.field.name}-radio-${key}`;
29
- return tempstream/* HTML */ `<input
30
- type="radio"
31
- name="${this.field.name}"
32
- value="${key}"
33
- id="${id}"
34
- style="display: none"
35
- ${fctx.form_id ? `form=${fctx.form_id}` : ""}
36
- ${this.field.required ? "required" : ""}
37
- ${key == current_value ? "checked" : ""}
38
- />
39
- <div class="bigradio">
40
- ${typeof description == "function"
41
- ? description(fctx)
42
- : description}
43
- <label class="bigradio__cta" for="${id}">Wybierz</label>
44
- </div>`;
45
- })}
46
- </div>`;
47
- }
48
- }
@@ -1,71 +0,0 @@
1
- import { Context } from "koa";
2
- import { FlatTemplatable } from "tempstream";
3
- import { EnumMultipleField, FormField } from "../fields/field";
4
- import { ProxyFormField } from "../fields/proxy-field";
5
- import { FormDataValue, FormMessage } from "../form";
6
- import { CheckboxWithValue } from "./checkbox";
7
- import { FieldGroup, FormFieldControl } from "./controls";
8
- import { FormControlContext } from "./form-control";
9
-
10
- export type DefaultCheckboxOptions = {
11
- id?: string;
12
- label?: string;
13
- hide_errors?: boolean;
14
- readonly?: boolean;
15
- name?: string;
16
- checkboxNameToLabel?: (name: string) => string;
17
- classes?: string[];
18
- };
19
-
20
- export class CheckboxGroup<
21
- Options extends DefaultCheckboxOptions = DefaultCheckboxOptions
22
- > extends FormFieldControl {
23
- constructor(
24
- public field: EnumMultipleField<readonly string[], boolean>,
25
- public options: Options = {} as Options
26
- ) {
27
- super([field]);
28
- }
29
-
30
- wrapGroup(
31
- fctx: FormControlContext,
32
- checkboxes: CheckboxWithValue[]
33
- ): Promise<FlatTemplatable> {
34
- return new FieldGroup(checkboxes, {
35
- label: this.options.label,
36
- classes: [
37
- ...(this.options.classes || []),
38
- "field-group--checkboxes",
39
- ],
40
- }).render(fctx);
41
- }
42
-
43
- async render<Fields extends Record<string, FormField>>(
44
- fctx: FormControlContext
45
- ): Promise<FlatTemplatable> {
46
- const { parsed: values } = await this.field.getValue(
47
- fctx.ctx,
48
- fctx.data
49
- );
50
- const checkboxes = this.field.options.map(
51
- (option) =>
52
- new CheckboxWithValue(
53
- new ProxyFormField(
54
- false,
55
- this.field.name,
56
- false,
57
- values.includes(option)
58
- ),
59
- {
60
- id: this.field.name + "__" + option,
61
- label: (
62
- this.options.checkboxNameToLabel ||
63
- ((s: string) => s)
64
- )(option),
65
- },
66
- option
67
- )
68
- );
69
- return this.wrapGroup(fctx, checkboxes);
70
- }
71
- }
@@ -1,34 +0,0 @@
1
- import { Context } from "koa";
2
- import { FormDataValue } from "../form";
3
- import { Tickable, TickableOptions } from "./tickable";
4
- import { FormField } from "../fields/field";
5
-
6
- export class Checkbox extends Tickable<boolean> {
7
- type = <const>"checkbox";
8
-
9
- isChecked(
10
- _ctx: Context,
11
- _data: Record<string, FormDataValue>,
12
- value: boolean
13
- ): boolean {
14
- return value;
15
- }
16
-
17
- getValueAttribute(): string {
18
- return "";
19
- }
20
- }
21
-
22
- export class CheckboxWithValue extends Checkbox {
23
- constructor(
24
- public field: FormField<boolean, boolean>,
25
- options: TickableOptions,
26
- public value: string
27
- ) {
28
- super(field, options);
29
- }
30
-
31
- getValueAttribute(): string {
32
- return this.value;
33
- }
34
- }
@@ -1,50 +0,0 @@
1
- import { is, predicates } from "@sealcode/ts-predicates";
2
- import { Context } from "koa";
3
- import { tempstream } from "tempstream";
4
- import { getRequiredClass, inputWrapper } from "../../utils/input-wrapper";
5
- import { ChekboxedListField } from "../fields/field";
6
- import { FormDataValue } from "../form";
7
- import { FormFieldControl } from "./controls";
8
- import { FormControlContext } from "./form-control";
9
-
10
- export class CheckboxedListInput extends FormFieldControl {
11
- constructor(
12
- public field: ChekboxedListField<boolean>,
13
- public options: { label: string } = { label: field.name }
14
- ) {
15
- super([field]);
16
- }
17
-
18
- async render(fctx: FormControlContext) {
19
- const { parsed: pickedValues } = await this.field.getValue(
20
- fctx.ctx,
21
- fctx.data
22
- );
23
- if (!is(pickedValues, predicates.array(predicates.string))) {
24
- throw new Error("picked values is not an array of strings");
25
- }
26
- const [options, isVisible] = await Promise.all([
27
- this.field.generateOptions(fctx.ctx),
28
- this.field.isVisible(fctx.ctx),
29
- ]);
30
-
31
- const { name, required } = this.field;
32
-
33
- return tempstream/* HTML */ `${isVisible
34
- ? Object.entries(options).map(([value, text]) =>
35
- inputWrapper(
36
- [name, getRequiredClass(required)],
37
- /* HTML */ `
38
- <input
39
- type="checkbox"
40
- id="${name}.${value}"
41
- name="${name}.${value}"
42
- ${pickedValues.includes(value) ? "checked" : ""}
43
- />
44
- <label for="${name}.${value}">${text}</label>
45
- `
46
- )
47
- )
48
- : ""}`;
49
- }
50
- }
@@ -1,28 +0,0 @@
1
- import { Context } from "koa";
2
- import { FlatTemplatable } from "tempstream";
3
- import { FormDataValue, FormMessage } from "../form";
4
- import { CheckboxWithValue } from "./checkbox";
5
- import { FieldGroup, FormFieldControl } from "./controls";
6
- import { CheckboxGroup, DefaultCheckboxOptions } from "./checkbox-group";
7
- import { CollapsibleFieldGroup } from "./collapsible-field-group";
8
- import { FormControlContext } from "./form-control";
9
-
10
- export class CollapsibleCheckboxGroup extends CheckboxGroup<
11
- DefaultCheckboxOptions & {
12
- textWhenOpen?: string;
13
- textWhenClosed?: string;
14
- groupID?: string;
15
- }
16
- > {
17
- wrapGroup(
18
- fctx: FormControlContext,
19
- checkboxes: CheckboxWithValue[]
20
- ): Promise<FlatTemplatable> {
21
- return new CollapsibleFieldGroup(checkboxes, {
22
- label: this.options.label,
23
- textWhenOpen: this.options.textWhenOpen,
24
- textWhenClosed: this.options.textWhenClosed,
25
- groupID: this.options.groupID,
26
- }).render(fctx);
27
- }
28
- }
@@ -1,94 +0,0 @@
1
- import { FlatTemplatable } from "tempstream";
2
- import { FieldGroup } from "./field-group";
3
- import { randomUUID } from "crypto";
4
- import { FormControl } from "./form-control";
5
-
6
- type CollapsibleFieldGroupOptions = {
7
- label?: string;
8
- classes?: string[];
9
- openOnStart?: boolean;
10
- textWhenOpen?: string;
11
- textWhenClosed?: string;
12
- groupID?: string;
13
- };
14
-
15
- export class CollapsibleFieldGroup extends FieldGroup {
16
- public collapseID: string;
17
- constructor(
18
- public controls: FormControl[],
19
- public options: CollapsibleFieldGroupOptions = {}
20
- ) {
21
- super([]);
22
- if (this.options.groupID == undefined) {
23
- this.options.groupID = "A" + randomUUID(); // "A" is needed as ids always have to start with a letter
24
- }
25
- this.collapseID = this.options.groupID + "collapse";
26
- }
27
-
28
- getGroupLabelProps() {
29
- return super.getGroupLabelProps() + ` for="${this.collapseID}"`;
30
- }
31
-
32
- preLabelContainer(): FlatTemplatable {
33
- return /* HTML */ `<style>
34
- input#${this.collapseID} {
35
- display: none;
36
- }
37
-
38
- input#${this.collapseID} ~ .field-group__fields {
39
- display: none;
40
- }
41
-
42
- input#${this.collapseID}:checked ~ .field-group__fields {
43
- display: block;
44
- }
45
-
46
- input#${this.collapseID}
47
- ~ .field-group__label-container
48
- .field-group__collapse-label-text--open {
49
- display: none;
50
- }
51
-
52
- input#${this.collapseID}:checked
53
- ~ .field-group__label-container
54
- .field-group__collapse-label-text--open {
55
- display: inline-block;
56
- }
57
-
58
- input#${this.collapseID}
59
- ~ .field-group__label-container
60
- .field-group__collapse-label-text--closed {
61
- display: inline-block;
62
- }
63
-
64
- input#${this.collapseID}:checked
65
- ~ .field-group__label-container
66
- .field-group__collapse-label-text--closed {
67
- display: none;
68
- }
69
- </style>
70
- <input
71
- type="checkbox"
72
- id="${this.collapseID}"
73
- ${this.options.openOnStart ? "checked" : ""}
74
- />`;
75
- }
76
-
77
- postLabel(): FlatTemplatable {
78
- return /* HTML */ `<label
79
- class="field-group__collapse-label"
80
- for="${this.collapseID}"
81
- >
82
- <span
83
- class="field-group__collapse-label-text field-group__collapse-label-text--open"
84
- >
85
- ${this.options.textWhenOpen || "close"}
86
- </span>
87
- <span
88
- class="field-group__collapse-label-text field-group__collapse-label-text--closed"
89
- >
90
- ${this.options.textWhenClosed || "open"}
91
- </span>
92
- </label>`;
93
- }
94
- }
@@ -1,30 +0,0 @@
1
- export { FormControl } from "./form-control";
2
- export { FormFieldControl } from "./form-field-control";
3
- export { EditableCollectionSubset } from "./editable-collection-subset";
4
- export { Frame } from "./frame";
5
- export { CheckboxedListInput } from "./checkboxed-list-input";
6
- export * from "./dropdown";
7
- export { SimpleInput } from "./simple-input";
8
- export { FormHeader } from "./form-header";
9
- export { FormParagraph } from "./form-paragraph";
10
- export { HTML } from "./html";
11
- export { HiddenInput } from "./hidden-input";
12
- export { Textarea } from "./textarea";
13
- export { FieldGroup } from "./field-group";
14
- export * from "./derived";
15
- export * from "./derived-frame";
16
- export * from "./tickable";
17
- export * from "./checkbox";
18
- export * from "./radio";
19
- export * from "./big-radio-group";
20
- export * from "./checkbox-group";
21
- export * from "./collapsible-field-group";
22
- export * from "./collapsible-checkbox-group";
23
- export * from "./autocomplete";
24
- export * from "./file";
25
- export * from "./photo";
26
- export * from "./multiple-files";
27
- export * from "./number";
28
- export * from "./multiple-photos";
29
- // export * from "./reverse-single-reference";
30
- export * from "./array";