2025-06-19 11:39:16 +00:00
|
|
|
import {
|
|
|
|
customElement,
|
|
|
|
DeesElement,
|
|
|
|
html,
|
|
|
|
css,
|
|
|
|
cssManager,
|
|
|
|
property,
|
|
|
|
type TemplateResult,
|
|
|
|
} from '@design.estate/dees-element';
|
|
|
|
import { demoFunc } from './dees-panel.demo.js';
|
2025-06-27 17:14:46 +00:00
|
|
|
import { cssGeistFontFamily } from './00fonts.js';
|
2025-06-19 11:39:16 +00:00
|
|
|
|
|
|
|
declare global {
|
|
|
|
interface HTMLElementTagNameMap {
|
|
|
|
'dees-panel': DeesPanel;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@customElement('dees-panel')
|
|
|
|
export class DeesPanel extends DeesElement {
|
|
|
|
public static demo = demoFunc;
|
|
|
|
|
|
|
|
@property({ type: String })
|
|
|
|
public title: string = '';
|
|
|
|
|
|
|
|
@property({ type: String })
|
|
|
|
public subtitle: string = '';
|
|
|
|
|
2025-06-27 16:39:17 +00:00
|
|
|
@property({ type: String })
|
|
|
|
public variant: 'default' | 'outline' | 'ghost' = 'default';
|
|
|
|
|
|
|
|
@property({ type: String })
|
|
|
|
public size: 'sm' | 'md' | 'lg' = 'md';
|
|
|
|
|
|
|
|
@property({ attribute: false })
|
|
|
|
public runAfterRender?: (elementArg: HTMLElement) => void | Promise<void>;
|
|
|
|
|
2025-06-19 11:39:16 +00:00
|
|
|
public static styles = [
|
|
|
|
cssManager.defaultStyles,
|
|
|
|
css`
|
|
|
|
:host {
|
|
|
|
display: block;
|
2025-06-27 17:14:46 +00:00
|
|
|
font-family: ${cssGeistFontFamily};
|
2025-06-27 16:39:17 +00:00
|
|
|
background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 3.9%)')};
|
|
|
|
border-radius: 6px;
|
2025-06-19 11:39:16 +00:00
|
|
|
padding: 24px;
|
2025-06-27 16:39:17 +00:00
|
|
|
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;
|
2025-06-19 11:39:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.title {
|
2025-06-27 16:39:17 +00:00
|
|
|
margin: 0;
|
2025-06-19 11:39:16 +00:00
|
|
|
font-size: 18px;
|
2025-06-27 11:50:07 +00:00
|
|
|
font-weight: 600;
|
2025-06-27 16:39:17 +00:00
|
|
|
color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 95%)')};
|
2025-06-27 11:50:07 +00:00
|
|
|
letter-spacing: -0.025em;
|
2025-06-27 16:39:17 +00:00
|
|
|
line-height: 1.5;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Title size variations */
|
|
|
|
:host([size="sm"]) .title {
|
|
|
|
font-size: 16px;
|
|
|
|
}
|
|
|
|
|
|
|
|
:host([size="lg"]) .title {
|
|
|
|
font-size: 20px;
|
2025-06-19 11:39:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.subtitle {
|
2025-06-27 16:39:17 +00:00
|
|
|
margin: 4px 0 0 0;
|
2025-06-19 11:39:16 +00:00
|
|
|
font-size: 14px;
|
2025-06-27 11:50:07 +00:00
|
|
|
color: ${cssManager.bdTheme('hsl(215.4 16.3% 56.9%)', 'hsl(215 20.2% 55.1%)')};
|
2025-06-27 16:39:17 +00:00
|
|
|
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;
|
2025-06-19 11:39:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.content {
|
2025-06-27 16:39:17 +00:00
|
|
|
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;
|
2025-06-19 11:39:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove margins from first and last children */
|
|
|
|
.content ::slotted(*:first-child) {
|
|
|
|
margin-top: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.content ::slotted(*:last-child) {
|
|
|
|
margin-bottom: 0;
|
|
|
|
}
|
2025-06-27 16:39:17 +00:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
2025-06-19 11:39:16 +00:00
|
|
|
`,
|
|
|
|
];
|
|
|
|
|
|
|
|
public render(): TemplateResult {
|
|
|
|
return html`
|
2025-06-27 16:39:17 +00:00
|
|
|
<div class="header">
|
|
|
|
${this.title ? html`<h3 class="title">${this.title}</h3>` : ''}
|
|
|
|
${this.subtitle ? html`<p class="subtitle">${this.subtitle}</p>` : ''}
|
|
|
|
</div>
|
2025-06-19 11:39:16 +00:00
|
|
|
<div class="content">
|
|
|
|
<slot></slot>
|
|
|
|
</div>
|
|
|
|
`;
|
|
|
|
}
|
2025-06-27 16:39:17 +00:00
|
|
|
|
|
|
|
public async firstUpdated() {
|
|
|
|
if (this.runAfterRender) {
|
|
|
|
await this.runAfterRender(this);
|
|
|
|
}
|
|
|
|
}
|
2025-06-19 11:39:16 +00:00
|
|
|
}
|