Skip to content

Commit 02f2e83

Browse files
committed
Refactor menuBar.js into something modular
Closer to one .js file per component
1 parent 811cd62 commit 02f2e83

File tree

5 files changed

+471
-455
lines changed

5 files changed

+471
-455
lines changed

cozy-viz/components/menu.js

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { html } from 'https://unpkg.com/htm/preact/index.module.js?module'
2+
import { Component, createRef } from 'https://unpkg.com/preact@latest?module'
3+
import { computePosition } from 'https://cdn.jsdelivr.net/npm/@floating-ui/[email protected]/+esm';
4+
5+
// this should be mounted and unmounted rather than toggled; adding and removing
6+
// the event-listener for closing the menu should be part of the mount/unmount
7+
// lifecycle
8+
export default class Menu extends Component {
9+
constructor() {
10+
super()
11+
this.button = createRef()
12+
this.options = createRef()
13+
}
14+
15+
static Option = class extends Component {
16+
render(props) {
17+
return html`<div class="option"
18+
data-selected=${props.selected}
19+
data-disabled=${props.disabled}
20+
onClick=${props.disabled ? null : props.onClick}>
21+
${props.children}
22+
</div>`
23+
}
24+
}
25+
26+
componentDidUpdate() {
27+
if (this.props.open == this.props.title) {
28+
computePosition(this.button.current, this.options.current, {
29+
placement: "bottom-start"
30+
}).then(({ x, y }) => {
31+
this.options.current.style.left = `${x}px`
32+
this.options.current.style.top = `${y}px`
33+
})
34+
}
35+
}
36+
37+
toggleOpen() {
38+
if (!this.props.enabled) return
39+
if (this.props.open != this.props.title) {
40+
this.props.setOpen(this.props.title)
41+
} else {
42+
this.props.setOpen(null)
43+
}
44+
}
45+
46+
render(props) {
47+
const optionStyle = {
48+
position: "absolute",
49+
display: "block",
50+
backgroundColor: "#e1e1e1"
51+
}
52+
const menuStyle = {
53+
color: props.enabled ? "black" : "#ccc",
54+
backgroundColor: props.open === props.title
55+
? "#e1e1e1"
56+
: "white"
57+
}
58+
return html`
59+
<button
60+
style=${menuStyle}
61+
ref=${this.button}
62+
onClick=${() => this.toggleOpen()}
63+
onMouseEnter=${() => props.open && this.props.enabled && props.setOpen(props.title)}>
64+
${props.title}
65+
</button>
66+
${props.open == props.title && html`
67+
<div style=${optionStyle} ref=${this.options} class="options-wrapper">
68+
${props.children}
69+
</div>`
70+
}`
71+
}
72+
}
73+

0 commit comments

Comments
 (0)