# DateRangeEditor Component

A comprehensive date range selection component built with Svelte, providing an intuitive interface for selecting start and end dates with dual calendar popups.

## Features

- **Dual Calendar Interface**: Side-by-side calendars for from/to date selection
- **Smart Date Constraints**: Automatic min/max validation between start and end dates
- **Multiple Visual Variants**: Support for plain, outlined, filled, and compact styles
- **Readonly Input Fields**: Prevents manual text input, ensuring data integrity
- **Flexible Date Formatting**: Customizable date display format
- **Clear Functionality**: Easy range clearing with integrated clear button
- **Popup Management**: Click-outside-to-close behavior
- **Responsive Design**: Automatically sized popup container
- **Integration Ready**: Works seamlessly with form layouts

## Installation

```bash
npm install @ticatec/uniface-element
```

```typescript
import DateRangeEditor from '@ticatec/uniface-element/DateRange';
```

Or if using within the same project:
```typescript
import DateRangeEditor from '$lib/date-range';
```

## Basic Usage

```svelte
<script>
  import DateRangeEditor from '$lib/date-range';
  
  let fromDate = null;
  let toDate = null;
</script>

<DateRangeEditor 
  bind:fromValue={fromDate} 
  bind:toValue={toDate} 
  placeholder="Select date range" 
/>
```

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `fromValue` | `UniDate` | `null` | Start date of the range |
| `toValue` | `UniDate` | `null` | End date of the range |
| `variant` | `'' \| 'plain' \| 'outlined' \| 'filled'` | `''` | Visual style variant |
| `compact` | `boolean` | `false` | Compact display mode |
| `style` | `string` | `''` | Custom CSS styles |
| `class` | `string` | `''` | Additional CSS classes |
| `format` | `string` | `'YYYY-MM-DD'` | Date display format |
| `min` | `string \| Date \| null` | `null` | Minimum selectable date |
| `max` | `string \| Date \| null` | `null` | Maximum selectable date |

## Examples

### Basic Date Range Selector

```svelte
<script>
  import DateRangeEditor from '$lib/date-range';
  
  let startDate = null;
  let endDate = null;
</script>

<DateRangeEditor 
  bind:fromValue={startDate} 
  bind:toValue={endDate} 
/>
```

### Outlined Date Range with Custom Format

```svelte
<DateRangeEditor 
  variant="outlined"
  bind:fromValue={projectStart} 
  bind:toValue={projectEnd}
  format="DD/MM/YYYY"
/>
```

### Filled Compact Date Range

```svelte
<DateRangeEditor 
  variant="filled"
  compact
  bind:fromValue={reportFrom} 
  bind:toValue={reportTo}
/>
```

### Date Range with Min/Max Constraints

```svelte
<script>
  // Only allow dates within the current year
  const currentYear = new Date().getFullYear();
  const yearStart = new Date(currentYear, 0, 1);
  const yearEnd = new Date(currentYear, 11, 31);
</script>

<DateRangeEditor 
  variant="outlined"
  bind:fromValue={periodStart} 
  bind:toValue={periodEnd}
  min={yearStart}
  max={yearEnd}
/>
```

### Custom Styled Date Range

```svelte
<DateRangeEditor 
  variant="filled"
  style="width: 300px; margin: 10px;"
  class="custom-date-range"
  bind:fromValue={eventStart} 
  bind:toValue={eventEnd}
  format="MMM DD, YYYY"
/>
```

## Smart Date Validation

The component automatically enforces logical date constraints:

- **From Date Maximum**: Cannot exceed the selected "to" date or global `max` value
- **To Date Minimum**: Cannot be before the selected "from" date or global `min` value
- **Global Constraints**: Both dates respect the `min` and `max` props

```svelte
<script>
  let checkIn = new Date('2024-01-15');
  let checkOut = null; // Will be constrained to dates after checkIn
</script>

<DateRangeEditor 
  bind:fromValue={checkIn} 
  bind:toValue={checkOut}
  min={new Date()} // No past dates allowed
/>
```

## Date Formats

The `format` prop supports Day.js formatting tokens:

| Format | Example | Description |
|--------|---------|-------------|
| `YYYY-MM-DD` | 2024-03-15 | ISO format (default) |
| `DD/MM/YYYY` | 15/03/2024 | European format |
| `MM/DD/YYYY` | 03/15/2024 | US format |
| `MMM DD, YYYY` | Mar 15, 2024 | Long month name |
| `DD MMM YYYY` | 15 Mar 2024 | Day-month-year |

```svelte
<!-- Different format examples -->
<DateRangeEditor format="DD/MM/YYYY" bind:fromValue={start} bind:toValue={end} />
<DateRangeEditor format="MMM DD, YYYY" bind:fromValue={start} bind:toValue={end} />
<DateRangeEditor format="DD MMM YYYY" bind:fromValue={start} bind:toValue={end} />
```

