This commit is contained in:
Juergen Kunz
2025-06-30 11:24:38 +00:00
parent aae4427281
commit 7d1e06701b
2 changed files with 195 additions and 1 deletions

View File

@ -12,6 +12,14 @@ import { demoFunc } from './dees-input-datepicker.demo.js';
import './dees-icon.js';
import './dees-label.js';
export interface IDateEvent {
date: string; // ISO date string (YYYY-MM-DD)
title?: string;
description?: string;
type?: 'info' | 'warning' | 'success' | 'error';
count?: number; // Number of events on this day
}
declare global {
interface HTMLElementTagNameMap {
'dees-input-datepicker': DeesInputDatepicker;
@ -58,6 +66,9 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
@property({ type: String })
public timezone: string = Intl.DateTimeFormat().resolvedOptions().timeZone;
@property({ type: Array })
public events: IDateEvent[] = [];
@state()
private isOpened: boolean = false;
@ -327,6 +338,95 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
opacity: 0.3;
}
/* Event indicators */
.day.has-event {
position: relative;
}
.event-indicator {
position: absolute;
bottom: 4px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 2px;
justify-content: center;
}
.event-dot {
width: 4px;
height: 4px;
border-radius: 50%;
background: ${cssManager.bdTheme('hsl(220 8.9% 46.1%)', 'hsl(215 20.2% 65.1%)')};
}
.event-dot.info {
background: ${cssManager.bdTheme('hsl(211 70% 52%)', 'hsl(211 70% 62%)')};
}
.event-dot.warning {
background: ${cssManager.bdTheme('hsl(45 90% 45%)', 'hsl(45 90% 55%)')};
}
.event-dot.success {
background: ${cssManager.bdTheme('hsl(142 69% 45%)', 'hsl(142 69% 55%)')};
}
.event-dot.error {
background: ${cssManager.bdTheme('hsl(0 72% 51%)', 'hsl(0 72% 61%)')};
}
.event-count {
position: absolute;
top: 2px;
right: 2px;
min-width: 16px;
height: 16px;
padding: 0 4px;
background: ${cssManager.bdTheme('hsl(0 72% 51%)', 'hsl(0 72% 61%)')};
color: white;
border-radius: 8px;
font-size: 10px;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
}
/* Tooltip for event details */
.event-tooltip {
position: absolute;
bottom: calc(100% + 8px);
left: 50%;
transform: translateX(-50%);
background: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
color: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 0%)')};
padding: 8px 12px;
border-radius: 6px;
font-size: 12px;
white-space: nowrap;
pointer-events: none;
opacity: 0;
transition: opacity 0.2s ease;
z-index: 10;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
.event-tooltip::after {
content: '';
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
border: 4px solid transparent;
border-top-color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 90%)')};
}
.day.has-event:hover .event-tooltip {
opacity: 1;
}
/* Time selector */
.time-selector {
margin-top: 12px;
@ -589,13 +689,33 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
const isSelected = this.isSelected(day);
const isOtherMonth = day.getMonth() !== this.viewDate.getMonth();
const isDisabled = this.isDisabled(day);
const dayEvents = this.getEventsForDate(day);
const hasEvents = dayEvents.length > 0;
const totalEventCount = dayEvents.reduce((sum, event) => sum + (event.count || 1), 0);
return html`
<div
class="day ${isOtherMonth ? 'other-month' : ''} ${isToday ? 'today' : ''} ${isSelected ? 'selected' : ''} ${isDisabled ? 'disabled' : ''}"
class="day ${isOtherMonth ? 'other-month' : ''} ${isToday ? 'today' : ''} ${isSelected ? 'selected' : ''} ${isDisabled ? 'disabled' : ''} ${hasEvents ? 'has-event' : ''}"
@click="${() => !isDisabled && this.selectDate(day)}"
>
${day.getDate()}
${hasEvents ? html`
${totalEventCount > 3 ? html`
<div class="event-count">${totalEventCount}</div>
` : html`
<div class="event-indicator">
${dayEvents.slice(0, 3).map(event => html`
<div class="event-dot ${event.type || 'info'}"></div>
`)}
</div>
`}
${dayEvents[0].title ? html`
<div class="event-tooltip">
${dayEvents[0].title}
${totalEventCount > 1 ? html` (+${totalEventCount - 1} more)` : ''}
</div>
` : ''}
` : ''}
</div>
`;
})}
@ -876,6 +996,13 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
return false;
}
private getEventsForDate(date: Date): IDateEvent[] {
if (!this.events || this.events.length === 0) return [];
const dateStr = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
return this.events.filter(event => event.date === dateStr);
}
private selectDate(date: Date): void {
this.selectedDate = new Date(
date.getFullYear(),