@operato/popup 9.0.0-beta.0 → 9.0.0-beta.10
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/CHANGELOG.md +37 -0
- package/dist/src/ox-floating-overlay.js +77 -32
- package/dist/src/ox-floating-overlay.js.map +1 -1
- package/dist/src/ox-popup-list.js +84 -65
- package/dist/src/ox-popup-list.js.map +1 -1
- package/dist/src/ox-popup-menu.d.ts +1 -1
- package/dist/src/ox-popup-menu.js +60 -63
- package/dist/src/ox-popup-menu.js.map +1 -1
- package/dist/src/ox-popup-menuitem.d.ts +1 -1
- package/dist/src/ox-popup-menuitem.js +49 -47
- package/dist/src/ox-popup-menuitem.js.map +1 -1
- package/dist/src/ox-popup.js +47 -50
- package/dist/src/ox-popup.js.map +1 -1
- package/dist/src/ox-prompt.js +99 -69
- package/dist/src/ox-prompt.js.map +1 -1
- package/dist/stories/open-popup.stories.js +2 -2
- package/dist/stories/open-popup.stories.js.map +1 -1
- package/dist/stories/ox-popup-list-sortable.stories.js +1 -1
- package/dist/stories/ox-popup-list-sortable.stories.js.map +1 -1
- package/dist/stories/ox-popup-list.stories.js +1 -1
- package/dist/stories/ox-popup-list.stories.js.map +1 -1
- package/dist/stories/ox-popup-menu.stories.js +1 -1
- package/dist/stories/ox-popup-menu.stories.js.map +1 -1
- package/dist/stories/ox-popup.stories.js +2 -2
- package/dist/stories/ox-popup.stories.js.map +1 -1
- package/dist/stories/ox-prompt-icon.stories.js +2 -2
- package/dist/stories/ox-prompt-icon.stories.js.map +1 -1
- package/dist/stories/ox-prompt-normal.stories.js +2 -2
- package/dist/stories/ox-prompt-normal.stories.js.map +1 -1
- package/dist/stories/ox-prompt.stories.js +2 -2
- package/dist/stories/ox-prompt.stories.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
@@ -3,6 +3,43 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
5
5
|
|
6
|
+
## [9.0.0-beta.10](https://github.com/hatiolab/operato/compare/v9.0.0-beta.9...v9.0.0-beta.10) (2025-01-25)
|
7
|
+
|
8
|
+
|
9
|
+
### :bug: Bug Fix
|
10
|
+
|
11
|
+
* i18next@24.2.1 ([1c5920c](https://github.com/hatiolab/operato/commit/1c5920c6f77d28f07051a0a49997b9fb1dbf08bf))
|
12
|
+
* tweak tsconfig.json ([3c424b1](https://github.com/hatiolab/operato/commit/3c424b18d046f95d5619076d113d49a4b4dc9bbb))
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
## [9.0.0-beta.6](https://github.com/hatiolab/operato/compare/v9.0.0-beta.5...v9.0.0-beta.6) (2025-01-20)
|
17
|
+
|
18
|
+
|
19
|
+
### :bug: Bug Fix
|
20
|
+
|
21
|
+
* esm module ([9642b97](https://github.com/hatiolab/operato/commit/9642b97650623d9ce71f6db0fd1995a2379205b5))
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
## [9.0.0-beta.5](https://github.com/hatiolab/operato/compare/v9.0.0-beta.4...v9.0.0-beta.5) (2025-01-20)
|
26
|
+
|
27
|
+
|
28
|
+
### :bug: Bug Fix
|
29
|
+
|
30
|
+
* esm module ([1319b00](https://github.com/hatiolab/operato/commit/1319b00d6955a514f63b3469fb514a28f84168a2))
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
## [9.0.0-beta.4](https://github.com/hatiolab/operato/compare/v9.0.0-beta.3...v9.0.0-beta.4) (2025-01-20)
|
35
|
+
|
36
|
+
|
37
|
+
### :bug: Bug Fix
|
38
|
+
|
39
|
+
* esm module ([0402232](https://github.com/hatiolab/operato/commit/04022327fa47eac64eaf3c56eeec55b9ace13e0e))
|
40
|
+
|
41
|
+
|
42
|
+
|
6
43
|
## [9.0.0-beta.0](https://github.com/hatiolab/operato/compare/v8.0.0-beta.11...v9.0.0-beta.0) (2025-01-13)
|
7
44
|
|
8
45
|
**Note:** Version bump only for package @operato/popup
|
@@ -31,37 +31,7 @@ function getPoint(e) {
|
|
31
31
|
* They are often used for modal dialogs, pop-ups, and similar UI elements.
|
32
32
|
*/
|
33
33
|
let OxFloatingOverlay = class OxFloatingOverlay extends LitElement {
|
34
|
-
|
35
|
-
super(...arguments);
|
36
|
-
/**
|
37
|
-
* A boolean property that determines whether a backdrop should be displayed behind the overlay.
|
38
|
-
* Backdrop provides a semi-transparent background that covers the entire screen when the overlay is open.
|
39
|
-
*/
|
40
|
-
this.backdrop = false;
|
41
|
-
/**
|
42
|
-
* A string property that sets the title of the overlay.
|
43
|
-
* The title is typically displayed in the header of the overlay.
|
44
|
-
*/
|
45
|
-
this.title = '';
|
46
|
-
/**
|
47
|
-
* A boolean property that determines whether the overlay can be closed by the user.
|
48
|
-
* If set to true, a close button will be displayed in the header.
|
49
|
-
*/
|
50
|
-
this.closable = false;
|
51
|
-
/**
|
52
|
-
* A boolean property that determines whether the overlay is considered historical.
|
53
|
-
* Historical overlays may have specific behavior or interactions, such as navigating back in history.
|
54
|
-
*/
|
55
|
-
this.historical = false;
|
56
|
-
/**
|
57
|
-
* A boolean property that determines whether the overlay can be moved by dragging.
|
58
|
-
* If set to true, the overlay can be repositioned by dragging its header.
|
59
|
-
*/
|
60
|
-
this.movable = false;
|
61
|
-
this.dragEndHandler = this.onDragEnd.bind(this);
|
62
|
-
this.dragMoveHandler = this.onDragMove.bind(this);
|
63
|
-
}
|
64
|
-
static { this.styles = [
|
34
|
+
static styles = [
|
65
35
|
ScrollbarStyles,
|
66
36
|
css `
|
67
37
|
/* for layout style */
|
@@ -309,7 +279,82 @@ let OxFloatingOverlay = class OxFloatingOverlay extends LitElement {
|
|
309
279
|
}
|
310
280
|
}
|
311
281
|
`
|
312
|
-
];
|
282
|
+
];
|
283
|
+
/**
|
284
|
+
* A boolean property that determines whether a backdrop should be displayed behind the overlay.
|
285
|
+
* Backdrop provides a semi-transparent background that covers the entire screen when the overlay is open.
|
286
|
+
*/
|
287
|
+
backdrop = false;
|
288
|
+
/**
|
289
|
+
* A string property that specifies the direction in which the overlay should appear.
|
290
|
+
* Possible values are: 'up', 'down', 'left', or 'right'.
|
291
|
+
*/
|
292
|
+
direction;
|
293
|
+
/**
|
294
|
+
* A string property that reflects the hovering state of the overlay.
|
295
|
+
* Possible values are: 'center', 'edge', or 'next'.
|
296
|
+
*/
|
297
|
+
hovering;
|
298
|
+
/**
|
299
|
+
* A string property that specifies the size of the overlay.
|
300
|
+
* Possible values are: 'small', 'medium', or 'large'.
|
301
|
+
*/
|
302
|
+
size;
|
303
|
+
/**
|
304
|
+
* A string property that represents the name of the overlay.
|
305
|
+
* This can be used for identification or other purposes.
|
306
|
+
*/
|
307
|
+
name;
|
308
|
+
/**
|
309
|
+
* A string property that sets the title of the overlay.
|
310
|
+
* The title is typically displayed in the header of the overlay.
|
311
|
+
*/
|
312
|
+
title = '';
|
313
|
+
/**
|
314
|
+
* A boolean property that determines whether the overlay can be closed by the user.
|
315
|
+
* If set to true, a close button will be displayed in the header.
|
316
|
+
*/
|
317
|
+
closable = false;
|
318
|
+
/**
|
319
|
+
* An object property that can hold custom properties for the template of the overlay.
|
320
|
+
* These properties can be used to customize the template's behavior.
|
321
|
+
*/
|
322
|
+
templateProperties;
|
323
|
+
/**
|
324
|
+
* An object property that can hold information related to help or assistance for the overlay.
|
325
|
+
* This information may be used to provide additional guidance to users.
|
326
|
+
*/
|
327
|
+
help;
|
328
|
+
/**
|
329
|
+
* A boolean property that determines whether the overlay is considered historical.
|
330
|
+
* Historical overlays may have specific behavior or interactions, such as navigating back in history.
|
331
|
+
*/
|
332
|
+
historical = false;
|
333
|
+
/**
|
334
|
+
* A boolean property that determines whether the overlay can be moved by dragging.
|
335
|
+
* If set to true, the overlay can be repositioned by dragging its header.
|
336
|
+
*/
|
337
|
+
movable = false;
|
338
|
+
/**
|
339
|
+
* An object property that can hold information related to a search feature within the overlay.
|
340
|
+
* It can include properties like 'value', 'handler', and 'placeholder'.
|
341
|
+
*/
|
342
|
+
search;
|
343
|
+
/**
|
344
|
+
* An object property that can hold information related to a filter feature within the overlay.
|
345
|
+
* It can include a 'handler' function for filtering content.
|
346
|
+
*/
|
347
|
+
filter;
|
348
|
+
/**
|
349
|
+
* A numeric property that specifies the z-index of the overlay.
|
350
|
+
* The z-index determines the stacking order of the overlay in relation to other elements on the page.
|
351
|
+
*/
|
352
|
+
zIndex;
|
353
|
+
dragStart;
|
354
|
+
dragEndHandler = this.onDragEnd.bind(this);
|
355
|
+
dragMoveHandler = this.onDragMove.bind(this);
|
356
|
+
overlayed;
|
357
|
+
content;
|
313
358
|
render() {
|
314
359
|
const direction = this.hovering == 'center' ? undefined : this.direction;
|
315
360
|
const { value = '', handler: searchHandler, placeholder = '', autofocus = true } = this.search || {};
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ox-floating-overlay.js","sourceRoot":"","sources":["../../src/ox-floating-overlay.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,yBAAyB;AACzB,6CAA6C;AAE7C,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEjD,SAAS,QAAQ,CAAC,CAAQ;IACxB,IAAK,CAAgB,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QAClC,OAAO;YACL,CAAC,EAAG,CAAgB,CAAC,OAAO;YAC5B,CAAC,EAAG,CAAgB,CAAC,OAAO;SAC7B,CAAA;IACH,CAAC;SAAM,IAAK,CAAgB,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC;QAClD,MAAM,KAAK,GAAI,CAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAC1C,OAAO;YACL,CAAC,EAAE,KAAK,CAAC,OAAO;YAChB,CAAC,EAAE,KAAK,CAAC,OAAO;SACjB,CAAA;IACH,CAAC;SAAM,CAAC;QACN,OAAM;IACR,CAAC;AACH,CAAC;AAED;;;;GAIG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,UAAU;IAA1C;;QA2PL;;;WAGG;QAC0B,aAAQ,GAAa,KAAK,CAAA;QA0BvD;;;WAGG;QACyB,UAAK,GAAW,EAAE,CAAA;QAE9C;;;WAGG;QAC0B,aAAQ,GAAa,KAAK,CAAA;QAcvD;;;WAGG;QAC0B,eAAU,GAAa,KAAK,CAAA;QAEzD;;;WAGG;QAC0B,YAAO,GAAa,KAAK,CAAA;QAyB9C,mBAAc,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAkB,CAAA;QAC3D,oBAAe,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAkB,CAAA;IAkPvE,CAAC;aAtkBQ,WAAM,GAAG;QACd,eAAe;QACf,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoJF;QACD,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgGF;KACF,AAxPY,CAwPZ;IAiGD,MAAM;QACJ,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAA;QAExE,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,GAAG,EAAE,EAAE,SAAS,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,IAAK,EAAU,CAAA;QAC7G,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,MAAM,IAAK,EAAU,CAAA;QAE7D,MAAM,UAAU,GAAG,OAAO,aAAa,IAAI,UAAU,CAAA;QACrD,MAAM,UAAU,GAAG,OAAO,aAAa,IAAI,UAAU,CAAA;QAErD,OAAO,IAAI,CAAA;QACP,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;YACtB,CAAC,CAAC,IAAI,CAAA;;;wBAGU,CAAC,IAAI,CAAC,QAAQ;uBACf,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC;;WAE5D;YACH,CAAC,CAAC,IAAI,CAAA,EAAE;;;;mBAIG,IAAI,CAAC,QAAQ,IAAI,QAAQ;oBACxB,SAAS,CAAC,SAAS,CAAC;eACzB,IAAI,CAAC,IAAI,IAAI,QAAQ;yBACX,CAAC,CAAQ,EAAE,EAAE;YAC5B,CAAC,CAAC,eAAe,EAAE,CAAA;YACnB,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;2BACkB,CAAC,CAAQ,EAAE,EAAE;YAC9B,yCAAyC;YACzC,CAAC;YAAC,CAAC,CAAC,MAAsB,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;QACvD,CAAC;yBACgB,CAAC,CAAQ,EAAE,EAAE;YAC5B,CAAC;YAAC,CAAC,CAAC,MAAsB,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;QACxD,CAAC;iBACQ,CAAC,CAAa,EAAE,EAAE;YACzB,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC/C,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;YACpC,CAAC;QACH,CAAC;;;;uBAIc,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;wBAC1B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;;;4BAGvB,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,QAAQ;YACxE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA,mCAAmC,CAAC,CAAC,CAAC,IAAI,CAAA,EAAE;;cAE7D,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ;YAC3B,CAAC,CAAC,IAAI,CAAA;;sBAEE,IAAI,CAAC,KAAK,IAAI,EAAE,SAAS,IAAI,CAAC,IAAI;gBAClC,CAAC,CAAC,IAAI,CAAA,wBAAwB,IAAI,CAAC,IAAI,kBAAkB;gBACzD,CAAC,CAAC,IAAI,CAAA,EAAE;;iBAEb;YACH,CAAC,CAAC,IAAI,CAAA,EAAE;cACR,UAAU,IAAI,UAAU;YACxB,CAAC,CAAC,IAAI,CAAA;;sBAEE,UAAU;gBACV,CAAC,CAAC,IAAI,CAAA;yCACa,WAAW;mCACjB,KAAK,IAAI,EAAE;uCACP,SAAS;oCACZ,CAAC,CAAQ,EAAE,EAAE;oBACrB,aAAa,CAAC,IAAI,CAAC,iBAAiB,EAAG,CAAC,CAAC,MAAc,CAAC,KAAK,CAAC,CAAA;gBAChE,CAAC;4CACiB;gBACtB,CAAC,CAAC,IAAI,CAAA,EAAE;sBACR,IAAI,CAAC,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAA,wBAAwB,IAAI,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAA,EAAE;sBAC1F,UAAU;gBACV,CAAC,CAAC,IAAI,CAAA,mBAAmB,CAAC,CAAa,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,iBAAiB,CAAC,iBAAiB;gBAClG,CAAC,CAAC,IAAI,CAAA,EAAE;;iBAEb;YACH,CAAC,CAAC,IAAI,CAAA,EAAE;cACR,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe;YACvD,CAAC,CAAC,IAAI,CAAA,wBAAwB,IAAI,CAAC,IAAI,kBAAkB;YACzD,CAAC,CAAC,IAAI,CAAA,EAAE;;4BAEM,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,QAAQ;;;;;;;KAO/E,CAAA;IACH,CAAC;IAED,OAAO,CAAC,OAA6B;QACnC,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACjE,IAAI,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAA;YACrC,IAAI,QAAQ,EAAE,CAAC;gBACb,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBACzC,YAAY;oBACZ,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAA;gBAChD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;QAC1D,CAAC;QAED,qBAAqB,CAAC,GAAG,EAAE;YACzB,sDAAsD;YACtD,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QAChD,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,iBAAiB;QACf,KAAK,CAAC,iBAAiB,EAAE,CAAA;QAEzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAA;QAElD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;YACzD,QAAQ,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;YAC1D,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;YAC7D,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;YAC5D,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;QAC9D,CAAC;IACH,CAAC;IAED,oBAAoB;QAClB,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAAC,gBAAgB,EAAE;YAChC,MAAM,EAAE,IAAI,CAAC,IAAI;SAClB,CAAC,CACH,CAAA;QAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAe,CAAC,CAAA;YAC7D,QAAQ,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,cAAe,CAAC,CAAA;YAC9D,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,cAAe,CAAC,CAAA;YACjE,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAgB,CAAC,CAAA;YAChE,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,eAAgB,CAAC,CAAA;QAClE,CAAC;QAED,KAAK,CAAC,oBAAoB,EAAE,CAAA;IAC9B,CAAC;IAED,WAAW,CAAC,CAAQ;QAClB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAM;QACR,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;QAEzB,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;YACtB,CAAC,CAAC,eAAe,EAAE,CAAA;YACnB,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,UAAU,CAAC,CAAQ;QACjB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACrC,OAAO,KAAK,CAAA;QACd,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;QAEzB,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,KAAK,CAAA;QACd,CAAC;QAED,CAAC,CAAC,eAAe,EAAE,CAAA;QACnB,CAAC,CAAC,cAAc,EAAE,CAAA;QAElB,MAAM,SAAS,GAAG,KAAK,CAAA;QACvB,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,KAAK,CAAA;QAEpB,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;QACrB,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;QAErB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAE1B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;QAEhC,IAAI,YAAY,GAAG,SAAS,CAAC,qBAAqB,EAAE,CAAA;QAEpD,SAAS,CAAC,KAAK,CAAC,IAAI;YAClB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,CAAC,WAAW,EAAE,YAAY,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;QAC9G,SAAS,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;QAEzG,SAAS,CAAC,KAAK,CAAC,SAAS,GAAG,SAAS,CAAA;QAErC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,SAAS,CAAC,CAAQ;QAChB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnC,CAAC,CAAC,eAAe,EAAE,CAAA;YACnB,CAAC,CAAC,cAAc,EAAE,CAAA;YAElB,OAAO,IAAI,CAAC,SAAS,CAAA;QACvB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,CAAA;IACpC,CAAC;IAED,OAAO,CAAC,CAAQ,EAAE,MAAgB;QAChC,CAAC,CAAC,eAAe,EAAE,CAAA;QACnB,qEAAqE;QAErE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;YACzB,IAAI,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAA;YAEnC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC3C,OAAM;YACR,CAAC;YAED,mFAAmF;YACnF,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;gBACjC,OAAO,IAAI,CAAA;YACb,CAAC;YAED,OAAO,CAAC,IAAI,EAAE,CAAA;QAChB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,EAAE,CAAA;QACd,CAAC;IACH,CAAC;;AAvU4B;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;mDAA2B;AAM3B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oDAA6C;AAM7B;IAA1C,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;mDAAsC;AAMpD;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CAAoC;AAMnC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CAAc;AAMb;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gDAAmB;AAMjB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;mDAA2B;AAM3B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6DAAwB;AAMvB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CAAU;AAMR;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;qDAA6B;AAM5B;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;kDAA0B;AAM1B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iDAI1B;AAM2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iDAA+C;AAMxB;IAAjD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;iDAAgB;AAM3C;IAArB,KAAK,CAAC,aAAa,CAAC;oDAA2B;AAC5B;IAAnB,KAAK,CAAC,WAAW,CAAC;kDAAyB;AAxVjC,iBAAiB;IAD7B,aAAa,CAAC,qBAAqB,CAAC;GACxB,iBAAiB,CAukB7B","sourcesContent":["import '@material/web/icon/icon.js'\n// 순환 참조가 되어서 일단 코멘트 처리함.\n// import '@operato/input/ox-input-search.js'\n\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\nimport { ScrollbarStyles } from '@operato/styles'\nimport { isHandheldDevice } from '@operato/utils'\n\nfunction getPoint(e: Event): { x: number; y: number } | undefined {\n if ((e as MouseEvent).button == 0) {\n return {\n x: (e as MouseEvent).clientX,\n y: (e as MouseEvent).clientY\n }\n } else if ((e as TouchEvent).touches?.length == 1) {\n const touch = (e as TouchEvent).touches[0]\n return {\n x: touch.clientX,\n y: touch.clientY\n }\n } else {\n return\n }\n}\n\n/**\n * Custom element for creating floating overlays.\n * These overlays can have various properties like direction, size, title, and more.\n * They are often used for modal dialogs, pop-ups, and similar UI elements.\n */\n@customElement('ox-floating-overlay')\nexport class OxFloatingOverlay extends LitElement {\n static styles = [\n ScrollbarStyles,\n css`\n /* for layout style */\n :host {\n position: relative;\n z-index: var(--z-index, 10);\n box-shadow: 2px 3px 10px 5px rgba(0, 0, 0, 0.15);\n }\n\n :host([hovering='edge']) {\n /* edge hovering 인 경우에는 상위 relative position 크기와 위치를 반영한다. */\n position: initial;\n }\n\n #backdrop {\n position: fixed;\n left: 0;\n top: 0;\n\n width: 100vw;\n height: 100vh;\n height: 100dvh;\n\n background-color: var(--md-sys-color-shadow, #000);\n opacity: 0.4;\n }\n\n [overlayed] {\n position: absolute;\n\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n [overlayed][hovering='center'] {\n position: fixed;\n\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n\n opacity: 0;\n border: 2px solid var(--md-sys-color-primary);\n }\n\n [overlayed][hovering='center'][opened] {\n opacity: 1;\n transition: opacity 0.3s ease-in;\n background-color: var(--md-sys-color-surface-container-lowest);\n }\n\n [hovering='center'] {\n width: var(--overlay-center-normal-width, 60%);\n height: var(--overlay-center-normal-height, 60%);\n }\n\n [hovering='center'][size='small'] {\n width: var(--overlay-center-small-width, 40%);\n height: var(--overlay-center-small-height, 40%);\n }\n\n [hovering='center'][size='large'] {\n width: var(--overlay-center-large-width, 100%);\n height: var(--overlay-center-large-height, 100%);\n }\n\n [header] {\n --help-icon-color: var(--md-sys-color-on-primary-container);\n --help-icon-hover-color: var(--md-sys-color-on-primary-container);\n\n pointer-events: initial;\n }\n\n [content] {\n flex: 1;\n overflow: hidden;\n }\n\n ::slotted(*) {\n box-sizing: border-box;\n pointer-events: initial;\n }\n\n [hovering='center'] [content] ::slotted(*) {\n width: 100%;\n height: 100%;\n }\n [direction='up'],\n [direction='down'] {\n width: 100%;\n\n max-height: 0;\n transition: max-height 0.7s ease-in;\n }\n [direction='up'] {\n bottom: 0;\n }\n [direction='down'] {\n top: 0;\n }\n\n [direction='up'][opened],\n [direction='down'][opened] {\n max-height: 100vh;\n max-height: 100dvh;\n }\n\n [settled][direction='down'] [content],\n [settled][direction='up'] [content] {\n overflow-y: auto;\n }\n\n [direction='left'],\n [direction='right'] {\n height: 100%;\n\n max-width: 0;\n transition: max-width 0.5s ease-in;\n }\n [direction='left'] {\n right: 0;\n }\n [direction='right'] {\n left: 0;\n }\n\n [direction='left'][opened],\n [direction='right'][opened] {\n max-width: 100vw;\n }\n\n [settled][direction='left'] [content],\n [settled][direction='right'] [content] {\n overflow-x: auto;\n }\n\n @media screen and (max-width: 460px) {\n [direction='up'],\n [direction='down'] {\n max-height: 100vh;\n max-height: 100dvh;\n }\n\n [direction='left'],\n [direction='right'] {\n max-width: 100vw;\n }\n }\n `,\n css`\n /* for header style */\n [header] {\n display: flex;\n flex-direction: row;\n align-items: center;\n background-color: var(--md-sys-color-primary);\n font-weight: var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500));\n color: var(--md-sys-color-on-primary);\n }\n\n slot[name='header'] {\n flex: 1;\n\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n text-transform: capitalize;\n }\n\n [name='header']::slotted(*) {\n margin: 0 auto;\n }\n\n [name='header'] > h1 {\n font-size: var(--md-sys-typescale-title-medium-size, 1rem);\n margin-block: 0.4rem;\n }\n\n [historyback] {\n margin-left: var(--spacing-medium);\n margin-right: auto;\n }\n\n [close] {\n margin-left: auto;\n margin-right: var(--spacing-medium);\n }\n\n [historyback],\n [close] {\n display: none;\n }\n\n [closable][close] {\n display: block;\n cursor: pointer;\n }\n\n [search] ox-help-icon {\n color: var(--md-sys-color-on-secondary-container);\n }\n\n [search] {\n --help-icon-color: var(--md-sys-color-primary);\n --help-icon-hover-color: var(--md-sys-color-primary);\n --help-icon-opacity: 0.2;\n --help-icon-size: 20px;\n\n --md-icon-size: 20px;\n\n --input-search-padding: var(--spacing-medium);\n --input-search-focus-border-bottom: none;\n --input-search-font: normal 16px var(--theme-font);\n\n display: flex;\n justify-content: space-between;\n align-items: center;\n\n align-self: center;\n color: var(--md-sys-color-primary);\n background-color: var(--md-sys-color-on-primary);\n border-radius: 999em;\n padding: 0 var(--spacing-medium);\n }\n\n [search] > * {\n align-self: center;\n }\n\n ox-input-search {\n color: var(--md-sys-color-primary);\n background-color: var(--md-sys-color-on-primary);\n border-radius: var(--md-sys-shape-corner-full);\n }\n\n @media screen and (max-width: 460px) {\n [closable][historyback] {\n display: block;\n }\n\n [closable][close] {\n display: none;\n }\n }\n `\n ]\n\n /**\n * A boolean property that determines whether a backdrop should be displayed behind the overlay.\n * Backdrop provides a semi-transparent background that covers the entire screen when the overlay is open.\n */\n @property({ type: Boolean }) backdrop?: boolean = false\n\n /**\n * A string property that specifies the direction in which the overlay should appear.\n * Possible values are: 'up', 'down', 'left', or 'right'.\n */\n @property({ type: String }) direction?: 'up' | 'down' | 'left' | 'right'\n\n /**\n * A string property that reflects the hovering state of the overlay.\n * Possible values are: 'center', 'edge', or 'next'.\n */\n @property({ type: String, reflect: true }) hovering?: 'center' | 'edge' | 'next'\n\n /**\n * A string property that specifies the size of the overlay.\n * Possible values are: 'small', 'medium', or 'large'.\n */\n @property({ type: String }) size?: 'small' | 'medium' | 'large'\n\n /**\n * A string property that represents the name of the overlay.\n * This can be used for identification or other purposes.\n */\n @property({ type: String }) name?: string\n\n /**\n * A string property that sets the title of the overlay.\n * The title is typically displayed in the header of the overlay.\n */\n @property({ type: String }) title: string = ''\n\n /**\n * A boolean property that determines whether the overlay can be closed by the user.\n * If set to true, a close button will be displayed in the header.\n */\n @property({ type: Boolean }) closable?: boolean = false\n\n /**\n * An object property that can hold custom properties for the template of the overlay.\n * These properties can be used to customize the template's behavior.\n */\n @property({ type: Object }) templateProperties: any\n\n /**\n * An object property that can hold information related to help or assistance for the overlay.\n * This information may be used to provide additional guidance to users.\n */\n @property({ type: Object }) help: any\n\n /**\n * A boolean property that determines whether the overlay is considered historical.\n * Historical overlays may have specific behavior or interactions, such as navigating back in history.\n */\n @property({ type: Boolean }) historical?: boolean = false\n\n /**\n * A boolean property that determines whether the overlay can be moved by dragging.\n * If set to true, the overlay can be repositioned by dragging its header.\n */\n @property({ type: Boolean }) movable?: boolean = false\n\n /**\n * An object property that can hold information related to a search feature within the overlay.\n * It can include properties like 'value', 'handler', and 'placeholder'.\n */\n @property({ type: Object }) search?: {\n value?: string\n handler?: (instance: any, value: string) => void\n placeholder?: string\n }\n\n /**\n * An object property that can hold information related to a filter feature within the overlay.\n * It can include a 'handler' function for filtering content.\n */\n @property({ type: Object }) filter?: { handler?: (instance: any) => void }\n\n /**\n * A numeric property that specifies the z-index of the overlay.\n * The z-index determines the stacking order of the overlay in relation to other elements on the page.\n */\n @property({ type: Number, attribute: 'z-index' }) zIndex?: number\n\n private dragStart?: { x: number; y: number }\n private dragEndHandler = this.onDragEnd.bind(this) as EventListener\n private dragMoveHandler = this.onDragMove.bind(this) as EventListener\n\n @query('[overlayed]') overlayed!: HTMLDivElement\n @query('[content]') content!: HTMLDivElement\n\n render() {\n const direction = this.hovering == 'center' ? undefined : this.direction\n\n const { value = '', handler: searchHandler, placeholder = '', autofocus = true } = this.search || ({} as any)\n const { handler: filterHandler } = this.filter || ({} as any)\n\n const searchable = typeof searchHandler == 'function'\n const filterable = typeof filterHandler == 'function'\n\n return html`\n ${Boolean(this.backdrop)\n ? html`\n <div\n id=\"backdrop\"\n ?hidden=${!this.backdrop}\n @click=${(e: Event) => this.onClose(e, true /* escape */)}\n ></div>\n `\n : html``}\n\n <div\n overlayed\n hovering=${this.hovering || 'center'}\n direction=${ifDefined(direction)}\n size=${this.size || 'medium'}\n @close-overlay=${(e: Event) => {\n e.stopPropagation()\n this.onClose(e)\n }}\n @transitionstart=${(e: Event) => {\n /* to hide scrollbar during transition */\n ;(e.target as HTMLElement).removeAttribute('settled')\n }}\n @transitionend=${(e: Event) => {\n ;(e.target as HTMLElement).setAttribute('settled', '')\n }}\n @click=${(e: MouseEvent) => {\n if (this.backdrop && e.target === this.content) {\n this.onClose(e, true /* escape */)\n }\n }}\n >\n <div\n header\n @mousedown=${this.onDragStart.bind(this)}\n @touchstart=${this.onDragStart.bind(this)}\n draggable=\"false\"\n >\n <md-icon @click=${(e: Event) => this.onClose(e)} ?closable=${this.closable} historyback>arrow_back</md-icon>\n ${this.movable ? html`<md-icon>drag_indicator</md-icon>` : html``}\n <slot name=\"header\">\n ${this.title || this.closable\n ? html`\n <h1>\n ${this.title || ''} ${this.help\n ? html`<ox-help-icon .topic=${this.help}></ox-help-icon>`\n : html``}\n </h1>\n `\n : html``}\n ${searchable || filterable\n ? html`\n <div search>\n ${searchable\n ? html` <ox-input-search\n .placeholder=${placeholder}\n .value=${value || ''}\n ?autofocus=${autofocus}\n @change=${(e: Event) => {\n searchHandler(this.firstElementChild, (e.target as any).value)\n }}\n ></ox-input-search>`\n : html``}\n ${this.help && searchable ? html`<ox-help-icon .topic=${this.help}></ox-help-icon>` : html``}\n ${filterable\n ? html`<md-icon @click=${(e: MouseEvent) => filterHandler(this.firstElementChild)}>tune</md-icon>`\n : html``}\n </div>\n `\n : html``}\n ${this.help && !searchable && !this.title /* help only */\n ? html`<ox-help-icon .topic=${this.help}></ox-help-icon>`\n : html``}\n </slot>\n <md-icon @click=${(e: Event) => this.onClose(e)} ?closable=${this.closable} close>close</md-icon>\n </div>\n\n <div content>\n <slot> </slot>\n </div>\n </div>\n `\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('templateProperties') && this.templateProperties) {\n var template = this.firstElementChild\n if (template) {\n for (let prop in this.templateProperties) {\n //@ts-ignore\n template[prop] = this.templateProperties[prop]\n }\n }\n }\n }\n\n firstUpdated() {\n if (this.zIndex) {\n this.style.setProperty('--z-index', String(this.zIndex))\n }\n\n requestAnimationFrame(() => {\n /* transition(animation) 효과를 위해 'opened' 속성을 변화시킨다. */\n this.overlayed?.setAttribute('opened', 'true')\n })\n }\n\n connectedCallback(): void {\n super.connectedCallback()\n\n this.movable = this.movable && !isHandheldDevice()\n\n if (this.movable) {\n document.addEventListener('mouseup', this.dragEndHandler)\n document.addEventListener('touchend', this.dragEndHandler)\n document.addEventListener('touchcancel', this.dragEndHandler)\n document.addEventListener('mousemove', this.dragMoveHandler)\n document.addEventListener('touchmove', this.dragMoveHandler)\n }\n }\n\n disconnectedCallback() {\n document.dispatchEvent(\n new CustomEvent('overlay-closed', {\n detail: this.name\n })\n )\n\n if (this.movable) {\n document.removeEventListener('mouseup', this.dragEndHandler!)\n document.removeEventListener('touchend', this.dragEndHandler!)\n document.removeEventListener('touchcancel', this.dragEndHandler!)\n document.removeEventListener('mousemove', this.dragMoveHandler!)\n document.removeEventListener('touchmove', this.dragMoveHandler!)\n }\n\n super.disconnectedCallback()\n }\n\n onDragStart(e: Event) {\n if (!this.movable) {\n return\n }\n\n const point = getPoint(e)\n\n if (point) {\n this.dragStart = point\n e.stopPropagation()\n return false\n }\n }\n\n onDragMove(e: Event) {\n if (!this.movable || !this.dragStart) {\n return false\n }\n\n const point = getPoint(e)\n\n if (!point) {\n return false\n }\n\n e.stopPropagation()\n e.preventDefault()\n\n const dragStart = point\n var { x, y } = point\n\n x -= this.dragStart.x\n y -= this.dragStart.y\n\n this.dragStart = dragStart\n\n const overlayed = this.overlayed\n\n var boundingRect = overlayed.getBoundingClientRect()\n\n overlayed.style.left =\n Math.min(document.body.offsetWidth - 40, Math.max(40 - overlayed.offsetWidth, boundingRect.left + x)) + 'px'\n overlayed.style.top = Math.min(document.body.offsetHeight - 40, Math.max(0, boundingRect.top + y)) + 'px'\n\n overlayed.style.transform = 'initial'\n\n return false\n }\n\n onDragEnd(e: Event) {\n if (this.movable && this.dragStart) {\n e.stopPropagation()\n e.preventDefault()\n\n delete this.dragStart\n }\n }\n\n /**\n * A method that closes the overlay by removing it from its parent node in the DOM.\n * When called, this method removes the overlay element, effectively hiding it from the user interface.\n */\n close() {\n this.parentNode?.removeChild(this)\n }\n\n onClose(e: Event, escape?: boolean) {\n e.stopPropagation()\n /* 현재 overlay state를 확인해서, 자신이 포함하고 있는 템플릿인 경우에 history.back() 한다. */\n\n if (this.historical) {\n var state = history.state\n var overlay = (state || {}).overlay\n\n if (!overlay || overlay.name !== this.name) {\n return\n }\n\n /* Backdrop click 경우는 escape 시도라고 정의한다. overlay 속성이 escapable이 아닌 경우에는 동작하지 않는다. */\n if (escape && !overlay.escapable) {\n return true\n }\n\n history.back()\n } else {\n this.close()\n }\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"ox-floating-overlay.js","sourceRoot":"","sources":["../../src/ox-floating-overlay.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n// 순환 참조가 되어서 일단 코멘트 처리함.\n// import '@operato/input/ox-input-search.js'\n\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\nimport { ScrollbarStyles } from '@operato/styles'\nimport { isHandheldDevice } from '@operato/utils'\n\nfunction getPoint(e: Event): { x: number; y: number } | undefined {\n if ((e as MouseEvent).button == 0) {\n return {\n x: (e as MouseEvent).clientX,\n y: (e as MouseEvent).clientY\n }\n } else if ((e as TouchEvent).touches?.length == 1) {\n const touch = (e as TouchEvent).touches[0]\n return {\n x: touch.clientX,\n y: touch.clientY\n }\n } else {\n return\n }\n}\n\n/**\n * Custom element for creating floating overlays.\n * These overlays can have various properties like direction, size, title, and more.\n * They are often used for modal dialogs, pop-ups, and similar UI elements.\n */\n@customElement('ox-floating-overlay')\nexport class OxFloatingOverlay extends LitElement {\n static styles = [\n ScrollbarStyles,\n css`\n /* for layout style */\n :host {\n position: relative;\n z-index: var(--z-index, 10);\n box-shadow: 2px 3px 10px 5px rgba(0, 0, 0, 0.15);\n }\n\n :host([hovering='edge']) {\n /* edge hovering 인 경우에는 상위 relative position 크기와 위치를 반영한다. */\n position: initial;\n }\n\n #backdrop {\n position: fixed;\n left: 0;\n top: 0;\n\n width: 100vw;\n height: 100vh;\n height: 100dvh;\n\n background-color: var(--md-sys-color-shadow, #000);\n opacity: 0.4;\n }\n\n [overlayed] {\n position: absolute;\n\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n [overlayed][hovering='center'] {\n position: fixed;\n\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n\n opacity: 0;\n border: 2px solid var(--md-sys-color-primary);\n }\n\n [overlayed][hovering='center'][opened] {\n opacity: 1;\n transition: opacity 0.3s ease-in;\n background-color: var(--md-sys-color-surface-container-lowest);\n }\n\n [hovering='center'] {\n width: var(--overlay-center-normal-width, 60%);\n height: var(--overlay-center-normal-height, 60%);\n }\n\n [hovering='center'][size='small'] {\n width: var(--overlay-center-small-width, 40%);\n height: var(--overlay-center-small-height, 40%);\n }\n\n [hovering='center'][size='large'] {\n width: var(--overlay-center-large-width, 100%);\n height: var(--overlay-center-large-height, 100%);\n }\n\n [header] {\n --help-icon-color: var(--md-sys-color-on-primary-container);\n --help-icon-hover-color: var(--md-sys-color-on-primary-container);\n\n pointer-events: initial;\n }\n\n [content] {\n flex: 1;\n overflow: hidden;\n }\n\n ::slotted(*) {\n box-sizing: border-box;\n pointer-events: initial;\n }\n\n [hovering='center'] [content] ::slotted(*) {\n width: 100%;\n height: 100%;\n }\n [direction='up'],\n [direction='down'] {\n width: 100%;\n\n max-height: 0;\n transition: max-height 0.7s ease-in;\n }\n [direction='up'] {\n bottom: 0;\n }\n [direction='down'] {\n top: 0;\n }\n\n [direction='up'][opened],\n [direction='down'][opened] {\n max-height: 100vh;\n max-height: 100dvh;\n }\n\n [settled][direction='down'] [content],\n [settled][direction='up'] [content] {\n overflow-y: auto;\n }\n\n [direction='left'],\n [direction='right'] {\n height: 100%;\n\n max-width: 0;\n transition: max-width 0.5s ease-in;\n }\n [direction='left'] {\n right: 0;\n }\n [direction='right'] {\n left: 0;\n }\n\n [direction='left'][opened],\n [direction='right'][opened] {\n max-width: 100vw;\n }\n\n [settled][direction='left'] [content],\n [settled][direction='right'] [content] {\n overflow-x: auto;\n }\n\n @media screen and (max-width: 460px) {\n [direction='up'],\n [direction='down'] {\n max-height: 100vh;\n max-height: 100dvh;\n }\n\n [direction='left'],\n [direction='right'] {\n max-width: 100vw;\n }\n }\n `,\n css`\n /* for header style */\n [header] {\n display: flex;\n flex-direction: row;\n align-items: center;\n background-color: var(--md-sys-color-primary);\n font-weight: var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500));\n color: var(--md-sys-color-on-primary);\n }\n\n slot[name='header'] {\n flex: 1;\n\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n text-transform: capitalize;\n }\n\n [name='header']::slotted(*) {\n margin: 0 auto;\n }\n\n [name='header'] > h1 {\n font-size: var(--md-sys-typescale-title-medium-size, 1rem);\n margin-block: 0.4rem;\n }\n\n [historyback] {\n margin-left: var(--spacing-medium);\n margin-right: auto;\n }\n\n [close] {\n margin-left: auto;\n margin-right: var(--spacing-medium);\n }\n\n [historyback],\n [close] {\n display: none;\n }\n\n [closable][close] {\n display: block;\n cursor: pointer;\n }\n\n [search] ox-help-icon {\n color: var(--md-sys-color-on-secondary-container);\n }\n\n [search] {\n --help-icon-color: var(--md-sys-color-primary);\n --help-icon-hover-color: var(--md-sys-color-primary);\n --help-icon-opacity: 0.2;\n --help-icon-size: 20px;\n\n --md-icon-size: 20px;\n\n --input-search-padding: var(--spacing-medium);\n --input-search-focus-border-bottom: none;\n --input-search-font: normal 16px var(--theme-font);\n\n display: flex;\n justify-content: space-between;\n align-items: center;\n\n align-self: center;\n color: var(--md-sys-color-primary);\n background-color: var(--md-sys-color-on-primary);\n border-radius: 999em;\n padding: 0 var(--spacing-medium);\n }\n\n [search] > * {\n align-self: center;\n }\n\n ox-input-search {\n color: var(--md-sys-color-primary);\n background-color: var(--md-sys-color-on-primary);\n border-radius: var(--md-sys-shape-corner-full);\n }\n\n @media screen and (max-width: 460px) {\n [closable][historyback] {\n display: block;\n }\n\n [closable][close] {\n display: none;\n }\n }\n `\n ]\n\n /**\n * A boolean property that determines whether a backdrop should be displayed behind the overlay.\n * Backdrop provides a semi-transparent background that covers the entire screen when the overlay is open.\n */\n @property({ type: Boolean }) backdrop?: boolean = false\n\n /**\n * A string property that specifies the direction in which the overlay should appear.\n * Possible values are: 'up', 'down', 'left', or 'right'.\n */\n @property({ type: String }) direction?: 'up' | 'down' | 'left' | 'right'\n\n /**\n * A string property that reflects the hovering state of the overlay.\n * Possible values are: 'center', 'edge', or 'next'.\n */\n @property({ type: String, reflect: true }) hovering?: 'center' | 'edge' | 'next'\n\n /**\n * A string property that specifies the size of the overlay.\n * Possible values are: 'small', 'medium', or 'large'.\n */\n @property({ type: String }) size?: 'small' | 'medium' | 'large'\n\n /**\n * A string property that represents the name of the overlay.\n * This can be used for identification or other purposes.\n */\n @property({ type: String }) name?: string\n\n /**\n * A string property that sets the title of the overlay.\n * The title is typically displayed in the header of the overlay.\n */\n @property({ type: String }) title: string = ''\n\n /**\n * A boolean property that determines whether the overlay can be closed by the user.\n * If set to true, a close button will be displayed in the header.\n */\n @property({ type: Boolean }) closable?: boolean = false\n\n /**\n * An object property that can hold custom properties for the template of the overlay.\n * These properties can be used to customize the template's behavior.\n */\n @property({ type: Object }) templateProperties: any\n\n /**\n * An object property that can hold information related to help or assistance for the overlay.\n * This information may be used to provide additional guidance to users.\n */\n @property({ type: Object }) help: any\n\n /**\n * A boolean property that determines whether the overlay is considered historical.\n * Historical overlays may have specific behavior or interactions, such as navigating back in history.\n */\n @property({ type: Boolean }) historical?: boolean = false\n\n /**\n * A boolean property that determines whether the overlay can be moved by dragging.\n * If set to true, the overlay can be repositioned by dragging its header.\n */\n @property({ type: Boolean }) movable?: boolean = false\n\n /**\n * An object property that can hold information related to a search feature within the overlay.\n * It can include properties like 'value', 'handler', and 'placeholder'.\n */\n @property({ type: Object }) search?: {\n value?: string\n handler?: (instance: any, value: string) => void\n placeholder?: string\n }\n\n /**\n * An object property that can hold information related to a filter feature within the overlay.\n * It can include a 'handler' function for filtering content.\n */\n @property({ type: Object }) filter?: { handler?: (instance: any) => void }\n\n /**\n * A numeric property that specifies the z-index of the overlay.\n * The z-index determines the stacking order of the overlay in relation to other elements on the page.\n */\n @property({ type: Number, attribute: 'z-index' }) zIndex?: number\n\n private dragStart?: { x: number; y: number }\n private dragEndHandler = this.onDragEnd.bind(this) as EventListener\n private dragMoveHandler = this.onDragMove.bind(this) as EventListener\n\n @query('[overlayed]') overlayed!: HTMLDivElement\n @query('[content]') content!: HTMLDivElement\n\n render() {\n const direction = this.hovering == 'center' ? undefined : this.direction\n\n const { value = '', handler: searchHandler, placeholder = '', autofocus = true } = this.search || ({} as any)\n const { handler: filterHandler } = this.filter || ({} as any)\n\n const searchable = typeof searchHandler == 'function'\n const filterable = typeof filterHandler == 'function'\n\n return html`\n ${Boolean(this.backdrop)\n ? html`\n <div\n id=\"backdrop\"\n ?hidden=${!this.backdrop}\n @click=${(e: Event) => this.onClose(e, true /* escape */)}\n ></div>\n `\n : html``}\n\n <div\n overlayed\n hovering=${this.hovering || 'center'}\n direction=${ifDefined(direction)}\n size=${this.size || 'medium'}\n @close-overlay=${(e: Event) => {\n e.stopPropagation()\n this.onClose(e)\n }}\n @transitionstart=${(e: Event) => {\n /* to hide scrollbar during transition */\n ;(e.target as HTMLElement).removeAttribute('settled')\n }}\n @transitionend=${(e: Event) => {\n ;(e.target as HTMLElement).setAttribute('settled', '')\n }}\n @click=${(e: MouseEvent) => {\n if (this.backdrop && e.target === this.content) {\n this.onClose(e, true /* escape */)\n }\n }}\n >\n <div\n header\n @mousedown=${this.onDragStart.bind(this)}\n @touchstart=${this.onDragStart.bind(this)}\n draggable=\"false\"\n >\n <md-icon @click=${(e: Event) => this.onClose(e)} ?closable=${this.closable} historyback>arrow_back</md-icon>\n ${this.movable ? html`<md-icon>drag_indicator</md-icon>` : html``}\n <slot name=\"header\">\n ${this.title || this.closable\n ? html`\n <h1>\n ${this.title || ''} ${this.help\n ? html`<ox-help-icon .topic=${this.help}></ox-help-icon>`\n : html``}\n </h1>\n `\n : html``}\n ${searchable || filterable\n ? html`\n <div search>\n ${searchable\n ? html` <ox-input-search\n .placeholder=${placeholder}\n .value=${value || ''}\n ?autofocus=${autofocus}\n @change=${(e: Event) => {\n searchHandler(this.firstElementChild, (e.target as any).value)\n }}\n ></ox-input-search>`\n : html``}\n ${this.help && searchable ? html`<ox-help-icon .topic=${this.help}></ox-help-icon>` : html``}\n ${filterable\n ? html`<md-icon @click=${(e: MouseEvent) => filterHandler(this.firstElementChild)}>tune</md-icon>`\n : html``}\n </div>\n `\n : html``}\n ${this.help && !searchable && !this.title /* help only */\n ? html`<ox-help-icon .topic=${this.help}></ox-help-icon>`\n : html``}\n </slot>\n <md-icon @click=${(e: Event) => this.onClose(e)} ?closable=${this.closable} close>close</md-icon>\n </div>\n\n <div content>\n <slot> </slot>\n </div>\n </div>\n `\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('templateProperties') && this.templateProperties) {\n var template = this.firstElementChild\n if (template) {\n for (let prop in this.templateProperties) {\n //@ts-ignore\n template[prop] = this.templateProperties[prop]\n }\n }\n }\n }\n\n firstUpdated() {\n if (this.zIndex) {\n this.style.setProperty('--z-index', String(this.zIndex))\n }\n\n requestAnimationFrame(() => {\n /* transition(animation) 효과를 위해 'opened' 속성을 변화시킨다. */\n this.overlayed?.setAttribute('opened', 'true')\n })\n }\n\n connectedCallback(): void {\n super.connectedCallback()\n\n this.movable = this.movable && !isHandheldDevice()\n\n if (this.movable) {\n document.addEventListener('mouseup', this.dragEndHandler)\n document.addEventListener('touchend', this.dragEndHandler)\n document.addEventListener('touchcancel', this.dragEndHandler)\n document.addEventListener('mousemove', this.dragMoveHandler)\n document.addEventListener('touchmove', this.dragMoveHandler)\n }\n }\n\n disconnectedCallback() {\n document.dispatchEvent(\n new CustomEvent('overlay-closed', {\n detail: this.name\n })\n )\n\n if (this.movable) {\n document.removeEventListener('mouseup', this.dragEndHandler!)\n document.removeEventListener('touchend', this.dragEndHandler!)\n document.removeEventListener('touchcancel', this.dragEndHandler!)\n document.removeEventListener('mousemove', this.dragMoveHandler!)\n document.removeEventListener('touchmove', this.dragMoveHandler!)\n }\n\n super.disconnectedCallback()\n }\n\n onDragStart(e: Event) {\n if (!this.movable) {\n return\n }\n\n const point = getPoint(e)\n\n if (point) {\n this.dragStart = point\n e.stopPropagation()\n return false\n }\n }\n\n onDragMove(e: Event) {\n if (!this.movable || !this.dragStart) {\n return false\n }\n\n const point = getPoint(e)\n\n if (!point) {\n return false\n }\n\n e.stopPropagation()\n e.preventDefault()\n\n const dragStart = point\n var { x, y } = point\n\n x -= this.dragStart.x\n y -= this.dragStart.y\n\n this.dragStart = dragStart\n\n const overlayed = this.overlayed\n\n var boundingRect = overlayed.getBoundingClientRect()\n\n overlayed.style.left =\n Math.min(document.body.offsetWidth - 40, Math.max(40 - overlayed.offsetWidth, boundingRect.left + x)) + 'px'\n overlayed.style.top = Math.min(document.body.offsetHeight - 40, Math.max(0, boundingRect.top + y)) + 'px'\n\n overlayed.style.transform = 'initial'\n\n return false\n }\n\n onDragEnd(e: Event) {\n if (this.movable && this.dragStart) {\n e.stopPropagation()\n e.preventDefault()\n\n delete this.dragStart\n }\n }\n\n /**\n * A method that closes the overlay by removing it from its parent node in the DOM.\n * When called, this method removes the overlay element, effectively hiding it from the user interface.\n */\n close() {\n this.parentNode?.removeChild(this)\n }\n\n onClose(e: Event, escape?: boolean) {\n e.stopPropagation()\n /* 현재 overlay state를 확인해서, 자신이 포함하고 있는 템플릿인 경우에 history.back() 한다. */\n\n if (this.historical) {\n var state = history.state\n var overlay = (state || {}).overlay\n\n if (!overlay || overlay.name !== this.name) {\n return\n }\n\n /* Backdrop click 경우는 escape 시도라고 정의한다. overlay 속성이 escapable이 아닌 경우에는 동작하지 않는다. */\n if (escape && !overlay.escapable) {\n return true\n }\n\n history.back()\n } else {\n this.close()\n }\n }\n}\n"]}
|
@@ -22,70 +22,7 @@ function guaranteeFocus(element) {
|
|
22
22
|
* A custom element representing a list-like popup menu.
|
23
23
|
*/
|
24
24
|
let OxPopupList = class OxPopupList extends OxPopup {
|
25
|
-
|
26
|
-
super(...arguments);
|
27
|
-
/**
|
28
|
-
* A boolean property that, when set to true, allows multiple options to be selected in the popup list.
|
29
|
-
* @type {boolean}
|
30
|
-
*/
|
31
|
-
this.multiple = false;
|
32
|
-
/**
|
33
|
-
* A boolean property that, when set to true, enables the drag-and-drop sorting functionality within the popup list.
|
34
|
-
* This allows users to reorder the options in the list by dragging them into new positions.
|
35
|
-
* @type {boolean|undefined}
|
36
|
-
*/
|
37
|
-
this.sortable = false;
|
38
|
-
this.nothingToSelect = false;
|
39
|
-
this.locked = false;
|
40
|
-
this._onkeydown = function (e) {
|
41
|
-
e.stopPropagation();
|
42
|
-
switch (e.key) {
|
43
|
-
case 'Esc': // for IE/Edge
|
44
|
-
case 'Escape':
|
45
|
-
this.close();
|
46
|
-
break;
|
47
|
-
case 'Left': // for IE/Edge
|
48
|
-
case 'ArrowLeft':
|
49
|
-
case 'Up': // for IE/Edge
|
50
|
-
case 'ArrowUp':
|
51
|
-
this.activeIndex--;
|
52
|
-
break;
|
53
|
-
case 'Right': // for IE/Edge
|
54
|
-
case 'ArrowRight':
|
55
|
-
case 'Down': // for IE/Edge
|
56
|
-
case 'ArrowDown':
|
57
|
-
this.activeIndex++;
|
58
|
-
break;
|
59
|
-
case 'Enter':
|
60
|
-
case ' ':
|
61
|
-
case 'Spacebar': // for old firefox
|
62
|
-
this.setActive(this.activeIndex, true);
|
63
|
-
this.select();
|
64
|
-
break;
|
65
|
-
}
|
66
|
-
}.bind(this);
|
67
|
-
this._onfocusout = function (e) {
|
68
|
-
const to = e.relatedTarget;
|
69
|
-
if (!this.contains(to)) {
|
70
|
-
/* If the focus has clearly moved to an element outside of my range, the ox-popup-list should be closed. */
|
71
|
-
// @ts-ignore for debug
|
72
|
-
!this.preventCloseOnBlur && !this.debug && !window.POPUP_DEBUG && this.close();
|
73
|
-
}
|
74
|
-
}.bind(this);
|
75
|
-
this._onclick = function (e) {
|
76
|
-
e.stopPropagation();
|
77
|
-
// Check if the click event target is a checkbox
|
78
|
-
if (e.target.closest('input[type="checkbox"]')) {
|
79
|
-
return; // Do not proceed if it's a checkbox click
|
80
|
-
}
|
81
|
-
const option = e.target?.closest('[option]');
|
82
|
-
if (option) {
|
83
|
-
this.setActive(option, true);
|
84
|
-
this.select();
|
85
|
-
}
|
86
|
-
}.bind(this);
|
87
|
-
}
|
88
|
-
static { this.styles = [
|
25
|
+
static styles = [
|
89
26
|
...OxPopup.styles,
|
90
27
|
css `
|
91
28
|
:host {
|
@@ -197,7 +134,42 @@ let OxPopupList = class OxPopupList extends OxPopup {
|
|
197
134
|
overflow: auto;
|
198
135
|
}
|
199
136
|
`
|
200
|
-
];
|
137
|
+
];
|
138
|
+
/**
|
139
|
+
* A boolean property that, when set to true, allows multiple options to be selected in the popup list.
|
140
|
+
* @type {boolean}
|
141
|
+
*/
|
142
|
+
multiple = false;
|
143
|
+
/**
|
144
|
+
* An optional attribute that specifies the name of the attribute used to mark selected options in the list.
|
145
|
+
* @type {string|undefined}
|
146
|
+
*/
|
147
|
+
attrSelected;
|
148
|
+
/**
|
149
|
+
* A boolean property that, when set to true, enables the search functionality in the popup list.
|
150
|
+
* Users can search/filter options by typing in a search bar.
|
151
|
+
* @type {boolean|undefined}
|
152
|
+
*/
|
153
|
+
withSearch;
|
154
|
+
/**
|
155
|
+
* A boolean property that, when set to true, enables the drag-and-drop sorting functionality within the popup list.
|
156
|
+
* This allows users to reorder the options in the list by dragging them into new positions.
|
157
|
+
* @type {boolean|undefined}
|
158
|
+
*/
|
159
|
+
sortable = false;
|
160
|
+
/**
|
161
|
+
* The value(s) of the selected option(s) in the popup list.
|
162
|
+
* This property can be a string or an array of strings, depending on whether multiple selections are allowed.
|
163
|
+
* @type {string|string[]|undefined}
|
164
|
+
*/
|
165
|
+
value;
|
166
|
+
activeIndex;
|
167
|
+
searchKeyword;
|
168
|
+
nothingToSelect = false;
|
169
|
+
searchInput;
|
170
|
+
body;
|
171
|
+
sortableObject;
|
172
|
+
locked = false;
|
201
173
|
render() {
|
202
174
|
return html `
|
203
175
|
<slot name="header"> </slot>
|
@@ -252,6 +224,53 @@ let OxPopupList = class OxPopupList extends OxPopup {
|
|
252
224
|
e.stopPropagation();
|
253
225
|
}
|
254
226
|
}
|
227
|
+
_onkeydown = function (e) {
|
228
|
+
e.stopPropagation();
|
229
|
+
switch (e.key) {
|
230
|
+
case 'Esc': // for IE/Edge
|
231
|
+
case 'Escape':
|
232
|
+
this.close();
|
233
|
+
break;
|
234
|
+
case 'Left': // for IE/Edge
|
235
|
+
case 'ArrowLeft':
|
236
|
+
case 'Up': // for IE/Edge
|
237
|
+
case 'ArrowUp':
|
238
|
+
this.activeIndex--;
|
239
|
+
break;
|
240
|
+
case 'Right': // for IE/Edge
|
241
|
+
case 'ArrowRight':
|
242
|
+
case 'Down': // for IE/Edge
|
243
|
+
case 'ArrowDown':
|
244
|
+
this.activeIndex++;
|
245
|
+
break;
|
246
|
+
case 'Enter':
|
247
|
+
case ' ':
|
248
|
+
case 'Spacebar': // for old firefox
|
249
|
+
this.setActive(this.activeIndex, true);
|
250
|
+
this.select();
|
251
|
+
break;
|
252
|
+
}
|
253
|
+
}.bind(this);
|
254
|
+
_onfocusout = function (e) {
|
255
|
+
const to = e.relatedTarget;
|
256
|
+
if (!this.contains(to)) {
|
257
|
+
/* If the focus has clearly moved to an element outside of my range, the ox-popup-list should be closed. */
|
258
|
+
// @ts-ignore for debug
|
259
|
+
!this.preventCloseOnBlur && !this.debug && !window.POPUP_DEBUG && this.close();
|
260
|
+
}
|
261
|
+
}.bind(this);
|
262
|
+
_onclick = function (e) {
|
263
|
+
e.stopPropagation();
|
264
|
+
// Check if the click event target is a checkbox
|
265
|
+
if (e.target.closest('input[type="checkbox"]')) {
|
266
|
+
return; // Do not proceed if it's a checkbox click
|
267
|
+
}
|
268
|
+
const option = e.target?.closest('[option]');
|
269
|
+
if (option) {
|
270
|
+
this.setActive(option, true);
|
271
|
+
this.select();
|
272
|
+
}
|
273
|
+
}.bind(this);
|
255
274
|
updated(changes) {
|
256
275
|
if (changes.has('activeIndex')) {
|
257
276
|
this.activeIndex !== undefined && this.setActive(this.activeIndex);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ox-popup-list.js","sourceRoot":"","sources":["../../src/ox-popup-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { css, CSSResult, html, PropertyValues } from 'lit'\nimport { render } from 'lit-html'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport Sortable from 'sortablejs'\n\nimport { OxPopup } from './ox-popup.js'\nimport { convertToFixedPosition } from './position-converter.js'\n\nfunction guaranteeFocus(element: HTMLElement) {\n // 1. Give focus opportunity to the first focusable element within the option element.\n const focusible = element.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])')\n\n if (focusible) {\n ;(focusible as HTMLElement).focus()\n return\n }\n\n // 2. Give focus opportunity to the closest parent, including itself.\n const closest = element.closest(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n ) as HTMLElement\n\n closest?.focus()\n}\n\n/**\n * A custom element representing a list-like popup menu.\n */\n@customElement('ox-popup-list')\nexport class OxPopupList extends OxPopup {\n static styles = [\n ...OxPopup.styles,\n css`\n :host {\n display: none;\n align-items: stretch;\n background-color: var(--ox-popup-list-background-color, var(--md-sys-color-surface-container-lowest));\n color: var(--ox-popup-list-color, var(--md-sys-color-on-surface));\n z-index: 100;\n box-shadow: 2px 3px 10px 5px rgba(0, 0, 0, 0.15);\n padding: var(--spacing-small) 0;\n border-radius: var(--md-sys-shape-corner-small, 5px);\n\n font-size: var(--md-sys-typescale-label-large-size, 0.875rem);\n }\n\n :host([active]) {\n display: flex;\n flex-direction: column;\n }\n\n :host(*:focus) {\n outline: none;\n }\n\n :host([nowrap]) ::slotted([option]) {\n white-space: nowrap;\n }\n\n ::slotted([option]) {\n border-left: 3px solid transparent;\n }\n\n ::slotted(*) {\n padding: var(--spacing-medium);\n border-bottom: 1px solid var(--md-sys-color-surface-variant);\n cursor: pointer;\n outline: none;\n color: var(--ox-popup-list-color, var(--md-sys-color-on-surface-variant));\n }\n\n ::slotted(*:focus) {\n outline: none;\n }\n\n ::slotted([option][active]),\n ::slotted([option]:hover) {\n background-color: var(--ox-popup-list-background-color-variant, var(--md-sys-color-surface-variant));\n color: var(--ox-popup-list-color-variant, var(--md-sys-color-on-surface-variant));\n }\n\n ::slotted([option][selected]) {\n border-left: 3px solid var(--md-sys-color-primary);\n font-weight: var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500));\n }\n\n ::slotted([separator]) {\n height: 1px;\n width: 100%;\n padding: 0;\n background-color: var(--ox-popup-menu-separator-color, var(--md-sys-color-surface-variant));\n }\n\n ::slotted([hidden]) {\n display: none;\n }\n\n [search] {\n display: flex;\n position: relative;\n align-items: center;\n padding: var(--spacing-small) var(--spacing-medium);\n\n --md-icon-size: var(--icon-size-small);\n }\n\n [search] [type='text'] {\n flex: 1;\n background-color: transparent;\n border: 0;\n padding: 0 0 0 var(--spacing-huge);\n outline: none;\n width: 50px;\n }\n\n [search] md-icon {\n color: var(--md-sys-color-secondary);\n }\n\n [search] md-icon[search-icon] {\n position: absolute;\n }\n\n [search] md-icon[delete-icon] {\n opacity: 0.5;\n --md-icon-size: var(--icon-size-tiny);\n }\n\n [nothing] {\n opacity: 0.5;\n text-align: center;\n }\n\n div[body] {\n flex: 1;\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n overflow: auto;\n }\n `\n ]\n\n /**\n * A boolean property that, when set to true, allows multiple options to be selected in the popup list.\n * @type {boolean}\n */\n @property({ type: Boolean, attribute: true, reflect: true }) multiple: boolean = false\n\n /**\n * An optional attribute that specifies the name of the attribute used to mark selected options in the list.\n * @type {string|undefined}\n */\n @property({ type: String, attribute: 'attr-selected', reflect: true }) attrSelected?: string\n\n /**\n * A boolean property that, when set to true, enables the search functionality in the popup list.\n * Users can search/filter options by typing in a search bar.\n * @type {boolean|undefined}\n */\n @property({ type: Boolean, attribute: 'with-search', reflect: true }) withSearch?: boolean\n\n /**\n * A boolean property that, when set to true, enables the drag-and-drop sorting functionality within the popup list.\n * This allows users to reorder the options in the list by dragging them into new positions.\n * @type {boolean|undefined}\n */\n @property({ type: Boolean, attribute: 'sortable', reflect: true }) sortable?: boolean = false\n\n /**\n * The value(s) of the selected option(s) in the popup list.\n * This property can be a string or an array of strings, depending on whether multiple selections are allowed.\n * @type {string|string[]|undefined}\n */\n @property({ type: String }) value?: string | string[]\n\n @state() activeIndex?: number\n @state() searchKeyword?: string\n @state() nothingToSelect: boolean = false\n\n @query('[search] input') searchInput!: HTMLInputElement\n @query('div[body]') body!: HTMLDivElement\n\n private sortableObject?: Sortable\n private locked: boolean = false\n\n render() {\n return html`\n <slot name=\"header\"> </slot>\n\n ${this.withSearch\n ? html`\n <label search for=\"search\" @input=${(e: InputEvent) => this._oninputsearch(e)}>\n <md-icon search-icon>search</md-icon>\n <input\n id=\"search\"\n type=\"text\"\n autocomplete=\"off\"\n @keydown=${(e: KeyboardEvent) => this._onkeydownsearch(e)}\n @change=${(e: InputEvent) => this._onchangesearch(e)}\n />\n <md-icon\n @click=${() => {\n this.searchInput.value = ''\n this.searchKeyword = ''\n }}\n delete-icon\n >delete</md-icon\n >\n </label>\n `\n : html``}\n\n <div body>\n <slot\n @change=${(e: Event) => {\n e.stopPropagation()\n }}\n >\n </slot>\n </div>\n\n ${this.nothingToSelect ? html`<label nothing>nothing to select</label>` : html``}\n `\n }\n\n protected _oninputsearch(e: InputEvent) {\n e.stopPropagation()\n e.preventDefault()\n\n this.searchKeyword = (e.target as HTMLInputElement).value\n }\n\n protected _onchangesearch(e: InputEvent) {\n e.stopPropagation()\n this.searchKeyword = (e.target as HTMLInputElement).value\n }\n\n protected _onkeydownsearch(e: KeyboardEvent) {\n const keys = ['Esc', 'Escape', 'Up', 'ArrowUp', 'Down', 'ArrowDown']\n if (!keys.includes(e.key)) {\n e.stopPropagation()\n }\n }\n\n protected _onkeydown: (e: KeyboardEvent) => void = function (this: OxPopupList, e: KeyboardEvent) {\n e.stopPropagation()\n\n switch (e.key) {\n case 'Esc': // for IE/Edge\n case 'Escape':\n this.close()\n break\n\n case 'Left': // for IE/Edge\n case 'ArrowLeft':\n case 'Up': // for IE/Edge\n case 'ArrowUp':\n this.activeIndex!--\n break\n\n case 'Right': // for IE/Edge\n case 'ArrowRight':\n case 'Down': // for IE/Edge\n case 'ArrowDown':\n this.activeIndex!++\n break\n\n case 'Enter':\n case ' ':\n case 'Spacebar': // for old firefox\n this.setActive(this.activeIndex!, true)\n this.select()\n break\n }\n }.bind(this)\n\n protected _onfocusout: (e: FocusEvent) => void = function (this: OxPopupList, e: FocusEvent) {\n const to = e.relatedTarget as HTMLElement\n\n if (!this.contains(to)) {\n /* If the focus has clearly moved to an element outside of my range, the ox-popup-list should be closed. */\n // @ts-ignore for debug\n !this.preventCloseOnBlur && !this.debug && !window.POPUP_DEBUG && this.close()\n }\n }.bind(this)\n\n protected _onclick: (e: MouseEvent) => void = function (this: OxPopupList, e: MouseEvent) {\n e.stopPropagation()\n\n // Check if the click event target is a checkbox\n if ((e.target as HTMLElement).closest('input[type=\"checkbox\"]')) {\n return // Do not proceed if it's a checkbox click\n }\n\n const option = (e.target as HTMLElement)?.closest('[option]')\n if (option) {\n this.setActive(option, true)\n this.select()\n }\n }.bind(this)\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('activeIndex')) {\n this.activeIndex !== undefined && this.setActive(this.activeIndex)\n }\n\n if (changes.has('sortable')) {\n this.sortableObject && this.sortableObject.destroy()\n\n if (this.sortable) {\n this.sortableObject = Sortable.create(this, {\n handle: '[option]',\n draggable: '[option]',\n direction: 'vertical',\n animation: 150,\n touchStartThreshold: 10,\n onEnd: e => {\n this.locked = false\n this.dispatchEvent(\n new CustomEvent('sorted', {\n detail: Array.from(this.querySelectorAll('[option]'))\n })\n )\n },\n onMove: e => {\n // Check if the drag event target is a checkbox\n if ((e.dragged as HTMLElement).querySelector('input[type=\"checkbox\"]')) {\n return false // Prevent sorting if it's a checkbox drag\n }\n this.locked = true\n }\n })\n }\n }\n\n if (changes.has('searchKeyword')) {\n const attrSelected = this.attrSelected || 'selected'\n this.querySelectorAll(`[option]`).forEach(item => {\n if (!this.searchKeyword || item.textContent?.match(new RegExp(this.searchKeyword, 'i'))) {\n item.removeAttribute('hidden')\n } else {\n item.removeAttribute('selected')\n item.setAttribute('hidden', '')\n }\n })\n this.nothingToSelect = this.querySelectorAll(`[option]:not([hidden])`).length === 0\n }\n\n if (changes.has('value')) {\n const options = Array.from(this.querySelectorAll(':scope > [option]'))\n\n var values = this.value\n if (!(values instanceof Array)) {\n values = [values as string]\n }\n\n options.forEach(option => {\n if (values?.includes((option as HTMLElement).getAttribute('value') || '')) {\n option.setAttribute(this.attrSelected || 'selected', '')\n } else {\n option.removeAttribute(this.attrSelected || 'selected')\n }\n })\n }\n }\n\n /**\n * Retrieves the labels of the selected options in the popup list.\n * If multiple selections are allowed, an array of labels is returned. Otherwise, a single label is returned.\n * @returns {string|string[]} The label(s) of the selected option(s).\n */\n public getSelectedLabels(): string | string[] {\n const options = Array.from(this.querySelectorAll(':scope > [option]'))\n\n const selected = options\n .filter(option => option.hasAttribute('value') && option.hasAttribute(this.attrSelected || 'selected'))\n .map(option => option.textContent || '')\n\n return this.multiple ? selected : selected[0]\n }\n\n /**\n * Handles the selection of options in the popup list and dispatches a 'select' event with the selected value(s).\n * If multiple selections are allowed, an array of selected values is dispatched; otherwise, a single value is dispatched.\n * Also, it checks whether the selected option should remain alive and whether the popup should be closed.\n */\n async select() {\n await this.updateComplete\n\n const options = Array.from(this.querySelectorAll(':scope > [option]'))\n\n const selected = options\n .filter(option => option.hasAttribute('value') && option.hasAttribute(this.attrSelected || 'selected'))\n .map(option => option.getAttribute('value'))\n\n this.dispatchEvent(\n new CustomEvent('select', {\n bubbles: true,\n composed: true,\n detail: this.multiple ? selected : selected[0]\n })\n )\n\n const option = options[this.activeIndex!]\n if (!option.hasAttribute('alive-on-select') && !this.hasAttribute('multiple')) {\n this.close()\n }\n }\n\n /**\n * Sets the active option within the popup list based on the given index or Element.\n * If 'withSelect' is true, it also manages the selection state of the option.\n *\n * @param {number | Element | null} active - The index or Element of the option to set as active.\n * @param {boolean | undefined} withSelect - Indicates whether to manage the selection state of the option.\n */\n setActive(active: number | Element | null, withSelect?: boolean) {\n var options = Array.from(this.querySelectorAll('[option]:not([hidden])'))\n if (this.withSearch) {\n options.push(this.renderRoot.querySelector('[search]')!)\n }\n\n if (active instanceof Element) {\n const index = options.findIndex(option => option === active)\n this.setActive(index === -1 ? 0 : index, withSelect)\n return\n }\n\n const attrSelected = this.attrSelected || 'selected'\n\n options.forEach(async (option, index) => {\n if (typeof active === 'number' && index === (active + options.length) % options.length) {\n option.setAttribute('active', '')\n\n if (withSelect && !this.attrSelected) {\n /* being set attribute attrs-selected means, that element should know how to do when event happened. */\n this.multiple ? option.toggleAttribute('selected') : option.setAttribute('selected', '')\n }\n\n guaranteeFocus(option as HTMLElement)\n\n this.activeIndex = index\n } else {\n option.removeAttribute('active')\n /* even thought attribute attrs-selected set, ox-popup-list have to unset others. */\n !this.multiple && withSelect && option.removeAttribute(attrSelected)\n }\n })\n }\n\n /**\n * Overrides the 'open' method of the base class 'OxPopup' to set the initial active index\n * when the popup list is opened. It ensures that an option is initially selected for user interaction.\n *\n * @param {object} params - The parameters for opening the popup, including position and size.\n */\n override open(params: {\n left?: number\n top?: number\n right?: number\n bottom?: number\n width?: string\n height?: string\n silent?: boolean\n // fixed?: boolean\n }) {\n super.open(params)\n\n if (this.activeIndex === undefined) {\n const activeElement = this.querySelector(`[${this.attrSelected || 'selected'}]`)\n this.setActive(activeElement || 0)\n } else {\n this.setActive(this.activeIndex)\n }\n }\n\n /**\n * Overrides the 'close' method of the base class 'OxPopup' to dispatch a custom event\n * indicating that the popup list is being closed. This event can be used for further interactions\n * or logic in the application.\n */\n override close() {\n if (this.locked) {\n return\n }\n\n if (this.hasAttribute('active')) {\n this.dispatchEvent(\n new CustomEvent('close', {\n bubbles: true,\n composed: true\n })\n )\n }\n\n super.close()\n }\n\n /**\n * Open OxPopup\n *\n * @param {PopupOpenOptions}\n */\n static open({\n template,\n top,\n left,\n right,\n bottom,\n parent,\n multiple,\n sortable,\n attrSelected,\n styles,\n debug\n }: {\n template: unknown\n top?: number\n left?: number\n right?: number\n bottom?: number\n parent?: Element | null\n multiple?: boolean\n sortable?: boolean\n debug?: boolean\n attrSelected?: string\n styles?: CSSResult\n }): OxPopupList {\n const target = document.createElement('ox-popup-list') as OxPopupList\n\n if (styles) {\n const style = document.createElement('style')\n style.textContent = styles.cssText\n\n const shadow = target.attachShadow({ mode: 'open' })\n shadow.appendChild(style)\n }\n\n if (!!debug) {\n target.setAttribute('debug', '')\n }\n\n if (!!multiple) {\n target.setAttribute('multiple', '')\n }\n\n if (!!sortable) {\n target.setAttribute('sortable', '')\n }\n\n if (attrSelected) {\n target.setAttribute('attr-selected', attrSelected)\n }\n\n render(template, target)\n\n if (parent) {\n var { left, top, right, bottom } = convertToFixedPosition({\n left,\n top,\n right,\n bottom,\n relativeElement: parent as HTMLElement\n })\n }\n\n document.body.appendChild(target)\n target.removeAfterUse = true\n target.open({ top, left, right, bottom })\n\n return target\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"ox-popup-list.js","sourceRoot":"","sources":["../../src/ox-popup-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { css, CSSResult, html, PropertyValues } from 'lit'\nimport { render } from 'lit-html'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport Sortable from 'sortablejs'\n\nimport { OxPopup } from './ox-popup.js'\nimport { convertToFixedPosition } from './position-converter.js'\n\nfunction guaranteeFocus(element: HTMLElement) {\n // 1. Give focus opportunity to the first focusable element within the option element.\n const focusible = element.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])')\n\n if (focusible) {\n ;(focusible as HTMLElement).focus()\n return\n }\n\n // 2. Give focus opportunity to the closest parent, including itself.\n const closest = element.closest(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n ) as HTMLElement\n\n closest?.focus()\n}\n\n/**\n * A custom element representing a list-like popup menu.\n */\n@customElement('ox-popup-list')\nexport class OxPopupList extends OxPopup {\n static styles = [\n ...OxPopup.styles,\n css`\n :host {\n display: none;\n align-items: stretch;\n background-color: var(--ox-popup-list-background-color, var(--md-sys-color-surface-container-lowest));\n color: var(--ox-popup-list-color, var(--md-sys-color-on-surface));\n z-index: 100;\n box-shadow: 2px 3px 10px 5px rgba(0, 0, 0, 0.15);\n padding: var(--spacing-small) 0;\n border-radius: var(--md-sys-shape-corner-small, 5px);\n\n font-size: var(--md-sys-typescale-label-large-size, 0.875rem);\n }\n\n :host([active]) {\n display: flex;\n flex-direction: column;\n }\n\n :host(*:focus) {\n outline: none;\n }\n\n :host([nowrap]) ::slotted([option]) {\n white-space: nowrap;\n }\n\n ::slotted([option]) {\n border-left: 3px solid transparent;\n }\n\n ::slotted(*) {\n padding: var(--spacing-medium);\n border-bottom: 1px solid var(--md-sys-color-surface-variant);\n cursor: pointer;\n outline: none;\n color: var(--ox-popup-list-color, var(--md-sys-color-on-surface-variant));\n }\n\n ::slotted(*:focus) {\n outline: none;\n }\n\n ::slotted([option][active]),\n ::slotted([option]:hover) {\n background-color: var(--ox-popup-list-background-color-variant, var(--md-sys-color-surface-variant));\n color: var(--ox-popup-list-color-variant, var(--md-sys-color-on-surface-variant));\n }\n\n ::slotted([option][selected]) {\n border-left: 3px solid var(--md-sys-color-primary);\n font-weight: var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500));\n }\n\n ::slotted([separator]) {\n height: 1px;\n width: 100%;\n padding: 0;\n background-color: var(--ox-popup-menu-separator-color, var(--md-sys-color-surface-variant));\n }\n\n ::slotted([hidden]) {\n display: none;\n }\n\n [search] {\n display: flex;\n position: relative;\n align-items: center;\n padding: var(--spacing-small) var(--spacing-medium);\n\n --md-icon-size: var(--icon-size-small);\n }\n\n [search] [type='text'] {\n flex: 1;\n background-color: transparent;\n border: 0;\n padding: 0 0 0 var(--spacing-huge);\n outline: none;\n width: 50px;\n }\n\n [search] md-icon {\n color: var(--md-sys-color-secondary);\n }\n\n [search] md-icon[search-icon] {\n position: absolute;\n }\n\n [search] md-icon[delete-icon] {\n opacity: 0.5;\n --md-icon-size: var(--icon-size-tiny);\n }\n\n [nothing] {\n opacity: 0.5;\n text-align: center;\n }\n\n div[body] {\n flex: 1;\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n overflow: auto;\n }\n `\n ]\n\n /**\n * A boolean property that, when set to true, allows multiple options to be selected in the popup list.\n * @type {boolean}\n */\n @property({ type: Boolean, attribute: true, reflect: true }) multiple: boolean = false\n\n /**\n * An optional attribute that specifies the name of the attribute used to mark selected options in the list.\n * @type {string|undefined}\n */\n @property({ type: String, attribute: 'attr-selected', reflect: true }) attrSelected?: string\n\n /**\n * A boolean property that, when set to true, enables the search functionality in the popup list.\n * Users can search/filter options by typing in a search bar.\n * @type {boolean|undefined}\n */\n @property({ type: Boolean, attribute: 'with-search', reflect: true }) withSearch?: boolean\n\n /**\n * A boolean property that, when set to true, enables the drag-and-drop sorting functionality within the popup list.\n * This allows users to reorder the options in the list by dragging them into new positions.\n * @type {boolean|undefined}\n */\n @property({ type: Boolean, attribute: 'sortable', reflect: true }) sortable?: boolean = false\n\n /**\n * The value(s) of the selected option(s) in the popup list.\n * This property can be a string or an array of strings, depending on whether multiple selections are allowed.\n * @type {string|string[]|undefined}\n */\n @property({ type: String }) value?: string | string[]\n\n @state() activeIndex?: number\n @state() searchKeyword?: string\n @state() nothingToSelect: boolean = false\n\n @query('[search] input') searchInput!: HTMLInputElement\n @query('div[body]') body!: HTMLDivElement\n\n private sortableObject?: Sortable\n private locked: boolean = false\n\n render() {\n return html`\n <slot name=\"header\"> </slot>\n\n ${this.withSearch\n ? html`\n <label search for=\"search\" @input=${(e: InputEvent) => this._oninputsearch(e)}>\n <md-icon search-icon>search</md-icon>\n <input\n id=\"search\"\n type=\"text\"\n autocomplete=\"off\"\n @keydown=${(e: KeyboardEvent) => this._onkeydownsearch(e)}\n @change=${(e: InputEvent) => this._onchangesearch(e)}\n />\n <md-icon\n @click=${() => {\n this.searchInput.value = ''\n this.searchKeyword = ''\n }}\n delete-icon\n >delete</md-icon\n >\n </label>\n `\n : html``}\n\n <div body>\n <slot\n @change=${(e: Event) => {\n e.stopPropagation()\n }}\n >\n </slot>\n </div>\n\n ${this.nothingToSelect ? html`<label nothing>nothing to select</label>` : html``}\n `\n }\n\n protected _oninputsearch(e: InputEvent) {\n e.stopPropagation()\n e.preventDefault()\n\n this.searchKeyword = (e.target as HTMLInputElement).value\n }\n\n protected _onchangesearch(e: InputEvent) {\n e.stopPropagation()\n this.searchKeyword = (e.target as HTMLInputElement).value\n }\n\n protected _onkeydownsearch(e: KeyboardEvent) {\n const keys = ['Esc', 'Escape', 'Up', 'ArrowUp', 'Down', 'ArrowDown']\n if (!keys.includes(e.key)) {\n e.stopPropagation()\n }\n }\n\n protected _onkeydown: (e: KeyboardEvent) => void = function (this: OxPopupList, e: KeyboardEvent) {\n e.stopPropagation()\n\n switch (e.key) {\n case 'Esc': // for IE/Edge\n case 'Escape':\n this.close()\n break\n\n case 'Left': // for IE/Edge\n case 'ArrowLeft':\n case 'Up': // for IE/Edge\n case 'ArrowUp':\n this.activeIndex!--\n break\n\n case 'Right': // for IE/Edge\n case 'ArrowRight':\n case 'Down': // for IE/Edge\n case 'ArrowDown':\n this.activeIndex!++\n break\n\n case 'Enter':\n case ' ':\n case 'Spacebar': // for old firefox\n this.setActive(this.activeIndex!, true)\n this.select()\n break\n }\n }.bind(this)\n\n protected _onfocusout: (e: FocusEvent) => void = function (this: OxPopupList, e: FocusEvent) {\n const to = e.relatedTarget as HTMLElement\n\n if (!this.contains(to)) {\n /* If the focus has clearly moved to an element outside of my range, the ox-popup-list should be closed. */\n // @ts-ignore for debug\n !this.preventCloseOnBlur && !this.debug && !window.POPUP_DEBUG && this.close()\n }\n }.bind(this)\n\n protected _onclick: (e: MouseEvent) => void = function (this: OxPopupList, e: MouseEvent) {\n e.stopPropagation()\n\n // Check if the click event target is a checkbox\n if ((e.target as HTMLElement).closest('input[type=\"checkbox\"]')) {\n return // Do not proceed if it's a checkbox click\n }\n\n const option = (e.target as HTMLElement)?.closest('[option]')\n if (option) {\n this.setActive(option, true)\n this.select()\n }\n }.bind(this)\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('activeIndex')) {\n this.activeIndex !== undefined && this.setActive(this.activeIndex)\n }\n\n if (changes.has('sortable')) {\n this.sortableObject && this.sortableObject.destroy()\n\n if (this.sortable) {\n this.sortableObject = Sortable.create(this, {\n handle: '[option]',\n draggable: '[option]',\n direction: 'vertical',\n animation: 150,\n touchStartThreshold: 10,\n onEnd: e => {\n this.locked = false\n this.dispatchEvent(\n new CustomEvent('sorted', {\n detail: Array.from(this.querySelectorAll('[option]'))\n })\n )\n },\n onMove: e => {\n // Check if the drag event target is a checkbox\n if ((e.dragged as HTMLElement).querySelector('input[type=\"checkbox\"]')) {\n return false // Prevent sorting if it's a checkbox drag\n }\n this.locked = true\n }\n })\n }\n }\n\n if (changes.has('searchKeyword')) {\n const attrSelected = this.attrSelected || 'selected'\n this.querySelectorAll(`[option]`).forEach(item => {\n if (!this.searchKeyword || item.textContent?.match(new RegExp(this.searchKeyword, 'i'))) {\n item.removeAttribute('hidden')\n } else {\n item.removeAttribute('selected')\n item.setAttribute('hidden', '')\n }\n })\n this.nothingToSelect = this.querySelectorAll(`[option]:not([hidden])`).length === 0\n }\n\n if (changes.has('value')) {\n const options = Array.from(this.querySelectorAll(':scope > [option]'))\n\n var values = this.value\n if (!(values instanceof Array)) {\n values = [values as string]\n }\n\n options.forEach(option => {\n if (values?.includes((option as HTMLElement).getAttribute('value') || '')) {\n option.setAttribute(this.attrSelected || 'selected', '')\n } else {\n option.removeAttribute(this.attrSelected || 'selected')\n }\n })\n }\n }\n\n /**\n * Retrieves the labels of the selected options in the popup list.\n * If multiple selections are allowed, an array of labels is returned. Otherwise, a single label is returned.\n * @returns {string|string[]} The label(s) of the selected option(s).\n */\n public getSelectedLabels(): string | string[] {\n const options = Array.from(this.querySelectorAll(':scope > [option]'))\n\n const selected = options\n .filter(option => option.hasAttribute('value') && option.hasAttribute(this.attrSelected || 'selected'))\n .map(option => option.textContent || '')\n\n return this.multiple ? selected : selected[0]\n }\n\n /**\n * Handles the selection of options in the popup list and dispatches a 'select' event with the selected value(s).\n * If multiple selections are allowed, an array of selected values is dispatched; otherwise, a single value is dispatched.\n * Also, it checks whether the selected option should remain alive and whether the popup should be closed.\n */\n async select() {\n await this.updateComplete\n\n const options = Array.from(this.querySelectorAll(':scope > [option]'))\n\n const selected = options\n .filter(option => option.hasAttribute('value') && option.hasAttribute(this.attrSelected || 'selected'))\n .map(option => option.getAttribute('value'))\n\n this.dispatchEvent(\n new CustomEvent('select', {\n bubbles: true,\n composed: true,\n detail: this.multiple ? selected : selected[0]\n })\n )\n\n const option = options[this.activeIndex!]\n if (!option.hasAttribute('alive-on-select') && !this.hasAttribute('multiple')) {\n this.close()\n }\n }\n\n /**\n * Sets the active option within the popup list based on the given index or Element.\n * If 'withSelect' is true, it also manages the selection state of the option.\n *\n * @param {number | Element | null} active - The index or Element of the option to set as active.\n * @param {boolean | undefined} withSelect - Indicates whether to manage the selection state of the option.\n */\n setActive(active: number | Element | null, withSelect?: boolean) {\n var options = Array.from(this.querySelectorAll('[option]:not([hidden])'))\n if (this.withSearch) {\n options.push(this.renderRoot.querySelector('[search]')!)\n }\n\n if (active instanceof Element) {\n const index = options.findIndex(option => option === active)\n this.setActive(index === -1 ? 0 : index, withSelect)\n return\n }\n\n const attrSelected = this.attrSelected || 'selected'\n\n options.forEach(async (option, index) => {\n if (typeof active === 'number' && index === (active + options.length) % options.length) {\n option.setAttribute('active', '')\n\n if (withSelect && !this.attrSelected) {\n /* being set attribute attrs-selected means, that element should know how to do when event happened. */\n this.multiple ? option.toggleAttribute('selected') : option.setAttribute('selected', '')\n }\n\n guaranteeFocus(option as HTMLElement)\n\n this.activeIndex = index\n } else {\n option.removeAttribute('active')\n /* even thought attribute attrs-selected set, ox-popup-list have to unset others. */\n !this.multiple && withSelect && option.removeAttribute(attrSelected)\n }\n })\n }\n\n /**\n * Overrides the 'open' method of the base class 'OxPopup' to set the initial active index\n * when the popup list is opened. It ensures that an option is initially selected for user interaction.\n *\n * @param {object} params - The parameters for opening the popup, including position and size.\n */\n override open(params: {\n left?: number\n top?: number\n right?: number\n bottom?: number\n width?: string\n height?: string\n silent?: boolean\n // fixed?: boolean\n }) {\n super.open(params)\n\n if (this.activeIndex === undefined) {\n const activeElement = this.querySelector(`[${this.attrSelected || 'selected'}]`)\n this.setActive(activeElement || 0)\n } else {\n this.setActive(this.activeIndex)\n }\n }\n\n /**\n * Overrides the 'close' method of the base class 'OxPopup' to dispatch a custom event\n * indicating that the popup list is being closed. This event can be used for further interactions\n * or logic in the application.\n */\n override close() {\n if (this.locked) {\n return\n }\n\n if (this.hasAttribute('active')) {\n this.dispatchEvent(\n new CustomEvent('close', {\n bubbles: true,\n composed: true\n })\n )\n }\n\n super.close()\n }\n\n /**\n * Open OxPopup\n *\n * @param {PopupOpenOptions}\n */\n static open({\n template,\n top,\n left,\n right,\n bottom,\n parent,\n multiple,\n sortable,\n attrSelected,\n styles,\n debug\n }: {\n template: unknown\n top?: number\n left?: number\n right?: number\n bottom?: number\n parent?: Element | null\n multiple?: boolean\n sortable?: boolean\n debug?: boolean\n attrSelected?: string\n styles?: CSSResult\n }): OxPopupList {\n const target = document.createElement('ox-popup-list') as OxPopupList\n\n if (styles) {\n const style = document.createElement('style')\n style.textContent = styles.cssText\n\n const shadow = target.attachShadow({ mode: 'open' })\n shadow.appendChild(style)\n }\n\n if (!!debug) {\n target.setAttribute('debug', '')\n }\n\n if (!!multiple) {\n target.setAttribute('multiple', '')\n }\n\n if (!!sortable) {\n target.setAttribute('sortable', '')\n }\n\n if (attrSelected) {\n target.setAttribute('attr-selected', attrSelected)\n }\n\n render(template, target)\n\n if (parent) {\n var { left, top, right, bottom } = convertToFixedPosition({\n left,\n top,\n right,\n bottom,\n relativeElement: parent as HTMLElement\n })\n }\n\n document.body.appendChild(target)\n target.removeAfterUse = true\n target.open({ top, left, right, bottom })\n\n return target\n }\n}\n"]}
|