@melodicdev/components 1.0.6 → 1.0.8
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/assets/melodic-components.js +121 -41
- package/assets/melodic-components.js.map +1 -1
- package/assets/melodic-components.min.js +1519 -1464
- package/lib/components/forms/select/select.component.d.ts +11 -3
- package/lib/components/forms/select/select.component.d.ts.map +1 -1
- package/lib/components/forms/select/select.component.js +61 -22
- package/lib/components/forms/select/select.styles.d.ts.map +1 -1
- package/lib/components/forms/select/select.styles.js +6 -12
- package/lib/components/forms/select/select.template.d.ts.map +1 -1
- package/lib/components/forms/select/select.template.js +2 -4
- package/lib/components/overlays/dialog/dialog.service.d.ts +1 -2
- package/lib/components/overlays/dialog/dialog.service.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -64,8 +64,10 @@ export declare class SelectComponent implements IElementRef, OnCreate, OnDestroy
|
|
|
64
64
|
/** Currently focused option index for keyboard navigation */
|
|
65
65
|
focusedIndex: number;
|
|
66
66
|
/** Bound event handlers for cleanup */
|
|
67
|
-
private readonly _handleDocumentClick;
|
|
68
67
|
private readonly _handleKeyDown;
|
|
68
|
+
private readonly _handlePopoverToggle;
|
|
69
|
+
private _handleScroll;
|
|
70
|
+
private _lastCloseTime;
|
|
69
71
|
private _syncingValues;
|
|
70
72
|
onCreate(): void;
|
|
71
73
|
onDestroy(): void;
|
|
@@ -93,8 +95,14 @@ export declare class SelectComponent implements IElementRef, OnCreate, OnDestroy
|
|
|
93
95
|
handleTagRemove: (event: Event, value: string) => void;
|
|
94
96
|
handleSearchInput: (event: Event) => void;
|
|
95
97
|
handleSearchClick: (event: Event) => void;
|
|
96
|
-
/** Handle
|
|
97
|
-
private
|
|
98
|
+
/** Handle popover toggle events (open/close via Popover API) */
|
|
99
|
+
private onPopoverToggle;
|
|
100
|
+
/** Position the dropdown relative to the trigger using fixed positioning */
|
|
101
|
+
private positionDropdown;
|
|
102
|
+
/** Close dropdown when any ancestor scrolls */
|
|
103
|
+
private addScrollListener;
|
|
104
|
+
private removeScrollListener;
|
|
105
|
+
private getDropdownEl;
|
|
98
106
|
/** Handle keyboard navigation */
|
|
99
107
|
private onKeyDown;
|
|
100
108
|
/** Move focus to next enabled option */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.component.d.ts","sourceRoot":"","sources":["../../../../src/components/forms/select/select.component.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"select.component.d.ts","sourceRoot":"","sources":["../../../../src/components/forms/select/select.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
import { MelodicComponent } from '@melodicdev/core';
|
|
8
|
+
import { computePosition, offset, flip, shift } from '../../../utils/positioning/index.js';
|
|
8
9
|
import { selectTemplate } from './select.template.js';
|
|
9
10
|
import { selectStyles } from './select.styles.js';
|
|
10
11
|
/**
|
|
@@ -70,8 +71,10 @@ let SelectComponent = class SelectComponent {
|
|
|
70
71
|
/** Currently focused option index for keyboard navigation */
|
|
71
72
|
this.focusedIndex = -1;
|
|
72
73
|
/** Bound event handlers for cleanup */
|
|
73
|
-
this._handleDocumentClick = this.onDocumentClick.bind(this);
|
|
74
74
|
this._handleKeyDown = this.onKeyDown.bind(this);
|
|
75
|
+
this._handlePopoverToggle = this.onPopoverToggle.bind(this);
|
|
76
|
+
this._handleScroll = null;
|
|
77
|
+
this._lastCloseTime = 0;
|
|
75
78
|
this._syncingValues = false;
|
|
76
79
|
/** Toggle dropdown open/close */
|
|
77
80
|
this.toggle = () => {
|
|
@@ -85,32 +88,22 @@ let SelectComponent = class SelectComponent {
|
|
|
85
88
|
}
|
|
86
89
|
if (this.isOpen) {
|
|
87
90
|
this.close();
|
|
88
|
-
return;
|
|
89
91
|
}
|
|
90
|
-
|
|
92
|
+
else if (Date.now() - this._lastCloseTime > 150) {
|
|
93
|
+
this.open();
|
|
94
|
+
}
|
|
91
95
|
};
|
|
92
96
|
/** Open the dropdown */
|
|
93
97
|
this.open = () => {
|
|
94
98
|
if (this.disabled || this.isOpen)
|
|
95
99
|
return;
|
|
96
|
-
this.
|
|
97
|
-
this.focusedIndex = this.getInitialFocusIndex();
|
|
98
|
-
this.elementRef.dispatchEvent(new CustomEvent('ml:open', {
|
|
99
|
-
bubbles: true,
|
|
100
|
-
composed: true
|
|
101
|
-
}));
|
|
100
|
+
this.getDropdownEl()?.showPopover();
|
|
102
101
|
};
|
|
103
102
|
/** Close the dropdown */
|
|
104
103
|
this.close = () => {
|
|
105
104
|
if (!this.isOpen)
|
|
106
105
|
return;
|
|
107
|
-
this.
|
|
108
|
-
this.focusedIndex = -1;
|
|
109
|
-
this.search = '';
|
|
110
|
-
this.elementRef.dispatchEvent(new CustomEvent('ml:close', {
|
|
111
|
-
bubbles: true,
|
|
112
|
-
composed: true
|
|
113
|
-
}));
|
|
106
|
+
this.getDropdownEl()?.hidePopover();
|
|
114
107
|
};
|
|
115
108
|
/** Select an option */
|
|
116
109
|
this.selectOption = (option) => {
|
|
@@ -162,12 +155,13 @@ let SelectComponent = class SelectComponent {
|
|
|
162
155
|
};
|
|
163
156
|
}
|
|
164
157
|
onCreate() {
|
|
165
|
-
document.addEventListener('click', this._handleDocumentClick);
|
|
166
158
|
this.elementRef.addEventListener('keydown', this._handleKeyDown);
|
|
159
|
+
this.getDropdownEl()?.addEventListener('toggle', this._handlePopoverToggle);
|
|
167
160
|
}
|
|
168
161
|
onDestroy() {
|
|
169
|
-
document.removeEventListener('click', this._handleDocumentClick);
|
|
170
162
|
this.elementRef.removeEventListener('keydown', this._handleKeyDown);
|
|
163
|
+
this.removeScrollListener();
|
|
164
|
+
this.getDropdownEl()?.removeEventListener('toggle', this._handlePopoverToggle);
|
|
171
165
|
}
|
|
172
166
|
onPropertyChange(name) {
|
|
173
167
|
if (this._syncingValues) {
|
|
@@ -259,13 +253,58 @@ let SelectComponent = class SelectComponent {
|
|
|
259
253
|
detail: { values: [...this.values], options: this.selectedOptions, option }
|
|
260
254
|
}));
|
|
261
255
|
}
|
|
262
|
-
/** Handle
|
|
263
|
-
|
|
264
|
-
const
|
|
265
|
-
if (
|
|
256
|
+
/** Handle popover toggle events (open/close via Popover API) */
|
|
257
|
+
onPopoverToggle(event) {
|
|
258
|
+
const toggleEvent = event;
|
|
259
|
+
if (toggleEvent.newState === 'open') {
|
|
260
|
+
this.isOpen = true;
|
|
261
|
+
this.focusedIndex = this.getInitialFocusIndex();
|
|
262
|
+
this.positionDropdown();
|
|
263
|
+
this.addScrollListener();
|
|
264
|
+
this.elementRef.dispatchEvent(new CustomEvent('ml:open', { bubbles: true, composed: true }));
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
this.isOpen = false;
|
|
268
|
+
this.focusedIndex = -1;
|
|
269
|
+
this.search = '';
|
|
270
|
+
this._lastCloseTime = Date.now();
|
|
271
|
+
this.removeScrollListener();
|
|
272
|
+
this.elementRef.dispatchEvent(new CustomEvent('ml:close', { bubbles: true, composed: true }));
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/** Position the dropdown relative to the trigger using fixed positioning */
|
|
276
|
+
positionDropdown() {
|
|
277
|
+
const triggerEl = this.elementRef.shadowRoot?.querySelector('.ml-select__trigger');
|
|
278
|
+
const dropdownEl = this.getDropdownEl();
|
|
279
|
+
if (!triggerEl || !dropdownEl)
|
|
280
|
+
return;
|
|
281
|
+
dropdownEl.style.width = `${triggerEl.offsetWidth}px`;
|
|
282
|
+
const { x, y } = computePosition(triggerEl, dropdownEl, {
|
|
283
|
+
placement: 'bottom-start',
|
|
284
|
+
middleware: [offset(4), flip(), shift({ padding: 8 })]
|
|
285
|
+
});
|
|
286
|
+
dropdownEl.style.left = `${x}px`;
|
|
287
|
+
dropdownEl.style.top = `${y}px`;
|
|
288
|
+
}
|
|
289
|
+
/** Close dropdown when any ancestor scrolls */
|
|
290
|
+
addScrollListener() {
|
|
291
|
+
this._handleScroll = (event) => {
|
|
292
|
+
const dropdownEl = this.getDropdownEl();
|
|
293
|
+
if (dropdownEl?.contains(event.target))
|
|
294
|
+
return;
|
|
266
295
|
this.close();
|
|
296
|
+
};
|
|
297
|
+
window.addEventListener('scroll', this._handleScroll, true);
|
|
298
|
+
}
|
|
299
|
+
removeScrollListener() {
|
|
300
|
+
if (this._handleScroll) {
|
|
301
|
+
window.removeEventListener('scroll', this._handleScroll, true);
|
|
302
|
+
this._handleScroll = null;
|
|
267
303
|
}
|
|
268
304
|
}
|
|
305
|
+
getDropdownEl() {
|
|
306
|
+
return this.elementRef.shadowRoot?.querySelector('.ml-select__dropdown');
|
|
307
|
+
}
|
|
269
308
|
/** Handle keyboard navigation */
|
|
270
309
|
onKeyDown(event) {
|
|
271
310
|
if (this.disabled)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/forms/select/select.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"select.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/forms/select/select.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,iDA0VxB,CAAC"}
|
|
@@ -25,10 +25,6 @@ export const selectStyles = () => css `
|
|
|
25
25
|
max-width: 100%;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
.ml-select--open .ml-select__control {
|
|
29
|
-
z-index: 100;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
28
|
.ml-select__label {
|
|
33
29
|
font-size: var(--ml-text-sm);
|
|
34
30
|
font-weight: var(--ml-font-medium);
|
|
@@ -216,12 +212,10 @@ export const selectStyles = () => css `
|
|
|
216
212
|
}
|
|
217
213
|
|
|
218
214
|
.ml-select__dropdown {
|
|
219
|
-
position:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
right: 0;
|
|
215
|
+
position: fixed;
|
|
216
|
+
inset: unset;
|
|
217
|
+
margin: 0;
|
|
223
218
|
z-index: 50;
|
|
224
|
-
margin-top: var(--ml-space-1);
|
|
225
219
|
background-color: var(--ml-color-surface);
|
|
226
220
|
border: var(--ml-border) solid var(--ml-color-border);
|
|
227
221
|
border-radius: var(--ml-radius);
|
|
@@ -229,13 +223,13 @@ export const selectStyles = () => css `
|
|
|
229
223
|
max-height: 280px;
|
|
230
224
|
overflow-y: auto;
|
|
231
225
|
padding: var(--ml-space-1-5);
|
|
232
|
-
display:
|
|
226
|
+
display: flex;
|
|
233
227
|
flex-direction: column;
|
|
234
228
|
gap: var(--ml-space-1);
|
|
235
229
|
}
|
|
236
230
|
|
|
237
|
-
.ml-select__dropdown
|
|
238
|
-
display:
|
|
231
|
+
.ml-select__dropdown:not(:popover-open) {
|
|
232
|
+
display: none;
|
|
239
233
|
}
|
|
240
234
|
|
|
241
235
|
.ml-select__empty {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.template.d.ts","sourceRoot":"","sources":["../../../../src/components/forms/select/select.template.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,wBAAgB,cAAc,CAAC,CAAC,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"select.template.d.ts","sourceRoot":"","sources":["../../../../src/components/forms/select/select.template.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,wBAAgB,cAAc,CAAC,CAAC,EAAE,eAAe,6CAkEhD"}
|
|
@@ -36,11 +36,9 @@ export function selectTemplate(c) {
|
|
|
36
36
|
</div>
|
|
37
37
|
|
|
38
38
|
<div
|
|
39
|
-
class
|
|
40
|
-
'ml-select__dropdown': true,
|
|
41
|
-
'ml-select__dropdown--open': c.isOpen
|
|
42
|
-
})}
|
|
39
|
+
class="ml-select__dropdown"
|
|
43
40
|
role="listbox"
|
|
41
|
+
popover="auto"
|
|
44
42
|
aria-multiselectable=${c.multiple || false}
|
|
45
43
|
>
|
|
46
44
|
${c.filteredOptions.length
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { UniqueID } from '../../../functions/new-id.function';
|
|
2
2
|
import { DialogRef } from './dialog-ref.class';
|
|
3
|
-
import type { DialogComponentLoader } from './dialog-loader.type';
|
|
4
3
|
import type { IDialogConfig } from './dialog-config.interface';
|
|
5
4
|
export declare class DialogService {
|
|
6
5
|
private readonly _dialogs;
|
|
7
6
|
addDialog(dialogID: UniqueID, dialogEl: HTMLDialogElement): DialogRef;
|
|
8
7
|
removeDialog(dialogID: UniqueID): void;
|
|
9
|
-
open<TResult = unknown, TData = unknown>(dialogComponent:
|
|
8
|
+
open<TResult = unknown, TData = unknown>(dialogComponent: new (...args: any[]) => any, config?: IDialogConfig<TData>): DialogRef<TResult, TData>;
|
|
10
9
|
open<TResult = unknown, TData = unknown>(dialogID: UniqueID): DialogRef<TResult, TData>;
|
|
11
10
|
close<T = unknown>(dialogID: UniqueID, result?: T): void;
|
|
12
11
|
private cleanUpDialog;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialog.service.d.ts","sourceRoot":"","sources":["../../../../src/components/overlays/dialog/dialog.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"dialog.service.d.ts","sourceRoot":"","sources":["../../../../src/components/overlays/dialog/dialog.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAI/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAW/D,qBACa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwC;IAEjE,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,SAAS;IAerE,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAItC,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO,EAAE,eAAe,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC;IAChJ,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC;IA2BvF,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI;IAOxD,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,aAAa;CAGrB"}
|