feat(structure): adjust
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
import * as plugins from './00plugins.js';
|
||||
import * as interfaces from './interfaces/index.js';
|
||||
|
||||
import { DeesContextmenu } from './dees-contextmenu.js';
|
||||
import './dees-icon.js';
|
||||
|
||||
import {
|
||||
DeesElement,
|
||||
type TemplateResult,
|
||||
property,
|
||||
customElement,
|
||||
html,
|
||||
css,
|
||||
cssManager,
|
||||
} from '@design.estate/dees-element';
|
||||
|
||||
/**
|
||||
* the property selector menu
|
||||
* mainly used to select assets within in an organization
|
||||
*/
|
||||
@customElement('dees-appui-mainselector')
|
||||
export class DeesAppuiMainselector extends DeesElement {
|
||||
public static demo = () => html`
|
||||
<dees-appui-mainselector
|
||||
.selectionOptions=${[
|
||||
{ key: 'Overview', iconName: 'home', action: () => console.log('Overview') },
|
||||
{ key: 'Components', iconName: 'package', action: () => console.log('Components') },
|
||||
{ key: 'Services', iconName: 'server', action: () => console.log('Services') },
|
||||
{ key: 'Database', iconName: 'database', action: () => console.log('Database') },
|
||||
{ key: 'Settings', iconName: 'settings', action: () => console.log('Settings') },
|
||||
]}
|
||||
></dees-appui-mainselector>
|
||||
`;
|
||||
|
||||
// INSTANCE
|
||||
@property({ type: Array })
|
||||
accessor selectionOptions: (interfaces.ISelectionOption | { divider: true })[] = [
|
||||
{ key: '⚠️ Please set selection options', action: () => console.warn('No selection options configured for mainselector') },
|
||||
];
|
||||
|
||||
@property()
|
||||
accessor selectedOption: interfaces.ISelectionOption = null;
|
||||
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
css`
|
||||
:host {
|
||||
color: ${cssManager.bdTheme('#333', '#fff')};
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
height: 100%;
|
||||
background: ${cssManager.bdTheme('#fafafa', '#000000')};
|
||||
border-right: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')};
|
||||
}
|
||||
.maincontainer {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
position: absolute;
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')};
|
||||
}
|
||||
|
||||
.topbar .heading {
|
||||
padding-left: 12px;
|
||||
font-family: 'Geist Sans', sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
color: ${cssManager.bdTheme('#666', '#999')};
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.selectionOptions {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
overflow-y: auto;
|
||||
font-family: 'Geist Sans', sans-serif;
|
||||
font-size: 12px;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.selectionOptions .selectionOption {
|
||||
cursor: default;
|
||||
padding: 8px 12px;
|
||||
margin: 0;
|
||||
transition: background 0.1s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: ${cssManager.bdTheme('#333', '#ccc')};
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.selectionOptions .selectionOption:hover {
|
||||
background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.04)', 'rgba(255, 255, 255, 0.08)')};
|
||||
}
|
||||
|
||||
.selectionOptions .selectionOption:active {
|
||||
background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.08)', 'rgba(255, 255, 255, 0.12)')};
|
||||
}
|
||||
|
||||
.selectionOptions .selectionOption.selectedOption {
|
||||
background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.08)', 'rgba(255, 255, 255, 0.12)')};
|
||||
color: ${cssManager.bdTheme('#000', '#fff')};
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.selectionOptions .selectionOption.selectedOption::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 3px;
|
||||
background: ${cssManager.bdTheme('#26a69a', '#26a69a')};
|
||||
}
|
||||
|
||||
.selectionOption {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.selection-divider {
|
||||
height: 1px;
|
||||
background: ${cssManager.bdTheme('#e0e0e0', '#202020')};
|
||||
margin: 4px 0;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`
|
||||
<style></style>
|
||||
<div class="maincontainer">
|
||||
<div class="topbar">
|
||||
<div class="heading">Selector</div>
|
||||
</div>
|
||||
<div class="selectionOptions">
|
||||
${this.selectionOptions.map((selectionOptionArg) => {
|
||||
if ('divider' in selectionOptionArg && selectionOptionArg.divider) {
|
||||
return html`<div class="selection-divider"></div>`;
|
||||
}
|
||||
|
||||
const option = selectionOptionArg as interfaces.ISelectionOption;
|
||||
return html`
|
||||
<div
|
||||
class="selectionOption ${this.selectedOption === option
|
||||
? 'selectedOption'
|
||||
: null}"
|
||||
@click="${() => {
|
||||
this.selectOption(option);
|
||||
}}"
|
||||
@contextmenu="${(eventArg: MouseEvent) => {
|
||||
DeesContextmenu.openContextMenuWithOptions(eventArg, [
|
||||
{
|
||||
name: 'property settings',
|
||||
action: async () => {},
|
||||
iconName: 'gear',
|
||||
},
|
||||
]);
|
||||
}}"
|
||||
>
|
||||
${option.iconName ? html`
|
||||
<dees-icon .icon="${`lucide:${option.iconName}`}" style="font-size: 14px; opacity: 0.7;"></dees-icon>
|
||||
` : ''}
|
||||
<span style="flex: 1;">${option.key}</span>
|
||||
</div>
|
||||
`;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private selectOption(optionArg: interfaces.ISelectionOption) {
|
||||
this.selectedOption = optionArg;
|
||||
this.selectedOption.action();
|
||||
|
||||
// Emit option-select event
|
||||
this.dispatchEvent(new CustomEvent('option-select', {
|
||||
detail: { option: optionArg },
|
||||
bubbles: true,
|
||||
composed: true
|
||||
}));
|
||||
}
|
||||
|
||||
async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) {
|
||||
await super.firstUpdated(_changedProperties);
|
||||
if (this.selectionOptions && this.selectionOptions.length > 0) {
|
||||
await this.updateComplete;
|
||||
// Find first non-divider option
|
||||
const firstOption = this.selectionOptions.find(option => !('divider' in option)) as interfaces.ISelectionOption;
|
||||
if (firstOption) {
|
||||
this.selectOption(firstOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user