@sealcode/sealgen 0.8.11 → 0.8.13

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.
@@ -21,5 +21,6 @@ export * from "./collapsible-field-group";
21
21
  export * from "./collapsible-checkbox-group";
22
22
  export * from "./autocomplete";
23
23
  export * from "./file";
24
+ export * from "./photo";
24
25
  export * from "./multiple-files";
25
26
  export * from "./number";
@@ -1,14 +1,15 @@
1
+ /// <reference types="node" />
1
2
  import { Context } from "koa";
3
+ import { FlatTemplatable } from "tempstream";
2
4
  import { FileContainer } from "../fields/file";
3
5
  import { FormDataValue } from "../form";
4
6
  import { SimpleInput } from "./simple-input";
5
7
  export declare class File extends SimpleInput<FileContainer> {
6
8
  getType(): string;
7
- preInput(ctx: Context, data: Record<string, FormDataValue>): Promise<string>;
8
- getInputAttributes(ctx: Context, data: Record<string, FormDataValue>, field_prefix: string, form_id: string): Promise<{
9
- name: string;
10
- required: boolean | "";
11
- value: boolean;
12
- onchange: string;
13
- }>;
9
+ renderFilePreview(ctx: Context, file_data: {
10
+ id?: string;
11
+ filename?: string;
12
+ }): Promise<FlatTemplatable>;
13
+ preInput(ctx: Context, data: Record<string, FormDataValue>): Promise<import("stream").Readable>;
14
+ getInputAttributes(ctx: Context, data: Record<string, FormDataValue>, field_prefix: string, form_id: string): Promise<Record<string, string | boolean>>;
14
15
  }
@@ -0,0 +1,20 @@
1
+ import { Context } from "koa";
2
+ import { FlatTemplatable } from "tempstream";
3
+ import { File } from "./file";
4
+ import { FileContainer, FormField } from "../fields/field";
5
+ import { SimpleInputOptions } from "./simple-input";
6
+ import KoaResponsiveImageRouter from "koa-responsive-image-router";
7
+ import { FormDataValue } from "../form";
8
+ export declare class Photo extends File {
9
+ field: FormField<boolean, FileContainer>;
10
+ imageRouter: KoaResponsiveImageRouter;
11
+ constructor(field: FormField<boolean, FileContainer>, imageRouter: KoaResponsiveImageRouter, options?: SimpleInputOptions);
12
+ getImgStyle(): Promise<string>;
13
+ renderFilePreview(ctx: Context, file_data: {
14
+ id?: string;
15
+ filename?: string;
16
+ }): Promise<FlatTemplatable>;
17
+ getInputAttributes(ctx: Context, data: Record<string, FormDataValue>, field_prefix: string, form_id: string): Promise<{
18
+ onchange: string;
19
+ }>;
20
+ }
@@ -47,6 +47,7 @@ __exportStar(require("./collapsible-field-group"), exports);
47
47
  __exportStar(require("./collapsible-checkbox-group"), exports);
48
48
  __exportStar(require("./autocomplete"), exports);
49
49
  __exportStar(require("./file"), exports);
50
+ __exportStar(require("./photo"), exports);
50
51
  __exportStar(require("./multiple-files"), exports);
51
52
  __exportStar(require("./number"), exports);
52
53
  //# sourceMappingURL=controls.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"controls.js","sourceRoot":"","sources":["../../../src/forms/controls/controls.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,2DAAwD;AAA/C,sHAAA,gBAAgB,OAAA;AACzB,2EAAwE;AAA/D,sIAAA,wBAAwB,OAAA;AACjC,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAC5B,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,6CAA2C;AAAlC,yGAAA,UAAU,OAAA;AACnB,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,6CAA2C;AAAlC,yGAAA,UAAU,OAAA;AACnB,4CAA0B;AAC1B,6CAA2B;AAC3B,6CAA2B;AAC3B,0CAAwB;AACxB,oDAAkC;AAClC,mDAAiC;AACjC,4DAA0C;AAC1C,+DAA6C;AAC7C,iDAA+B;AAC/B,yCAAuB;AACvB,mDAAiC;AACjC,2CAAyB"}
