@umbraco-ui/uui 2.0.0-alpha.1 → 2.0.0-rc.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.
- package/custom-elements.json +45 -8
- package/dist/components/avatar/avatar.element.js +1 -0
- package/dist/components/avatar/avatar.element.js.map +1 -1
- package/dist/components/boolean-input/boolean-input.element.js +7 -1
- package/dist/components/boolean-input/boolean-input.element.js.map +1 -1
- package/dist/components/button/button.element.d.ts +0 -1
- package/dist/components/button/button.element.js +64 -18
- package/dist/components/button/button.element.js.map +1 -1
- package/dist/components/card-block-type/card-block-type.element.js +13 -4
- package/dist/components/card-block-type/card-block-type.element.js.map +1 -1
- package/dist/components/card-content-node/card-content-node.element.js +2 -2
- package/dist/components/card-content-node/card-content-node.element.js.map +1 -1
- package/dist/components/card-media/card-media.element.js +10 -3
- package/dist/components/card-media/card-media.element.js.map +1 -1
- package/dist/components/card-user/card-user.element.js +2 -2
- package/dist/components/card-user/card-user.element.js.map +1 -1
- package/dist/components/checkbox/checkbox.element.js +3 -6
- package/dist/components/checkbox/checkbox.element.js.map +1 -1
- package/dist/components/color-slider/color-slider.element.js +13 -3
- package/dist/components/color-slider/color-slider.element.js.map +1 -1
- package/dist/components/color-swatch/color-swatch.element.js +33 -1
- package/dist/components/color-swatch/color-swatch.element.js.map +1 -1
- package/dist/components/combobox/combobox.element.d.ts +9 -0
- package/dist/components/combobox/combobox.element.js +127 -15
- package/dist/components/combobox/combobox.element.js.map +1 -1
- package/dist/components/combobox-list/combobox-list-option.element.d.ts +1 -0
- package/dist/components/combobox-list/combobox-list-option.element.js +49 -10
- package/dist/components/combobox-list/combobox-list-option.element.js.map +1 -1
- package/dist/components/combobox-list/combobox-list.element.d.ts +14 -0
- package/dist/components/combobox-list/combobox-list.element.js +74 -25
- package/dist/components/combobox-list/combobox-list.element.js.map +1 -1
- package/dist/components/file-dropzone/file-dropzone.element.d.ts +2 -8
- package/dist/components/file-dropzone/file-dropzone.element.js +14 -25
- package/dist/components/file-dropzone/file-dropzone.element.js.map +1 -1
- package/dist/components/icon-registry-essential/UUIIconRegistryEssential.js +1 -1
- package/dist/components/icon-registry-essential/icon-registry-essential.js +33 -0
- package/dist/components/icon-registry-essential/icon-registry-essential.js.map +1 -1
- package/dist/components/index.d.ts +81 -0
- package/dist/components/input/input.element.js +33 -3
- package/dist/components/input/input.element.js.map +1 -1
- package/dist/components/input-file/input-file.element.js +33 -1
- package/dist/components/input-file/input-file.element.js.map +1 -1
- package/dist/components/input-lock/input-lock.element.js +33 -4
- package/dist/components/input-lock/input-lock.element.js.map +1 -1
- package/dist/components/input-password/input-password.element.js +33 -3
- package/dist/components/input-password/input-password.element.js.map +1 -1
- package/dist/components/keyboard-shortcut/key.element.js +7 -1
- package/dist/components/keyboard-shortcut/key.element.js.map +1 -1
- package/dist/components/loader/loader.element.js +19 -2
- package/dist/components/loader/loader.element.js.map +1 -1
- package/dist/components/modal/modal-container.js +6 -2
- package/dist/components/modal/modal-container.js.map +1 -1
- package/dist/components/modal/modal-dialog.element.js +5 -5
- package/dist/components/modal/modal-dialog.element.js.map +1 -1
- package/dist/components/modal/modal-sidebar.element.js +14 -10
- package/dist/components/modal/modal-sidebar.element.js.map +1 -1
- package/dist/components/modal/modal-with-toasts-example.element.d.ts +22 -0
- package/dist/components/modal/modal.element.d.ts +3 -1
- package/dist/components/modal/modal.element.js +31 -12
- package/dist/components/modal/modal.element.js.map +1 -1
- package/dist/components/modal/modal.js +7 -1
- package/dist/components/modal/modal.js.map +1 -1
- package/dist/components/pagination/pagination.element.d.ts +2 -0
- package/dist/components/pagination/pagination.element.js +26 -20
- package/dist/components/pagination/pagination.element.js.map +1 -1
- package/dist/components/progress-bar/progress-bar.element.js +6 -5
- package/dist/components/progress-bar/progress-bar.element.js.map +1 -1
- package/dist/components/responsive-container/responsive-container.element.js +36 -14
- package/dist/components/responsive-container/responsive-container.element.js.map +1 -1
- package/dist/components/scroll-container/scroll-container.element.js +4 -4
- package/dist/components/scroll-container/scroll-container.element.js.map +1 -1
- package/dist/components/symbol-expand/symbol-expand.element.js +1 -1
- package/dist/components/symbol-expand/symbol-expand.element.js.map +1 -1
- package/dist/components/symbol-file-thumbnail/symbol-file-thumbnail.element.js +34 -1
- package/dist/components/symbol-file-thumbnail/symbol-file-thumbnail.element.js.map +1 -1
- package/dist/components/table/table-head.element.js +4 -0
- package/dist/components/table/table-head.element.js.map +1 -1
- package/dist/components/table/table.element.js +5 -1
- package/dist/components/table/table.element.js.map +1 -1
- package/dist/components/tag/tag.element.js +4 -3
- package/dist/components/tag/tag.element.js.map +1 -1
- package/dist/components/toast-notification/toast-notification.element.js +34 -2
- package/dist/components/toast-notification/toast-notification.element.js.map +1 -1
- package/dist/components/toggle/toggle.element.js +38 -3
- package/dist/components/toggle/toggle.element.js.map +1 -1
- package/dist/index.d.ts +1 -81
- package/dist/internal/mixins/LabelMixin.js +14 -1
- package/dist/internal/mixins/LabelMixin.js.map +1 -1
- package/dist/internal/mixins/SelectOnlyMixin.d.ts +1 -1
- package/dist/internal/mixins/SelectOnlyMixin.js.map +1 -1
- package/dist/package.json.js +1 -1
- package/dist/themes/dark.css +1 -1
- package/dist/themes/high-contrast.css +1 -1
- package/dist/themes/light.css +1 -1
- package/package.json +26 -26
- package/vscode.html-custom-data.json +33 -18
|
@@ -24,33 +24,53 @@ const _UUIComboboxListElement = class _UUIComboboxListElement extends LitElement
|
|
|
24
24
|
super(...arguments);
|
|
25
25
|
__privateAdd(this, _UUIComboboxListElement_instances);
|
|
26
26
|
this.displayValue = "";
|
|
27
|
+
this.multiple = false;
|
|
27
28
|
this._value = "";
|
|
28
29
|
this._activeElementValue = null;
|
|
30
|
+
this._selectedValues = [];
|
|
31
|
+
this._selectedElements = [];
|
|
29
32
|
this._onSlotChange = () => {
|
|
30
33
|
__privateMethod(this, _UUIComboboxListElement_instances, updateActiveElement_fn).call(this);
|
|
34
|
+
for (const option of this._options) {
|
|
35
|
+
option.multiple = this.multiple;
|
|
36
|
+
}
|
|
31
37
|
this._updateSelection();
|
|
32
38
|
this.dispatchEvent(
|
|
33
39
|
new UUIComboboxListEvent(UUIComboboxListEvent.INNER_SLOT_CHANGE)
|
|
34
40
|
);
|
|
35
41
|
};
|
|
36
42
|
this._onSelected = (e) => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
this.
|
|
43
|
+
const option = e.composedPath()[0];
|
|
44
|
+
if (this.multiple) {
|
|
45
|
+
option.deselectable = true;
|
|
46
|
+
this._selectedElements.push(option);
|
|
47
|
+
this._selectedValues = [...this._selectedValues, option.value || ""];
|
|
48
|
+
} else {
|
|
49
|
+
if (this._selectedElement) {
|
|
50
|
+
this._selectedElement.selected = false;
|
|
51
|
+
this._selectedElement.active = false;
|
|
52
|
+
this._selectedElement = void 0;
|
|
53
|
+
}
|
|
54
|
+
this._selectedElement = option;
|
|
55
|
+
this.value = option.value || "";
|
|
56
|
+
this.displayValue = option.displayValue || "";
|
|
41
57
|
}
|
|
42
|
-
this._selectedElement = e.composedPath()[0];
|
|
43
|
-
this.value = this._selectedElement.value || "";
|
|
44
|
-
this.displayValue = this._selectedElement.displayValue || "";
|
|
45
58
|
this.dispatchEvent(new UUIComboboxListEvent(UUIComboboxListEvent.CHANGE));
|
|
46
59
|
};
|
|
47
60
|
this._onDeselected = (e) => {
|
|
48
61
|
const el = e.composedPath()[0];
|
|
49
|
-
if (this.
|
|
50
|
-
this.
|
|
51
|
-
this.
|
|
52
|
-
|
|
62
|
+
if (this.multiple) {
|
|
63
|
+
this._selectedElements = this._selectedElements.filter((opt) => opt !== el);
|
|
64
|
+
this._selectedValues = this._selectedValues.filter(
|
|
65
|
+
(v) => v !== (el.value || "")
|
|
66
|
+
);
|
|
67
|
+
} else {
|
|
68
|
+
if (this._selectedElement === el) {
|
|
69
|
+
this.value = "";
|
|
70
|
+
this.displayValue = "";
|
|
71
|
+
}
|
|
53
72
|
}
|
|
73
|
+
this.dispatchEvent(new UUIComboboxListEvent(UUIComboboxListEvent.CHANGE));
|
|
54
74
|
};
|
|
55
75
|
this._moveIndex = (distance) => {
|
|
56
76
|
const newIndex = Math.min(
|
|
@@ -88,13 +108,6 @@ const _UUIComboboxListElement = class _UUIComboboxListElement extends LitElement
|
|
|
88
108
|
this._getActiveElement?.click();
|
|
89
109
|
break;
|
|
90
110
|
}
|
|
91
|
-
//Space key
|
|
92
|
-
case "Space": {
|
|
93
|
-
e.preventDefault();
|
|
94
|
-
e.stopPropagation();
|
|
95
|
-
this._getActiveElement?.click();
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
111
|
case "End": {
|
|
99
112
|
e.preventDefault();
|
|
100
113
|
this._goToIndex(this._options.length - 1);
|
|
@@ -125,6 +138,20 @@ const _UUIComboboxListElement = class _UUIComboboxListElement extends LitElement
|
|
|
125
138
|
this._for.addEventListener("keydown", this._onKeyDown);
|
|
126
139
|
}
|
|
127
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Array of selected option values. Only relevant when multiple is true.
|
|
143
|
+
* @type {string[]}
|
|
144
|
+
*/
|
|
145
|
+
get selectedValues() {
|
|
146
|
+
return this._selectedValues;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Array of display values for selected options. Only relevant when multiple is true.
|
|
150
|
+
* @type {string[]}
|
|
151
|
+
*/
|
|
152
|
+
get selectedDisplayValues() {
|
|
153
|
+
return this._selectedElements.map((el) => el.displayValue || el.value || "");
|
|
154
|
+
}
|
|
128
155
|
connectedCallback() {
|
|
129
156
|
super.connectedCallback();
|
|
130
157
|
this._for ??= this;
|
|
@@ -138,16 +165,32 @@ const _UUIComboboxListElement = class _UUIComboboxListElement extends LitElement
|
|
|
138
165
|
this.removeEventListener(UUISelectableEvent.DESELECTED, this._onDeselected);
|
|
139
166
|
}
|
|
140
167
|
_updateSelection() {
|
|
141
|
-
this.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
168
|
+
if (this.multiple) {
|
|
169
|
+
for (const option of this._options) {
|
|
170
|
+
if (this._selectedValues.includes(option.value)) {
|
|
171
|
+
option.selected = true;
|
|
172
|
+
option.deselectable = true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
this._selectedElements = this._options.filter(
|
|
176
|
+
(opt) => this._selectedValues.includes(opt.value)
|
|
177
|
+
);
|
|
178
|
+
} else {
|
|
179
|
+
this.displayValue = "";
|
|
180
|
+
for (const option of this._options) {
|
|
181
|
+
if (option.value === this._value) {
|
|
182
|
+
this.displayValue = option.displayValue || "";
|
|
183
|
+
option.selected = true;
|
|
184
|
+
} else {
|
|
185
|
+
option.selected = false;
|
|
186
|
+
}
|
|
148
187
|
}
|
|
149
188
|
}
|
|
150
189
|
}
|
|
190
|
+
resetSelection() {
|
|
191
|
+
this._selectedValues = [];
|
|
192
|
+
this._selectedElements = [];
|
|
193
|
+
}
|
|
151
194
|
get _getActiveIndex() {
|
|
152
195
|
if (this._activeElementValue === null) return -1;
|
|
153
196
|
return this._options.findIndex(
|
|
@@ -206,6 +249,9 @@ __decorateClass([
|
|
|
206
249
|
__decorateClass([
|
|
207
250
|
property({ type: String })
|
|
208
251
|
], UUIComboboxListElement.prototype, "displayValue", 2);
|
|
252
|
+
__decorateClass([
|
|
253
|
+
property({ type: Boolean, reflect: true })
|
|
254
|
+
], UUIComboboxListElement.prototype, "multiple", 2);
|
|
209
255
|
__decorateClass([
|
|
210
256
|
property({ attribute: false })
|
|
211
257
|
], UUIComboboxListElement.prototype, "for", 1);
|
|
@@ -227,6 +273,9 @@ __decorateClass([
|
|
|
227
273
|
__decorateClass([
|
|
228
274
|
state()
|
|
229
275
|
], UUIComboboxListElement.prototype, "_activeElementValue", 2);
|
|
276
|
+
__decorateClass([
|
|
277
|
+
state()
|
|
278
|
+
], UUIComboboxListElement.prototype, "_selectedValues", 2);
|
|
230
279
|
export {
|
|
231
280
|
UUIComboboxListElement
|
|
232
281
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox-list.element.js","sources":["../../../src/components/combobox-list/combobox-list.element.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { property, queryAssignedElements, state } from 'lit/decorators.js';\nimport { UUISelectableEvent } from '../../internal/events/index.js';\nimport type { UUIComboboxListOptionElement } from './combobox-list-option.element.js';\nimport { UUIComboboxListEvent } from './UUIComboboxListEvent.js';\n\n/**\n * @element uui-combobox-list\n * @fires {UUIComboboxListEvent} change - fires when selection is changed\n * @slot - for uui-combobox-list-options\n * @description - A list that uses uui-combobox-list-options and handles keyboard navigation and selection.\n */\nexport class UUIComboboxListElement extends LitElement {\n /**\n * Value of selected option.\n * @type {FormDataEntryValue | FormData}\n * @attr\n * @default \"\"\n */\n @property()\n public get value() {\n return this._value;\n }\n public set value(newValue) {\n if (this._value === newValue) return;\n\n const oldValue = this._value;\n this._value = newValue;\n\n this._updateSelection();\n this.requestUpdate('value', oldValue);\n }\n\n /**\n * A readable value to display to show the selected value.\n * @type {string}\n * @attr\n * @default \"\"\n */\n @property({ type: String })\n public displayValue = '';\n\n private _for?: HTMLElement;\n /**\n * provide another element of which keyboard navigation\n * @type {HTMLElement}\n * @attr\n * @default this\n */\n @property({ attribute: false })\n public get for() {\n return this._for;\n }\n public set for(newValue: HTMLElement | undefined) {\n if (this._for) {\n this._for.removeEventListener('keydown', this._onKeyDown);\n }\n\n this._for = newValue;\n if (this._for) {\n this._for.addEventListener('keydown', this._onKeyDown);\n }\n }\n\n @queryAssignedElements({\n flatten: true,\n selector: 'uui-combobox-list-option:not([disabled])',\n })\n private readonly _options!: UUIComboboxListOptionElement[];\n\n @queryAssignedElements({\n flatten: true,\n selector: 'uui-combobox-list-option[active]',\n })\n private readonly _activeOptions!: UUIComboboxListOptionElement[];\n\n @state()\n private _value: FormDataEntryValue | FormData = '';\n\n @state()\n private _activeElementValue: string | null = null;\n\n private _selectedElement: UUIComboboxListOptionElement | undefined;\n\n connectedCallback(): void {\n super.connectedCallback();\n\n this._for ??= this;\n\n this.addEventListener(UUISelectableEvent.SELECTED, this._onSelected);\n this.addEventListener(UUISelectableEvent.DESELECTED, this._onDeselected);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('keydown', this._onKeyDown);\n\n this.removeEventListener(UUISelectableEvent.SELECTED, this._onSelected);\n this.removeEventListener(UUISelectableEvent.DESELECTED, this._onDeselected);\n }\n\n private _updateSelection() {\n this.displayValue = '';\n\n // Ensure the right items are selected.\n for (const option of this._options) {\n if (option.value === this._value) {\n this.displayValue = option.displayValue || '';\n option.selected = true;\n } else {\n option.selected = false;\n }\n }\n }\n\n private readonly _onSlotChange = () => {\n // Get index from first active, remove active from the rest.\n this.#updateActiveElement();\n\n this._updateSelection();\n this.dispatchEvent(\n new UUIComboboxListEvent(UUIComboboxListEvent.INNER_SLOT_CHANGE),\n );\n };\n\n #updateActiveElement() {\n for (const option of this._activeOptions) {\n option.active = false;\n }\n\n const activeElement = this._getActiveElement;\n if (activeElement) {\n activeElement.active = true;\n } else {\n this._goToIndex(0);\n }\n }\n\n private readonly _onSelected = (e: Event) => {\n if (this._selectedElement) {\n this._selectedElement.selected = false;\n this._selectedElement.active = false;\n this._selectedElement = undefined;\n }\n this._selectedElement = e.composedPath()[0] as UUIComboboxListOptionElement;\n\n this.value = this._selectedElement.value || '';\n this.displayValue = this._selectedElement.displayValue || '';\n\n this.dispatchEvent(new UUIComboboxListEvent(UUIComboboxListEvent.CHANGE));\n };\n private readonly _onDeselected = (e: Event) => {\n const el = e.composedPath()[0] as UUIComboboxListOptionElement;\n if (this._selectedElement === el) {\n this.value = '';\n this.displayValue = '';\n this.dispatchEvent(new UUIComboboxListEvent(UUIComboboxListEvent.CHANGE));\n }\n };\n\n private get _getActiveIndex(): number {\n if (this._activeElementValue === null) return -1;\n\n return this._options.findIndex(\n element => element.value === this._activeElementValue,\n );\n }\n\n private get _getActiveElement() {\n if (this._activeElementValue === null) return null;\n\n return this._options.find(\n element => element.value === this._activeElementValue,\n );\n }\n\n private readonly _moveIndex = (distance: number) => {\n const newIndex = Math.min(\n Math.max(this._getActiveIndex + distance, 0),\n this._options.length - 1,\n );\n\n this._goToIndex(newIndex);\n };\n\n private _goToIndex(index: number) {\n if (this._options.length === 0) return;\n\n index = Math.min(Math.max(index, 0), this._options.length - 1); // Makes sure the index stays within array length\n const activeElement = this._options[index];\n this._activeElementValue = activeElement.value;\n this.#updateActiveElement();\n\n if (activeElement) {\n activeElement.scrollIntoView({\n behavior: 'auto',\n block: 'nearest',\n inline: 'nearest',\n });\n }\n }\n\n private readonly _onKeyDown = (e: KeyboardEvent) => {\n if (this._options.length <= 0) return;\n\n switch (e.code) {\n case 'ArrowUp':\n e.preventDefault();\n if (e.ctrlKey) {\n this._moveIndex(-10);\n } else {\n this._moveIndex(-1);\n }\n break;\n\n case 'ArrowDown':\n e.preventDefault();\n if (e.ctrlKey) {\n this._moveIndex(10);\n } else {\n this._moveIndex(1);\n }\n\n break;\n\n case 'Home': {\n e.preventDefault();\n this._goToIndex(0);\n break;\n }\n\n case 'Enter': {\n e.preventDefault();\n this._getActiveElement?.click();\n break;\n }\n\n //Space key\n case 'Space': {\n e.preventDefault();\n e.stopPropagation();\n this._getActiveElement?.click();\n break;\n }\n\n case 'End': {\n e.preventDefault();\n this._goToIndex(this._options.length - 1);\n break;\n }\n\n default:\n break;\n }\n };\n\n render() {\n return html` <slot @slotchange=${this._onSlotChange}></slot> `;\n }\n\n static override readonly styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n }\n `,\n ];\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"combobox-list.element.js","sources":["../../../src/components/combobox-list/combobox-list.element.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { property, queryAssignedElements, state } from 'lit/decorators.js';\nimport { UUISelectableEvent } from '../../internal/events/index.js';\nimport type { UUIComboboxListOptionElement } from './combobox-list-option.element.js';\nimport { UUIComboboxListEvent } from './UUIComboboxListEvent.js';\n\n/**\n * @element uui-combobox-list\n * @fires {UUIComboboxListEvent} change - fires when selection is changed\n * @slot - for uui-combobox-list-options\n * @description - A list that uses uui-combobox-list-options and handles keyboard navigation and selection.\n */\nexport class UUIComboboxListElement extends LitElement {\n /**\n * Value of selected option.\n * @type {FormDataEntryValue | FormData}\n * @attr\n * @default \"\"\n */\n @property()\n public get value() {\n return this._value;\n }\n public set value(newValue) {\n if (this._value === newValue) return;\n\n const oldValue = this._value;\n this._value = newValue;\n\n this._updateSelection();\n this.requestUpdate('value', oldValue);\n }\n\n /**\n * A readable value to display to show the selected value.\n * @type {string}\n * @attr\n * @default \"\"\n */\n @property({ type: String })\n public displayValue = '';\n\n @property({ type: Boolean, reflect: true })\n multiple = false;\n\n private _for?: HTMLElement;\n /**\n * provide another element of which keyboard navigation\n * @type {HTMLElement}\n * @attr\n * @default this\n */\n @property({ attribute: false })\n public get for() {\n return this._for;\n }\n public set for(newValue: HTMLElement | undefined) {\n if (this._for) {\n this._for.removeEventListener('keydown', this._onKeyDown);\n }\n\n this._for = newValue;\n if (this._for) {\n this._for.addEventListener('keydown', this._onKeyDown);\n }\n }\n\n @queryAssignedElements({\n flatten: true,\n selector: 'uui-combobox-list-option:not([disabled])',\n })\n private readonly _options!: UUIComboboxListOptionElement[];\n\n @queryAssignedElements({\n flatten: true,\n selector: 'uui-combobox-list-option[active]',\n })\n private readonly _activeOptions!: UUIComboboxListOptionElement[];\n\n @state()\n private _value: FormDataEntryValue | FormData = '';\n\n @state()\n private _activeElementValue: string | null = null;\n\n private _selectedElement: UUIComboboxListOptionElement | undefined;\n\n @state()\n private _selectedValues: string[] = [];\n private _selectedElements: UUIComboboxListOptionElement[] = [];\n /**\n * Array of selected option values. Only relevant when multiple is true.\n * @type {string[]}\n */\n public get selectedValues(): string[] {\n return this._selectedValues;\n }\n\n /**\n * Array of display values for selected options. Only relevant when multiple is true.\n * @type {string[]}\n */\n public get selectedDisplayValues(): string[] {\n return this._selectedElements.map(el => el.displayValue || el.value || '');\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n\n this._for ??= this;\n\n this.addEventListener(UUISelectableEvent.SELECTED, this._onSelected);\n this.addEventListener(UUISelectableEvent.DESELECTED, this._onDeselected);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('keydown', this._onKeyDown);\n\n this.removeEventListener(UUISelectableEvent.SELECTED, this._onSelected);\n this.removeEventListener(UUISelectableEvent.DESELECTED, this._onDeselected);\n }\n\n private _updateSelection() {\n if (this.multiple) {\n for (const option of this._options) {\n if (this._selectedValues.includes(option.value)) {\n option.selected = true;\n option.deselectable = true;\n }\n }\n this._selectedElements = this._options.filter(opt =>\n this._selectedValues.includes(opt.value),\n );\n } else {\n this.displayValue = '';\n for (const option of this._options) {\n if (option.value === this._value) {\n this.displayValue = option.displayValue || '';\n option.selected = true;\n } else {\n option.selected = false;\n }\n }\n }\n }\n\n private readonly _onSlotChange = () => {\n // Get index from first active, remove active from the rest.\n this.#updateActiveElement();\n\n for (const option of this._options) {\n option.multiple = this.multiple;\n }\n\n this._updateSelection();\n this.dispatchEvent(\n new UUIComboboxListEvent(UUIComboboxListEvent.INNER_SLOT_CHANGE),\n );\n };\n\n #updateActiveElement() {\n for (const option of this._activeOptions) {\n option.active = false;\n }\n\n const activeElement = this._getActiveElement;\n if (activeElement) {\n activeElement.active = true;\n } else {\n this._goToIndex(0);\n }\n }\n\n private readonly _onSelected = (e: Event) => {\n const option = e.composedPath()[0] as UUIComboboxListOptionElement;\n\n if (this.multiple) {\n // Allow this option to be toggled off on next click\n option.deselectable = true;\n // Add to array\n this._selectedElements.push(option);\n this._selectedValues = [...this._selectedValues, option.value || ''];\n } else {\n // Existing single-select logic\n if (this._selectedElement) {\n this._selectedElement.selected = false;\n this._selectedElement.active = false;\n this._selectedElement = undefined;\n }\n this._selectedElement = option;\n this.value = option.value || '';\n this.displayValue = option.displayValue || '';\n }\n\n this.dispatchEvent(new UUIComboboxListEvent(UUIComboboxListEvent.CHANGE));\n };\n\n private readonly _onDeselected = (e: Event) => {\n const el = e.composedPath()[0] as UUIComboboxListOptionElement;\n if (this.multiple) {\n // Remove from arrays\n this._selectedElements = this._selectedElements.filter(opt => opt !== el);\n this._selectedValues = this._selectedValues.filter(\n v => v !== (el.value || ''),\n );\n } else {\n // Existing single-select logic\n if (this._selectedElement === el) {\n this.value = '';\n this.displayValue = '';\n }\n }\n\n this.dispatchEvent(new UUIComboboxListEvent(UUIComboboxListEvent.CHANGE));\n };\n\n public resetSelection() {\n this._selectedValues = [];\n this._selectedElements = [];\n }\n\n private get _getActiveIndex(): number {\n if (this._activeElementValue === null) return -1;\n\n return this._options.findIndex(\n element => element.value === this._activeElementValue,\n );\n }\n\n private get _getActiveElement() {\n if (this._activeElementValue === null) return null;\n\n return this._options.find(\n element => element.value === this._activeElementValue,\n );\n }\n\n private readonly _moveIndex = (distance: number) => {\n const newIndex = Math.min(\n Math.max(this._getActiveIndex + distance, 0),\n this._options.length - 1,\n );\n\n this._goToIndex(newIndex);\n };\n\n private _goToIndex(index: number) {\n if (this._options.length === 0) return;\n\n index = Math.min(Math.max(index, 0), this._options.length - 1); // Makes sure the index stays within array length\n const activeElement = this._options[index];\n this._activeElementValue = activeElement.value;\n this.#updateActiveElement();\n\n if (activeElement) {\n activeElement.scrollIntoView({\n behavior: 'auto',\n block: 'nearest',\n inline: 'nearest',\n });\n }\n }\n\n private readonly _onKeyDown = (e: KeyboardEvent) => {\n if (this._options.length <= 0) return;\n\n switch (e.code) {\n case 'ArrowUp':\n e.preventDefault();\n if (e.ctrlKey) {\n this._moveIndex(-10);\n } else {\n this._moveIndex(-1);\n }\n break;\n\n case 'ArrowDown':\n e.preventDefault();\n if (e.ctrlKey) {\n this._moveIndex(10);\n } else {\n this._moveIndex(1);\n }\n\n break;\n\n case 'Home': {\n e.preventDefault();\n this._goToIndex(0);\n break;\n }\n\n case 'Enter': {\n e.preventDefault();\n this._getActiveElement?.click();\n break;\n }\n\n case 'End': {\n e.preventDefault();\n this._goToIndex(this._options.length - 1);\n break;\n }\n\n default:\n break;\n }\n };\n\n render() {\n return html` <slot @slotchange=${this._onSlotChange}></slot> `;\n }\n\n static override readonly styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n }\n `,\n ];\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -46,21 +46,15 @@ export declare class UUIFileDropzoneElement extends UUIFileDropzoneElement_base
|
|
|
46
46
|
*/
|
|
47
47
|
browse(): void;
|
|
48
48
|
constructor();
|
|
49
|
-
/**
|
|
50
|
-
* Process a single file entry and categorize it as accepted or rejected.
|
|
51
|
-
* @param entry - The data transfer item containing the file
|
|
52
|
-
* @param files - Array to store accepted files
|
|
53
|
-
* @param rejectedFiles - Array to store rejected files
|
|
54
|
-
*/
|
|
55
|
-
private _processFileEntry;
|
|
56
49
|
/**
|
|
57
50
|
* Check if folder upload should be processed based on component settings.
|
|
58
51
|
* @returns true if folder upload is allowed and multiple files are enabled
|
|
59
52
|
*/
|
|
60
53
|
private _shouldProcessFolder;
|
|
61
54
|
private _getAllEntries;
|
|
55
|
+
private _processRootEntries;
|
|
62
56
|
/**
|
|
63
|
-
* Get the
|
|
57
|
+
* Get the filesystem entry (file or directory) from a DataTransferItem.
|
|
64
58
|
* @remark Supports both WebKit and non-WebKit browsers.
|
|
65
59
|
*/
|
|
66
60
|
private _getEntry;
|
|
@@ -58,21 +58,6 @@ const _UUIFileDropzoneElement = class _UUIFileDropzoneElement extends LabelMixin
|
|
|
58
58
|
browse() {
|
|
59
59
|
this._input.click();
|
|
60
60
|
}
|
|
61
|
-
/**
|
|
62
|
-
* Process a single file entry and categorize it as accepted or rejected.
|
|
63
|
-
* @param entry - The data transfer item containing the file
|
|
64
|
-
* @param files - Array to store accepted files
|
|
65
|
-
* @param rejectedFiles - Array to store rejected files
|
|
66
|
-
*/
|
|
67
|
-
_processFileEntry(entry, files, rejectedFiles) {
|
|
68
|
-
const file = entry.getAsFile();
|
|
69
|
-
if (!file) return;
|
|
70
|
-
if (this._isAccepted(file)) {
|
|
71
|
-
files.push(file);
|
|
72
|
-
} else {
|
|
73
|
-
rejectedFiles.push(file);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
61
|
/**
|
|
77
62
|
* Check if folder upload should be processed based on component settings.
|
|
78
63
|
* @returns true if folder upload is allowed and multiple files are enabled
|
|
@@ -81,25 +66,29 @@ const _UUIFileDropzoneElement = class _UUIFileDropzoneElement extends LabelMixin
|
|
|
81
66
|
return !this.disallowFolderUpload && this.multiple;
|
|
82
67
|
}
|
|
83
68
|
async _getAllEntries(dataTransferItemList) {
|
|
84
|
-
const
|
|
69
|
+
const rootEntries = [...dataTransferItemList].filter((item) => item?.kind === "file").map((item) => this._getEntry(item)).filter((entry) => entry !== null);
|
|
70
|
+
return this._processRootEntries(rootEntries);
|
|
71
|
+
}
|
|
72
|
+
async _processRootEntries(rootEntries) {
|
|
85
73
|
const folders = [];
|
|
86
74
|
const files = [];
|
|
87
75
|
const rejectedFiles = [];
|
|
88
|
-
for (const entry of
|
|
89
|
-
if (entry
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
76
|
+
for (const entry of rootEntries) {
|
|
77
|
+
if (!entry.isDirectory) {
|
|
78
|
+
const file = await this._getAsFile(entry);
|
|
79
|
+
if (this._isAccepted(file)) {
|
|
80
|
+
files.push(file);
|
|
81
|
+
} else {
|
|
82
|
+
rejectedFiles.push(file);
|
|
83
|
+
}
|
|
94
84
|
} else if (this._shouldProcessFolder()) {
|
|
95
|
-
|
|
96
|
-
folders.push(structure);
|
|
85
|
+
folders.push(await this._mkdir(entry));
|
|
97
86
|
}
|
|
98
87
|
}
|
|
99
88
|
return { files, folders, rejectedFiles };
|
|
100
89
|
}
|
|
101
90
|
/**
|
|
102
|
-
* Get the
|
|
91
|
+
* Get the filesystem entry (file or directory) from a DataTransferItem.
|
|
103
92
|
* @remark Supports both WebKit and non-WebKit browsers.
|
|
104
93
|
*/
|
|
105
94
|
_getEntry(entry) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-dropzone.element.js","sources":["../../../src/components/file-dropzone/file-dropzone.element.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { query, property } from 'lit/decorators.js';\nimport { UUIFileDropzoneEvent } from './UUIFileDropzoneEvent.js';\nimport { LabelMixin } from '../../internal/mixins/index.js';\n\nimport '../symbol-file-dropzone/symbol-file-dropzone.js';\n\nexport interface UUIFileFolder {\n folderName: string;\n folders: UUIFileFolder[];\n files: File[];\n}\n\n/**\n * @element uui-file-dropzone\n * @fires {UUIFileDropzoneEvent} change - fires when a file has been selected.\n * @fires {UUIFileDropzoneEvent} reject - fires when files are rejected due to not matching the accept attribute.\n * @slot - For the content of the dropzone\n * @description - Dropzone for file upload. Supports native browsing and drag n drop.\n */\nexport class UUIFileDropzoneElement extends LabelMixin('', LitElement) {\n @query('#input')\n private readonly _input!: HTMLInputElement;\n\n @query('#dropzone')\n private readonly _dropzone!: HTMLElement;\n\n private _acceptedFileExtensions: string[] = [];\n private _acceptedMimeTypes: string[] = [];\n private _accept = '';\n\n /**\n * Comma-separated list of accepted mime types or file extensions (denoted with a `.`).\n * If this is left empty, it will allow all types.\n *\n * @type {string}\n * @attr\n * @examples [\n * \"image/*,application/pdf\",\n * \".gif,.png,.jpg,.jpeg,.pdf\",\n * ]\n */\n @property({ type: String })\n public set accept(value: string) {\n if (value) {\n const mimetypes: string[] = [];\n const fileextensions: string[] = [];\n\n // Create the arrays defined above\n value.split(',').forEach(item => {\n item = item.trim().toLowerCase();\n\n // If the item is a mime type, add it to the accept list\n if (/^[a-z]+\\/[a-z*]+$/.test(item)) {\n mimetypes.push(item);\n } else {\n fileextensions.push(item.replace(/^\\./, ''));\n }\n });\n\n this._acceptedMimeTypes = mimetypes;\n this._acceptedFileExtensions = fileextensions;\n } else {\n this._acceptedMimeTypes = [];\n this._acceptedFileExtensions = [];\n }\n const old = this._accept;\n this._accept = value;\n this.requestUpdate('accept', old);\n }\n public get accept(): string {\n return this._accept;\n }\n\n @property({\n type: Boolean,\n reflect: true,\n attribute: 'disallow-folder-upload',\n })\n public disallowFolderUpload: boolean = false;\n\n /**\n * Allows for multiple files to be selected.\n * @type {boolean}\n * @attr\n * @default false\n */\n @property({ type: Boolean })\n public multiple: boolean = false;\n\n /**\n * Opens the native file picker to select a file.\n * @method browse\n */\n public browse() {\n this._input.click();\n }\n\n constructor() {\n super();\n\n this.addEventListener('dragenter', this._onDragEnter, false);\n this.addEventListener('dragleave', this._onDragLeave, false);\n this.addEventListener('dragover', this._onDragOver, false);\n this.addEventListener('drop', this._onDrop, false);\n }\n\n /**\n * Process a single file entry and categorize it as accepted or rejected.\n * @param entry - The data transfer item containing the file\n * @param files - Array to store accepted files\n * @param rejectedFiles - Array to store rejected files\n */\n private _processFileEntry(\n entry: DataTransferItem,\n files: File[],\n rejectedFiles: File[],\n ): void {\n const file = entry.getAsFile();\n if (!file) return;\n\n if (this._isAccepted(file)) {\n files.push(file);\n } else {\n rejectedFiles.push(file);\n }\n }\n\n /**\n * Check if folder upload should be processed based on component settings.\n * @returns true if folder upload is allowed and multiple files are enabled\n */\n private _shouldProcessFolder(): boolean {\n return !this.disallowFolderUpload && this.multiple;\n }\n\n private async _getAllEntries(dataTransferItemList: DataTransferItemList) {\n // Use BFS to traverse entire directory/file structure\n const queue = [...dataTransferItemList];\n\n const folders: UUIFileFolder[] = [];\n const files: File[] = [];\n const rejectedFiles: File[] = [];\n\n for (const entry of queue) {\n if (entry?.kind !== 'file') continue;\n\n const fileEntry = this._getEntry(entry);\n if (!fileEntry) continue;\n\n if (!fileEntry.isDirectory) {\n // Entry is a file\n this._processFileEntry(entry, files, rejectedFiles);\n } else if (this._shouldProcessFolder()) {\n // Entry is a directory\n const structure = await this._mkdir(fileEntry);\n folders.push(structure);\n }\n }\n\n return { files, folders, rejectedFiles };\n }\n\n /**\n * Get the directory entry from a DataTransferItem.\n * @remark Supports both WebKit and non-WebKit browsers.\n */\n private _getEntry(entry: DataTransferItem): FileSystemDirectoryEntry | null {\n let dir: FileSystemDirectoryEntry | null = null;\n\n if ('webkitGetAsEntry' in entry) {\n dir = entry.webkitGetAsEntry() as FileSystemDirectoryEntry;\n } else if ('getAsEntry' in entry) {\n // non-WebKit browsers may rename webkitGetAsEntry to getAsEntry. MDN recommends looking for both.\n dir = (entry as any).getAsEntry();\n }\n\n return dir;\n }\n\n // Process entries from a directory reader\n private async _processEntries(\n entries: FileSystemEntry[],\n folders: UUIFileFolder[],\n files: File[],\n ): Promise<void> {\n for (const en of entries) {\n if (en.isFile) {\n const file = await this._getAsFile(en as FileSystemFileEntry);\n if (this._isAccepted(file)) {\n files.push(file);\n }\n } else if (en.isDirectory) {\n const directory = await this._mkdir(en as FileSystemDirectoryEntry);\n folders.push(directory);\n }\n }\n }\n\n // Read entries from a directory reader recursively\n private async _readAllEntries(\n reader: FileSystemDirectoryReader,\n folders: UUIFileFolder[],\n files: File[],\n ): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n reader.readEntries(async entries => {\n if (!entries.length) {\n resolve();\n return;\n }\n\n await this._processEntries(entries, folders, files);\n\n // readEntries only reads up to 100 entries at a time. It is on purpose we call readEntries recursively.\n await this._readAllEntries(reader, folders, files);\n\n resolve();\n }, reject);\n });\n }\n\n // Make directory structure\n private async _mkdir(\n entry: FileSystemDirectoryEntry,\n ): Promise<UUIFileFolder> {\n const reader = entry.createReader();\n const folders: UUIFileFolder[] = [];\n const files: File[] = [];\n\n await this._readAllEntries(reader, folders, files);\n\n const result: UUIFileFolder = { folderName: entry.name, folders, files };\n return result;\n }\n\n private _isAccepted(file: File) {\n if (\n this._acceptedFileExtensions.length === 0 &&\n this._acceptedMimeTypes.length === 0\n ) {\n return true;\n }\n\n const fileType = file.type.toLowerCase();\n const fileExtension = file.name.split('.').pop();\n\n if (\n fileExtension &&\n this._acceptedFileExtensions.includes(fileExtension.toLowerCase())\n ) {\n return true;\n }\n\n for (const mimeType of this._acceptedMimeTypes) {\n if (\n fileType === mimeType ||\n (mimeType.endsWith('/*') &&\n fileType.startsWith(mimeType.replace('*', '')))\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n private async _getAsFile(fileEntry: FileSystemFileEntry): Promise<File> {\n return new Promise((resolve, reject) => fileEntry.file(resolve, reject));\n }\n\n private async _onDrop(e: DragEvent) {\n e.preventDefault();\n this._dropzone.classList.remove('hover');\n\n const items = e.dataTransfer?.items;\n\n if (items) {\n const fileSystemResult = await this._getAllEntries(items);\n\n if (this.multiple === false && fileSystemResult.files.length) {\n fileSystemResult.files = [fileSystemResult.files[0]];\n fileSystemResult.folders = [];\n // When multiple is false and we have an accepted file, don't report rejections\n fileSystemResult.rejectedFiles = [];\n }\n\n if (fileSystemResult.rejectedFiles.length > 0) {\n this.dispatchEvent(\n new UUIFileDropzoneEvent(UUIFileDropzoneEvent.REJECT, {\n detail: { files: fileSystemResult.rejectedFiles, folders: [] },\n }),\n );\n }\n\n if (!fileSystemResult.files.length && !fileSystemResult.folders.length) {\n return;\n }\n\n this.dispatchEvent(\n new UUIFileDropzoneEvent(UUIFileDropzoneEvent.CHANGE, {\n detail: {\n files: fileSystemResult.files,\n folders: fileSystemResult.folders,\n },\n }),\n );\n }\n }\n\n private _onDragOver(e: DragEvent) {\n e.preventDefault();\n }\n\n private _onDragEnter(e: DragEvent) {\n // TODO: make visual indication of wether the file is acceptable or not. If not we need to make a more negative/disabled visual look.\n this._dropzone.classList.add('hover');\n e.preventDefault();\n }\n\n private _onDragLeave(e: DragEvent) {\n this._dropzone.classList.remove('hover');\n e.preventDefault();\n }\n\n private _onFileInputChange() {\n const files = this._input.files ? Array.from(this._input.files) : [];\n\n if (this.multiple === false && files.length > 1) {\n files.splice(1, files.length - 1);\n }\n\n const allowedFiles = files.filter(file => this._isAccepted(file));\n const rejectedFiles = files.filter(file => !this._isAccepted(file));\n\n // When multiple is false and we have an accepted file, don't report rejections\n const shouldReportRejections =\n rejectedFiles.length > 0 && (this.multiple || allowedFiles.length === 0);\n\n if (shouldReportRejections) {\n this.dispatchEvent(\n new UUIFileDropzoneEvent(UUIFileDropzoneEvent.REJECT, {\n detail: { files: rejectedFiles, folders: [] },\n }),\n );\n }\n\n if (!allowedFiles.length) {\n return;\n }\n\n this.dispatchEvent(\n new UUIFileDropzoneEvent(UUIFileDropzoneEvent.CHANGE, {\n detail: {\n files: allowedFiles,\n folders: [],\n },\n }),\n );\n }\n\n render() {\n return html`\n <div id=\"dropzone\">\n <uui-symbol-file-dropzone id=\"symbol\"></uui-symbol-file-dropzone>\n ${this.renderLabel()}\n <input\n @click=${(e: Event) => e.stopImmediatePropagation()}\n id=\"input\"\n type=\"file\"\n accept=${this.accept}\n ?multiple=${this.multiple}\n @change=${this._onFileInputChange}\n aria-label=\"${this.label}\" />\n <slot></slot>\n </div>\n `;\n }\n\n static override readonly styles = [\n css`\n #dropzone {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n position: relative;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n padding: var(--uui-size-4);\n border: 3px solid transparent;\n margin: -3px;\n backdrop-filter: blur(2px);\n }\n #dropzone.hover {\n border-color: var(--uui-color-default);\n }\n #dropzone.hover::before {\n content: '';\n position: absolute;\n inset: 0;\n opacity: 0.2;\n border-color: var(--uui-color-default);\n background-color: var(--uui-color-default);\n }\n #symbol {\n color: var(--uui-color-default);\n max-width: 100%;\n max-height: 100%;\n }\n #input {\n position: absolute;\n width: 0px;\n height: 0px;\n opacity: 0;\n display: none;\n }\n `,\n ];\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"file-dropzone.element.js","sources":["../../../src/components/file-dropzone/file-dropzone.element.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { query, property } from 'lit/decorators.js';\nimport { UUIFileDropzoneEvent } from './UUIFileDropzoneEvent.js';\nimport { LabelMixin } from '../../internal/mixins/index.js';\n\nimport '../symbol-file-dropzone/symbol-file-dropzone.js';\n\nexport interface UUIFileFolder {\n folderName: string;\n folders: UUIFileFolder[];\n files: File[];\n}\n\n/**\n * @element uui-file-dropzone\n * @fires {UUIFileDropzoneEvent} change - fires when a file has been selected.\n * @fires {UUIFileDropzoneEvent} reject - fires when files are rejected due to not matching the accept attribute.\n * @slot - For the content of the dropzone\n * @description - Dropzone for file upload. Supports native browsing and drag n drop.\n */\nexport class UUIFileDropzoneElement extends LabelMixin('', LitElement) {\n @query('#input')\n private readonly _input!: HTMLInputElement;\n\n @query('#dropzone')\n private readonly _dropzone!: HTMLElement;\n\n private _acceptedFileExtensions: string[] = [];\n private _acceptedMimeTypes: string[] = [];\n private _accept = '';\n\n /**\n * Comma-separated list of accepted mime types or file extensions (denoted with a `.`).\n * If this is left empty, it will allow all types.\n *\n * @type {string}\n * @attr\n * @examples [\n * \"image/*,application/pdf\",\n * \".gif,.png,.jpg,.jpeg,.pdf\",\n * ]\n */\n @property({ type: String })\n public set accept(value: string) {\n if (value) {\n const mimetypes: string[] = [];\n const fileextensions: string[] = [];\n\n // Create the arrays defined above\n value.split(',').forEach(item => {\n item = item.trim().toLowerCase();\n\n // If the item is a mime type, add it to the accept list\n if (/^[a-z]+\\/[a-z*]+$/.test(item)) {\n mimetypes.push(item);\n } else {\n fileextensions.push(item.replace(/^\\./, ''));\n }\n });\n\n this._acceptedMimeTypes = mimetypes;\n this._acceptedFileExtensions = fileextensions;\n } else {\n this._acceptedMimeTypes = [];\n this._acceptedFileExtensions = [];\n }\n const old = this._accept;\n this._accept = value;\n this.requestUpdate('accept', old);\n }\n public get accept(): string {\n return this._accept;\n }\n\n @property({\n type: Boolean,\n reflect: true,\n attribute: 'disallow-folder-upload',\n })\n public disallowFolderUpload: boolean = false;\n\n /**\n * Allows for multiple files to be selected.\n * @type {boolean}\n * @attr\n * @default false\n */\n @property({ type: Boolean })\n public multiple: boolean = false;\n\n /**\n * Opens the native file picker to select a file.\n * @method browse\n */\n public browse() {\n this._input.click();\n }\n\n constructor() {\n super();\n\n this.addEventListener('dragenter', this._onDragEnter, false);\n this.addEventListener('dragleave', this._onDragLeave, false);\n this.addEventListener('dragover', this._onDragOver, false);\n this.addEventListener('drop', this._onDrop, false);\n }\n\n /**\n * Check if folder upload should be processed based on component settings.\n * @returns true if folder upload is allowed and multiple files are enabled\n */\n private _shouldProcessFolder(): boolean {\n return !this.disallowFolderUpload && this.multiple;\n }\n\n private async _getAllEntries(dataTransferItemList: DataTransferItemList) {\n // Phase 1: Extract ALL FileSystemEntry refs synchronously.\n // DataTransferItem.webkitGetAsEntry() returns null after the first await\n // because the browser expires the drag data store. FileSystemEntry objects\n // obtained here remain valid indefinitely.\n const rootEntries = [...dataTransferItemList]\n .filter(item => item?.kind === 'file')\n .map(item => this._getEntry(item))\n .filter((entry): entry is FileSystemEntry => entry !== null);\n\n return this._processRootEntries(rootEntries);\n }\n\n private async _processRootEntries(rootEntries: FileSystemEntry[]) {\n const folders: UUIFileFolder[] = [];\n const files: File[] = [];\n const rejectedFiles: File[] = [];\n\n for (const entry of rootEntries) {\n if (!entry.isDirectory) {\n const file = await this._getAsFile(entry as FileSystemFileEntry);\n if (this._isAccepted(file)) {\n files.push(file);\n } else {\n rejectedFiles.push(file);\n }\n } else if (this._shouldProcessFolder()) {\n folders.push(await this._mkdir(entry as FileSystemDirectoryEntry));\n }\n }\n\n return { files, folders, rejectedFiles };\n }\n\n /**\n * Get the filesystem entry (file or directory) from a DataTransferItem.\n * @remark Supports both WebKit and non-WebKit browsers.\n */\n private _getEntry(entry: DataTransferItem): FileSystemEntry | null {\n let dir: FileSystemDirectoryEntry | null = null;\n\n if ('webkitGetAsEntry' in entry) {\n dir = entry.webkitGetAsEntry() as FileSystemDirectoryEntry;\n } else if ('getAsEntry' in entry) {\n // non-WebKit browsers may rename webkitGetAsEntry to getAsEntry. MDN recommends looking for both.\n dir = (entry as any).getAsEntry();\n }\n\n return dir;\n }\n\n // Process entries from a directory reader\n private async _processEntries(\n entries: FileSystemEntry[],\n folders: UUIFileFolder[],\n files: File[],\n ): Promise<void> {\n for (const en of entries) {\n if (en.isFile) {\n const file = await this._getAsFile(en as FileSystemFileEntry);\n if (this._isAccepted(file)) {\n files.push(file);\n }\n } else if (en.isDirectory) {\n const directory = await this._mkdir(en as FileSystemDirectoryEntry);\n folders.push(directory);\n }\n }\n }\n\n // Read entries from a directory reader recursively\n private async _readAllEntries(\n reader: FileSystemDirectoryReader,\n folders: UUIFileFolder[],\n files: File[],\n ): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n reader.readEntries(async entries => {\n if (!entries.length) {\n resolve();\n return;\n }\n\n await this._processEntries(entries, folders, files);\n\n // readEntries only reads up to 100 entries at a time. It is on purpose we call readEntries recursively.\n await this._readAllEntries(reader, folders, files);\n\n resolve();\n }, reject);\n });\n }\n\n // Make directory structure\n private async _mkdir(\n entry: FileSystemDirectoryEntry,\n ): Promise<UUIFileFolder> {\n const reader = entry.createReader();\n const folders: UUIFileFolder[] = [];\n const files: File[] = [];\n\n await this._readAllEntries(reader, folders, files);\n\n const result: UUIFileFolder = { folderName: entry.name, folders, files };\n return result;\n }\n\n private _isAccepted(file: File) {\n if (\n this._acceptedFileExtensions.length === 0 &&\n this._acceptedMimeTypes.length === 0\n ) {\n return true;\n }\n\n const fileType = file.type.toLowerCase();\n const fileExtension = file.name.split('.').pop();\n\n if (\n fileExtension &&\n this._acceptedFileExtensions.includes(fileExtension.toLowerCase())\n ) {\n return true;\n }\n\n for (const mimeType of this._acceptedMimeTypes) {\n if (\n fileType === mimeType ||\n (mimeType.endsWith('/*') &&\n fileType.startsWith(mimeType.replace('*', '')))\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n private async _getAsFile(fileEntry: FileSystemFileEntry): Promise<File> {\n return new Promise((resolve, reject) => fileEntry.file(resolve, reject));\n }\n\n private async _onDrop(e: DragEvent) {\n e.preventDefault();\n this._dropzone.classList.remove('hover');\n\n const items = e.dataTransfer?.items;\n\n if (items) {\n const fileSystemResult = await this._getAllEntries(items);\n\n if (this.multiple === false && fileSystemResult.files.length) {\n fileSystemResult.files = [fileSystemResult.files[0]];\n fileSystemResult.folders = [];\n // When multiple is false and we have an accepted file, don't report rejections\n fileSystemResult.rejectedFiles = [];\n }\n\n if (fileSystemResult.rejectedFiles.length > 0) {\n this.dispatchEvent(\n new UUIFileDropzoneEvent(UUIFileDropzoneEvent.REJECT, {\n detail: { files: fileSystemResult.rejectedFiles, folders: [] },\n }),\n );\n }\n\n if (!fileSystemResult.files.length && !fileSystemResult.folders.length) {\n return;\n }\n\n this.dispatchEvent(\n new UUIFileDropzoneEvent(UUIFileDropzoneEvent.CHANGE, {\n detail: {\n files: fileSystemResult.files,\n folders: fileSystemResult.folders,\n },\n }),\n );\n }\n }\n\n private _onDragOver(e: DragEvent) {\n e.preventDefault();\n }\n\n private _onDragEnter(e: DragEvent) {\n // TODO: make visual indication of wether the file is acceptable or not. If not we need to make a more negative/disabled visual look.\n this._dropzone.classList.add('hover');\n e.preventDefault();\n }\n\n private _onDragLeave(e: DragEvent) {\n this._dropzone.classList.remove('hover');\n e.preventDefault();\n }\n\n private _onFileInputChange() {\n const files = this._input.files ? Array.from(this._input.files) : [];\n\n if (this.multiple === false && files.length > 1) {\n files.splice(1, files.length - 1);\n }\n\n const allowedFiles = files.filter(file => this._isAccepted(file));\n const rejectedFiles = files.filter(file => !this._isAccepted(file));\n\n // When multiple is false and we have an accepted file, don't report rejections\n const shouldReportRejections =\n rejectedFiles.length > 0 && (this.multiple || allowedFiles.length === 0);\n\n if (shouldReportRejections) {\n this.dispatchEvent(\n new UUIFileDropzoneEvent(UUIFileDropzoneEvent.REJECT, {\n detail: { files: rejectedFiles, folders: [] },\n }),\n );\n }\n\n if (!allowedFiles.length) {\n return;\n }\n\n this.dispatchEvent(\n new UUIFileDropzoneEvent(UUIFileDropzoneEvent.CHANGE, {\n detail: {\n files: allowedFiles,\n folders: [],\n },\n }),\n );\n }\n\n render() {\n return html`\n <div id=\"dropzone\">\n <uui-symbol-file-dropzone id=\"symbol\"></uui-symbol-file-dropzone>\n ${this.renderLabel()}\n <input\n @click=${(e: Event) => e.stopImmediatePropagation()}\n id=\"input\"\n type=\"file\"\n accept=${this.accept}\n ?multiple=${this.multiple}\n @change=${this._onFileInputChange}\n aria-label=\"${this.label}\" />\n <slot></slot>\n </div>\n `;\n }\n\n static override readonly styles = [\n css`\n #dropzone {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n position: relative;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n padding: var(--uui-size-4);\n border: 3px solid transparent;\n margin: -3px;\n backdrop-filter: blur(2px);\n }\n #dropzone.hover {\n border-color: var(--uui-color-default);\n }\n #dropzone.hover::before {\n content: '';\n position: absolute;\n inset: 0;\n opacity: 0.2;\n border-color: var(--uui-color-default);\n background-color: var(--uui-color-default);\n }\n #symbol {\n color: var(--uui-color-default);\n max-width: 100%;\n max-height: 100%;\n }\n #input {\n position: absolute;\n width: 0px;\n height: 0px;\n opacity: 0;\n display: none;\n }\n `,\n ];\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import { iconAdd } from "./svgs/iconAdd.js";
|
|
|
3
3
|
import { iconAlert } from "./svgs/iconAlert.js";
|
|
4
4
|
import { iconAttachment } from "./svgs/iconAttachment.js";
|
|
5
5
|
import { iconCalendar } from "./svgs/iconCalendar.js";
|
|
6
|
+
import { iconCheck } from "./svgs/iconCheck.js";
|
|
6
7
|
import { iconClipboard } from "./svgs/iconClipboard.js";
|
|
7
8
|
import { iconCode } from "./svgs/iconCode.js";
|
|
8
9
|
import { iconColorPicker } from "./svgs/iconColorPicker.js";
|
|
@@ -30,7 +31,6 @@ import { iconSync } from "./svgs/iconSync.js";
|
|
|
30
31
|
import { iconUnlock } from "./svgs/iconUnlock.js";
|
|
31
32
|
import { iconUnsee } from "./svgs/iconUnsee.js";
|
|
32
33
|
import { iconWand } from "./svgs/iconWand.js";
|
|
33
|
-
import { iconCheck } from "./svgs/iconCheck.js";
|
|
34
34
|
import { iconWrong } from "./svgs/iconWrong.js";
|
|
35
35
|
class UUIIconRegistryEssential extends UUIIconRegistry {
|
|
36
36
|
constructor() {
|
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
import { defineElement } from "../../internal/registration/index.js";
|
|
2
2
|
import { UUIIconRegistryEssentialElement } from "./icon-registry-essential.element.js";
|
|
3
3
|
import "../icon/UUIIconRequestEvent.js";
|
|
4
|
+
import "./svgs/iconAdd.js";
|
|
5
|
+
import "./svgs/iconAlert.js";
|
|
6
|
+
import "./svgs/iconAttachment.js";
|
|
7
|
+
import "./svgs/iconCalendar.js";
|
|
8
|
+
import "./svgs/iconCheck.js";
|
|
9
|
+
import "./svgs/iconClipboard.js";
|
|
10
|
+
import "./svgs/iconCode.js";
|
|
11
|
+
import "./svgs/iconColorPicker.js";
|
|
12
|
+
import "./svgs/iconCopy.js";
|
|
13
|
+
import "./svgs/iconDelete.js";
|
|
14
|
+
import "./svgs/iconDocument.js";
|
|
15
|
+
import "./svgs/iconDownload.js";
|
|
16
|
+
import "./svgs/iconDrag.js";
|
|
17
|
+
import "./svgs/iconEdit.js";
|
|
18
|
+
import "./svgs/iconFavorite.js";
|
|
19
|
+
import "./svgs/iconFolder.js";
|
|
20
|
+
import "./svgs/iconForbidden.js";
|
|
21
|
+
import "./svgs/iconInfo.js";
|
|
22
|
+
import "./svgs/iconLink.js";
|
|
23
|
+
import "./svgs/iconLock.js";
|
|
24
|
+
import "./svgs/iconPause.js";
|
|
25
|
+
import "./svgs/iconPicture.js";
|
|
26
|
+
import "./svgs/iconPlay.js";
|
|
27
|
+
import "./svgs/iconRemove.js";
|
|
28
|
+
import "./svgs/iconSearch.js";
|
|
29
|
+
import "./svgs/iconSee.js";
|
|
30
|
+
import "./svgs/iconSettings.js";
|
|
31
|
+
import "./svgs/iconSubtract.js";
|
|
32
|
+
import "./svgs/iconSync.js";
|
|
33
|
+
import "./svgs/iconUnlock.js";
|
|
34
|
+
import "./svgs/iconUnsee.js";
|
|
35
|
+
import "./svgs/iconWand.js";
|
|
36
|
+
import "./svgs/iconWrong.js";
|
|
4
37
|
defineElement("uui-icon-registry-essential", UUIIconRegistryEssentialElement);
|
|
5
38
|
export {
|
|
6
39
|
UUIIconRegistryEssentialElement,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon-registry-essential.js","sources":["../../../src/components/icon-registry-essential/icon-registry-essential.ts"],"sourcesContent":["import { defineElement } from '../../internal/registration/index.js';\nimport { UUIIconRegistryEssentialElement } from './icon-registry-essential.element.js';\n\ndefineElement('uui-icon-registry-essential', UUIIconRegistryEssentialElement);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'uui-icon-registry-essential': UUIIconRegistryEssentialElement;\n }\n}\n\nexport * from './icon-registry-essential.element.js';\nexport * from './UUIIconRegistryEssential.js';\nexport { UUIIconRegistryEssentialElement as default } from './icon-registry-essential.element.js';\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"icon-registry-essential.js","sources":["../../../src/components/icon-registry-essential/icon-registry-essential.ts"],"sourcesContent":["import { defineElement } from '../../internal/registration/index.js';\nimport { UUIIconRegistryEssentialElement } from './icon-registry-essential.element.js';\n\ndefineElement('uui-icon-registry-essential', UUIIconRegistryEssentialElement);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'uui-icon-registry-essential': UUIIconRegistryEssentialElement;\n }\n}\n\nexport * from './icon-registry-essential.element.js';\nexport * from './UUIIconRegistryEssential.js';\nexport { UUIIconRegistryEssentialElement as default } from './icon-registry-essential.element.js';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,cAAc,+BAA+B,+BAA+B;"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export * from './button/button.js';
|
|
2
|
+
export * from './badge/badge.js';
|
|
3
|
+
export * from './icon/icon.js';
|
|
4
|
+
export * from './icon-registry/icon-registry.js';
|
|
5
|
+
export * from './icon-registry-essential/icon-registry-essential.js';
|
|
6
|
+
export * from './input/input.js';
|
|
7
|
+
export * from './input-password/input-password.js';
|
|
8
|
+
export * from './dialog/dialog.js';
|
|
9
|
+
export * from './dialog-layout/dialog-layout.js';
|
|
10
|
+
export * from './table/table.js';
|
|
11
|
+
export * from './label/label.js';
|
|
12
|
+
export * from './action-bar/action-bar.js';
|
|
13
|
+
export * from './avatar/avatar.js';
|
|
14
|
+
export * from './boolean-input/boolean-input.js';
|
|
15
|
+
export * from './breadcrumbs/breadcrumbs.js';
|
|
16
|
+
export * from './checkbox/checkbox.js';
|
|
17
|
+
export * from './color-area/color-area.js';
|
|
18
|
+
export * from './color-slider/color-slider.js';
|
|
19
|
+
export * from './color-swatch/color-swatch.js';
|
|
20
|
+
export * from './form/form.js';
|
|
21
|
+
export * from './form-layout-item/form-layout-item.js';
|
|
22
|
+
export * from './form-validation-message/form-validation-message.js';
|
|
23
|
+
export * from './keyboard-shortcut/keyboard-shortcut.js';
|
|
24
|
+
export * from './loader/loader.js';
|
|
25
|
+
export * from './loader-bar/loader-bar.js';
|
|
26
|
+
export * from './loader-circle/loader-circle.js';
|
|
27
|
+
export * from './modal/modal.js';
|
|
28
|
+
export * from './popover-container/popover-container.js';
|
|
29
|
+
export * from './progress-bar/progress-bar.js';
|
|
30
|
+
export * from './radio/radio.js';
|
|
31
|
+
export * from './range-slider/range-slider.js';
|
|
32
|
+
export * from './responsive-container/responsive-container.js';
|
|
33
|
+
export * from './scroll-container/scroll-container.js';
|
|
34
|
+
export * from './select/select.js';
|
|
35
|
+
export * from './slider/slider.js';
|
|
36
|
+
export * from './symbol-drag-handle/symbol-drag-handle.js';
|
|
37
|
+
export * from './symbol-expand/symbol-expand.js';
|
|
38
|
+
export * from './symbol-file/symbol-file.js';
|
|
39
|
+
export * from './symbol-folder/symbol-folder.js';
|
|
40
|
+
export * from './symbol-lock/symbol-lock.js';
|
|
41
|
+
export * from './symbol-more/symbol-more.js';
|
|
42
|
+
export * from './symbol-sort/symbol-sort.js';
|
|
43
|
+
export * from './tag/tag.js';
|
|
44
|
+
export * from './textarea/textarea.js';
|
|
45
|
+
export * from './toggle/toggle.js';
|
|
46
|
+
export * from './visually-hidden/visually-hidden.js';
|
|
47
|
+
export * from './box/box.js';
|
|
48
|
+
export * from './card/card.js';
|
|
49
|
+
export * from './avatar-group/avatar-group.js';
|
|
50
|
+
export * from './button-group/button-group.js';
|
|
51
|
+
export * from './button-inline-create/button-inline-create.js';
|
|
52
|
+
export * from './button-copy-text/button-copy-text.js';
|
|
53
|
+
export * from './color-swatches/color-swatches.js';
|
|
54
|
+
export * from './combobox-list/combobox-list.js';
|
|
55
|
+
export * from './menu-item/menu-item.js';
|
|
56
|
+
export * from './ref/ref.js';
|
|
57
|
+
export * from './symbol-file-dropzone/symbol-file-dropzone.js';
|
|
58
|
+
export * from './tabs/tabs.js';
|
|
59
|
+
export * from './toast-notification/toast-notification.js';
|
|
60
|
+
export * from './card-block-type/card-block-type.js';
|
|
61
|
+
export * from './card-content-node/card-content-node.js';
|
|
62
|
+
export * from './card-media/card-media.js';
|
|
63
|
+
export * from './card-user/card-user.js';
|
|
64
|
+
export * from './ref-list/ref-list.js';
|
|
65
|
+
export * from './ref-node/ref-node.js';
|
|
66
|
+
export * from './symbol-file-thumbnail/symbol-file-thumbnail.js';
|
|
67
|
+
export * from './toast-notification-container/toast-notification-container.js';
|
|
68
|
+
export * from './toast-notification-layout/toast-notification-layout.js';
|
|
69
|
+
export * from './input-lock/input-lock.js';
|
|
70
|
+
export * from './pagination/pagination.js';
|
|
71
|
+
export * from './ref-node-data-type/ref-node-data-type.js';
|
|
72
|
+
export * from './ref-node-document-type/ref-node-document-type.js';
|
|
73
|
+
export * from './ref-node-form/ref-node-form.js';
|
|
74
|
+
export * from './ref-node-member/ref-node-member.js';
|
|
75
|
+
export * from './ref-node-package/ref-node-package.js';
|
|
76
|
+
export * from './ref-node-user/ref-node-user.js';
|
|
77
|
+
export * from './file-dropzone/file-dropzone.js';
|
|
78
|
+
export * from './file-preview/file-preview.js';
|
|
79
|
+
export * from './input-file/input-file.js';
|
|
80
|
+
export * from './combobox/combobox.js';
|
|
81
|
+
export * from './color-picker/color-picker.js';
|
|
@@ -115,7 +115,10 @@ const _UUIInputElement = class _UUIInputElement extends UUIFormControlWithBasics
|
|
|
115
115
|
render() {
|
|
116
116
|
return html`
|
|
117
117
|
${this.renderPrepend()}
|
|
118
|
-
|
|
118
|
+
<div id="inner">
|
|
119
|
+
<slot></slot>
|
|
120
|
+
${this.autoWidth ? this.renderInputWithAutoWidth() : this.renderInput()}
|
|
121
|
+
</div>
|
|
119
122
|
${this.renderAppend()}
|
|
120
123
|
`;
|
|
121
124
|
}
|
|
@@ -138,7 +141,12 @@ const _UUIInputElement = class _UUIInputElement extends UUIFormControlWithBasics
|
|
|
138
141
|
spellcheck=${this.spellcheck}
|
|
139
142
|
autocomplete=${ifDefined(this.autocomplete)}
|
|
140
143
|
placeholder=${ifDefined(this.placeholder)}
|
|
141
|
-
aria-label=${ifDefined(
|
|
144
|
+
aria-label=${ifDefined(
|
|
145
|
+
this.getAttribute("aria-label") || this.label || void 0
|
|
146
|
+
)}
|
|
147
|
+
aria-labelledby=${ifDefined(
|
|
148
|
+
this.getAttribute("aria-labelledby") || void 0
|
|
149
|
+
)}
|
|
142
150
|
inputmode=${ifDefined(this.inputMode)}
|
|
143
151
|
?disabled=${this.disabled}
|
|
144
152
|
?autofocus=${this.autofocus}
|
|
@@ -182,7 +190,8 @@ _UUIInputElement.styles = [
|
|
|
182
190
|
border-radius: var(--uui-input-border-radius, var(--uui-border-radius));
|
|
183
191
|
min-width: 0;
|
|
184
192
|
|
|
185
|
-
--uui-input-padding: 1px var(--uui-size-space-3)
|
|
193
|
+
--uui-input-padding: 1px var(--uui-size-space-3) 3px
|
|
194
|
+
var(--uui-size-space-3);
|
|
186
195
|
--uui-button-height: 100%;
|
|
187
196
|
--uui-button-border-radius: var(
|
|
188
197
|
--uui-input-border-radius,
|
|
@@ -284,6 +293,9 @@ _UUIInputElement.styles = [
|
|
|
284
293
|
text-align: inherit;
|
|
285
294
|
outline: none;
|
|
286
295
|
text-overflow: ellipsis;
|
|
296
|
+
line-height: 1;
|
|
297
|
+
flex: 1 1 auto;
|
|
298
|
+
min-width: 60px;
|
|
287
299
|
}
|
|
288
300
|
|
|
289
301
|
input[type='password']::-ms-reveal {
|
|
@@ -306,11 +318,29 @@ _UUIInputElement.styles = [
|
|
|
306
318
|
min-width: 0;
|
|
307
319
|
}
|
|
308
320
|
|
|
321
|
+
uui-input,
|
|
322
|
+
uui-input-lock,
|
|
309
323
|
::slotted(uui-input),
|
|
310
324
|
::slotted(uui-input-lock) {
|
|
311
325
|
height: 100%;
|
|
312
326
|
--uui-input-border-width: 0;
|
|
313
327
|
}
|
|
328
|
+
|
|
329
|
+
uui-button,
|
|
330
|
+
::slotted(uui-button) {
|
|
331
|
+
height: 100%;
|
|
332
|
+
--uui-button-border-width: 0;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
#inner {
|
|
336
|
+
display: flex;
|
|
337
|
+
flex-wrap: wrap;
|
|
338
|
+
align-items: center;
|
|
339
|
+
gap: 4px;
|
|
340
|
+
flex: 1 1 auto;
|
|
341
|
+
min-width: 0;
|
|
342
|
+
padding: 2px;
|
|
343
|
+
}
|
|
314
344
|
`
|
|
315
345
|
];
|
|
316
346
|
let UUIInputElement = _UUIInputElement;
|