@pageboard/html 0.15.0 → 0.15.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/elements/form.js CHANGED
@@ -103,16 +103,62 @@ exports.api_form = {
103
103
  },
104
104
  request: {
105
105
  title: 'Map inputs',
106
+ description: `
107
+ expr is supposed to be used to merge stuff into html,
108
+ not really to merge stuff into methods parameters
109
+ Also expr has a bad design because
110
+ - it can be replaced by a binding element inside the block
111
+ - it forces the expression to be in a specific attribute,
112
+ and mostly when a block has no content (so a binding cannot be used)
113
+ - the editor is ugly and shows fields that might not even be merged into html
114
+ Use cases
115
+ - links in anchors, images
116
+ - input or buttons values, checked attributes
117
+ - hidden attributes
118
+ - show/hide blocks depending on response
119
+ The "expr" mecanism could instead be a list of expressions like
120
+ [url|as:url|assign:.query.reservation:$query.reservation]
121
+ [url][$query|pick:text:cover|as:query]
122
+
123
+ Things to solve:
124
+ - do we want expr to be able to do changes outside the DOM of the block itself ? (no, this should be done by a binding element)
125
+ - do we want expr to change only data before merge - outside of any dom context ? Possibly ! In which case the current system is not that bad,
126
+ but it should not use matchdom dom plugin at all
127
+ - how to deal with "template" expressions when one cannot insert a binding
128
+ element ? Is it really something that happens ?
129
+
130
+
131
+
132
+ `,
106
133
  type: 'object',
107
134
  nullable: true
108
135
  },
109
136
  response: {
110
137
  title: 'Map outputs',
138
+ description: `
139
+ 'item.id': '[item.data.id]'
140
+ 'item.title': '[item.content.title]'
141
+ // etc...
142
+ `,
111
143
  type: 'object',
112
144
  nullable: true
113
145
  },
114
146
  redirection: {
115
147
  title: 'Success',
148
+ description: `
149
+ redirection can be used by client,
150
+ to change the page state. In which case the "url" is not an api url.
151
+ It can be used by the server, in which case the "url" is an api url.
152
+ The parameters for a page url make the query, and $query, $request, $response are available.
153
+ The parameters for a user api call are...?
154
+ The user api endpoint is a real url (/@api/xxx) that can expect
155
+ a body ($request) and a query ($query) too.
156
+ Currently client pages use a trick to redirect and submit: a specific parameter triggers a form submit on the redirected page. This makes sense in the context of page navigation - the body is filled by the form that is triggered by the parameters.
157
+ How can that be transposed for internal user api redirection ?
158
+ 1. since it redirects, output mapping can be done to format the $response
159
+ 2. in the next api call, parameters mean $query, $response becomes $request ?
160
+ 3. this works if output can merge $query, $request as well
161
+ `,
116
162
  type: 'object',
117
163
  properties: {
118
164
  url: {
@@ -0,0 +1,56 @@
1
+ exports.input_otp = {
2
+ title: 'OTP',
3
+ icon: '<i class="icons"><i class="text cursor icon"></i><i class="corner lock icon"></i></i>',
4
+ menu: "form",
5
+ required: ["name"],
6
+ group: "block input_field",
7
+ context: 'form//',
8
+ properties: {
9
+ name: {
10
+ title: "Name",
11
+ description: "The form object key",
12
+ type: "string",
13
+ format: "singleline",
14
+ $helper: 'element-property'
15
+ },
16
+ value: {
17
+ title: "Default value",
18
+ nullable: true,
19
+ type: "string",
20
+ format: "singleline"
21
+ },
22
+ required: {
23
+ title: 'Required',
24
+ type: 'boolean',
25
+ default: false
26
+ },
27
+ disabled: {
28
+ title: 'Disabled',
29
+ type: 'boolean',
30
+ default: false
31
+ },
32
+ readonly: {
33
+ title: 'Read only',
34
+ type: 'boolean',
35
+ default: false
36
+ }
37
+ },
38
+ contents: {
39
+ id: 'label',
40
+ nodes: 'inline*'
41
+ },
42
+ html: `<div class="otp field">
43
+ <label block-content="label">Label</label>
44
+ <input is="element-input-otp" name="[name]"
45
+ required="[required]"
46
+ readonly="[readonly]"
47
+ disabled="[disabled]"
48
+ value="[value]"
49
+ inputmode="numeric"
50
+ maxlength="6"
51
+ pattern="\\d{6}"
52
+ autocomplete="off" />
53
+ </div>`,
54
+ stylesheets: ['../ui/otp.css'],
55
+ scripts: ['../ui/otp.js']
56
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pageboard/html",
3
- "version": "0.15.0",
3
+ "version": "0.15.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "repository": {
package/ui/otp.css ADDED
@@ -0,0 +1,28 @@
1
+ form .otp.field > input[is="element-input-otp"] {
2
+ --otp-digits: 6;
3
+ --otp-ls: 2ch;
4
+ --otp-gap: 1.25;
5
+ --otp-fz: 1.5em;
6
+ --otp-pb: 0.5ch;
7
+
8
+ /* private consts */
9
+ --otp-bgsz: calc(var(--otp-ls) + 1ch);
10
+ --otp-digit: 0;
11
+
12
+ all: unset;
13
+ background:
14
+ linear-gradient(90deg, var(--otp-bg, #BBB) calc(var(--otp-gap) * var(--otp-ls)),
15
+ transparent 0),
16
+ linear-gradient(90deg, var(--otp-bg, #EEE) calc(var(--otp-gap) * var(--otp-ls)),
17
+ transparent 0) !important;
18
+ background-position: calc(var(--otp-digit) * var(--otp-bgsz)) 0, 0 0 !important;
19
+ background-repeat: no-repeat, repeat-x !important;
20
+ background-size: var(--otp-bgsz) 100% !important;
21
+ caret-color: var(--otp-cc, #222);
22
+ clip-path: inset(0% calc(var(--otp-ls) / 2) 0% 0%);
23
+ font-size: var(--otp-fz, 2.5em);
24
+ inline-size: calc(var(--otp-digits) * var(--otp-bgsz));
25
+ letter-spacing: var(--otp-ls);
26
+ padding-block: var(--otp-pb, 1ch);
27
+ padding-inline-start: calc(((var(--otp-ls) - 1ch) / 2) * var(--otp-gap));
28
+ }
package/ui/otp.js ADDED
@@ -0,0 +1,13 @@
1
+ class HTMLElementInputOtp extends Page.create(HTMLInputElement) {
2
+ handleInput() {
3
+ this.style.setProperty('--otp-digit', this.selectionStart);
4
+ }
5
+ handleFocus() {
6
+ this.value = "";
7
+ }
8
+ paint() {
9
+ this.focus();
10
+ }
11
+ }
12
+
13
+ Page.define('element-input-otp', HTMLElementInputOtp, 'input');