1
+ {"version":3,"file":"controls.js","sourceRoot":"","sources":["../../../src/forms/controls/controls.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,2DAAwD;AAA/C,sHAAA,gBAAgB,OAAA;AACzB,2EAAwE;AAA/D,sIAAA,wBAAwB,OAAA;AACjC,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAC5B,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,6CAA2C;AAAlC,yGAAA,UAAU,OAAA;AACnB,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,6CAA2C;AAAlC,yGAAA,UAAU,OAAA;AACnB,4CAA0B;AAC1B,6CAA2B;AAC3B,6CAA2B;AAC3B,0CAAwB;AACxB,oDAAkC;AAClC,mDAAiC;AACjC,4DAA0C;AAC1C,+DAA6C;AAC7C,iDAA+B;AAC/B,yCAAuB;AACvB,0CAAwB;AACxB,mDAAiC;AACjC,2CAAyB"}
@@ -1,14 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.File = void 0;
4
+ const tempstream_1 = require("tempstream");
4
5
  const simple_input_1 = require("./simple-input");
5
6
  class File extends simple_input_1.SimpleInput {
6
7
  getType() {
7
8
  return "file";
8
9
  }
10
+ async renderFilePreview(ctx, file_data) {
11
+ return file_data.filename || "";
12
+ }
9
13
  async preInput(ctx, data) {
10
14
  const { parsed } = await this.field.getValue(ctx, data);
11
- return /* HTML */ ` ${parsed.old?.filename || ""}
15
+ return tempstream_1.tempstream /* HTML */ `${parsed.old
16
+ ? this.renderFilePreview(ctx, parsed.old)
17
+ : ""}
12
18
  <input
13
19
  type="hidden"
14
20
  name="${this.field.name}[old][id]"
@@ -28,9 +34,6 @@ class File extends simple_input_1.SimpleInput {
28
34
  name: this.field.name + "[new]",
29
35
  required: original.required && !parsed.old,
30
36
  value: false,
31
- onchange: (original.onchange || "") +
32
- ";" +
33
- "filename = this.value.split('\\\\').slice(-1)[0]; this.parentElement.style.setProperty('--filename', '\\'Wybrany plik: ' + filename + '\\'')",
34
37
  };
35
38
  }
36
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"file.js","sourceRoot":"","sources":["../../../src/forms/controls/file.ts"],"names":[],"mappings":";;;AAGA,iDAA6C;AAE7C,MAAa,IAAK,SAAQ,0BAA0B;IACnD,OAAO;QACN,OAAO,MAAM,CAAC;IACf,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAY,EAAE,IAAmC;QAC/D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACxD,OAAO,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,EAAE,QAAQ,IAAI,EAAE;;;YAGtC,IAAI,CAAC,KAAK,CAAC,IAAI;aACd,MAAM,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE;;;;YAIrB,IAAI,CAAC,KAAK,CAAC,IAAI;aACd,MAAM,CAAC,GAAG,EAAE,QAAQ,IAAI,EAAE;MACjC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,kBAAkB,CACvB,GAAY,EACZ,IAAmC,EACnC,YAAoB,EACpB,OAAe;QAEf,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,kBAAkB,CAC9C,GAAG,EACH,IAAI,EACJ,YAAY,EACZ,OAAO,CACP,CAAC;QACF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACxD,OAAO;YACN,GAAG,QAAQ;YACX,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO;YAC/B,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG;YAC1C,KAAK,EAAE,KAAK;YACZ,QAAQ,EACP,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC;gBACzB,GAAG;gBACH,8IAA8I;SAC/I,CAAC;IACH,CAAC;CACD;AA5CD,oBA4CC"}
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../../src/forms/controls/file.ts"],"names":[],"mappings":";;;AACA,2CAAyD;AAGzD,iDAA6C;AAE7C,MAAa,IAAK,SAAQ,0BAA0B;IACnD,OAAO;QACN,OAAO,MAAM,CAAC;IACf,CAAC;IAED,KAAK,CAAC,iBAAiB,CACtB,GAAY,EACZ,SAA6C;QAE7C,OAAO,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAY,EAAE,IAAmC;QAC/D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACxD,OAAO,uBAAU,CAAA,UAAU,CAAC,GAAG,MAAM,CAAC,GAAG;YACvC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC;YACzC,CAAC,CAAC,EAAE;;;YAGI,IAAI,CAAC,KAAK,CAAC,IAAI;aACd,MAAM,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE;;;;YAIrB,IAAI,CAAC,KAAK,CAAC,IAAI;aACd,MAAM,CAAC,GAAG,EAAE,QAAQ,IAAI,EAAE;MACjC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,kBAAkB,CACvB,GAAY,EACZ,IAAmC,EACnC,YAAoB,EACpB,OAAe;QAEf,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,kBAAkB,CAC9C,GAAG,EACH,IAAI,EACJ,YAAY,EACZ,OAAO,CACP,CAAC;QACF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACxD,OAAO;YACN,GAAG,QAAQ;YACX,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO;YAC/B,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG;YAC1C,KAAK,EAAE,KAAK;SACZ,CAAC;IACH,CAAC;CACD;AAjDD,oBAiDC"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Photo = void 0;
4
+ const tempstream_1 = require("tempstream");
5
+ const file_1 = require("./file");
6
+ const sealious_1 = require("sealious");
7
+ class Photo extends file_1.File {
8
+ constructor(field, imageRouter, options) {
9
+ super(field, options);
10
+ this.field = field;
11
+ this.imageRouter = imageRouter;
12
+ }
13
+ async getImgStyle() {
14
+ return "width: 100px; height: 100px; object-fit: contain";
15
+ }
16
+ async renderFilePreview(ctx, file_data) {
17
+ const { id, filename } = file_data;
18
+ const class_name = "file_preview";
19
+ if (!id) {
20
+ return `<div class="${class_name}"></div>`;
21
+ }
22
+ const file = await sealious_1.File.fromID(ctx.$app, id);
23
+ return tempstream_1.tempstream /* HTML */ `<div class="${class_name}">
24
+ ${this.imageRouter.image({
25
+ resolutions: [100],
26
+ sizes_attr: "100px",
27
+ path: file.getDataPath(),
28
+ img_style: await this.getImgStyle(),
29
+ })}
30
+ </div>`;
31
+ }
32
+ async getInputAttributes(ctx, data, field_prefix, form_id) {
33
+ const original = (await super.getInputAttributes(ctx, data, field_prefix, form_id));
34
+ const { parsed } = await this.field.getValue(ctx, data);
35
+ return {
36
+ ...original,
37
+ onchange: (original.onchange || "") +
38
+ ";" +
39
+ `
40
+ const file = this.files[0];
41
+ const preview_container = this.parentElement.querySelector(".file_preview");
42
+ const target = this;
43
+ if (file) {
44
+ const fileReader = new FileReader();
45
+ fileReader.readAsDataURL(file);
46
+ fileReader.addEventListener("load", function () {
47
+ preview_container.innerHTML = \`<img src="\${this.result}" style="${await this.getImgStyle()}" />\`;
48
+ });
49
+ }`
50
+ .replaceAll("\n", " ")
51
+ .replaceAll(`"`, "'"),
52
+ };
53
+ }
54
+ }
55
+ exports.Photo = Photo;
56
+ //# sourceMappingURL=photo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"photo.js","sourceRoot":"","sources":["../../../src/forms/controls/photo.ts"],"names":[],"mappings":";;;AACA,2CAAyD;AACzD,iCAA8B;AAC9B,uCAAgD;AAMhD,MAAa,KAAM,SAAQ,WAAI;IAC9B,YACQ,KAAwC,EACxC,WAAqC,EAC5C,OAA4B;QAE5B,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAJf,UAAK,GAAL,KAAK,CAAmC;QACxC,gBAAW,GAAX,WAAW,CAA0B;IAI7C,CAAC;IAED,KAAK,CAAC,WAAW;QAChB,OAAO,kDAAkD,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,iBAAiB,CACtB,GAAY,EACZ,SAA6C;QAE7C,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC;QACnC,MAAM,UAAU,GAAG,cAAc,CAAC;QAClC,IAAI,CAAC,EAAE,EAAE;YACR,OAAO,eAAe,UAAU,UAAU,CAAC;SAC3C;QACD,MAAM,IAAI,GAAG,MAAM,eAAY,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACrD,OAAO,uBAAU,CAAA,UAAU,CAAC,eAAe,UAAU;KAClD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;YACxB,WAAW,EAAE,CAAC,GAAG,CAAC;YAClB,UAAU,EAAE,OAAO;YACnB,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE;YACxB,SAAS,EAAE,MAAM,IAAI,CAAC,WAAW,EAAE;SACnC,CAAC;SACI,CAAC;IACT,CAAC;IAED,KAAK,CAAC,kBAAkB,CACvB,GAAY,EACZ,IAAmC,EACnC,YAAoB,EACpB,OAAe;QAEf,MAAM,QAAQ,GAAG,CAAC,MAAM,KAAK,CAAC,kBAAkB,CAC/C,GAAG,EACH,IAAI,EACJ,YAAY,EACZ,OAAO,CACP,CAAqC,CAAC;QACvC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACxD,OAAO;YACN,GAAG,QAAQ;YACX,QAAQ,EACP,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC;gBACzB,GAAG;gBACH;;;;;;;;4EAQwE,MAAM,IAAI,CAAC,WAAW,EAAE;;EAElG;qBACI,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC;qBACrB,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC;SACvB,CAAC;IACH,CAAC;CACD;AAlED,sBAkEC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sealcode/sealgen",
3
- "version": "0.8.11",
3
+ "version": "0.8.13",
4
4
  "description": "Module to automate adding routes and collections to a sealious application",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -52,6 +52,7 @@
52
52
  "peerDependencies": {
53
53
  "@koa/router": "^10.1.1",
54
54
  "koa": "^2.13.0",
55
+ "koa-responsive-image-router": "^0.2.2",
55
56
  "sealious": "^0.17.9"
56
57
  }
57
58
  }
