feat(sdk,client): add menu to help navigation between apps
All checks were successful
arcad/edge/pipeline/head This commit looks good
All checks were successful
arcad/edge/pipeline/head This commit looks good
This commit is contained in:
130
pkg/sdk/client/src/components/menu-item.ts
Normal file
130
pkg/sdk/client/src/components/menu-item.ts
Normal file
@ -0,0 +1,130 @@
|
||||
import { LitElement, html, css } from 'lit';
|
||||
import { property, state } from 'lit/decorators.js';
|
||||
|
||||
export const EVENT_MENU_ITEM_SELECTED = 'menu-item-selected';
|
||||
export const EVENT_MENU_ITEM_UNSELECTED = 'menu-item-unselected';
|
||||
|
||||
export class MenuItem extends LitElement {
|
||||
@property({ attribute: 'icon-url', type: String })
|
||||
iconUrl: string;
|
||||
|
||||
@property({ attribute: 'label', type: String })
|
||||
label: string;
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-bottom: 1px solid rgb(229,231,235);
|
||||
border-top: 10px solid transparent;
|
||||
transition: all 100ms ease-out;
|
||||
background-color: #fff;
|
||||
}
|
||||
:host(:hover) {
|
||||
background-color: rgb(249,250,251);
|
||||
}
|
||||
:host(.selected) {
|
||||
border-top: 10px solid #03A9F4;
|
||||
border-bottom: 1px solid transparent;
|
||||
background-color: #fff;
|
||||
}
|
||||
:host(.unselected) {
|
||||
background-color: hsl(210 20% 95% / 1);
|
||||
}
|
||||
.menu-item-icon {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.menu-item-icon > img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.menu-item-panel {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 65px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 9999;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 4px 5px 0px hsl(0deg 0% 0% / 10%);
|
||||
max-height: 75%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
:host(.selected) .menu-item-panel {
|
||||
display: block;
|
||||
}
|
||||
.menu-item-label {
|
||||
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
|
||||
color: black;
|
||||
font-size: 14px;
|
||||
margin: 3px 0;
|
||||
}
|
||||
`;
|
||||
|
||||
@state()
|
||||
selected: boolean
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener('click', this._handleClick.bind(this));
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="menu-item-icon">
|
||||
${
|
||||
this.iconUrl ?
|
||||
html`<img src="${this.iconUrl}" />` :
|
||||
''
|
||||
}
|
||||
</div>
|
||||
<div class="menu-item-label">
|
||||
${this.label}
|
||||
</div>
|
||||
<div class="menu-item-panel">
|
||||
<slot></slot>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
_handleClick() {
|
||||
if (this.selected) {
|
||||
this.unselect();
|
||||
} else {
|
||||
this.select();
|
||||
}
|
||||
}
|
||||
|
||||
select() {
|
||||
this.selected = true;
|
||||
const event = new CustomEvent(EVENT_MENU_ITEM_SELECTED, {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: {
|
||||
element: this,
|
||||
}
|
||||
});
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
unselect() {
|
||||
this.selected = false;
|
||||
const event = new CustomEvent(EVENT_MENU_ITEM_UNSELECTED, {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: {
|
||||
element: this,
|
||||
}
|
||||
});
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user