- Implemented DeesInputFileupload component with file upload functionality, including drag-and-drop support, file previews, and clear all option. - Developed DeesInputRichtext component featuring a rich text editor with a formatting toolbar, link management, and word count display. - Created demo for DeesInputRichtext showcasing various use cases including basic editing, placeholder text, different heights, and disabled state. - Added styles for both components to ensure a consistent and user-friendly interface. - Introduced types for toolbar buttons in the rich text editor for better type safety and maintainability.
180 lines
8.0 KiB
TypeScript
180 lines
8.0 KiB
TypeScript
import { html, type TemplateResult } from '@design.estate/dees-element';
|
|
import type { DeesInputDatepicker } from './component.js';
|
|
|
|
export const renderDatepicker = (component: DeesInputDatepicker): TemplateResult => {
|
|
const monthNames = [
|
|
'January', 'February', 'March', 'April', 'May', 'June',
|
|
'July', 'August', 'September', 'October', 'November', 'December'
|
|
];
|
|
|
|
const weekDays = component.weekStartsOn === 1
|
|
? ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']
|
|
: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
|
|
|
|
const days = component.getDaysInMonth();
|
|
const isAM = component.selectedHour < 12;
|
|
const timezones = component.getTimezones();
|
|
|
|
return html`
|
|
<div class="input-wrapper">
|
|
<dees-label .label=${component.label} .description=${component.description} .required=${component.required}></dees-label>
|
|
<div class="input-container">
|
|
<input
|
|
type="text"
|
|
class="date-input ${component.isOpened ? 'open' : ''}"
|
|
.value=${component.formatDate(component.value)}
|
|
.placeholder=${component.placeholder}
|
|
?disabled=${component.disabled}
|
|
@click=${component.toggleCalendar}
|
|
@keydown=${component.handleKeydown}
|
|
@input=${component.handleManualInput}
|
|
@blur=${component.handleInputBlur}
|
|
style="padding-right: ${component.value ? '64px' : '40px'}"
|
|
/>
|
|
<div class="icon-container">
|
|
${component.value && !component.disabled ? html`
|
|
<button class="clear-button" @click=${component.clearValue} title="Clear">
|
|
<dees-icon icon="lucide:x" iconSize="14"></dees-icon>
|
|
</button>
|
|
` : ''}
|
|
<dees-icon class="calendar-icon" icon="lucide:calendar" iconSize="16"></dees-icon>
|
|
</div>
|
|
|
|
<!-- Calendar Popup -->
|
|
<div class="calendar-popup ${component.isOpened ? 'show' : ''} ${component.opensToTop ? 'top' : 'bottom'}">
|
|
<!-- Month/Year Navigation -->
|
|
<div class="calendar-header">
|
|
<button class="nav-button" @click=${component.previousMonth}>
|
|
<dees-icon icon="lucide:chevronLeft" iconSize="16"></dees-icon>
|
|
</button>
|
|
<div class="month-year-display">
|
|
${monthNames[component.viewDate.getMonth()]} ${component.viewDate.getFullYear()}
|
|
</div>
|
|
<button class="nav-button" @click=${component.nextMonth}>
|
|
<dees-icon icon="lucide:chevronRight" iconSize="16"></dees-icon>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Weekday Headers -->
|
|
<div class="weekdays">
|
|
${weekDays.map(day => html`<div class="weekday">${day}</div>`)}
|
|
</div>
|
|
|
|
<!-- Days Grid -->
|
|
<div class="days-grid">
|
|
${days.map(day => {
|
|
const isToday = component.isToday(day);
|
|
const isSelected = component.isSelected(day);
|
|
const isOtherMonth = day.getMonth() !== component.viewDate.getMonth();
|
|
const isDisabled = component.isDisabled(day);
|
|
const dayEvents = component.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' : ''} ${hasEvents ? 'has-event' : ''}"
|
|
@click=${() => !isDisabled && component.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>
|
|
`;
|
|
})}
|
|
</div>
|
|
|
|
<!-- Time Selector -->
|
|
${component.enableTime ? html`
|
|
<div class="time-selector">
|
|
<div class="time-selector-title">Time</div>
|
|
<div class="time-inputs">
|
|
<input
|
|
type="number"
|
|
class="time-input"
|
|
.value=${component.timeFormat === '12h'
|
|
? (component.selectedHour === 0 ? 12 : component.selectedHour > 12 ? component.selectedHour - 12 : component.selectedHour).toString().padStart(2, '0')
|
|
: component.selectedHour.toString().padStart(2, '0')}
|
|
@input=${(e: InputEvent) => component.handleHourInput(e)}
|
|
min="${component.timeFormat === '12h' ? 1 : 0}"
|
|
max="${component.timeFormat === '12h' ? 12 : 23}"
|
|
/>
|
|
<span class="time-separator">:</span>
|
|
<input
|
|
type="number"
|
|
class="time-input"
|
|
.value=${component.selectedMinute.toString().padStart(2, '0')}
|
|
@input=${(e: InputEvent) => component.handleMinuteInput(e)}
|
|
min="0"
|
|
max="59"
|
|
step="${component.minuteIncrement || 1}"
|
|
/>
|
|
${component.timeFormat === '12h' ? html`
|
|
<div class="am-pm-selector">
|
|
<button
|
|
class="am-pm-button ${isAM ? 'selected' : ''}"
|
|
@click=${() => component.setAMPM('am')}
|
|
>
|
|
AM
|
|
</button>
|
|
<button
|
|
class="am-pm-button ${!isAM ? 'selected' : ''}"
|
|
@click=${() => component.setAMPM('pm')}
|
|
>
|
|
PM
|
|
</button>
|
|
</div>
|
|
` : ''}
|
|
</div>
|
|
</div>
|
|
` : ''}
|
|
|
|
<!-- Timezone Selector -->
|
|
${component.enableTimezone ? html`
|
|
<div class="timezone-selector">
|
|
<div class="timezone-selector-title">Timezone</div>
|
|
<select
|
|
class="timezone-select"
|
|
.value=${component.timezone}
|
|
@change=${(e: Event) => component.handleTimezoneChange(e)}
|
|
>
|
|
${timezones.map(tz => html`
|
|
<option value="${tz.value}" ?selected=${tz.value === component.timezone}>
|
|
${tz.label}
|
|
</option>
|
|
`)}
|
|
</select>
|
|
</div>
|
|
` : ''}
|
|
|
|
<!-- Action Buttons -->
|
|
<div class="calendar-actions">
|
|
<button class="action-button today-button" @click=${component.selectToday}>
|
|
Today
|
|
</button>
|
|
<button class="action-button clear-button" @click=${component.clear}>
|
|
Clear
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
};
|