Skip to content

Commit 33ef6d2

Browse files
committed
Update select with overlayMenu
1 parent 1ef9167 commit 33ef6d2

File tree

6 files changed

+61
-55
lines changed

6 files changed

+61
-55
lines changed

src/pg/inputSelect/__examples__/basic/basic.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ export default class XPgInputSelectBasic extends HTMLElement {
1919
{ label: 'Option 3', value: 'option3' },
2020
{ label: 'Option 4', value: 'option4' }
2121
);
22-
this.$input.value = this.$input.options[1].value;
23-
this.$input.addEventListener('change', this.handleChange.bind(this));
22+
//this.$input.value = this.$input.options[1].value;
23+
this.$input.addEventListener('change', this.#handleChange.bind(this));
2424
}
2525

26-
handleChange(e) {
26+
#handleChange(e) {
2727
const { value } = e.detail;
28+
this.$input.value = value;
2829
this.$value.innerText = `${value}`;
2930
}
3031
}

src/pg/inputSelect/inputSelect.css

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,32 @@
11
:host {
2-
display: block;
3-
font-family: var(--pg-font-family);
2+
display: contents;
43
}
54

6-
[part="wrapper"] {
5+
[part=button] {
6+
font-family: var(--pg-font-family);
7+
text-align: left;
78
display: grid;
89
grid-template-rows: auto;
910
grid-template-columns: 100% 0;
10-
}
11-
12-
[part="select"] {
13-
grid-row: 1;
14-
grid-column: 1;
1511
border: 1px solid var(--pg-input-select-border-color, #453C4F);
1612
border-radius: 0.25rem;
17-
padding: 0.5rem 0.75rem;
13+
padding: 0;
1814
width: 100%;
1915
font-size: 1rem;
2016
outline: 0;
21-
-webkit-appearance: none;
2217
}
2318

24-
[part="select"]:focus {
19+
[part=button]:focus {
2520
box-shadow: 0 0 0 3px rgba(79, 143, 249, 0.5);
2621
}
2722

28-
[part="chevron"] {
23+
[part=label] {
24+
grid-row: 1;
25+
grid-column: 1;
26+
padding: 0.5rem 0.75rem;
27+
}
28+
29+
[part=chevron] {
2930
grid-row: 1;
3031
grid-column: 2;
3132
pointer-events: none;
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div part="wrapper">
2-
<button part="select"></button>
1+
<button part="button">
2+
<span part="label"></span>
33
<svg part="chevron" viewBox="0 0 24 24"><path d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" /></svg>
4-
</div>
4+
</button>

src/pg/inputSelect/inputSelect.ts

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Component, Prop, Part, forEach } from '@pictogrammers/element';
2+
import PgOverlayMenu from '../overlayMenu/overlayMenu';
23

34
import template from './inputSelect.html';
45
import style from './inputSelect.css';
@@ -18,49 +19,36 @@ export default class PgInputSelect extends HTMLElement {
1819
@Prop() value: string = '';
1920
@Prop() name: string = '';
2021

21-
@Part() $select: HTMLSelectElement;
22+
@Part() $button: HTMLButtonElement;
23+
@Part() $label: HTMLSpanElement;
2224

23-
//cacheKeys: string[] = [];
25+
connectedCallback() {
26+
this.$button.addEventListener('click', this.#handleClick.bind(this));
27+
}
2428

2529
render(changes) {
26-
/*if (changes.options) {
27-
this.options.forEach((o) => {
28-
const option = document.createElement('option');
29-
option.textContent = o.label;
30-
option.value = o.value;
31-
this.$select.appendChild(option);
32-
});
33-
if (this.$select.value !== this.value) {
34-
this.$select.value = this.value;
35-
}
36-
}*/
3730
if (changes.value) {
38-
if (this.$select.value !== this.value) {
39-
this.$select.value = this.value;
40-
}
31+
this.$label.textContent = this.value ? this.value : '\u00A0';
4132
}
4233
}
4334

44-
connectedCallback() {
45-
forEach({
46-
container: this.$select,
47-
items: this.options,
48-
type: () => {
49-
return HTMLOptionElement;
50-
}
51-
})
52-
this.$select.addEventListener('change', this.handleSelect.bind(this));
53-
}
54-
55-
handleSelect(e) {
56-
const { value } = e.target;
57-
this.dispatchEvent(
58-
new CustomEvent('change', {
35+
#menuOpen = false;
36+
async #handleClick() {
37+
if (this.#menuOpen) { return; }
38+
this.#menuOpen = true;
39+
const result = await PgOverlayMenu.open({
40+
source: this.$button,
41+
value: this.options.find(x => x.value === this.value) ?? null,
42+
items: this.options
43+
});
44+
if (result !== undefined) {
45+
this.dispatchEvent(new CustomEvent('change', {
5946
detail: {
60-
value,
61-
name: this.name
47+
value: result.value
6248
}
63-
})
64-
)
49+
}));
50+
this.$label.textContent = result.label;
51+
}
52+
this.#menuOpen = false;
6553
}
6654
}

src/pg/menu/menu.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default class PgMenu extends HTMLElement {
4545
* @param startIndex Start index.
4646
* @param endIndex End index.
4747
*/
48-
getItemHeight(startIndex, endIndex): number {
48+
getItemOffset(startIndex, endIndex): number {
4949
const computedStyle = getComputedStyle(this.$items);
5050
let height = parseInt(computedStyle.getPropertyValue('padding-top'), 10);
5151
const total = this.$items.children.length;
@@ -59,4 +59,9 @@ export default class PgMenu extends HTMLElement {
5959
return height;
6060
}
6161

62+
getItemHeight(index) {
63+
const ele = this.$items.children[index] as any;
64+
return ele.getHeight();
65+
}
66+
6267
}

src/pg/overlayMenu/overlayMenu.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export default class PgOverlayMenu extends PgOverlay {
3737
// Position (replace with css once Firefox supports it)
3838
const rect = this.source?.getBoundingClientRect();
3939
let x = rect?.left ?? 0, y = rect?.top ?? 0;
40+
this.$overlay.style.minWidth = `${rect?.width}px`;
4041
const value = this.value === null || typeof this.value !== 'object'
4142
? this.value
4243
: this.value.value;
@@ -45,8 +46,18 @@ export default class PgOverlayMenu extends PgOverlay {
4546
? -1
4647
: this.items.findIndex(x => x.value === value);
4748
if (index !== -1) {
49+
const height = this.$menu.getItemHeight(index);
4850
// Overlap item
49-
y -= this.$menu.getItemHeight(0, index);
51+
y -= this.$menu.getItemOffset(0, index);
52+
if (rect?.height !== height && rect?.height) {
53+
y += (rect.height - height) / 2;
54+
}
55+
} else if (this.items.length > 0) {
56+
const height = this.$menu.getItemHeight(0);
57+
y -= this.$menu.getItemOffset(0, 0);
58+
if (rect?.height !== height && rect?.height) {
59+
y += (rect.height - height) / 2;
60+
}
5061
}
5162
this.$overlay.style.translate = `${x}px ${y}px`;
5263
// Focus

0 commit comments

Comments
 (0)