203 lines
6.2 KiB
TypeScript
203 lines
6.2 KiB
TypeScript
|
|
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"><${selected.tag}></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>`;
|