Files
dees-catalog-mobile/ts_web/pages/component-showcase.ts

203 lines
6.2 KiB
TypeScript
Raw Normal View History

2025-12-22 10:53:15 +00:00
import { html, css, DeesElement, customElement, state } from '@design.estate/dees-element';
// Import all components
import '../elements/index.js';
// Import demo functions
import { demoFunc as buttonDemo } from '../elements/00group-ui/dees-mobile-button/dees-mobile-button.demo.js';
import { demoFunc as iconDemo } from '../elements/00group-ui/dees-mobile-icon/dees-mobile-icon.demo.js';
import { demoFunc as headerDemo } from '../elements/00group-ui/dees-mobile-header/dees-mobile-header.demo.js';
import { demoFunc as modalDemo } from '../elements/00group-ui/dees-mobile-modal/dees-mobile-modal.demo.js';
import { demoFunc as actionsheetDemo } from '../elements/00group-ui/dees-mobile-actionsheet/dees-mobile-actionsheet.demo.js';
import { demoFunc as toastDemo } from '../elements/00group-ui/dees-mobile-toast/dees-mobile-toast.demo.js';
import { demoFunc as navigationDemo } from '../elements/00group-layout/dees-mobile-navigation/dees-mobile-navigation.demo.js';
import { demoFunc as applayoutDemo } from '../elements/00group-layout/dees-mobile-applayout/dees-mobile-applayout.demo.js';
import { demoFunc as inputDemo } from '../elements/00group-input/dees-mobile-input/dees-mobile-input.demo.js';
interface IComponentDemo {
name: string;
tag: string;
category: string;
demo: () => ReturnType<typeof html>;
}
const components: IComponentDemo[] = [
{ name: 'Button', tag: 'dees-mobile-button', category: 'UI', demo: buttonDemo },
{ name: 'Icon', tag: 'dees-mobile-icon', category: 'UI', demo: iconDemo },
{ name: 'Header', tag: 'dees-mobile-header', category: 'UI', demo: headerDemo },
{ name: 'Modal', tag: 'dees-mobile-modal', category: 'UI', demo: modalDemo },
{ name: 'Action Sheet', tag: 'dees-mobile-actionsheet', category: 'UI', demo: actionsheetDemo },
{ name: 'Toast', tag: 'dees-mobile-toast', category: 'UI', demo: toastDemo },
{ name: 'Navigation', tag: 'dees-mobile-navigation', category: 'Layout', demo: navigationDemo },
{ name: 'App Layout', tag: 'dees-mobile-applayout', category: 'Layout', demo: applayoutDemo },
{ name: 'Input', tag: 'dees-mobile-input', category: 'Input', demo: inputDemo },
];
@customElement('component-showcase')
export class ComponentShowcase extends DeesElement {
@state()
accessor selectedComponent: string = 'dees-mobile-button';
public static styles = [
css`
:host {
display: block;
min-height: 100vh;
background: var(--dees-background);
}
.showcase {
display: grid;
grid-template-columns: 250px 1fr;
min-height: 100vh;
}
@media (max-width: 768px) {
.showcase {
grid-template-columns: 1fr;
}
.sidebar {
display: none;
}
}
.sidebar {
background: var(--dees-surface);
border-right: 1px solid var(--dees-border);
padding: 1.5rem;
overflow-y: auto;
}
.sidebar h1 {
font-size: 1.125rem;
font-weight: 700;
margin: 0 0 1.5rem 0;
color: var(--dees-foreground);
}
.category {
margin-bottom: 1.5rem;
}
.category-title {
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--dees-muted-foreground);
margin-bottom: 0.5rem;
}
.component-list {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.component-item {
padding: 0.5rem 0.75rem;
border-radius: var(--dees-radius-sm);
font-size: 0.875rem;
color: var(--dees-foreground);
cursor: pointer;
transition: background 150ms;
}
.component-item:hover {
background: var(--dees-accent);
}
.component-item.active {
background: var(--dees-primary);
color: var(--dees-primary-foreground);
}
.main-content {
padding: 2rem;
overflow-y: auto;
}
.component-header {
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 1px solid var(--dees-border);
}
.component-header h2 {
font-size: 1.5rem;
font-weight: 700;
margin: 0 0 0.25rem 0;
color: var(--dees-foreground);
}
.component-tag {
font-family: ui-monospace, monospace;
font-size: 0.875rem;
color: var(--dees-muted-foreground);
}
.demo-container {
background: var(--dees-card);
border: 1px solid var(--dees-border);
border-radius: var(--dees-radius-lg);
padding: 2rem;
}
`,
];
private getCategories(): string[] {
return [...new Set(components.map(c => c.category))];
}
private getComponentsByCategory(category: string): IComponentDemo[] {
return components.filter(c => c.category === category);
}
private getSelectedComponent(): IComponentDemo | undefined {
return components.find(c => c.tag === this.selectedComponent);
}
public render() {
const selected = this.getSelectedComponent();
return html`
<div class="showcase">
<aside class="sidebar">
<h1>Components</h1>
${this.getCategories().map(category => html`
<div class="category">
<div class="category-title">${category}</div>
<div class="component-list">
${this.getComponentsByCategory(category).map(comp => html`
<div
class="component-item ${this.selectedComponent === comp.tag ? 'active' : ''}"
@click=${() => this.selectedComponent = comp.tag}
>
${comp.name}
</div>
`)}
</div>
</div>
`)}
</aside>
<main class="main-content">
${selected ? html`
<div class="component-header">
<h2>${selected.name}</h2>
<code class="component-tag">&lt;${selected.tag}&gt;</code>
</div>
<div class="demo-container">
${selected.demo()}
</div>
` : html`
<p>Select a component from the sidebar</p>
`}
</main>
</div>
`;
}
}
export const componentShowcase = () => html`<component-showcase></component-showcase>`;