feat(structure): adjust
This commit is contained in:
172
ts_web/elements/dees-panel/dees-panel.demo.ts
Normal file
172
ts_web/elements/dees-panel/dees-panel.demo.ts
Normal file
@@ -0,0 +1,172 @@
|
||||
import { html, css, cssManager } from '@design.estate/dees-element';
|
||||
|
||||
export const demoFunc = () => html`
|
||||
<style>
|
||||
${css`
|
||||
.demo-background {
|
||||
padding: 24px;
|
||||
background: ${cssManager.bdTheme('hsl(0 0% 95%)', 'hsl(0 0% 5%)')};
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.demo-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
margin: 32px 0 16px 0;
|
||||
color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 95%)')};
|
||||
letter-spacing: -0.025em;
|
||||
}
|
||||
|
||||
.section-title:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.grid-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.grid-3col {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
@media (max-width: 968px) {
|
||||
.grid-3col {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.grid-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
background: ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-size: 13px;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
|
||||
<div class="demo-background">
|
||||
<div class="demo-container">
|
||||
<h2 class="section-title">Default Panels</h2>
|
||||
|
||||
<dees-panel .title=${'Panel Component'} .subtitle=${'The default panel variant with shadcn-inspired styling'}>
|
||||
<p>The panel component automatically follows the theme and provides consistent styling for grouped content.</p>
|
||||
<p>It's perfect for creating sections in your application with proper spacing and borders.</p>
|
||||
</dees-panel>
|
||||
|
||||
<div class="grid-layout">
|
||||
<dees-panel .title=${'Feature Overview'} .subtitle=${'Key capabilities'}>
|
||||
<p>Grid layouts work great with panels for creating dashboards and feature sections.</p>
|
||||
<dees-button>Learn More</dees-button>
|
||||
</dees-panel>
|
||||
|
||||
<dees-panel .title=${'Quick Actions'} .subtitle=${'Common tasks'}>
|
||||
<p>Each panel maintains consistent spacing and styling across your application.</p>
|
||||
<dees-button>Get Started</dees-button>
|
||||
</dees-panel>
|
||||
</div>
|
||||
|
||||
<h2 class="section-title">Panel Variants</h2>
|
||||
|
||||
<dees-panel .title=${'Default Variant'} .variant=${'default'}>
|
||||
<p>The default variant has a white background, subtle border, and minimal shadow. It's the standard choice for most content.</p>
|
||||
<p>Use <code>variant="default"</code> or omit the variant property.</p>
|
||||
</dees-panel>
|
||||
|
||||
<dees-panel .title=${'Outline Variant'} .subtitle=${'Transparent background with border'} .variant=${'outline'}>
|
||||
<p>The outline variant removes the background color and shadow, keeping only the border.</p>
|
||||
<p>Use <code>variant="outline"</code> for a lighter visual weight.</p>
|
||||
</dees-panel>
|
||||
|
||||
<dees-panel .title=${'Ghost Variant'} .subtitle=${'Minimal styling for subtle sections'} .variant=${'ghost'}>
|
||||
<p>The ghost variant has no border or background by default, only showing a subtle background on hover.</p>
|
||||
<p>Use <code>variant="ghost"</code> for the most minimal appearance.</p>
|
||||
</dees-panel>
|
||||
|
||||
<h2 class="section-title">Panel Sizes</h2>
|
||||
|
||||
<div class="grid-3col">
|
||||
<dees-panel .title=${'Small Panel'} .size=${'sm'}>
|
||||
<p>Compact padding for dense layouts.</p>
|
||||
<p>Use <code>size="sm"</code></p>
|
||||
</dees-panel>
|
||||
|
||||
<dees-panel .title=${'Medium Panel'} .size=${'md'}>
|
||||
<p>Default size with balanced spacing.</p>
|
||||
<p>Use <code>size="md"</code> or omit.</p>
|
||||
</dees-panel>
|
||||
|
||||
<dees-panel .title=${'Large Panel'} .size=${'lg'}>
|
||||
<p>Generous padding for prominent sections.</p>
|
||||
<p>Use <code>size="lg"</code></p>
|
||||
</dees-panel>
|
||||
</div>
|
||||
|
||||
<h2 class="section-title">Complex Examples</h2>
|
||||
|
||||
<dees-panel .title=${'Form Example'} .subtitle=${'Panels work great for organizing form sections'}>
|
||||
<dees-form>
|
||||
<dees-input-text .label=${'Project Name'} .required=${true}></dees-input-text>
|
||||
<dees-input-text .label=${'Description'} .inputType=${'textarea'}></dees-input-text>
|
||||
<dees-input-dropdown
|
||||
.label=${'Category'}
|
||||
.options=${[
|
||||
{ option: 'Web Development', key: 'web' },
|
||||
{ option: 'Mobile App', key: 'mobile' },
|
||||
{ option: 'Desktop Software', key: 'desktop' }
|
||||
]}
|
||||
></dees-input-dropdown>
|
||||
<dees-form-submit>Create Project</dees-form-submit>
|
||||
</dees-form>
|
||||
</dees-panel>
|
||||
|
||||
<dees-panel .title=${'Nested Panels'} .subtitle=${'Panels can be nested for hierarchical organization'}>
|
||||
<p>You can nest panels to create more complex layouts:</p>
|
||||
|
||||
<dees-panel .title=${'Nested Panel 1'} .variant=${'outline'} .size=${'sm'}>
|
||||
<p>This is a nested panel with outline variant and small size.</p>
|
||||
</dees-panel>
|
||||
|
||||
<dees-panel .title=${'Nested Panel 2'} .variant=${'ghost'} .size=${'sm'}>
|
||||
<p>This is another nested panel with ghost variant.</p>
|
||||
</dees-panel>
|
||||
</dees-panel>
|
||||
|
||||
<h2 class="section-title">Untitled Panels</h2>
|
||||
|
||||
<dees-panel>
|
||||
<p>Panels work great even without a title for simple content grouping.</p>
|
||||
<p>They provide visual separation and consistent padding throughout your interface.</p>
|
||||
</dees-panel>
|
||||
|
||||
<div class="grid-layout">
|
||||
<dees-panel .variant=${'outline'}>
|
||||
<h4 style="margin-top: 0;">Custom Content</h4>
|
||||
<p>You can add your own headings and structure within untitled panels.</p>
|
||||
</dees-panel>
|
||||
|
||||
<dees-panel .variant=${'ghost'}>
|
||||
<h4 style="margin-top: 0;">Minimal Style</h4>
|
||||
<p>Ghost panels without titles create very subtle content sections.</p>
|
||||
</dees-panel>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
199
ts_web/elements/dees-panel/dees-panel.ts
Normal file
199
ts_web/elements/dees-panel/dees-panel.ts
Normal file
@@ -0,0 +1,199 @@
|
||||
import {
|
||||
customElement,
|
||||
DeesElement,
|
||||
html,
|
||||
css,
|
||||
cssManager,
|
||||
property,
|
||||
type TemplateResult,
|
||||
} from '@design.estate/dees-element';
|
||||
import { demoFunc } from './dees-panel.demo.js';
|
||||
import { cssGeistFontFamily } from './00fonts.js';
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'dees-panel': DeesPanel;
|
||||
}
|
||||
}
|
||||
|
||||
@customElement('dees-panel')
|
||||
export class DeesPanel extends DeesElement {
|
||||
public static demo = demoFunc;
|
||||
|
||||
@property({ type: String })
|
||||
accessor title: string = '';
|
||||
|
||||
@property({ type: String })
|
||||
accessor subtitle: string = '';
|
||||
|
||||
@property({ type: String })
|
||||
accessor variant: 'default' | 'outline' | 'ghost' = 'default';
|
||||
|
||||
@property({ type: String })
|
||||
accessor size: 'sm' | 'md' | 'lg' = 'md';
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor runAfterRender: ((elementArg: HTMLElement) => void | Promise<void>) | undefined = undefined;
|
||||
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
font-family: ${cssGeistFontFamily};
|
||||
background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 3.9%)')};
|
||||
border-radius: 6px;
|
||||
padding: 24px;
|
||||
border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
|
||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
/* Variant: default */
|
||||
:host([variant="default"]) {
|
||||
box-shadow: 0 1px 2px 0 hsl(0 0% 0% / 0.05);
|
||||
}
|
||||
|
||||
/* Variant: outline */
|
||||
:host([variant="outline"]) {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* Variant: ghost */
|
||||
:host([variant="ghost"]) {
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
/* Size variations */
|
||||
:host([size="sm"]) {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
:host([size="lg"]) {
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.header:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 95%)')};
|
||||
letter-spacing: -0.025em;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* Title size variations */
|
||||
:host([size="sm"]) .title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
:host([size="lg"]) .title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
margin: 4px 0 0 0;
|
||||
font-size: 14px;
|
||||
color: ${cssManager.bdTheme('hsl(215.4 16.3% 56.9%)', 'hsl(215 20.2% 55.1%)')};
|
||||
letter-spacing: -0.006em;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* Subtitle size variations */
|
||||
:host([size="sm"]) .subtitle {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
:host([size="lg"]) .subtitle {
|
||||
font-size: 15px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.content {
|
||||
color: ${cssManager.bdTheme('hsl(215.3 25% 26.7%)', 'hsl(217.9 10.6% 84.9%)')};
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Content size variations */
|
||||
:host([size="sm"]) .content {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
:host([size="lg"]) .content {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
/* Remove margins from first and last children */
|
||||
.content ::slotted(*:first-child) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.content ::slotted(*:last-child) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Interactive states for default variant */
|
||||
:host([variant="default"]:hover) {
|
||||
border-color: ${cssManager.bdTheme('hsl(0 0% 79.8%)', 'hsl(0 0% 20.9%)')};
|
||||
box-shadow: 0 4px 6px -1px hsl(0 0% 0% / 0.1), 0 2px 4px -2px hsl(0 0% 0% / 0.1);
|
||||
}
|
||||
|
||||
/* Interactive states for outline variant */
|
||||
:host([variant="outline"]:hover) {
|
||||
border-color: ${cssManager.bdTheme('hsl(0 0% 79.8%)', 'hsl(0 0% 20.9%)')};
|
||||
background: ${cssManager.bdTheme('hsl(0 0% 98%)', 'hsl(0 0% 7.8%)')};
|
||||
}
|
||||
|
||||
/* Interactive states for ghost variant */
|
||||
:host([variant="ghost"]:hover) {
|
||||
background: ${cssManager.bdTheme('hsl(0 0% 95.1%)', 'hsl(0 0% 14.9%)')};
|
||||
}
|
||||
|
||||
/* Focus states */
|
||||
:host(:focus-within) {
|
||||
outline: none;
|
||||
border-color: ${cssManager.bdTheme('hsl(222.2 47.4% 51.2%)', 'hsl(217.2 91.2% 59.8%)')};
|
||||
box-shadow: 0 0 0 3px ${cssManager.bdTheme('hsl(222.2 47.4% 51.2% / 0.1)', 'hsl(217.2 91.2% 59.8% / 0.1)')};
|
||||
}
|
||||
|
||||
/* Nested panels spacing */
|
||||
::slotted(dees-panel) {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
::slotted(dees-panel:first-child) {
|
||||
margin-top: 0;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`
|
||||
<div class="header">
|
||||
${this.title ? html`<h3 class="title">${this.title}</h3>` : ''}
|
||||
${this.subtitle ? html`<p class="subtitle">${this.subtitle}</p>` : ''}
|
||||
</div>
|
||||
<div class="content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
public async firstUpdated() {
|
||||
if (this.runAfterRender) {
|
||||
await this.runAfterRender(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user