@@ -21,5 +21,6 @@ export * from "./collapsible-field-group";
21
21
  export * from "./collapsible-checkbox-group";
22
22
  export * from "./autocomplete";
23
23
  export * from "./file";
24
+ export * from "./photo";
24
25
  export * from "./multiple-files";
25
26
  export * from "./number";
@@ -1,4 +1,5 @@
1
1
  import { Context } from "koa";
2
+ import { FlatTemplatable, tempstream } from "tempstream";
2
3
  import { FileContainer } from "../fields/file";
3
4
  import { FormDataValue } from "../form";
4
5
  import { SimpleInput } from "./simple-input";
@@ -8,9 +9,18 @@ export class File extends SimpleInput<FileContainer> {
8
9
  return "file";
9
10
  }
10
11
 
12
+ async renderFilePreview(
13
+ ctx: Context,
14
+ file_data: { id?: string; filename?: string }
15
+ ): Promise<FlatTemplatable> {
16
+ return file_data.filename || "";
17
+ }
18
+
11
19
  async preInput(ctx: Context, data: Record<string, FormDataValue>) {
12
20
  const { parsed } = await this.field.getValue(ctx, data);
13
- return /* HTML */ ` ${parsed.old?.filename || ""}
21
+ return tempstream/* HTML */ `${parsed.old
22
+ ? this.renderFilePreview(ctx, parsed.old)
23
+ : ""}
14
24
  <input
15
25
  type="hidden"
16
26
  name="${this.field.name}[old][id]"
@@ -28,7 +38,7 @@ export class File extends SimpleInput<FileContainer> {
28
38
  data: Record<string, FormDataValue>,
29
39
  field_prefix: string,
30
40
  form_id: string
31
- ) {
41
+ ): Promise<Record<string, string | boolean>> {
32
42
  const original = await super.getInputAttributes(
33
43
  ctx,
34
44
  data,
@@ -41,10 +51,6 @@ export class File extends SimpleInput<FileContainer> {
41
51
  name: this.field.name + "[new]",
42
52
  required: original.required && !parsed.old,
43
53
  value: false,
44
- onchange:
45
- (original.onchange || "") +
46
- ";" +
47
- "filename = this.value.split('\\\\').slice(-1)[0]; this.parentElement.style.setProperty('--filename', '\\'Wybrany plik: ' + filename + '\\'')",
48
54
  };
49
55
  }
50
56
  }
@@ -0,0 +1,76 @@
1
+ import { Context } from "koa";
2
+ import { FlatTemplatable, tempstream } from "tempstream";
3
+ import { File } from "./file";
4
+ import { File as SealiousFile } from "sealious";
5
+ import { FileContainer, FormField } from "../fields/field";
6
+ import { SimpleInputOptions } from "./simple-input";
7
+ import KoaResponsiveImageRouter from "koa-responsive-image-router";
8
+ import { FormDataValue } from "../form";
9
+
10
+ export class Photo extends File {
11
+ constructor(
12
+ public field: FormField<boolean, FileContainer>,
13
+ public imageRouter: KoaResponsiveImageRouter,
14
+ options?: SimpleInputOptions
15
+ ) {
16
+ super(field, options);
17
+ }
18
+
19
+ async getImgStyle() {
20
+ return "width: 100px; height: 100px; object-fit: contain";
21
+ }
22
+
23
+ async renderFilePreview(
24
+ ctx: Context,
25
+ file_data: { id?: string; filename?: string }
26
+ ): Promise<FlatTemplatable> {
27
+ const { id, filename } = file_data;
28
+ const class_name = "file_preview";
29
+ if (!id) {
30
+ return `<div class="${class_name}"></div>`;
31
+ }
32
+ const file = await SealiousFile.fromID(ctx.$app, id);
33
+ return tempstream/* HTML */ `<div class="${class_name}">
34
+ ${this.imageRouter.image({
35
+ resolutions: [100],
36
+ sizes_attr: "100px",
37
+ path: file.getDataPath(),
38
+ img_style: await this.getImgStyle(),
39
+ })}
40
+ </div>`;
41
+ }
42
+
43
+ async getInputAttributes(
44
+ ctx: Context,
45
+ data: Record<string, FormDataValue>,
46
+ field_prefix: string,
47
+ form_id: string
48
+ ) {
49
+ const original = (await super.getInputAttributes(
50
+ ctx,
51
+ data,
52
+ field_prefix,
53
+ form_id
54
+ )) as Record<string, string | boolean>;
55
+ const { parsed } = await this.field.getValue(ctx, data);
56
+ return {
57
+ ...original,
58
+ onchange:
59
+ (original.onchange || "") +
60
+ ";" +
61
+ `
62
+ const file = this.files[0];
63
+ const preview_container = this.parentElement.querySelector(".file_preview");
64
+ const target = this;
65
+ if (file) {
66
+ const fileReader = new FileReader();
67
+ fileReader.readAsDataURL(file);
68
+ fileReader.addEventListener("load", function () {
69
+ preview_container.innerHTML = \`<img src="\${this.result}" style="${await this.getImgStyle()}" />\`;
70
+ });
71
+ }`
72
+ .replaceAll("\n", " ")
73
+ .replaceAll(`"`, "'"),
74
+ };
75
+ }
76
+ }
@@ -1,172 +0,0 @@
1
- import { Context } from "koa";
2
- import { FlatTemplatable, tempstream } from "tempstream";
3
- import { attribute } from "../../sanitize";
4
- import { getRequiredClass, inputWrapper } from "../../utils/input-wrapper";
5
- import { FormField } from "../fields/field";
6
- import { FormDataValue, FormMessage } from "../form";
7
- import { FormFieldControl } from "./controls";
8
-
9
- export type SimpleInputOptions = {
10
- id?: string;
11
- label?: string;
12
- autocomplete?: boolean;
13
- hide_errors?: boolean;
14
- type?:
15
- | "color"
16
- | "date"
17
- | "email"
18
- | "file"
19
- | "month"
20
- | "number"
21
- | "password"
22
- | "search"
23
- | "tel"
24
- | "text"
25
- | "time"
26
- | "url"
27
- | "week";
28
- value?: string;
29
- placeholder?: string;
30
- readonly?: boolean;
31
- step?: number;
32
- };
33
-
34
- export class SimpleInput<
35
- ParsedValue,
36
- Options extends SimpleInputOptions = SimpleInputOptions
37
- > extends FormFieldControl {
38
- options: SimpleInputOptions;
39
- constructor(
40
- public field: FormField<boolean, ParsedValue>,
41
- options?: Options
42
- ) {
43
- super([field]);
44
- this.options = options || {};
45
- }
46
-
47
- async preInput(
48
- _ctx: Context,
49
- _data: Record<string, FormDataValue>
50
- ): Promise<FlatTemplatable> {
51
- return "";
52
- }
53
-
54
- getType(): string {
55
- return this.options.type || "text";
56
- }
57
-
58
- getLabel(): string {
59
- return this.options.label != undefined
60
- ? this.options.label
61
- : this.field.name;
62
- }
63
-
64
- getID(): string {
65
- return this.options.id || this.field.name;
66
- }
67
-
68
- getPlaceholder(): string {
69
- return (!this.options.placeholder )|| this.getType();
70
- }
71
-
72
- async getInputAttributes(
73
- ctx: Context,
74
- data: Record<string, FormDataValue>,
75
- field_prefix: string,
76
- form_id: string
77
- ): Promise<Record<string, string | boolean>> {
78
- const readonly = this.options.readonly || false;
79
- const required = this.field.required;
80
- const { parsed, raw, valid } = await this.field.getValue(ctx, data);
81
- return Object.fromEntries([
82
- <const>["id", this.getID()],
83
- <const>["type", this.getType()],
84
- <const>["name", `${field_prefix}${this.field.name}`],
85
- <const>[
86
- "value",
87
- !valid && raw
88
- ? raw.toString()
89
- : parsed !== undefined && parsed !== null
90
- ? ((parsed as any)?.toString() as string) || ""
91
- : "",
92
- ],
93
- ...(form_id ? [["form", form_id]] : []),
94
- <const>["placeholder", this.getPlaceholder()],
95
- ...(readonly ? [["readonly", true]] : []),
96
- ...(required ? [["required", true]] : []),
97
- ...(!this.options.autocomplete ? [["autocomplete", "off"]] : []),
98
- ...(this.options.step ? [["step", this.options.step]] : []),
99
- ]);
100
- }
101
-
102
- renderAttributes(attrs: Record<string, string | boolean>) {
103
- return Object.entries(attrs)
104
- .map(([key, value]) => {
105
- if (typeof value === "boolean") {
106
- if (value) {
107
- return key;
108
- } else {
109
- return "";
110
- }
111
- } else {
112
- return `${key}="${attribute(value)}"`;
113
- }
114
- })
115
- .join(" ");
116
- }
117
-
118
- async postInput(ctx: Context): Promise<FlatTemplatable> {
119
- return "";
120
- }
121
-
122
- async renderInput(
123
- ctx: Context,
124
- attributes_str: string,
125
- data: Record<string, FormDataValue>
126
- ): Promise<FlatTemplatable> {
127
- return `<input ${attributes_str} />`;
128
- }
129
-
130
- async render<Fields extends Record<string, FormField>>(
131
- ctx: Context,
132
- data: Record<string, FormDataValue>,
133
- _messages: FormMessage[],
134
- field_prefix: string,
135
- form_id: string,
136
- show_errors: boolean
137
- ): Promise<FlatTemplatable> {
138
- const id = this.getID();
139
- const label = this.getLabel();
140
- const type = this.getType();
141
-
142
- const { parsed, raw, valid, message } = await this.field.getValue(
143
- ctx,
144
- data
145
- );
146
- const placeholder = this.getPlaceholder();
147
-
148
- return inputWrapper(
149
- [id, type, getRequiredClass(this.field.required)],
150
- tempstream/* HTML */ `
151
- ${label ? `<label for="${id}">${label}</label>` : ""}
152
- ${await this.preInput(ctx, data)}
153
- ${this.renderInput(
154
- ctx,
155
- this.renderAttributes(
156
- await this.getInputAttributes(
157
- ctx,
158
- data,
159
- field_prefix,
160
- form_id
161
- )
162
- ),
163
- data
164
- )}
165
- ${this.postInput(ctx)}
166
- ${~valid && !this.options.hide_errors && show_errors
167
- ? `<div class="input__error">${message}</div>`
168
- : ""}
169
- `
170
- );
171
- }
172
- }