This commit is contained in:
2025-12-22 10:53:15 +00:00
commit 753a98c67b
63 changed files with 15976 additions and 0 deletions

View File

@@ -0,0 +1,223 @@
import {
DeesElement,
css,
cssManager,
customElement,
html,
property,
type TemplateResult,
} from '@design.estate/dees-element';
import { mobileComponentStyles } from '../../00componentstyles.js';
import '../dees-mobile-icon/dees-mobile-icon.js';
import { demoFunc } from './dees-mobile-actionsheet.demo.js';
export interface IActionSheetOption {
id: string;
icon?: string;
iconColor?: string;
iconBackground?: string;
title: string;
subtitle?: string;
}
declare global {
interface HTMLElementTagNameMap {
'dees-mobile-actionsheet': DeesMobileActionsheet;
}
}
@customElement('dees-mobile-actionsheet')
export class DeesMobileActionsheet extends DeesElement {
public static demo = demoFunc;
@property({ type: String })
accessor title: string = '';
@property({ type: Array })
accessor options: IActionSheetOption[] = [];
@property({ type: String })
accessor cancelText: string = 'Cancel';
public static styles = [
cssManager.defaultStyles,
mobileComponentStyles,
css`
:host {
position: fixed;
inset: 0;
z-index: var(--dees-z-modal, 500);
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.backdrop {
position: absolute;
inset: 0;
background: rgba(0, 0, 0, 0);
animation: fadeInBackdrop 0.2s ease-out forwards;
}
@keyframes fadeInBackdrop {
to {
background: rgba(0, 0, 0, 0.5);
}
}
.sheet {
position: relative;
background: var(--dees-card);
border-radius: var(--dees-radius-lg) var(--dees-radius-lg) 0 0;
padding: var(--dees-space-md);
padding-bottom: calc(var(--dees-space-md) + env(safe-area-inset-bottom, 0px));
transform: translateY(100%);
animation: slideUp 0.3s ease-out forwards;
}
@keyframes slideUp {
to {
transform: translateY(0);
}
}
.sheet-title {
text-align: center;
font-size: 0.875rem;
color: var(--dees-muted-foreground);
margin-bottom: var(--dees-space-md);
padding-bottom: var(--dees-space-sm);
border-bottom: 1px solid var(--dees-border);
}
.options {
display: flex;
flex-direction: column;
gap: var(--dees-space-xs);
}
.option {
display: flex;
align-items: center;
gap: var(--dees-space-md);
padding: var(--dees-space-md);
border: none;
background: var(--dees-background);
border-radius: var(--dees-radius-md);
cursor: pointer;
color: var(--dees-foreground);
font-size: 1rem;
font-weight: 500;
text-align: left;
transition: background var(--dees-transition-fast);
}
.option:hover {
background: var(--dees-muted);
}
.option:active {
background: var(--dees-accent);
}
.option-icon {
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--dees-radius-full);
flex-shrink: 0;
background: var(--dees-accent);
color: var(--dees-primary);
}
.option-text {
flex: 1;
}
.option-title {
font-weight: 500;
}
.option-subtitle {
font-size: 0.75rem;
color: var(--dees-muted-foreground);
font-weight: normal;
margin-top: 2px;
}
.cancel {
margin-top: var(--dees-space-sm);
padding: var(--dees-space-md);
border: none;
background: var(--dees-background);
border-radius: var(--dees-radius-md);
cursor: pointer;
color: var(--dees-danger);
font-size: 1rem;
font-weight: 500;
width: 100%;
transition: background var(--dees-transition-fast);
}
.cancel:hover {
background: rgba(220, 38, 38, 0.1);
}
`,
];
private handleSelect(option: IActionSheetOption) {
this.dispatchEvent(new CustomEvent('select', {
detail: option,
bubbles: true,
composed: true,
}));
}
private handleClose() {
this.dispatchEvent(new CustomEvent('close', {
bubbles: true,
composed: true,
}));
}
public render(): TemplateResult {
return html`
<div class="backdrop" @click=${this.handleClose}></div>
<div class="sheet">
${this.title ? html`<div class="sheet-title">${this.title}</div>` : ''}
<div class="options">
${this.options.map(option => html`
<button class="option" @click=${() => this.handleSelect(option)}>
${option.icon ? html`
<div
class="option-icon"
style=${option.iconBackground ? `background: ${option.iconBackground}` : ''}
>
<dees-mobile-icon
icon=${option.icon}
size="24"
color=${option.iconColor || 'currentColor'}
></dees-mobile-icon>
</div>
` : ''}
<div class="option-text">
<div class="option-title">${option.title}</div>
${option.subtitle ? html`
<div class="option-subtitle">${option.subtitle}</div>
` : ''}
</div>
</button>
`)}
</div>
<button class="cancel" @click=${this.handleClose}>
${this.cancelText}
</button>
</div>
`;
}
}