@proximus/lavender-dropdown 1.0.0-alpha.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/dist/Dropdown.d.ts +32 -0
- package/dist/anchorPolyfill.d.ts +2 -0
- package/dist/common.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +139 -0
- package/package.json +22 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { WithExtraAttributes } from '@proximus/lavender-common';
|
|
2
|
+
import { type AnchorAlignment } from './common.ts';
|
|
3
|
+
export declare class Dropdown extends WithExtraAttributes {
|
|
4
|
+
private template;
|
|
5
|
+
/**
|
|
6
|
+
* Instance level styling for the dropdown component.
|
|
7
|
+
* This is used to set the anchor name and position of the popover.
|
|
8
|
+
* @private
|
|
9
|
+
*/
|
|
10
|
+
private get css();
|
|
11
|
+
static get observedAttributes(): string[];
|
|
12
|
+
constructor();
|
|
13
|
+
connectedCallback(): void;
|
|
14
|
+
private isAboutToClose;
|
|
15
|
+
/**
|
|
16
|
+
* Handles the manual display of the popover when the trigger is clicked.
|
|
17
|
+
* This is necessary for cases where the trigger is not a button or input element.
|
|
18
|
+
* This method adds event listeners to the trigger element to toggle the popover.
|
|
19
|
+
* It also manages the state of whether the popover is about to close or not to avoid
|
|
20
|
+
* race conditions when the popover is toggled and the trigger click event is fired.
|
|
21
|
+
*/
|
|
22
|
+
handleManualPopoverDisplay(): void;
|
|
23
|
+
attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
|
|
24
|
+
private initPopover;
|
|
25
|
+
private get popoverId();
|
|
26
|
+
private get anchorName();
|
|
27
|
+
private get $style();
|
|
28
|
+
get $trigger(): HTMLElement;
|
|
29
|
+
get $popoverElement(): HTMLElement;
|
|
30
|
+
get anchorAlignment(): AnchorAlignment;
|
|
31
|
+
set anchorAlignment(value: AnchorAlignment);
|
|
32
|
+
}
|
package/dist/common.d.ts
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Dropdown.ts';
|
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { WithExtraAttributes as c } from "@proximus/lavender-common";
|
|
2
|
+
const m = ':host{position:relative}::slotted([slot="popover"]){position:absolute;border-radius:var(--px-radius-main, 8px);background:var(--px-color-background-container-light-default, #fff);box-shadow:0 20px 25px -5px #25252514;margin:0;padding:var(--px-padding-xs-mobile) 0;border:0;right:0;width:auto}:host([grow]) ::slotted([slot="trigger"]):after{right:0;padding-right:var(--px-padding-xs-mobile)}:host([anchoralignment="top-left"]) ::slotted([slot="popover"]){top:auto}:host([anchoralignment="top-right"]) ::slotted([slot="popover"]){top:auto}:host([anchoralignment="bottom-right"]) ::slotted([slot="popover"]){left:auto}@media screen and (max-width: 767px){::slotted([slot="trigger"]){display:block;width:100%}:host([anchoralignment="top-left"]) ::slotted([slot="popover"]){left:var(--px-padding-s-mobile)}:host([anchoralignment="top-right"]) ::slotted([slot="popover"]){left:var(--px-padding-s-mobile)}}@media screen and (min-width: 768px){::slotted([slot="popover"]){padding-block:var(--px-padding-s-desktop);right:auto;width:auto}}', u = [
|
|
3
|
+
"top-left",
|
|
4
|
+
"top-right",
|
|
5
|
+
"bottom-left",
|
|
6
|
+
"bottom-right"
|
|
7
|
+
];
|
|
8
|
+
function b(a, t, e = "bottom-left", r) {
|
|
9
|
+
"anchorName" in document.documentElement.style || t.addEventListener("toggle", () => {
|
|
10
|
+
var l, h;
|
|
11
|
+
if (!a || !t)
|
|
12
|
+
return;
|
|
13
|
+
const o = a.getBoundingClientRect(), g = ((l = window.visualViewport) == null ? void 0 : l.height) ?? window.innerHeight, i = ((h = window.visualViewport) == null ? void 0 : h.width) ?? window.innerWidth, s = r.getPropertyValue("--px-padding-s-mobile") || "16px", d = parseInt(
|
|
14
|
+
(r.getPropertyValue("--px-icon-size-xs-desktop") || "24").replace("px", "")
|
|
15
|
+
);
|
|
16
|
+
["top-left", "top-right"].includes(e) ? (t.style.bottom = `calc( ${s} + ${g - o.top - window.scrollY}px)`, t.style.top = "auto", e === "top-left" ? t.style.left = i < 768 ? `${s}px` : `${o.left}px` : t.style.right = i < 768 ? `${s}px` : `${i - o.right}px`) : (t.style.top = `${o.bottom + window.scrollY}px`, e === "bottom-left" ? t.style.left = i < 768 ? `${s}px` : `${o.left}px` : t.style.right = i < 768 ? `${s}px` : `${i - o.right - d}px`);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
const p = new CSSStyleSheet();
|
|
20
|
+
p.replaceSync(m);
|
|
21
|
+
const n = "bottom-left";
|
|
22
|
+
class f extends c {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(p), this.template = () => `
|
|
25
|
+
<style>${this.css}</style>
|
|
26
|
+
<slot name="trigger"></slot>
|
|
27
|
+
<slot name="popover"></slot>`, this.isAboutToClose = !1, this.shadowRoot.innerHTML = this.template();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Instance level styling for the dropdown component.
|
|
31
|
+
* This is used to set the anchor name and position of the popover.
|
|
32
|
+
* @private
|
|
33
|
+
*/
|
|
34
|
+
get css() {
|
|
35
|
+
return `::slotted([slot='trigger']) {
|
|
36
|
+
anchor-name: ${this.anchorName};
|
|
37
|
+
}
|
|
38
|
+
:host([anchoralignment="bottom-left"]) {
|
|
39
|
+
::slotted([slot="popover"]) {
|
|
40
|
+
position-anchor: ${this.anchorName};
|
|
41
|
+
top: anchor(${this.anchorName} bottom);
|
|
42
|
+
left: anchor(${this.anchorName} left);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
:host([anchoralignment="bottom-right"]) {
|
|
46
|
+
::slotted([slot="popover"]) {
|
|
47
|
+
position-anchor: ${this.anchorName};
|
|
48
|
+
top: anchor(${this.anchorName} bottom);
|
|
49
|
+
right: calc(anchor(${this.anchorName} right) - var(--px-size-icon-xs));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
:host([anchoralignment="top-left"]) {
|
|
53
|
+
::slotted([slot="popover"]) {
|
|
54
|
+
position-anchor: ${this.anchorName};
|
|
55
|
+
bottom: calc( var(--px-padding-s-mobile) + anchor(${this.anchorName} top));
|
|
56
|
+
left: anchor(${this.anchorName} left);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
:host([anchoralignment="top-right"]) {
|
|
60
|
+
::slotted([slot="popover"]) {
|
|
61
|
+
position-anchor: ${this.anchorName};
|
|
62
|
+
bottom: calc( var(--px-padding-s-mobile) + anchor(${this.anchorName} top));
|
|
63
|
+
right: anchor(${this.anchorName} right);
|
|
64
|
+
}
|
|
65
|
+
}`;
|
|
66
|
+
}
|
|
67
|
+
static get observedAttributes() {
|
|
68
|
+
return [...super.observedAttributes, "id", "anchoralignment"];
|
|
69
|
+
}
|
|
70
|
+
connectedCallback() {
|
|
71
|
+
this.getAttribute("id") || this.setAttribute(
|
|
72
|
+
"id",
|
|
73
|
+
`px-dropdown-${Math.random().toString(36).substring(2, 15)}`
|
|
74
|
+
), this.getAttribute("anchoralignment") || this.setAttribute("anchoralignment", n), b(
|
|
75
|
+
this.$trigger,
|
|
76
|
+
this.$popoverElement,
|
|
77
|
+
this.anchorAlignment,
|
|
78
|
+
getComputedStyle(this)
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Handles the manual display of the popover when the trigger is clicked.
|
|
83
|
+
* This is necessary for cases where the trigger is not a button or input element.
|
|
84
|
+
* This method adds event listeners to the trigger element to toggle the popover.
|
|
85
|
+
* It also manages the state of whether the popover is about to close or not to avoid
|
|
86
|
+
* race conditions when the popover is toggled and the trigger click event is fired.
|
|
87
|
+
*/
|
|
88
|
+
handleManualPopoverDisplay() {
|
|
89
|
+
this.$trigger && !["button", "input"].includes(this.$trigger.localName) && (this.$trigger.addEventListener("click", () => {
|
|
90
|
+
this.isAboutToClose || (this.$popoverElement.togglePopover({ source: this.$trigger }), this.$trigger.ariaExpanded = "true");
|
|
91
|
+
}), this.$popoverElement.addEventListener("beforetoggle", () => {
|
|
92
|
+
this.$popoverElement.matches(":popover-open") && (this.isAboutToClose = !0, this.$trigger.ariaExpanded = "false");
|
|
93
|
+
}), this.$popoverElement.addEventListener("toggle", () => {
|
|
94
|
+
this.$popoverElement.matches(":popover-open") || setTimeout(() => {
|
|
95
|
+
this.isAboutToClose = !1;
|
|
96
|
+
});
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
attributeChangedCallback(t, e, r) {
|
|
100
|
+
switch (t) {
|
|
101
|
+
case "id":
|
|
102
|
+
e !== r && this.initPopover();
|
|
103
|
+
break;
|
|
104
|
+
default:
|
|
105
|
+
super.attributeChangedCallback(t, e, r);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
initPopover() {
|
|
110
|
+
this.$trigger && (this.$trigger.setAttribute("popovertarget", this.popoverId), this.$trigger.setAttribute("aria-controls", this.popoverId), this.$trigger.setAttribute("aria-expanded", "false"), this.$popoverElement.setAttribute("id", this.popoverId), this.$popoverElement.setAttribute("popover", ""), this.$style.innerHTML = this.css, this.handleManualPopoverDisplay());
|
|
111
|
+
}
|
|
112
|
+
get popoverId() {
|
|
113
|
+
return `${this.getAttribute("id")}-popover`;
|
|
114
|
+
}
|
|
115
|
+
get anchorName() {
|
|
116
|
+
return `--${this.getAttribute("id")}-anchor`;
|
|
117
|
+
}
|
|
118
|
+
get $style() {
|
|
119
|
+
return this.shadowRoot.querySelector("style");
|
|
120
|
+
}
|
|
121
|
+
get $trigger() {
|
|
122
|
+
return this.querySelector('[slot="trigger"]');
|
|
123
|
+
}
|
|
124
|
+
get $popoverElement() {
|
|
125
|
+
return this.querySelector('[slot="popover"]');
|
|
126
|
+
}
|
|
127
|
+
get anchorAlignment() {
|
|
128
|
+
return this.getAttribute("anchoralignment") || n;
|
|
129
|
+
}
|
|
130
|
+
set anchorAlignment(t) {
|
|
131
|
+
u.includes(t) ? this.setAttribute("anchoralignment", t) : (console.warn(
|
|
132
|
+
`Invalid anchor alignment value: ${t}. Using default ${n}.`
|
|
133
|
+
), this.setAttribute("anchoralignment", n));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
customElements.get("px-dropdown") || customElements.define("px-dropdown", f);
|
|
137
|
+
export {
|
|
138
|
+
f as Dropdown
|
|
139
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@proximus/lavender-dropdown",
|
|
3
|
+
"version": "1.0.0-alpha.10",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.es.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"type": "module",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"transform-package-json": "node ../../../scripts/tranformPackageJson.js package.json dist/far/away",
|
|
12
|
+
"clean": "rm -rf dist",
|
|
13
|
+
"build": "npm run clean && NODE_ENV=development vite build && tsc && npm run transform-package-json && npm run wc-manifest",
|
|
14
|
+
"test": "vitest run --coverage",
|
|
15
|
+
"wc-manifest": "cem analyze --globs \"src/*\" --config ../custom-elements-manifest.config.js --outdir dist"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"customElements": "dist/custom-elements.json",
|
|
21
|
+
"web-types": "./dist/web-types.json"
|
|
22
|
+
}
|