@noctuatech/uswds 1.1.4 → 1.1.6
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/package.json +2 -1
- package/src/lib/file-input/file-input-preview/file-input-preview.element.ts +43 -76
- package/src/lib/file-input/file-input.element.ts +30 -19
- package/target/lib/file-input/file-input-preview/file-input-preview.element.d.ts +10 -4
- package/target/lib/file-input/file-input-preview/file-input-preview.element.js +23 -67
- package/target/lib/file-input/file-input-preview/file-input-preview.element.js.map +1 -1
- package/target/lib/file-input/file-input.element.d.ts +3 -1
- package/target/lib/file-input/file-input.element.js +20 -14
- package/target/lib/file-input/file-input.element.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noctuatech/uswds",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"workspaces": ["packages/**"],
|
|
6
6
|
"main": "./target/lib.js",
|
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
"@joist/di": "^4.2.3-next.7",
|
|
74
74
|
"@joist/element": "^4.2.3-next.7",
|
|
75
75
|
"@joist/observable": "^4.2.3-next.7",
|
|
76
|
+
"@joist/templating": "^4.2.3-next.7",
|
|
76
77
|
"tslib": "2.8.1"
|
|
77
78
|
},
|
|
78
79
|
"devDependencies": {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import "@joist/templating/define.js";
|
|
2
|
+
|
|
3
|
+
import { css, element, html } from "@joist/element";
|
|
4
|
+
import { bind } from "@joist/templating";
|
|
3
5
|
|
|
4
6
|
declare global {
|
|
5
7
|
interface HTMLElementTagNameMap {
|
|
@@ -41,7 +43,7 @@ declare global {
|
|
|
41
43
|
|
|
42
44
|
.preview-heading {
|
|
43
45
|
align-items: center;
|
|
44
|
-
background:
|
|
46
|
+
background: var(--usa-input-bg-color);
|
|
45
47
|
display: flex;
|
|
46
48
|
pointer-events: none;
|
|
47
49
|
position: relative;
|
|
@@ -54,7 +56,7 @@ declare global {
|
|
|
54
56
|
|
|
55
57
|
.preview-item {
|
|
56
58
|
align-items: center;
|
|
57
|
-
background:
|
|
59
|
+
background: var(--usa-input-bg-color);
|
|
58
60
|
display: flex;
|
|
59
61
|
padding: 0.5rem;
|
|
60
62
|
width: 100%;
|
|
@@ -62,88 +64,53 @@ declare global {
|
|
|
62
64
|
}
|
|
63
65
|
`,
|
|
64
66
|
html`
|
|
65
|
-
<template>
|
|
66
|
-
<div class="preview-item">
|
|
67
|
-
<img height="40" width="40" aria-hidden="true" style="display: none" />
|
|
68
|
-
<usa-icon icon="file_present" style="display: none"></usa-icon>
|
|
69
|
-
</div>
|
|
70
|
-
</template>
|
|
71
|
-
|
|
72
67
|
<slot class="preview-heading"></slot>
|
|
68
|
+
|
|
69
|
+
<j-for bind="fileEntries" key="src">
|
|
70
|
+
<template>
|
|
71
|
+
<div class="preview-item">
|
|
72
|
+
<j-if bind="each.value.isImage">
|
|
73
|
+
<template>
|
|
74
|
+
<j-props>
|
|
75
|
+
<img height="40" width="40" aria-hidden="true" $.src="each.value.src" />
|
|
76
|
+
</j-props>
|
|
77
|
+
</template>
|
|
78
|
+
|
|
79
|
+
<template else>
|
|
80
|
+
<usa-icon icon="file_present"></usa-icon>
|
|
81
|
+
</template>
|
|
82
|
+
</j-if>
|
|
83
|
+
|
|
84
|
+
<j-value bind="each.value.file.name"></j-value>
|
|
85
|
+
</div>
|
|
86
|
+
</template>
|
|
87
|
+
</j-for>
|
|
73
88
|
`,
|
|
74
89
|
],
|
|
75
90
|
})
|
|
76
91
|
export class USAFileInputPreviewElement extends HTMLElement {
|
|
77
|
-
@
|
|
78
|
-
accessor
|
|
92
|
+
@bind()
|
|
93
|
+
accessor fileEntries: FileEntry[] = [];
|
|
79
94
|
|
|
80
|
-
#
|
|
81
|
-
#template = query("template");
|
|
95
|
+
#files: FileList | null = null;
|
|
82
96
|
|
|
83
|
-
|
|
84
|
-
this
|
|
97
|
+
get files() {
|
|
98
|
+
return this.#files;
|
|
85
99
|
}
|
|
86
100
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
throw new Error("no shadow root");
|
|
90
|
-
}
|
|
101
|
+
set files(value: FileList | null) {
|
|
102
|
+
this.#files = value;
|
|
91
103
|
|
|
92
|
-
|
|
104
|
+
this.fileEntries = Array.from(value ?? []).map((file) => ({
|
|
105
|
+
file,
|
|
106
|
+
src: URL.createObjectURL(file),
|
|
107
|
+
isImage: file.type.startsWith("image"),
|
|
108
|
+
}));
|
|
93
109
|
}
|
|
110
|
+
}
|
|
94
111
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (this.files?.length) {
|
|
100
|
-
this.hidden = false;
|
|
101
|
-
|
|
102
|
-
const names = new Set<string>();
|
|
103
|
-
|
|
104
|
-
for (const file of this.files) {
|
|
105
|
-
names.add(file.name);
|
|
106
|
-
|
|
107
|
-
if (!this.#items.has(file.name)) {
|
|
108
|
-
const clone = template.content.cloneNode(true) as DocumentFragment;
|
|
109
|
-
|
|
110
|
-
const item = clone.firstElementChild;
|
|
111
|
-
|
|
112
|
-
if (!item) {
|
|
113
|
-
throw new Error("SOMETHING HAS GONE VERY WRONG");
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
item.id = file.name;
|
|
117
|
-
item.append(document.createTextNode(file.name));
|
|
118
|
-
|
|
119
|
-
const img = item.querySelector("img");
|
|
120
|
-
const icon = item.querySelector("usa-icon");
|
|
121
|
-
|
|
122
|
-
if (!img || !icon) {
|
|
123
|
-
throw Error("Something went very wrong");
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (file.type.startsWith("image")) {
|
|
127
|
-
img.style.display = "block";
|
|
128
|
-
img.src = URL.createObjectURL(file);
|
|
129
|
-
} else {
|
|
130
|
-
icon.style.display = "block";
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
this.shadow.append(item);
|
|
134
|
-
|
|
135
|
-
this.#items.set(file.name, item);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
for (const [name, item] of this.#items) {
|
|
140
|
-
if (!names.has(name)) {
|
|
141
|
-
item.remove();
|
|
142
|
-
this.#items.delete(name);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
} else {
|
|
146
|
-
this.hidden = true;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
112
|
+
interface FileEntry {
|
|
113
|
+
file: File;
|
|
114
|
+
src: string;
|
|
115
|
+
isImage: boolean;
|
|
149
116
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import "@joist/templating/define.js";
|
|
2
|
+
|
|
1
3
|
import { attr, css, element, html, listen, query } from "@joist/element";
|
|
2
|
-
import { effect
|
|
4
|
+
import { effect } from "@joist/observable";
|
|
5
|
+
import { bind } from "@joist/templating";
|
|
3
6
|
|
|
4
7
|
declare global {
|
|
5
8
|
interface HTMLElementTagNameMap {
|
|
@@ -16,6 +19,8 @@ declare global {
|
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
:host {
|
|
22
|
+
--usa-input-radius: 0;
|
|
23
|
+
|
|
19
24
|
display: block;
|
|
20
25
|
max-width: 30rem;
|
|
21
26
|
position: relative;
|
|
@@ -58,6 +63,7 @@ declare global {
|
|
|
58
63
|
|
|
59
64
|
.box {
|
|
60
65
|
border: 1px dashed #adadad;
|
|
66
|
+
border-radius: var(--usa-input-radius);
|
|
61
67
|
display: flex;
|
|
62
68
|
font-size: 0.93rem;
|
|
63
69
|
position: relative;
|
|
@@ -79,15 +85,23 @@ declare global {
|
|
|
79
85
|
<div class="container">
|
|
80
86
|
<input type="file" tabindex="0"/>
|
|
81
87
|
|
|
82
|
-
<
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
<j-if bind="!filesVisible">
|
|
89
|
+
<template>
|
|
90
|
+
<div class="box">
|
|
91
|
+
<slot name="description">
|
|
92
|
+
Drag file here or <usa-link>choose from folder</usa-link>
|
|
93
|
+
</slot>
|
|
94
|
+
</div>
|
|
95
|
+
</template>
|
|
96
|
+
|
|
97
|
+
<template else>
|
|
98
|
+
<j-props>
|
|
99
|
+
<usa-file-input-preview $.files="files">
|
|
100
|
+
Selected file <usa-link>Change file</usa-link>
|
|
101
|
+
</usa-file-input-preview>
|
|
102
|
+
</j-props>
|
|
103
|
+
</template>
|
|
104
|
+
</j-if>
|
|
91
105
|
</div>
|
|
92
106
|
</label>
|
|
93
107
|
`,
|
|
@@ -108,13 +122,14 @@ export class USAFileInputElement extends HTMLElement {
|
|
|
108
122
|
@attr()
|
|
109
123
|
accessor required = false;
|
|
110
124
|
|
|
111
|
-
@
|
|
125
|
+
@bind()
|
|
112
126
|
accessor files: FileList | null = null;
|
|
113
127
|
|
|
128
|
+
@bind()
|
|
129
|
+
accessor filesVisible = false;
|
|
130
|
+
|
|
114
131
|
#internals = this.attachInternals();
|
|
115
132
|
#input = query("input");
|
|
116
|
-
#box = query(".box");
|
|
117
|
-
#preview = query("usa-file-input-preview");
|
|
118
133
|
|
|
119
134
|
attributeChangedCallback() {
|
|
120
135
|
this.#input({
|
|
@@ -138,16 +153,11 @@ export class USAFileInputElement extends HTMLElement {
|
|
|
138
153
|
}
|
|
139
154
|
|
|
140
155
|
@effect()
|
|
141
|
-
|
|
156
|
+
syncFormValues() {
|
|
142
157
|
const input = this.#input({ files: this.files });
|
|
143
|
-
this.#preview({ files: this.files });
|
|
144
|
-
|
|
145
|
-
const box = this.#box();
|
|
146
158
|
|
|
147
159
|
const formData = new FormData();
|
|
148
160
|
|
|
149
|
-
box.style.display = this.files?.length ? "none" : "flex";
|
|
150
|
-
|
|
151
161
|
if (this.files?.length) {
|
|
152
162
|
for (const file of this.files) {
|
|
153
163
|
formData.append(this.name, file);
|
|
@@ -172,6 +182,7 @@ export class USAFileInputElement extends HTMLElement {
|
|
|
172
182
|
const input = this.#input();
|
|
173
183
|
|
|
174
184
|
this.files = input.files;
|
|
185
|
+
this.filesVisible = !!input.files?.length;
|
|
175
186
|
|
|
176
187
|
this.dispatchEvent(new Event("change"));
|
|
177
188
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import "@joist/templating/define.js";
|
|
1
2
|
declare global {
|
|
2
3
|
interface HTMLElementTagNameMap {
|
|
3
4
|
"usa-file-input-preview": USAFileInputPreviewElement;
|
|
@@ -5,8 +6,13 @@ declare global {
|
|
|
5
6
|
}
|
|
6
7
|
export declare class USAFileInputPreviewElement extends HTMLElement {
|
|
7
8
|
#private;
|
|
8
|
-
accessor
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
onChange(): void;
|
|
9
|
+
accessor fileEntries: FileEntry[];
|
|
10
|
+
get files(): FileList | null;
|
|
11
|
+
set files(value: FileList | null);
|
|
12
12
|
}
|
|
13
|
+
interface FileEntry {
|
|
14
|
+
file: File;
|
|
15
|
+
src: string;
|
|
16
|
+
isImage: boolean;
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -1,91 +1,47 @@
|
|
|
1
1
|
import { __esDecorate, __runInitializers } from "tslib";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
2
|
+
import "@joist/templating/define.js";
|
|
3
|
+
import { css, element, html } from "@joist/element";
|
|
4
|
+
import { bind } from "@joist/templating";
|
|
4
5
|
let USAFileInputPreviewElement = (() => {
|
|
5
6
|
let _classDecorators = [element({
|
|
6
7
|
tagName: "usa-file-input-preview",
|
|
7
8
|
shadowDom: [
|
|
8
|
-
css `*{box-sizing:border-box}:host{display:block;font-size:.87rem;pointer-events:none;position:relative;text-align:left;word-wrap:anywhere;z-index:3}:host([hidden]){display:none}img{border:0;display:block;height:2.5rem;margin-right:.5rem;-o-object-fit:contain;object-fit:contain;width:2.5rem}.preview-heading{align-items:center;background
|
|
9
|
-
html `<template><div class="preview-item"><img height="40" width="40" aria-hidden="true"
|
|
9
|
+
css `*{box-sizing:border-box}:host{display:block;font-size:.87rem;pointer-events:none;position:relative;text-align:left;word-wrap:anywhere;z-index:3}:host([hidden]){display:none}img{border:0;display:block;height:2.5rem;margin-right:.5rem;-o-object-fit:contain;object-fit:contain;width:2.5rem}.preview-heading{align-items:center;background:var(--usa-input-bg-color);display:flex;pointer-events:none;position:relative;z-index:3;font-weight:700;justify-content:space-between;padding:.5rem;text-align:left}.preview-item{align-items:center;background:var(--usa-input-bg-color);display:flex;padding:.5rem;width:100%;margin-top:1px}`,
|
|
10
|
+
html `<slot class="preview-heading"></slot><j-for bind="fileEntries" key="src"><template><div class="preview-item"><j-if bind="each.value.isImage"><template><j-props><img height="40" width="40" aria-hidden="true" $.src="each.value.src"></j-props></template><template else><usa-icon icon="file_present"></usa-icon></template></j-if><j-value bind="each.value.file.name"></j-value></div></template></j-for>`,
|
|
10
11
|
],
|
|
11
12
|
})];
|
|
12
13
|
let _classDescriptor;
|
|
13
14
|
let _classExtraInitializers = [];
|
|
14
15
|
let _classThis;
|
|
15
16
|
let _classSuper = HTMLElement;
|
|
16
|
-
let
|
|
17
|
-
let
|
|
18
|
-
let
|
|
19
|
-
let _files_extraInitializers = [];
|
|
20
|
-
let _onChange_decorators;
|
|
17
|
+
let _fileEntries_decorators;
|
|
18
|
+
let _fileEntries_initializers = [];
|
|
19
|
+
let _fileEntries_extraInitializers = [];
|
|
21
20
|
var USAFileInputPreviewElement = class extends _classSuper {
|
|
22
21
|
static { _classThis = this; }
|
|
23
22
|
static {
|
|
24
23
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
__esDecorate(this, null, _files_decorators, { kind: "accessor", name: "files", static: false, private: false, access: { has: obj => "files" in obj, get: obj => obj.files, set: (obj, value) => { obj.files = value; } }, metadata: _metadata }, _files_initializers, _files_extraInitializers);
|
|
28
|
-
__esDecorate(this, null, _onChange_decorators, { kind: "method", name: "onChange", static: false, private: false, access: { has: obj => "onChange" in obj, get: obj => obj.onChange }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
24
|
+
_fileEntries_decorators = [bind()];
|
|
25
|
+
__esDecorate(this, null, _fileEntries_decorators, { kind: "accessor", name: "fileEntries", static: false, private: false, access: { has: obj => "fileEntries" in obj, get: obj => obj.fileEntries, set: (obj, value) => { obj.fileEntries = value; } }, metadata: _metadata }, _fileEntries_initializers, _fileEntries_extraInitializers);
|
|
29
26
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
30
27
|
USAFileInputPreviewElement = _classThis = _classDescriptor.value;
|
|
31
28
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
32
29
|
__runInitializers(_classThis, _classExtraInitializers);
|
|
33
30
|
}
|
|
34
|
-
#
|
|
35
|
-
get
|
|
36
|
-
set
|
|
37
|
-
#
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
this.onChange();
|
|
31
|
+
#fileEntries_accessor_storage = __runInitializers(this, _fileEntries_initializers, []);
|
|
32
|
+
get fileEntries() { return this.#fileEntries_accessor_storage; }
|
|
33
|
+
set fileEntries(value) { this.#fileEntries_accessor_storage = value; }
|
|
34
|
+
#files = (__runInitializers(this, _fileEntries_extraInitializers), null);
|
|
35
|
+
get files() {
|
|
36
|
+
return this.#files;
|
|
41
37
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const template = this.#template();
|
|
50
|
-
if (this.files?.length) {
|
|
51
|
-
this.hidden = false;
|
|
52
|
-
const names = new Set();
|
|
53
|
-
for (const file of this.files) {
|
|
54
|
-
names.add(file.name);
|
|
55
|
-
if (!this.#items.has(file.name)) {
|
|
56
|
-
const clone = template.content.cloneNode(true);
|
|
57
|
-
const item = clone.firstElementChild;
|
|
58
|
-
if (!item) {
|
|
59
|
-
throw new Error("SOMETHING HAS GONE VERY WRONG");
|
|
60
|
-
}
|
|
61
|
-
item.id = file.name;
|
|
62
|
-
item.append(document.createTextNode(file.name));
|
|
63
|
-
const img = item.querySelector("img");
|
|
64
|
-
const icon = item.querySelector("usa-icon");
|
|
65
|
-
if (!img || !icon) {
|
|
66
|
-
throw Error("Something went very wrong");
|
|
67
|
-
}
|
|
68
|
-
if (file.type.startsWith("image")) {
|
|
69
|
-
img.style.display = "block";
|
|
70
|
-
img.src = URL.createObjectURL(file);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
icon.style.display = "block";
|
|
74
|
-
}
|
|
75
|
-
this.shadow.append(item);
|
|
76
|
-
this.#items.set(file.name, item);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
for (const [name, item] of this.#items) {
|
|
80
|
-
if (!names.has(name)) {
|
|
81
|
-
item.remove();
|
|
82
|
-
this.#items.delete(name);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
this.hidden = true;
|
|
88
|
-
}
|
|
38
|
+
set files(value) {
|
|
39
|
+
this.#files = value;
|
|
40
|
+
this.fileEntries = Array.from(value ?? []).map((file) => ({
|
|
41
|
+
file,
|
|
42
|
+
src: URL.createObjectURL(file),
|
|
43
|
+
isImage: file.type.startsWith("image"),
|
|
44
|
+
}));
|
|
89
45
|
}
|
|
90
46
|
};
|
|
91
47
|
return USAFileInputPreviewElement = _classThis;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-input-preview.element.js","sourceRoot":"","sources":["../../../../src/lib/file-input/file-input-preview/file-input-preview.element.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"file-input-preview.element.js","sourceRoot":"","sources":["../../../../src/lib/file-input/file-input-preview/file-input-preview.element.ts"],"names":[],"mappings":";AAAA,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;IAuF5B,0BAA0B;4BA/EtC,OAAO,CAAC;YACP,OAAO,EAAE,wBAAwB;YACjC,SAAS,EAAE;gBACT,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkDF;gBACD,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;KAsBH;aACF;SACF,CAAC;;;;sBAC8C,WAAW;;;;0CAAnB,SAAQ,WAAW;;;;uCACxD,IAAI,EAAE;YACP,sLAAS,WAAW,6BAAX,WAAW,iGAAmB;YAFzC,6KAmBC;;;YAnBY,uDAA0B;;QAErC,mFAAoC,EAAE,EAAC;QAAvC,IAAS,WAAW,iDAAmB;QAAvC,IAAS,WAAW,uDAAmB;QAEvC,MAAM,6DAAoB,IAAI,EAAC;QAE/B,IAAI,KAAK;YACP,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QAED,IAAI,KAAK,CAAC,KAAsB;YAC9B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YAEpB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACxD,IAAI;gBACJ,GAAG,EAAE,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC;gBAC9B,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;aACvC,CAAC,CAAC,CAAC;QACN,CAAC;;;;SAlBU,0BAA0B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import "@joist/templating/define.js";
|
|
1
2
|
declare global {
|
|
2
3
|
interface HTMLElementTagNameMap {
|
|
3
4
|
"usa-file-input": USAFileInputElement;
|
|
@@ -11,9 +12,10 @@ export declare class USAFileInputElement extends HTMLElement {
|
|
|
11
12
|
accessor accept: string;
|
|
12
13
|
accessor required: boolean;
|
|
13
14
|
accessor files: FileList | null;
|
|
15
|
+
accessor filesVisible: boolean;
|
|
14
16
|
attributeChangedCallback(): void;
|
|
15
17
|
connectedCallback(): void;
|
|
16
|
-
|
|
18
|
+
syncFormValues(): void;
|
|
17
19
|
onInputChange(): void;
|
|
18
20
|
onDragEnter(): void;
|
|
19
21
|
onDragLeave(): void;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { __esDecorate, __runInitializers } from "tslib";
|
|
2
|
+
import "@joist/templating/define.js";
|
|
2
3
|
import { attr, css, element, html, listen, query } from "@joist/element";
|
|
3
|
-
import { effect
|
|
4
|
+
import { effect } from "@joist/observable";
|
|
5
|
+
import { bind } from "@joist/templating";
|
|
4
6
|
let USAFileInputElement = (() => {
|
|
5
7
|
let _classDecorators = [element({
|
|
6
8
|
tagName: "usa-file-input",
|
|
7
9
|
shadowDom: [
|
|
8
|
-
css `*{box-sizing:border-box}:host{display:block;max-width:30rem;position:relative;margin-bottom:1.5rem}label{display:block}input{cursor:pointer;left:0;margin:0;max-width:none;position:absolute;text-indent:-999em;width:100%;z-index:1;bottom:0;top:0}input:focus{outline:.25rem solid #2491ff;outline-offset:0}label slot.label{font-size:1.06rem;line-height:1.3;display:block;font-weight:400;margin-bottom:.5rem}:host(.dragenter) .box{border-color:#2491ff}.box{border:1px dashed #adadad;display:flex;font-size:.93rem;position:relative;text-align:center;width:100%;height:5.2rem;align-items:center;justify-content:center}.container{position:relative}`,
|
|
9
|
-
html `<label><slot class="label"></slot><div class="container"><input type="file" tabindex="0"><div class="box"><slot name="description">Drag file here or<usa-link>choose from folder</usa-link></slot></div><usa-file-input-preview>Selected file<usa-link>Change file</usa-link></usa-file-input-preview></div></label>`,
|
|
10
|
+
css `*{box-sizing:border-box}:host{--usa-input-radius:0;display:block;max-width:30rem;position:relative;margin-bottom:1.5rem}label{display:block}input{cursor:pointer;left:0;margin:0;max-width:none;position:absolute;text-indent:-999em;width:100%;z-index:1;bottom:0;top:0}input:focus{outline:.25rem solid #2491ff;outline-offset:0}label slot.label{font-size:1.06rem;line-height:1.3;display:block;font-weight:400;margin-bottom:.5rem}:host(.dragenter) .box{border-color:#2491ff}.box{border:1px dashed #adadad;border-radius:var(--usa-input-radius);display:flex;font-size:.93rem;position:relative;text-align:center;width:100%;height:5.2rem;align-items:center;justify-content:center}.container{position:relative}`,
|
|
11
|
+
html `<label><slot class="label"></slot><div class="container"><input type="file" tabindex="0"><j-if bind="!filesVisible"><template><div class="box"><slot name="description">Drag file here or<usa-link>choose from folder</usa-link></slot></div></template><template else><j-props><usa-file-input-preview $.files="files">Selected file<usa-link>Change file</usa-link></usa-file-input-preview></j-props></template></j-if></div></label>`,
|
|
10
12
|
],
|
|
11
13
|
})];
|
|
12
14
|
let _classDescriptor;
|
|
@@ -29,7 +31,10 @@ let USAFileInputElement = (() => {
|
|
|
29
31
|
let _files_decorators;
|
|
30
32
|
let _files_initializers = [];
|
|
31
33
|
let _files_extraInitializers = [];
|
|
32
|
-
let
|
|
34
|
+
let _filesVisible_decorators;
|
|
35
|
+
let _filesVisible_initializers = [];
|
|
36
|
+
let _filesVisible_extraInitializers = [];
|
|
37
|
+
let _syncFormValues_decorators;
|
|
33
38
|
let _onInputChange_decorators;
|
|
34
39
|
let _onDragEnter_decorators;
|
|
35
40
|
let _onDragLeave_decorators;
|
|
@@ -42,8 +47,9 @@ let USAFileInputElement = (() => {
|
|
|
42
47
|
_multiple_decorators = [attr()];
|
|
43
48
|
_accept_decorators = [attr()];
|
|
44
49
|
_required_decorators = [attr()];
|
|
45
|
-
_files_decorators = [
|
|
46
|
-
|
|
50
|
+
_files_decorators = [bind()];
|
|
51
|
+
_filesVisible_decorators = [bind()];
|
|
52
|
+
_syncFormValues_decorators = [effect()];
|
|
47
53
|
_onInputChange_decorators = [listen("change")];
|
|
48
54
|
_onDragEnter_decorators = [listen("dragenter")];
|
|
49
55
|
_onDragLeave_decorators = [listen("dragleave")];
|
|
@@ -53,7 +59,8 @@ let USAFileInputElement = (() => {
|
|
|
53
59
|
__esDecorate(this, null, _accept_decorators, { kind: "accessor", name: "accept", static: false, private: false, access: { has: obj => "accept" in obj, get: obj => obj.accept, set: (obj, value) => { obj.accept = value; } }, metadata: _metadata }, _accept_initializers, _accept_extraInitializers);
|
|
54
60
|
__esDecorate(this, null, _required_decorators, { kind: "accessor", name: "required", static: false, private: false, access: { has: obj => "required" in obj, get: obj => obj.required, set: (obj, value) => { obj.required = value; } }, metadata: _metadata }, _required_initializers, _required_extraInitializers);
|
|
55
61
|
__esDecorate(this, null, _files_decorators, { kind: "accessor", name: "files", static: false, private: false, access: { has: obj => "files" in obj, get: obj => obj.files, set: (obj, value) => { obj.files = value; } }, metadata: _metadata }, _files_initializers, _files_extraInitializers);
|
|
56
|
-
__esDecorate(this, null,
|
|
62
|
+
__esDecorate(this, null, _filesVisible_decorators, { kind: "accessor", name: "filesVisible", static: false, private: false, access: { has: obj => "filesVisible" in obj, get: obj => obj.filesVisible, set: (obj, value) => { obj.filesVisible = value; } }, metadata: _metadata }, _filesVisible_initializers, _filesVisible_extraInitializers);
|
|
63
|
+
__esDecorate(this, null, _syncFormValues_decorators, { kind: "method", name: "syncFormValues", static: false, private: false, access: { has: obj => "syncFormValues" in obj, get: obj => obj.syncFormValues }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
57
64
|
__esDecorate(this, null, _onInputChange_decorators, { kind: "method", name: "onInputChange", static: false, private: false, access: { has: obj => "onInputChange" in obj, get: obj => obj.onInputChange }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
58
65
|
__esDecorate(this, null, _onDragEnter_decorators, { kind: "method", name: "onDragEnter", static: false, private: false, access: { has: obj => "onDragEnter" in obj, get: obj => obj.onDragEnter }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
59
66
|
__esDecorate(this, null, _onDragLeave_decorators, { kind: "method", name: "onDragLeave", static: false, private: false, access: { has: obj => "onDragLeave" in obj, get: obj => obj.onDragLeave }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
@@ -78,10 +85,11 @@ let USAFileInputElement = (() => {
|
|
|
78
85
|
#files_accessor_storage = (__runInitializers(this, _required_extraInitializers), __runInitializers(this, _files_initializers, null));
|
|
79
86
|
get files() { return this.#files_accessor_storage; }
|
|
80
87
|
set files(value) { this.#files_accessor_storage = value; }
|
|
81
|
-
#
|
|
88
|
+
#filesVisible_accessor_storage = (__runInitializers(this, _files_extraInitializers), __runInitializers(this, _filesVisible_initializers, false));
|
|
89
|
+
get filesVisible() { return this.#filesVisible_accessor_storage; }
|
|
90
|
+
set filesVisible(value) { this.#filesVisible_accessor_storage = value; }
|
|
91
|
+
#internals = (__runInitializers(this, _filesVisible_extraInitializers), this.attachInternals());
|
|
82
92
|
#input = query("input");
|
|
83
|
-
#box = query(".box");
|
|
84
|
-
#preview = query("usa-file-input-preview");
|
|
85
93
|
attributeChangedCallback() {
|
|
86
94
|
this.#input({
|
|
87
95
|
name: this.name,
|
|
@@ -96,12 +104,9 @@ let USAFileInputElement = (() => {
|
|
|
96
104
|
this.#internals.setValidity({ customError: true }, input.validationMessage, input);
|
|
97
105
|
}
|
|
98
106
|
}
|
|
99
|
-
|
|
107
|
+
syncFormValues() {
|
|
100
108
|
const input = this.#input({ files: this.files });
|
|
101
|
-
this.#preview({ files: this.files });
|
|
102
|
-
const box = this.#box();
|
|
103
109
|
const formData = new FormData();
|
|
104
|
-
box.style.display = this.files?.length ? "none" : "flex";
|
|
105
110
|
if (this.files?.length) {
|
|
106
111
|
for (const file of this.files) {
|
|
107
112
|
formData.append(this.name, file);
|
|
@@ -118,6 +123,7 @@ let USAFileInputElement = (() => {
|
|
|
118
123
|
onInputChange() {
|
|
119
124
|
const input = this.#input();
|
|
120
125
|
this.files = input.files;
|
|
126
|
+
this.filesVisible = !!input.files?.length;
|
|
121
127
|
this.dispatchEvent(new Event("change"));
|
|
122
128
|
}
|
|
123
129
|
onDragEnter() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-input.element.js","sourceRoot":"","sources":["../../../src/lib/file-input/file-input.element.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"file-input.element.js","sourceRoot":"","sources":["../../../src/lib/file-input/file-input.element.ts"],"names":[],"mappings":";AAAA,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;IAyG5B,mBAAmB;4BAjG/B,OAAO,CAAC;YACP,OAAO,EAAE,gBAAgB;YACzB,SAAS,EAAE;gBACT,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgEF;gBACD,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;KA0BH;aACF;SACF,CAAC;;;;sBACuC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;mCAAnB,SAAQ,WAAW;;;;gCAGjD,IAAI,EAAE;oCAGN,IAAI,EAAE;kCAGN,IAAI,EAAE;oCAGN,IAAI,EAAE;iCAGN,IAAI,EAAE;wCAGN,IAAI,EAAE;0CA2BN,MAAM,EAAE;yCAyBR,MAAM,CAAC,QAAQ,CAAC;uCAUhB,MAAM,CAAC,WAAW,CAAC;uCAKnB,MAAM,CAAC,WAAW,CAAC;kCAKnB,MAAM,CAAC,MAAM,CAAC;YAtFf,iKAAS,IAAI,6BAAJ,IAAI,mFAAM;YAGnB,6KAAS,QAAQ,6BAAR,QAAQ,2FAAQ;YAGzB,uKAAS,MAAM,6BAAN,MAAM,uFAAM;YAGrB,6KAAS,QAAQ,6BAAR,QAAQ,2FAAS;YAG1B,oKAAS,KAAK,6BAAL,KAAK,qFAAyB;YAGvC,yLAAS,YAAY,6BAAZ,YAAY,mGAAS;YA2B9B,6LAAA,cAAc,6DAsBb;YAGD,0LAAA,aAAa,6DAOZ;YAGD,oLAAA,WAAW,6DAEV;YAGD,oLAAA,WAAW,6DAEV;YAGD,qKAAA,MAAM,6DAoBL;YA/GH,6KAgHC;;;;QA/GC,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;QAG7B,0BAJW,mDAAmB,8CAId,EAAE,GAAC;QAAnB,IAAS,IAAI,0CAAM;QAAnB,IAAS,IAAI,gDAAM;QAGnB,gIAAoB,IAAI,GAAC;QAAzB,IAAS,QAAQ,8CAAQ;QAAzB,IAAS,QAAQ,oDAAQ;QAGzB,gIAAkB,EAAE,GAAC;QAArB,IAAS,MAAM,4CAAM;QAArB,IAAS,MAAM,kDAAM;QAGrB,kIAAoB,KAAK,GAAC;QAA1B,IAAS,QAAQ,8CAAS;QAA1B,IAAS,QAAQ,oDAAS;QAG1B,8HAAkC,IAAI,GAAC;QAAvC,IAAS,KAAK,2CAAyB;QAAvC,IAAS,KAAK,iDAAyB;QAGvC,yIAAwB,KAAK,GAAC;QAA9B,IAAS,YAAY,kDAAS;QAA9B,IAAS,YAAY,wDAAS;QAE9B,UAAU,8DAAG,IAAI,CAAC,eAAe,EAAE,EAAC;QACpC,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;QAExB,wBAAwB;YACtB,IAAI,CAAC,MAAM,CAAC;gBACV,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC,CAAC;QACL,CAAC;QAED,iBAAiB;YACf,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAE5B,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;gBAC5B,IAAI,CAAC,UAAU,CAAC,WAAW,CACzB,EAAE,WAAW,EAAE,IAAI,EAAE,EACrB,KAAK,CAAC,iBAAiB,EACvB,KAAK,CACN,CAAC;YACJ,CAAC;QACH,CAAC;QAGD,cAAc;YACZ,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAEjD,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;YAEhC,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;gBACvB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBAC9B,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC;YAED,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAEvC,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;gBAC5B,IAAI,CAAC,UAAU,CAAC,WAAW,CACzB,EAAE,WAAW,EAAE,IAAI,EAAE,EACrB,KAAK,CAAC,iBAAiB,EACvB,KAAK,CACN,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAGD,aAAa;YACX,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAE5B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YACzB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC;YAE1C,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1C,CAAC;QAGD,WAAW;YACT,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAClC,CAAC;QAGD,WAAW;YACT,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACrC,CAAC;QAGD,MAAM,CAAC,CAAY;YACjB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAEnC,IAAI,CAAC,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC;gBAC1B,CAAC,CAAC,cAAc,EAAE,CAAC;gBAEnB,MAAM,IAAI,GAAG,IAAI,YAAY,EAAE,CAAC;gBAEhC,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;oBACxC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;wBACzB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;wBAE9B,IAAI,IAAI,EAAE,CAAC;4BACT,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;wBACvB,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YAC1B,CAAC;QACH,CAAC;;YA/GU,uDAAmB;;;;;SAAnB,mBAAmB"}
|