@excom/super-input 0.1.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.
Files changed (41) hide show
  1. package/.rush/temp/chunked-rush-logs/super-input.apply-exports.chunks.jsonl +1 -0
  2. package/.rush/temp/chunked-rush-logs/super-input.build_docs.chunks.jsonl +1 -0
  3. package/.rush/temp/chunked-rush-logs/super-input.build_package-metas.chunks.jsonl +1 -0
  4. package/.rush/temp/operation/apply-exports/all.log +1 -0
  5. package/.rush/temp/operation/apply-exports/log-chunks.jsonl +1 -0
  6. package/.rush/temp/operation/apply-exports/state.json +3 -0
  7. package/.rush/temp/operation/build_docs/all.log +1 -0
  8. package/.rush/temp/operation/build_docs/log-chunks.jsonl +1 -0
  9. package/.rush/temp/operation/build_docs/state.json +3 -0
  10. package/.rush/temp/operation/build_package-metas/all.log +1 -0
  11. package/.rush/temp/operation/build_package-metas/log-chunks.jsonl +1 -0
  12. package/.rush/temp/operation/build_package-metas/state.json +3 -0
  13. package/.rush/temp/shrinkwrap-deps.json +9 -0
  14. package/config/rig.json +5 -0
  15. package/index.css +5 -0
  16. package/index.ts +17 -0
  17. package/package.json +44 -0
  18. package/rush-logs/super-input.apply-exports.cache.log +1 -0
  19. package/rush-logs/super-input.apply-exports.log +1 -0
  20. package/rush-logs/super-input.build_docs.cache.log +1 -0
  21. package/rush-logs/super-input.build_docs.log +1 -0
  22. package/rush-logs/super-input.build_package-metas.cache.log +1 -0
  23. package/rush-logs/super-input.build_package-metas.log +1 -0
  24. package/src/super-input.css +372 -0
  25. package/super-input.ts +165 -0
  26. package/support/custom-elements.json +327 -0
  27. package/support/demos/comprehensive.html +13 -0
  28. package/support/demos/invalid-message.html +7 -0
  29. package/support/demos/reflect-value.html +15 -0
  30. package/support/demos/slider.html +4 -0
  31. package/support/demos/with-format.html +4 -0
  32. package/support/dist-docs/super-input.md +208 -0
  33. package/support/docs/README.md +71 -0
  34. package/support/package-meta.json +275 -0
  35. package/support/tests/comprehensive.view.test.ts +22 -0
  36. package/support/tests/invalid-message.view.test.ts +21 -0
  37. package/support/tests/reflect-value.view.test.ts +24 -0
  38. package/support/tests/slider.view.test.ts +24 -0
  39. package/support/tests/super-input.test.ts +245 -0
  40. package/support/tests/with-format.view.test.ts +20 -0
  41. package/tsconfig.json +5 -0