## Calendar Interaction

### Dual Calendar Layout

The popup displays two side-by-side calendars:
- **Left Calendar**: For selecting the "from" date
- **Right Calendar**: For selecting the "to" date
- **Smart Constraints**: Each calendar respects the constraints based on the other's selection

### Selection Workflow

1. Click anywhere on the component to open the popup
2. Select start date from the left calendar
3. Select end date from the right calendar (automatically closes popup)
4. Use the clear button (×) to reset both dates

## Variants

### Default (`''`)
Basic styling with standard borders and backgrounds.

```svelte
<DateRangeEditor bind:fromValue={start} bind:toValue={end} />
```

### Plain (`'plain'`)
Minimal styling with reduced visual elements.

```svelte
<DateRangeEditor variant="plain" bind:fromValue={start} bind:toValue={end} />
```

### Outlined (`'outlined'`)
Prominent border styling for emphasis.

```svelte
<DateRangeEditor variant="outlined" bind:fromValue={start} bind:toValue={end} />
```

### Filled (`'filled'`)
Background-filled styling for better visual hierarchy.

```svelte
<DateRangeEditor variant="filled" bind:fromValue={start} bind:toValue={end} />
```

## Integration with Forms

The DateRangeEditor works seamlessly with form layouts and FormField components:

```svelte
<script>
  import FormField from '$lib/form-field';
  import DateRangeEditor from '$lib/date-range';
</script>

<FormField label="Project Duration">
  <DateRangeEditor 
    variant="outlined"
    bind:fromValue={projectStart} 
    bind:toValue={projectEnd}
  />
</FormField>

<FormField label="Reporting Period">
  <DateRangeEditor 
    variant="filled"
    format="MMM DD, YYYY"
    bind:fromValue={reportStart} 
    bind:toValue={reportEnd}
  />
</FormField>
```

## Styling

The component inherits styling from the Uniface design system and can be customized:

```css
.custom-date-range {
  --uniface-inside-border-color: #e0e0e0;
  --uniface-primary-color: #1976d2;
}

.uniface-range-editor {
  /* Custom styling for the range editor */
}

.date-popover {
  /* Custom styling for the popup */
}
```

## Accessibility

- **Keyboard Navigation**: Tab through input fields and use Enter/Space to open popup
- **ARIA Support**: Proper labeling and descriptions for screen readers
- **Focus Management**: Logical focus flow and clear visual indicators
- **Readonly Inputs**: Prevents invalid manual input while maintaining accessibility

## Event Handling

```svelte
<script>
  import DateRangeEditor from '$lib/date-range';
  
  let fromDate = null;
  let toDate = null;
  
  // React to changes
  $: if (fromDate && toDate) {
    console.log('Date range selected:', fromDate, 'to', toDate);
    calculateDateDifference();
  }
  
  function calculateDateDifference() {
    if (fromDate && toDate) {
      const diffTime = Math.abs(toDate - fromDate);
      const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
      console.log(`Duration: ${diffDays} days`);
    }
  }
</script>

<DateRangeEditor 
  bind:fromValue={fromDate} 
  bind:toValue={toDate}
  on:blur={() => console.log('Range editor lost focus')}
/>
```

## Type Definitions

```typescript
type UniDate = Date | dayjs.Dayjs | string | null;

interface DateRangeEditorProps {
  fromValue: UniDate;
  toValue: UniDate;
  variant?: '' | 'plain' | 'outlined' | 'filled';
  compact?: boolean;
  style?: string;
  class?: string;
  format?: string;
  min?: string | Date | null;
  max?: string | Date | null;
}
```

## Common Use Cases

### Project Timeline Selection
```svelte
<DateRangeEditor 
  variant="outlined"
  bind:fromValue={projectStart} 
  bind:toValue={projectEnd}
  format="MMM DD, YYYY"
/>
```

### Booking Date Range
```svelte
<DateRangeEditor 
  variant="filled"
  bind:fromValue={checkIn} 
  bind:toValue={checkOut}
  min={new Date()} // No past dates
/>
```

### Report Period Filter
```svelte
<DateRangeEditor 
  compact
  bind:fromValue={reportFrom} 
  bind:toValue={reportTo}
  format="DD/MM/YYYY"
/>
```

### Event Duration
```svelte
<DateRangeEditor 
  variant="outlined"
  bind:fromValue={eventStart} 
  bind:toValue={eventEnd}
  min={new Date()}
  max={new Date(Date.now() + 365 * 24 * 60 * 60 * 1000)} // Max 1 year ahead
/>
```

## Notes

- The component uses Day.js internally for date manipulation and formatting
- Input fields are readonly to prevent invalid manual entry
- Popup automatically positions itself to fit within the viewport
- Clear functionality is only shown when at least one date is selected
- Date constraints are enforced in real-time as selections are made
- The component maintains internal state for popup visibility and constraints