158 lines
3.5 KiB
TypeScript
158 lines
3.5 KiB
TypeScript
import {
|
|
customElement,
|
|
DeesElement,
|
|
type TemplateResult,
|
|
html,
|
|
property,
|
|
css,
|
|
cssManager,
|
|
} from '@design.estate/dees-element';
|
|
import { DeesIcon } from '@design.estate/dees-catalog';
|
|
|
|
// Ensure icon component is registered
|
|
DeesIcon;
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
'eco-view-home': EcoViewHome;
|
|
}
|
|
}
|
|
|
|
export interface IAppIcon {
|
|
name: string;
|
|
icon: string;
|
|
action?: () => void;
|
|
view?: TemplateResult;
|
|
}
|
|
|
|
@customElement('eco-view-home')
|
|
export class EcoViewHome extends DeesElement {
|
|
public static styles = [
|
|
cssManager.defaultStyles,
|
|
css`
|
|
:host {
|
|
display: block;
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.apps-area {
|
|
padding: 48px;
|
|
min-height: 100%;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.apps-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
|
gap: 32px;
|
|
width: 100%;
|
|
}
|
|
|
|
.app-icon {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 16px;
|
|
border-radius: 16px;
|
|
cursor: pointer;
|
|
transition: background 0.2s ease, transform 0.15s ease;
|
|
user-select: none;
|
|
-webkit-tap-highlight-color: transparent;
|
|
}
|
|
|
|
.app-icon:hover {
|
|
background: ${cssManager.bdTheme('hsl(220 15% 92%)', 'hsl(240 5% 12%)')};
|
|
}
|
|
|
|
.app-icon:active {
|
|
transform: scale(0.95);
|
|
background: ${cssManager.bdTheme('hsl(220 15% 88%)', 'hsl(240 5% 16%)')};
|
|
}
|
|
|
|
.app-icon-circle {
|
|
width: 64px;
|
|
height: 64px;
|
|
border-radius: 16px;
|
|
background: ${cssManager.bdTheme('hsl(220 15% 90%)', 'hsl(240 5% 15%)')};
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: ${cssManager.bdTheme('hsl(0 0% 40%)', 'hsl(0 0% 80%)')};
|
|
}
|
|
|
|
.app-icon-circle dees-icon {
|
|
--dees-icon-size: 28px;
|
|
}
|
|
|
|
.app-icon-name {
|
|
font-size: 13px;
|
|
font-weight: 500;
|
|
color: ${cssManager.bdTheme('hsl(0 0% 25%)', 'hsl(0 0% 85%)')};
|
|
text-align: center;
|
|
max-width: 90px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
@media (max-width: 600px) {
|
|
.apps-area {
|
|
padding: 24px;
|
|
}
|
|
|
|
.apps-grid {
|
|
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
|
|
gap: 16px;
|
|
}
|
|
|
|
.app-icon-circle {
|
|
width: 56px;
|
|
height: 56px;
|
|
font-size: 24px;
|
|
}
|
|
|
|
.app-icon-name {
|
|
font-size: 12px;
|
|
}
|
|
}
|
|
`,
|
|
];
|
|
|
|
@property({ type: Array })
|
|
accessor apps: IAppIcon[] = [];
|
|
|
|
public render(): TemplateResult {
|
|
return html`
|
|
<div class="apps-area">
|
|
<div class="apps-grid">
|
|
${this.apps.map((app) => this.renderAppIcon(app))}
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
private renderAppIcon(app: IAppIcon): TemplateResult {
|
|
return html`
|
|
<div class="app-icon" @click=${() => this.handleAppClick(app)}>
|
|
<div class="app-icon-circle">
|
|
<dees-icon .icon=${app.icon} .iconSize=${28}></dees-icon>
|
|
</div>
|
|
<span class="app-icon-name">${app.name}</span>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
private handleAppClick(app: IAppIcon): void {
|
|
this.dispatchEvent(
|
|
new CustomEvent('app-click', {
|
|
detail: { app },
|
|
bubbles: true,
|
|
composed: true,
|
|
})
|
|
);
|
|
}
|
|
}
|