@@ -0,0 +1,327 @@
1
+ {
2
+ "schemaVersion": "1.0.0",
3
+ "modules": [
4
+ {
5
+ "kind": "javascript-module",
6
+ "path": "super-input.ts",
7
+ "declarations": [
8
+ {
9
+ "kind": "class",
10
+ "name": "SuperInput",
11
+ "customElement": true,
12
+ "tagName": "super-input",
13
+ "description": "Wrapper around a native `<input>` that adds live text formatting, auto-labeling, and a reflected value attribute. Does not replace the input — enhances it. Pair it with `<super-form>` for form-level submission handling.",
14
+ "attributes": [
15
+ {
16
+ "name": "text-format",
17
+ "type": {
18
+ "text": "string"
19
+ },
20
+ "description": "Pattern defining visible formatting. Use `x` for any digit and any other character as a literal. Examples: `(xxx) xxx-xxxx`, `xx/xx/xxxx`, `xxx-xx-xxxx`. When set, the input value is live-formatted on every keystroke.",
21
+ "fieldName": "textFormat"
22
+ },
23
+ {
24
+ "name": "invalid-message",
25
+ "type": {
26
+ "text": "string"
27
+ },
28
+ "description": "If set, this message is installed via `setCustomValidity()` when the native `invalid` event fires, and cleared on the next `keydown`. Makes built-in HTML validation surface a custom message.",
29
+ "fieldName": "invalidMessage"
30
+ },
31
+ {
32
+ "name": "reflect-value",
33
+ "type": {
34
+ "text": "boolean"
35
+ },
36
+ "description": "When set, the current input value is mirrored to the `current-value` attribute so CSS and selectors can respond to it. Off by default because reflecting every keystroke is not free.",
37
+ "fieldName": "reflectValue"
38
+ },
39
+ {
40
+ "name": "current-value",
41
+ "type": {
42
+ "text": "string"
43
+ },
44
+ "description": "Mirrors the wrapped `<input>`'s value when `reflect-value` is set. Read-only from the app's point of view — writing it does not change the input.",
45
+ "fieldName": "currentValue"
46
+ },
47
+ {
48
+ "name": "auto-label",
49
+ "type": {
50
+ "text": "boolean"
51
+ },
52
+ "description": "When set, generates or uses an existing `id` on the `<input>` and associates the `<label>`.",
53
+ "fieldName": "autoLabel"
54
+ }
55
+ ],
56
+ "members": [
57
+ {
58
+ "kind": "field",
59
+ "name": "textFormat",
60
+ "type": {
61
+ "text": "string"
62
+ },
63
+ "privacy": "public",
64
+ "readonly": false,
65
+ "description": "Pattern defining visible formatting. Use `x` for any digit and any other character as a literal. Examples: `(xxx) xxx-xxxx`, `xx/xx/xxxx`, `xxx-xx-xxxx`. When set, the input value is live-formatted on every keystroke.",
66
+ "_neutron": {
67
+ "surface": "option"
68
+ }
69
+ },
70
+ {
71
+ "kind": "field",
72
+ "name": "invalidMessage",
73
+ "type": {
74
+ "text": "string"
75
+ },
76
+ "privacy": "public",
77
+ "readonly": false,
78
+ "description": "If set, this message is installed via `setCustomValidity()` when the native `invalid` event fires, and cleared on the next `keydown`. Makes built-in HTML validation surface a custom message.",
79
+ "_neutron": {
80
+ "surface": "option"
81
+ }
82
+ },
83
+ {
84
+ "kind": "field",
85
+ "name": "reflectValue",
86
+ "type": {
87
+ "text": "boolean"
88
+ },
89
+ "privacy": "public",
90
+ "readonly": false,
91
+ "description": "When set, the current input value is mirrored to the `current-value` attribute so CSS and selectors can respond to it. Off by default because reflecting every keystroke is not free.",
92
+ "_neutron": {
93
+ "surface": "option"
94
+ }
95
+ },
96
+ {
97
+ "kind": "field",
98
+ "name": "currentValue",
99
+ "type": {
100
+ "text": "string"
101
+ },
102
+ "privacy": "public",
103
+ "readonly": true,
104
+ "description": "Mirrors the wrapped `<input>`'s value when `reflect-value` is set. Read-only from the app's point of view — writing it does not change the input.",
105
+ "_neutron": {
106
+ "surface": "state"
107
+ }
108
+ },
109
+ {
110
+ "kind": "field",
111
+ "name": "autoLabel",
112
+ "type": {
113
+ "text": "boolean"
114
+ },
115
+ "privacy": "public",
116
+ "readonly": false,
117
+ "description": "When set, generates or uses an existing `id` on the `<input>` and associates the `<label>`.",
118
+ "_neutron": {
119
+ "surface": "option"
120
+ }
121
+ }
122
+ ],
123
+ "_neutron": {
124
+ "expectedChildren": [
125
+ {
126
+ "relationship": "descendant",
127
+ "selector": "input",
128
+ "required": true,
129
+ "description": "Required native `<input>` to enhance."
130
+ },
131
+ {
132
+ "relationship": "descendant",
133
+ "selector": "label",
134
+ "required": false,
135
+ "description": "Optional native `<label>`. When `auto-label` is set, its `for` attribute is linked to the input's `id`."
136
+ }
137
+ ],
138
+ "cssClasses": [
139
+ {
140
+ "name": "raised",
141
+ "description": "Raised / floating-label text field appearance. Apply as `class=\"raised\"` on `<super-input>` wrapping a text-like `<input>`."
142
+ }
143
+ ],
144
+ "cssAliases": [
145
+ {
146
+ "name": ":--super-input",
147
+ "selectors": [
148
+ "super-input",
149
+ ".tag-super-input"
150
+ ],
151
+ "kind": "element"
152
+ },
153
+ {
154
+ "name": ":--super-input--has-reflect-value",
155
+ "selectors": [
156
+ "[reflect-value]",
157
+ "[data-reflect-value]"
158
+ ],
159
+ "kind": "state"
160
+ },
161
+ {
162
+ "name": ":--super-input--has-current-value",
163
+ "selectors": [
164
+ "[current-value]",
165
+ "[data-current-value]"
166
+ ],
167
+ "kind": "state"
168
+ }
169
+ ]
170
+ },
171
+ "cssProperties": [
172
+ {
173
+ "name": "--super-input-color",
174
+ "description": "Foreground / label color.",
175
+ "syntax": "<color>",
176
+ "default": "var(--v-color, inherit)"
177
+ },
178
+ {
179
+ "name": "--super-input-bg",
180
+ "description": "Surface background behind the control (and raised-label mask).",
181
+ "syntax": "<color>",
182
+ "default": "var(--v-form-element-background-color, transparent)"
183
+ },
184
+ {
185
+ "name": "--super-input-border-color",
186
+ "description": "Default border color for raised inputs.",
187
+ "syntax": "<color>",
188
+ "default": "var( --v-form-element-border-color, currentColor )"
189
+ },
190
+ {
191
+ "name": "--super-input-focus-color",
192
+ "description": "Focus ring / focus border color.",
193
+ "syntax": "<color>",
194
+ "default": "var( --v-form-element-focus-color, var(--super-input-border-color) )"
195
+ },
196
+ {
197
+ "name": "--super-input-border-radius",
198
+ "description": "Corner radius for raised inputs.",
199
+ "syntax": "<length>",
200
+ "default": "var(--v-border-radius, 4px)"
201
+ },
202
+ {
203
+ "name": "--super-input-border-width",
204
+ "description": "Border width for raised inputs.",
205
+ "syntax": "<length>",
206
+ "default": "var(--v-border-width, 1px)"
207
+ },
208
+ {
209
+ "name": "--super-input-transition-duration",
210
+ "description": "Duration for border / label transitions.",
211
+ "syntax": "<time>",
212
+ "default": "var(--v-transition-duration-fast, 0.15s)"
213
+ },
214
+ {
215
+ "name": "--super-input-transition-ease",
216
+ "description": "Easing for border / label transitions.",
217
+ "syntax": "*",
218
+ "default": "var(--v-transition-ease-out, ease-out)"
219
+ },
220
+ {
221
+ "name": "--super-input-primary",
222
+ "description": "Accent color (range fill, thumb border, focus chrome).",
223
+ "syntax": "<color>",
224
+ "default": "var(--v-primary, blue)"
225
+ },
226
+ {
227
+ "name": "--super-input-label-margin-bottom",
228
+ "description": "Gap between a floating label and the control.",
229
+ "syntax": "<length>",
230
+ "default": "calc(21px * 0.375)"
231
+ },
232
+ {
233
+ "name": "--super-input-font-size",
234
+ "description": "Base font size for the control and value readout.",
235
+ "syntax": "<length>",
236
+ "default": "16px"
237
+ },
238
+ {
239
+ "name": "--super-input-label-height",
240
+ "description": "Computed label line box height (used when a `<label>` is present).",
241
+ "syntax": "<length>",
242
+ "default": "calc( var(--v-line-height, 1.5) * var(--super-input-font-size) )"
243
+ },
244
+ {
245
+ "name": "--super-input-height",
246
+ "description": "Host height for range layout (thumb + value readout).",
247
+ "syntax": "<length>",
248
+ "default": "calc(var(--super-input-thumb-size) + 36px)"
249
+ },
250
+ {
251
+ "name": "--super-input-width",
252
+ "description": "Host width for range layout.",
253
+ "syntax": "<length> | <percentage>",
254
+ "default": "100%"
255
+ },
256
+ {
257
+ "name": "--super-input-min",
258
+ "description": "Range minimum. Prefer setting on the host (or via CSS): CSS cannot read the child input's `min` attribute from the parent.",
259
+ "syntax": "<number>",
260
+ "default": "0"
261
+ },
262
+ {
263
+ "name": "--super-input-max",
264
+ "description": "Range maximum. Prefer setting on the host (or via CSS).",
265
+ "syntax": "<number>",
266
+ "default": "100"
267
+ },
268
+ {
269
+ "name": "--super-input-value",
270
+ "description": "Current range value used for fill / readout positioning. With `reflect-value`, may be driven from `attr(current-value)` where typed `attr()` is supported.",
271
+ "syntax": "<number>",
272
+ "default": "50"
273
+ },
274
+ {
275
+ "name": "--super-input-thumb-size",
276
+ "description": "Diameter of the range thumb.",
277
+ "syntax": "<length>",
278
+ "default": "44px"
279
+ },
280
+ {
281
+ "name": "--super-input-thumb-color",
282
+ "description": "Range thumb fill color.",
283
+ "syntax": "<color>",
284
+ "default": "var( --v-range-thumb-color, var(--super-input-bg) )"
285
+ },
286
+ {
287
+ "name": "--super-input-accent",
288
+ "description": "Active track / accent color for the range fill.",
289
+ "syntax": "<color>",
290
+ "default": "var(--super-input-primary, blue)"
291
+ },
292
+ {
293
+ "name": "--super-input-track-height",
294
+ "description": "Height of the range track.",
295
+ "syntax": "<length>",
296
+ "default": "2px"
297
+ },
298
+ {
299
+ "name": "--super-input-font-weight",
300
+ "description": "Font weight for the range value readout.",
301
+ "syntax": "<number> | <integer>",
302
+ "default": "700"
303
+ }
304
+ ]
305
+ }
306
+ ],
307
+ "exports": [
308
+ {
309
+ "kind": "js",
310
+ "name": "SuperInput",
311
+ "declaration": {
312
+ "name": "SuperInput",
313
+ "module": "super-input.ts"
314
+ }
315
+ },
316
+ {
317
+ "kind": "custom-element-definition",
318
+ "name": "super-input",
319
+ "declaration": {
320
+ "name": "SuperInput",
321
+ "module": "super-input.ts"
322
+ }
323
+ }
324
+ ]
325
+ }
326
+ ]
327
+ }
@@ -0,0 +1,13 @@
1
+ <form>
2
+ <super-input
3
+ text-format="(xxx) xxx-xxxx"
4
+ invalid-message="That doesn't look like a US phone number"
5
+ auto-label
6
+ class="raised"
7
+ >
8
+ <label>Phone number</label>
9
+ <input required pattern="^\(\d{3}\)\s\d{3}-\d{4}" placeholder="(123) 456-7890"/>
10
+ </super-input>
11
+ <!-- Form and button exist purely for the demo -->
12
+ <button type="submit">Submit</button>
13
+ </form>
@@ -0,0 +1,7 @@
1
+ <form>
2
+ <super-input text-format="(xxx) xxx-xxxx" invalid-message="That doesn't look like a US phone number">
3
+ <label>Phone number</label>
4
+ <input required pattern="^\(\d{3}\)\s\d{3}-\d{4}" />
5
+ </super-input>
6
+ <button type="submit">Submit</button>
7
+ </form>
@@ -0,0 +1,15 @@
1
+ <super-input reflect-value class="raised" id="si-rv">
2
+ <label>Email</label>
3
+ <input type="email" />
4
+ <style>
5
+ super-input#si-rv {
6
+ &::after { color: orange; }
7
+ &:not([current-value*="."])::after {
8
+ content: 'Email is missing "." character.';
9
+ }
10
+ &:not([current-value*="@"])::after {
11
+ content: 'Email is missing "@" character.';
12
+ }
13
+ }
14
+ </style>
15
+ </super-input>
@@ -0,0 +1,4 @@
1
+ <super-input reflect-value style="--super-input-min: 18; --super-input-max: 85;">
2
+ <label>Age</label>
3
+ <input type="range" name="age" step="1" value="36" min="18" max="85">
4
+ </super-input>
@@ -0,0 +1,4 @@
1
+ <super-input text-format="(xxx) xxx-xxxx">
2
+ <label>Phone number</label>
3
+ <input value="8902340170" />
4
+ </super-input>
@@ -0,0 +1,208 @@
1
+ # super-input
2
+
3
+ A lightweight element that wraps and upgrades the native `<input>` element.
4
+
5
+
6
+ ```html
7
+ <form>
8
+ <super-input
9
+ text-format="(xxx) xxx-xxxx"
10
+ invalid-message="That doesn't look like a US phone number"
11
+ auto-label
12
+ class="raised"
13
+ >
14
+ <label>Phone number</label>
15
+ <input required pattern="^\(\d{3}\)\s\d{3}-\d{4}" placeholder="(123) 456-7890"/>
16
+ </super-input>
17
+ <!-- Form and button exist purely for the demo -->
18
+ <button type="submit">Submit</button>
19
+ </form>
20
+ ```
21
+
22
+
23
+ ## Features
24
+
25
+ - **Live text formatting** e.g. phone numbers, dates, SSNs
26
+ - **Custom, native validity messages** uses the browser's built-in validation UI to show your message
27
+ - **Auto-labeling** it stitches a sibling `<label>` to the `<input>` via `id`/`for`
28
+ - **Progressively enhanced** Does **not** replace the native input; it enhances it. Everything you know
29
+ about `<input>` still applies.
30
+ - **Range slider** ships with upgraded slider styling and functionality
31
+
32
+ ## Installation
33
+
34
+
35
+ `@excom/super-input` v0.1.0
36
+
37
+ ```bash
38
+ pnpm add @excom/super-input
39
+ ```
40
+
41
+ ```bash
42
+ npm install @excom/super-input
43
+ ```
44
+
45
+ ```bash
46
+ yarn add @excom/super-input
47
+ ```
48
+
49
+ ### Import
50
+
51
+ ```ts
52
+ import "@excom/super-input";
53
+ ```
54
+
55
+
56
+
57
+ ## Usage
58
+
59
+ Wrap a native `<input>` and optionally a `<label>`. Nothing else is required.
60
+
61
+ ### API Reference
62
+
63
+
64
+ #### Attributes
65
+
66
+ | Name | Surface | Type | Default | Values | Description |
67
+ | --- | --- | --- | --- | --- | --- |
68
+ | `text-format` | option | `string` | | | Pattern defining visible formatting. Use `x` for any digit and any other character as a literal. Examples: `(xxx) xxx-xxxx`, `xx/xx/xxxx`, `xxx-xx-xxxx`. When set, the input value is live-formatted on every keystroke. |
69
+ | `invalid-message` | option | `string` | | | If set, this message is installed via `setCustomValidity()` when the native `invalid` event fires, and cleared on the next `keydown`. Makes built-in HTML validation surface a custom message. |
70
+ | `reflect-value` | option | `boolean` | | | When set, the current input value is mirrored to the `current-value` attribute so CSS and selectors can respond to it. Off by default because reflecting every keystroke is not free. |
71
+ | `current-value` | state | `string` | | | Mirrors the wrapped `<input>`'s value when `reflect-value` is set. Read-only from the app's point of view — writing it does not change the input. |
72
+ | `auto-label` | option | `boolean` | | | When set, generates or uses an existing `id` on the `<input>` and associates the `<label>`. |
73
+
74
+ #### Recognized Elements
75
+
76
+ | Relationship | Selector | Required | Description |
77
+ | --- | --- | --- | --- |
78
+ | `input` | descendant | yes | Required native `<input>` to enhance. |
79
+ | `label` | descendant | no | Optional native `<label>`. When `auto-label` is set, its `for` attribute is linked to the input's `id`. |
80
+
81
+ #### CSS Custom Properties
82
+
83
+ | Name | Syntax | Default | Description |
84
+ | --- | --- | --- | --- |
85
+ | `--super-input-color` | `<color>` | `var(--v-color, inherit)` | Foreground / label color. |
86
+ | `--super-input-bg` | `<color>` | `var(--v-form-element-background-color, transparent)` | Surface background behind the control (and raised-label mask). |
87
+ | `--super-input-border-color` | `<color>` | `var( --v-form-element-border-color, currentColor )` | Default border color for raised inputs. |
88
+ | `--super-input-focus-color` | `<color>` | `var( --v-form-element-focus-color, var(--super-input-border-color) )` | Focus ring / focus border color. |
89
+ | `--super-input-border-radius` | `<length>` | `var(--v-border-radius, 4px)` | Corner radius for raised inputs. |
90
+ | `--super-input-border-width` | `<length>` | `var(--v-border-width, 1px)` | Border width for raised inputs. |
91
+ | `--super-input-transition-duration` | `<time>` | `var(--v-transition-duration-fast, 0.15s)` | Duration for border / label transitions. |
92
+ | `--super-input-transition-ease` | `*` | `var(--v-transition-ease-out, ease-out)` | Easing for border / label transitions. |
93
+ | `--super-input-primary` | `<color>` | `var(--v-primary, blue)` | Accent color (range fill, thumb border, focus chrome). |
94
+ | `--super-input-label-margin-bottom` | `<length>` | `calc(21px * 0.375)` | Gap between a floating label and the control. |
95
+ | `--super-input-font-size` | `<length>` | `16px` | Base font size for the control and value readout. |
96
+ | `--super-input-label-height` | `<length>` | `calc( var(--v-line-height, 1.5) * var(--super-input-font-size) )` | Computed label line box height (used when a `<label>` is present). |
97
+ | `--super-input-height` | `<length>` | `calc(var(--super-input-thumb-size) + 36px)` | Host height for range layout (thumb + value readout). |
98
+ | `--super-input-width` | `<length> \| <percentage>` | `100%` | Host width for range layout. |
99
+ | `--super-input-min` | `<number>` | `0` | Range minimum. Prefer setting on the host (or via CSS): CSS cannot read the child input's `min` attribute from the parent. |
100
+ | `--super-input-max` | `<number>` | `100` | Range maximum. Prefer setting on the host (or via CSS). |
101
+ | `--super-input-value` | `<number>` | `50` | Current range value used for fill / readout positioning. With `reflect-value`, may be driven from `attr(current-value)` where typed `attr()` is supported. |
102
+ | `--super-input-thumb-size` | `<length>` | `44px` | Diameter of the range thumb. |
103
+ | `--super-input-thumb-color` | `<color>` | `var( --v-range-thumb-color, var(--super-input-bg) )` | Range thumb fill color. |
104
+ | `--super-input-accent` | `<color>` | `var(--super-input-primary, blue)` | Active track / accent color for the range fill. |
105
+ | `--super-input-track-height` | `<length>` | `2px` | Height of the range track. |
106
+ | `--super-input-font-weight` | `<number> \| <integer>` | `700` | Font weight for the range value readout. |
107
+
108
+ #### CSS Classes
109
+
110
+ | Name | Description |
111
+ | --- | --- |
112
+ | `.raised` | Raised / floating-label text field appearance. Apply as `class="raised"` on `<super-input>` wrapping a text-like `<input>`. |
113
+
114
+ #### CSS Aliases
115
+
116
+ | Alias | Kind | Matches | Description |
117
+ | --- | --- | --- | --- |
118
+ | `:--super-input` | element | `super-input`, `.tag-super-input` | |
119
+ | `:--super-input--has-reflect-value` | state | `[reflect-value]`, `[data-reflect-value]` | |
120
+ | `:--super-input--has-current-value` | state | `[current-value]`, `[data-current-value]` | |
121
+
122
+
123
+
124
+ ### Examples
125
+
126
+ #### Formatting input as the user types
127
+
128
+ Set `text-format` to a template using `x` as a character placeholder.
129
+
130
+
131
+ ```html
132
+ <super-input text-format="(xxx) xxx-xxxx">
133
+ <label>Phone number</label>
134
+ <input value="8902340170" />
135
+ </super-input>
136
+ ```
137
+
138
+
139
+ Common templates:
140
+
141
+ - Phone (US): `(xxx) xxx-xxxx`
142
+ - Date: `xx/xx/xxxx`
143
+ - SSN: `xxx-xx-xxxx`
144
+
145
+ The wrapped `<input>` sees the formatted value. Pair with `pattern` for
146
+ validation.
147
+
148
+ #### Custom validity messages
149
+
150
+ Set `invalid-message` and the browser's native validation UI will surface it
151
+ when the input fails. Use the native `pattern`, `required`, `min`, `max`, etc for validation.
152
+ Try submitting the form in the demo below with an invalid phone number.
153
+
154
+
155
+ ```html
156
+ <form>
157
+ <super-input text-format="(xxx) xxx-xxxx" invalid-message="That doesn't look like a US phone number">
158
+ <label>Phone number</label>
159
+ <input required pattern="^\(\d{3}\)\s\d{3}-\d{4}" />
160
+ </super-input>
161
+ <button type="submit">Submit</button>
162
+ </form>
163
+ ```
164
+
165
+
166
+ The message is installed via `setCustomValidity()` on the `invalid` event and
167
+ cleared on the next `keydown`, so the input stops being marked invalid as
168
+ soon as the user tries again.
169
+
170
+ #### Using reflect-value
171
+ The `reflect-value` attribute has two primary uses:
172
+ - Is required for animating `raised` labels without an input `placeholder` attribute
173
+ - Allows you to hook into it to run your own behaviors
174
+
175
+ Here's an example with a raising label that will display an error if the user has not entered an email with an `@` or `.` characters.
176
+
177
+
178
+ ```html
179
+ <super-input reflect-value class="raised" id="si-rv">
180
+ <label>Email</label>
181
+ <input type="email" />
182
+ <style>
183
+ super-input#si-rv {
184
+ &::after { color: orange; }
185
+ &:not([current-value*="."])::after {
186
+ content: 'Email is missing "." character.';
187
+ }
188
+ &:not([current-value*="@"])::after {
189
+ content: 'Email is missing "@" character.';
190
+ }
191
+ }
192
+ </style>
193
+ </super-input>
194
+ ```
195
+
196
+
197
+ #### Range slider
198
+ `<super-input>` ships with advanced slider CSS. Add `[type="range"]` to the `input`. `[reflect-value]` is required for this to work natively in Chromium browsers. Safari and Firefox will need some help via Quark or JS until they support [the CSS `type()` function](https://caniuse.com/mdn-css_types_type). You must also set the min/max CSS variables to match the min/max on the input.
199
+
200
+ Be cautious using this feature, as it aesthetically relies on non-standard pseudo elements for the time being.
201
+
202
+
203
+ ```html
204
+ <super-input reflect-value style="--super-input-min: 18; --super-input-max: 85;">
205
+ <label>Age</label>
206
+ <input type="range" name="age" step="1" value="36" min="18" max="85">
207
+ </super-input>
208
+ ```
@@ -0,0 +1,71 @@
1
+ # super-input
2
+
3
+ A lightweight element that wraps and upgrades the native `<input>` element.
4
+
5
+ <include-content data-demo="comprehensive"></include-content>
6
+
7
+ ## Features
8
+
9
+ - **Live text formatting** e.g. phone numbers, dates, SSNs
10
+ - **Custom, native validity messages** uses the browser's built-in validation UI to show your message
11
+ - **Auto-labeling** it stitches a sibling `<label>` to the `<input>` via `id`/`for`
12
+ - **Progressively enhanced** Does **not** replace the native input; it enhances it. Everything you know
13
+ about `<input>` still applies.
14
+ - **Range slider** ships with upgraded slider styling and functionality
15
+
16
+ ## Installation
17
+
18
+ <include-content is-active template-ref="/views/install-section/install-section.html"></include-content>
19
+
20
+ ## Usage
21
+
22
+ Wrap a native `<input>` and optionally a `<label>`. Nothing else is required.
23
+
24
+ ### API Reference
25
+
26
+ <include-content is-active template-ref="/views/api-reference/api-reference.html"></include-content>
27
+
28
+ ### Examples
29
+
30
+ #### Formatting input as the user types
31
+
32
+ Set `text-format` to a template using `x` as a character placeholder.
33
+
34
+ <include-content data-demo="with-format"></include-content>
35
+
36
+ Common templates:
37
+
38
+ - Phone (US): `(xxx) xxx-xxxx`
39
+ - Date: `xx/xx/xxxx`
40
+ - SSN: `xxx-xx-xxxx`
41
+
42
+ The wrapped `<input>` sees the formatted value. Pair with `pattern` for
43
+ validation.
44
+
45
+ #### Custom validity messages
46
+
47
+ Set `invalid-message` and the browser's native validation UI will surface it
48
+ when the input fails. Use the native `pattern`, `required`, `min`, `max`, etc for validation.
49
+ Try submitting the form in the demo below with an invalid phone number.
50
+
51
+ <include-content data-demo="invalid-message"></include-content>
52
+
53
+ The message is installed via `setCustomValidity()` on the `invalid` event and
54
+ cleared on the next `keydown`, so the input stops being marked invalid as
55
+ soon as the user tries again.
56
+
57
+ #### Using reflect-value
58
+ The `reflect-value` attribute has two primary uses:
59
+ - Is required for animating `raised` labels without an input `placeholder` attribute
60
+ - Allows you to hook into it to run your own behaviors
61
+
62
+ Here's an example with a raising label that will display an error if the user has not entered an email with an `@` or `.` characters.
63
+
64
+ <include-content data-demo="reflect-value"></include-content>
65
+
66
+ #### Range slider
67
+ `<super-input>` ships with advanced slider CSS. Add `[type="range"]` to the `input`. `[reflect-value]` is required for this to work natively in Chromium browsers. Safari and Firefox will need some help via Quark or JS until they support [the CSS `type()` function](https://caniuse.com/mdn-css_types_type). You must also set the min/max CSS variables to match the min/max on the input.
68
+
69
+ Be cautious using this feature, as it aesthetically relies on non-standard pseudo elements for the time being.
70
+
71
+ <include-content data-demo="slider"></include-content>