update
This commit is contained in:
23
readme.md
23
readme.md
@ -455,15 +455,15 @@ Dynamic list input for managing arrays of typed values.
|
||||
```
|
||||
|
||||
#### `DeesInputDatepicker`
|
||||
Date and time picker component with calendar interface.
|
||||
Date and time picker component with calendar interface and manual typing support.
|
||||
|
||||
```typescript
|
||||
<dees-input-datepicker
|
||||
key="eventDate"
|
||||
label="Event Date"
|
||||
placeholder="Select date"
|
||||
placeholder="YYYY-MM-DD"
|
||||
value="2025-01-15T14:30:00Z" // ISO string format
|
||||
dateFormat="DD/MM/YYYY" // Display format
|
||||
dateFormat="YYYY-MM-DD" // Display format (default: YYYY-MM-DD)
|
||||
enableTime={true} // Enable time selection
|
||||
timeFormat="24h" // Options: 24h, 12h
|
||||
minuteIncrement={15} // Time step in minutes
|
||||
@ -481,6 +481,7 @@ Date and time picker component with calendar interface.
|
||||
|
||||
Key Features:
|
||||
- Interactive calendar popup
|
||||
- Manual date typing with multiple formats
|
||||
- Optional time selection
|
||||
- Configurable date format
|
||||
- Min/max date constraints
|
||||
@ -490,6 +491,22 @@ Key Features:
|
||||
- Clear functionality
|
||||
- 12/24 hour time formats
|
||||
- Theme-aware styling
|
||||
- Live parsing and validation
|
||||
|
||||
Manual Input Formats:
|
||||
```typescript
|
||||
// Date formats supported
|
||||
"2023-12-20" // ISO format (YYYY-MM-DD)
|
||||
"20.12.2023" // European format (DD.MM.YYYY)
|
||||
"12/20/2023" // US format (MM/DD/YYYY)
|
||||
|
||||
// Date with time (add space and time after any date format)
|
||||
"2023-12-20 14:30"
|
||||
"20.12.2023 9:45"
|
||||
"12/20/2023 16:00"
|
||||
```
|
||||
|
||||
The component automatically parses and validates input as you type, updating the internal date value when a valid date is recognized.
|
||||
|
||||
#### `DeesInputSearchselect`
|
||||
Search-enabled dropdown selection component.
|
||||
|
@ -56,7 +56,6 @@ export const demoFunc = () => html`
|
||||
<dees-input-datepicker
|
||||
label="Select Date"
|
||||
description="Choose a date from the calendar"
|
||||
placeholder="Pick a date"
|
||||
></dees-input-datepicker>
|
||||
</dees-panel>
|
||||
</dees-demowrapper>
|
||||
|
@ -35,7 +35,7 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
|
||||
public minuteIncrement: number = 1;
|
||||
|
||||
@property({ type: String })
|
||||
public dateFormat: string = 'DD/MM/YYYY';
|
||||
public dateFormat: string = 'YYYY-MM-DD';
|
||||
|
||||
@property({ type: String })
|
||||
public minDate: string = '';
|
||||
@ -50,7 +50,7 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
|
||||
public weekStartsOn: 0 | 1 = 1; // Default to Monday
|
||||
|
||||
@property({ type: String })
|
||||
public placeholder: string = 'Select date';
|
||||
public placeholder: string = 'YYYY-MM-DD';
|
||||
|
||||
@state()
|
||||
private isOpened: boolean = false;
|
||||
@ -479,7 +479,8 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
|
||||
?disabled=${this.disabled}
|
||||
@click=${this.toggleCalendar}
|
||||
@keydown=${this.handleKeydown}
|
||||
readonly
|
||||
@input=${this.handleManualInput}
|
||||
@blur=${this.handleInputBlur}
|
||||
style="padding-right: ${this.value ? '64px' : '40px'}"
|
||||
/>
|
||||
<div class="icon-container">
|
||||
@ -641,10 +642,11 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||
const year = date.getFullYear().toString();
|
||||
|
||||
formatted = formatted.replace('DD', day);
|
||||
formatted = formatted.replace('MM', month);
|
||||
// Replace in correct order to avoid conflicts
|
||||
formatted = formatted.replace('YYYY', year);
|
||||
formatted = formatted.replace('YY', year.slice(-2));
|
||||
formatted = formatted.replace('MM', month);
|
||||
formatted = formatted.replace('DD', day);
|
||||
|
||||
// Time formatting if enabled
|
||||
if (this.enableTime) {
|
||||
@ -894,6 +896,117 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
|
||||
this.changeSubject.next(this);
|
||||
}
|
||||
|
||||
private handleManualInput(e: InputEvent): void {
|
||||
const input = e.target as HTMLInputElement;
|
||||
const inputValue = input.value.trim();
|
||||
|
||||
if (!inputValue) {
|
||||
// Clear the value if input is empty
|
||||
this.value = '';
|
||||
this.selectedDate = null;
|
||||
return;
|
||||
}
|
||||
|
||||
const parsedDate = this.parseManualDate(inputValue);
|
||||
if (parsedDate && !isNaN(parsedDate.getTime())) {
|
||||
// Update internal state without triggering re-render of input
|
||||
this.value = parsedDate.toISOString();
|
||||
this.selectedDate = parsedDate;
|
||||
this.viewDate = new Date(parsedDate);
|
||||
this.selectedHour = parsedDate.getHours();
|
||||
this.selectedMinute = parsedDate.getMinutes();
|
||||
this.changeSubject.next(this);
|
||||
}
|
||||
}
|
||||
|
||||
private handleInputBlur(e: FocusEvent): void {
|
||||
const input = e.target as HTMLInputElement;
|
||||
const inputValue = input.value.trim();
|
||||
|
||||
if (!inputValue) {
|
||||
this.value = '';
|
||||
this.selectedDate = null;
|
||||
this.changeSubject.next(this);
|
||||
return;
|
||||
}
|
||||
|
||||
const parsedDate = this.parseManualDate(inputValue);
|
||||
if (parsedDate && !isNaN(parsedDate.getTime())) {
|
||||
this.value = parsedDate.toISOString();
|
||||
this.selectedDate = parsedDate;
|
||||
this.viewDate = new Date(parsedDate);
|
||||
this.selectedHour = parsedDate.getHours();
|
||||
this.selectedMinute = parsedDate.getMinutes();
|
||||
this.changeSubject.next(this);
|
||||
// Update the input with formatted date
|
||||
input.value = this.formatDate(this.value);
|
||||
} else {
|
||||
// Revert to previous valid value on blur if parsing failed
|
||||
input.value = this.formatDate(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
private parseManualDate(input: string): Date | null {
|
||||
if (!input) return null;
|
||||
|
||||
// Split date and time parts if present
|
||||
const parts = input.split(' ');
|
||||
let datePart = parts[0];
|
||||
let timePart = parts[1] || '';
|
||||
|
||||
let parsedDate: Date | null = null;
|
||||
|
||||
// Try different date formats
|
||||
// Format 1: YYYY-MM-DD (ISO-like)
|
||||
const isoMatch = datePart.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/);
|
||||
if (isoMatch) {
|
||||
const [_, year, month, day] = isoMatch;
|
||||
parsedDate = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
|
||||
}
|
||||
|
||||
// Format 2: DD.MM.YYYY (European)
|
||||
if (!parsedDate) {
|
||||
const euMatch = datePart.match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})$/);
|
||||
if (euMatch) {
|
||||
const [_, day, month, year] = euMatch;
|
||||
parsedDate = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
|
||||
}
|
||||
}
|
||||
|
||||
// Format 3: MM/DD/YYYY (US)
|
||||
if (!parsedDate) {
|
||||
const usMatch = datePart.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
|
||||
if (usMatch) {
|
||||
const [_, month, day, year] = usMatch;
|
||||
parsedDate = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
|
||||
}
|
||||
}
|
||||
|
||||
// If no date was parsed, return null
|
||||
if (!parsedDate || isNaN(parsedDate.getTime())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Parse time if present (HH:MM format)
|
||||
if (timePart) {
|
||||
const timeMatch = timePart.match(/^(\d{1,2}):(\d{2})$/);
|
||||
if (timeMatch) {
|
||||
const [_, hours, minutes] = timeMatch;
|
||||
parsedDate.setHours(parseInt(hours));
|
||||
parsedDate.setMinutes(parseInt(minutes));
|
||||
}
|
||||
} else if (!this.enableTime) {
|
||||
// If time is not enabled and not provided, use current time
|
||||
const now = new Date();
|
||||
parsedDate.setHours(now.getHours());
|
||||
parsedDate.setMinutes(now.getMinutes());
|
||||
parsedDate.setSeconds(0);
|
||||
parsedDate.setMilliseconds(0);
|
||||
}
|
||||
|
||||
return parsedDate;
|
||||
}
|
||||
|
||||
public getValue(): string {
|
||||
return this.value;
|
||||
}
|
||||
|
Reference in New Issue
Block a user