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`
|
#### `DeesInputDatepicker`
|
||||||
Date and time picker component with calendar interface.
|
Date and time picker component with calendar interface and manual typing support.
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
<dees-input-datepicker
|
<dees-input-datepicker
|
||||||
key="eventDate"
|
key="eventDate"
|
||||||
label="Event Date"
|
label="Event Date"
|
||||||
placeholder="Select date"
|
placeholder="YYYY-MM-DD"
|
||||||
value="2025-01-15T14:30:00Z" // ISO string format
|
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
|
enableTime={true} // Enable time selection
|
||||||
timeFormat="24h" // Options: 24h, 12h
|
timeFormat="24h" // Options: 24h, 12h
|
||||||
minuteIncrement={15} // Time step in minutes
|
minuteIncrement={15} // Time step in minutes
|
||||||
@ -481,6 +481,7 @@ Date and time picker component with calendar interface.
|
|||||||
|
|
||||||
Key Features:
|
Key Features:
|
||||||
- Interactive calendar popup
|
- Interactive calendar popup
|
||||||
|
- Manual date typing with multiple formats
|
||||||
- Optional time selection
|
- Optional time selection
|
||||||
- Configurable date format
|
- Configurable date format
|
||||||
- Min/max date constraints
|
- Min/max date constraints
|
||||||
@ -490,6 +491,22 @@ Key Features:
|
|||||||
- Clear functionality
|
- Clear functionality
|
||||||
- 12/24 hour time formats
|
- 12/24 hour time formats
|
||||||
- Theme-aware styling
|
- 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`
|
#### `DeesInputSearchselect`
|
||||||
Search-enabled dropdown selection component.
|
Search-enabled dropdown selection component.
|
||||||
|
@ -56,7 +56,6 @@ export const demoFunc = () => html`
|
|||||||
<dees-input-datepicker
|
<dees-input-datepicker
|
||||||
label="Select Date"
|
label="Select Date"
|
||||||
description="Choose a date from the calendar"
|
description="Choose a date from the calendar"
|
||||||
placeholder="Pick a date"
|
|
||||||
></dees-input-datepicker>
|
></dees-input-datepicker>
|
||||||
</dees-panel>
|
</dees-panel>
|
||||||
</dees-demowrapper>
|
</dees-demowrapper>
|
||||||
|
@ -35,7 +35,7 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
|
|||||||
public minuteIncrement: number = 1;
|
public minuteIncrement: number = 1;
|
||||||
|
|
||||||
@property({ type: String })
|
@property({ type: String })
|
||||||
public dateFormat: string = 'DD/MM/YYYY';
|
public dateFormat: string = 'YYYY-MM-DD';
|
||||||
|
|
||||||
@property({ type: String })
|
@property({ type: String })
|
||||||
public minDate: string = '';
|
public minDate: string = '';
|
||||||
@ -50,7 +50,7 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
|
|||||||
public weekStartsOn: 0 | 1 = 1; // Default to Monday
|
public weekStartsOn: 0 | 1 = 1; // Default to Monday
|
||||||
|
|
||||||
@property({ type: String })
|
@property({ type: String })
|
||||||
public placeholder: string = 'Select date';
|
public placeholder: string = 'YYYY-MM-DD';
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
private isOpened: boolean = false;
|
private isOpened: boolean = false;
|
||||||
@ -479,7 +479,8 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
|
|||||||
?disabled=${this.disabled}
|
?disabled=${this.disabled}
|
||||||
@click=${this.toggleCalendar}
|
@click=${this.toggleCalendar}
|
||||||
@keydown=${this.handleKeydown}
|
@keydown=${this.handleKeydown}
|
||||||
readonly
|
@input=${this.handleManualInput}
|
||||||
|
@blur=${this.handleInputBlur}
|
||||||
style="padding-right: ${this.value ? '64px' : '40px'}"
|
style="padding-right: ${this.value ? '64px' : '40px'}"
|
||||||
/>
|
/>
|
||||||
<div class="icon-container">
|
<div class="icon-container">
|
||||||
@ -641,10 +642,11 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
|
|||||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||||
const year = date.getFullYear().toString();
|
const year = date.getFullYear().toString();
|
||||||
|
|
||||||
formatted = formatted.replace('DD', day);
|
// Replace in correct order to avoid conflicts
|
||||||
formatted = formatted.replace('MM', month);
|
|
||||||
formatted = formatted.replace('YYYY', year);
|
formatted = formatted.replace('YYYY', year);
|
||||||
formatted = formatted.replace('YY', year.slice(-2));
|
formatted = formatted.replace('YY', year.slice(-2));
|
||||||
|
formatted = formatted.replace('MM', month);
|
||||||
|
formatted = formatted.replace('DD', day);
|
||||||
|
|
||||||
// Time formatting if enabled
|
// Time formatting if enabled
|
||||||
if (this.enableTime) {
|
if (this.enableTime) {
|
||||||
@ -894,6 +896,117 @@ export class DeesInputDatepicker extends DeesInputBase<DeesInputDatepicker> {
|
|||||||
this.changeSubject.next(this);
|
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 {
|
public getValue(): string {
|
||||||
return this.value;
|
return this.value;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user