dees-catalog/ts_web/elements/dees-contextmenu.ts

181 lines
4.4 KiB
TypeScript
Raw Normal View History

2023-01-12 18:19:31 +00:00
import * as plugins from './plugins.js';
2023-01-12 17:14:59 +00:00
import {
customElement,
html,
DeesElement,
property,
TemplateResult,
cssManager,
css,
unsafeCSS,
} from '@designestate/dees-element';
import * as domtools from '@designestate/dees-domtools';
2023-01-12 23:30:56 +00:00
import { DeesWindowLayer } from './dees-windowlayer.js';
2023-01-12 17:14:59 +00:00
declare global {
interface HTMLElementTagNameMap {
'dees-contextmenu': DeesContextmenu;
}
}
@customElement('dees-contextmenu')
export class DeesContextmenu extends DeesElement {
2023-01-12 23:30:56 +00:00
// DEMO
2023-01-12 17:14:59 +00:00
public static demo = () => html`
2023-01-12 23:30:56 +00:00
<style>
.withMargin {
display: block;
margin: 20px;
2023-01-12 18:19:31 +00:00
}
2023-01-12 23:30:56 +00:00
</style>
2023-01-13 01:15:30 +00:00
<dees-button @contextmenu=${(eventArg) => {
DeesContextmenu.openContextMenuWithOptions(eventArg, [
{
name: 'copy',
iconName: 'copySolid',
action: async () => {
return null;
},
},
{
name: 'edit',
iconName: 'penToSquare',
action: async () => {
return null;
},
},{
name: 'paste',
iconName: 'pasteSolid',
action: async () => {
return null;
},
},
]);
2023-01-12 23:30:56 +00:00
}}>Hello</dees-button>
<dees-contextmenu class="withMargin"></dees-contextmenu>
<dees-contextmenu
class="withMargin"
.menuItems=${[
{
name: 'copy',
iconName: 'copySolid',
action: async () => {},
},
{
name: 'edit',
iconName: 'penToSquare',
action: async () => {},
},{
name: 'paste',
iconName: 'pasteSolid',
action: async () => {},
},
] as plugins.tsclass.website.IMenuItem[]}
></dees-contextmenu>
2023-01-12 17:14:59 +00:00
`;
2023-01-12 23:30:56 +00:00
// STATIC
2023-01-13 01:15:30 +00:00
public static async openContextMenuWithOptions(eventArg: MouseEvent, menuItemsArg: plugins.tsclass.website.IMenuItem[]) {
eventArg.preventDefault();
2023-01-12 23:30:56 +00:00
const contextMenu = new DeesContextmenu();
contextMenu.style.position = 'absolute';
2023-01-13 01:15:30 +00:00
contextMenu.style.top = `${eventArg.clientY.toString()}px`;
contextMenu.style.left = `${eventArg.clientX.toString()}px`;
contextMenu.style.opacity = '0';
contextMenu.style.transform = 'scale(0.95,0.95)';
contextMenu.style.transformOrigin = 'top left';
contextMenu.menuItems = menuItemsArg;
document.body.append(contextMenu);
await domtools.plugins.smartdelay.delayFor(0);
contextMenu.style.opacity = '1';
contextMenu.style.transform = 'scale(1,1)';
2023-01-12 23:30:56 +00:00
}
@property({
type: Array,
})
public menuItems: plugins.tsclass.website.IMenuItem[] = [];
2023-01-12 17:14:59 +00:00
constructor() {
super();
}
public static styles = [
cssManager.defaultStyles,
css`
:host {
display: block;
2023-01-13 01:15:30 +00:00
transition: all 0.1s;
2023-01-12 17:14:59 +00:00
}
.mainbox {
2023-01-12 23:30:56 +00:00
color: ${cssManager.bdTheme('#222', '#ccc')};
font-size: 14px;
width: 200px;
border: 1px solid #444;
min-height: 40px;
border-radius: 3px;
background: #222;
box-shadow: 0px 1px 4px #000;
user-select: none;
}
.mainbox .menuitem {
padding: 8px;
}
.mainbox .menuitem dees-icon {
display: inline-block;
margin-right: 8px;
width: 14px;
transform: translateY(2px);
2023-01-12 17:14:59 +00:00
}
2023-01-12 23:30:56 +00:00
.mainbox .menuitem:hover {
cursor: pointer;
background: #ffffff10;
}
.mainbox .menuitem:active {
cursor: pointer;
background: #ffffff05;
}
2023-01-12 17:14:59 +00:00
`,
];
public render(): TemplateResult {
return html`
<div class="mainbox">
2023-01-12 23:30:56 +00:00
${this.menuItems.map((menuItemArg) => {
return html`
2023-01-13 01:15:30 +00:00
<div class="menuitem" @click=${() => this.handleClick(menuItemArg)}>
2023-01-12 23:30:56 +00:00
<dees-icon .iconFA=${(menuItemArg.iconName as any) || 'minus'}></dees-icon
>${menuItemArg.name}
</div>
`;
})}
2023-01-12 17:14:59 +00:00
</div>
`;
}
public async firstUpdated() {
2023-01-12 23:30:56 +00:00
if (!this.menuItems || this.menuItems.length === 0) {
const mainbox = this.shadowRoot.querySelector('.mainbox');
mainbox.textContent = 'no menu items present';
2023-01-12 17:14:59 +00:00
}
}
2023-01-13 01:15:30 +00:00
public async handleClick(menuItem: plugins.tsclass.website.IMenuItem) {
menuItem.action();
await this.destroy();
}
public async destroy() {
this.style.opacity = '0';
this.style.transform = 'scale(0.95,0,95)';
await domtools.plugins.smartdelay.delayFor(100);
this.parentElement.removeChild(this);
}
2023-01-12 17:14:59 +00:00
}