# Date Dropper & Wheel Picker

# Date Dropper & Wheel Picker

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [src/lib/browser-iana-timezone.ts](src/lib/browser-iana-timezone.ts)
- [src/lib/components/date-dropper/date-wheel-picker.svelte](src/lib/components/date-dropper/date-wheel-picker.svelte)
- [src/lib/components/ui/wheel-picker/ctx.svelte.ts](src/lib/components/ui/wheel-picker/ctx.svelte.ts)
- [src/lib/components/ui/wheel-picker/wheel-picker-group.svelte](src/lib/components/ui/wheel-picker/wheel-picker-group.svelte)
- [src/lib/components/ui/wheel-picker/wheel-picker-item.svelte](src/lib/components/ui/wheel-picker/wheel-picker-item.svelte)
- [src/lib/components/ui/wheel-picker/wheel-picker.svelte](src/lib/components/ui/wheel-picker/wheel-picker.svelte)
- [src/lib/entity-list/format-datetime-iana-cell.ts](src/lib/entity-list/format-datetime-iana-cell.ts)
- [src/lib/entity-list/index.ts](src/lib/entity-list/index.ts)

</details>



The Date Dropper system provides a touch-friendly, wheel-based interface for selecting dates and times. It is built upon a custom `WheelPicker` primitive and supports high-precision `CalendarDate` and `CalendarDateTime` objects from the `@internationalized/date` library.

## 1. DateDropper Component

The `DateDropper` (implemented as `date-wheel-picker.svelte`) is the primary UI component for date selection. It wraps the wheel selection logic in a `Popover` and handles the conversion between internal wheel states and structured date objects [src/lib/components/date-dropper/date-wheel-picker.svelte:1-26]().

### 1.1 Value Types and Props
The component supports two primary modes of operation based on the `includeTime` prop:
*   **CalendarDate**: Used when `includeTime` is false.
*   **CalendarDateTime**: Used when `includeTime` is true, adding hour, minute, and second precision [src/lib/components/date-dropper/date-wheel-picker.svelte:176-191]().

| Prop | Type | Description |
| :--- | :--- | :--- |
| `value` | `CalendarDate \| CalendarDateTime` | The $bindable value representing the selected point in time [src/lib/components/date-dropper/date-wheel-picker.svelte:26-26](). |
| `includeTime` | `boolean` | Enables time selection (hours/minutes/seconds) [src/lib/components/date-dropper/date-wheel-picker.svelte:26-26](). |
| `timezone` | `string` | $bindable IANA timezone string [src/lib/components/date-dropper/date-wheel-picker.svelte:26-26](). |
| `defaultTime` | `string` | Optional "HH:mm:ss" string to initialize the time wheels [src/lib/components/date-dropper/date-wheel-picker.svelte:26-26](). |

### 1.2 Timezone Management
The component integrates with the browser's IANA timezone database. It uses `getResolvedIanaTimeZone` to detect the user's system timezone on mount [src/lib/components/date-dropper/date-wheel-picker.svelte:80-85]().
*   **IANA Toggle**: Users can search and select from all supported IANA timezones via an internal `DropdownMenu` [src/lib/components/date-dropper/date-wheel-picker.svelte:93-124]().
*   **Display Logic**: Timezones are retrieved via `Intl.supportedValuesOf('timeZone')` with a fallback list for legacy environments [src/lib/components/date-dropper/date-wheel-picker.svelte:93-116]().

**Sources:**
* [src/lib/components/date-dropper/date-wheel-picker.svelte:26-124]()
* [src/lib/browser-iana-timezone.ts:6-13]()

---

## 2. WheelPicker Primitive

The `WheelPicker` is a low-level UI primitive that provides a 3D-rotated, scrollable selection interface. It uses Svelte 5 Runes for reactive state management across a group of items.

### 2.1 Component Architecture
The system is divided into three parts:
1.  **WheelPicker (Container)**: Provides the 3D perspective and visual overlays (gradients and selection highlight) [src/lib/components/ui/wheel-picker/wheel-picker.svelte:12-32]().
2.  **WheelPickerGroup**: Manages the physics, scrolling, and snapping logic for a single column (e.g., "Month" or "Hour") [src/lib/components/ui/wheel-picker/wheel-picker-group.svelte:7-19]().
3.  **WheelPickerItem**: Individual selectable nodes that calculate their own 3D transform based on their distance from the center [src/lib/components/ui/wheel-picker/wheel-picker-item.svelte:33-73]().

### 2.2 State Management (`ctx.svelte.ts`)
The `WheelState` class uses `$state` to share real-time scroll positions and dragging status between the group and its items [src/lib/components/ui/wheel-picker/ctx.svelte.ts:5-10]().

### 2.3 Physics and Interaction
The `WheelPickerGroup` implements custom scroll physics:
*   **Inertia**: Calculates velocity during drag and continues movement after release with friction [src/lib/components/ui/wheel-picker/wheel-picker-group.svelte:143-165]().
*   **Snapping**: Automatically aligns the nearest item to the center highlight using `snapToNearest` [src/lib/components/ui/wheel-picker/wheel-picker-group.svelte:168-171]().
*   **Looping**: If `loop` is enabled, items wrap around infinitely using modulo arithmetic on the scroll position [src/lib/components/ui/wheel-picker/wheel-picker-group.svelte:72-79]().

### Wheel Picker Data Flow
The following diagram illustrates how interaction with the UI updates the shared context and eventually the bound value.

Title: Wheel Picker Interaction Flow
```mermaid
graph TD
    subgraph "User Input"
        "onmousedown"["onmousedown / ontouchstart"]
        "onwheel"["onwheel"]
    end

    subgraph "WheelPickerGroup (Logic)"
        "handleStart"["handleStart()"]
        "setScroll"["setScroll(y)"]
        "snapTo"["snapTo(targetY)"]
        "commitValue"["commitValue()"]
    end

    subgraph "WheelState (Context)"
        "translateY"["$state: translateY"]
        "isDragging"["$state: isDragging"]
    end

    subgraph "WheelPickerItem (View)"
        "calcTransform"["calculate 3D transform"]
        "isSelected"["aria-selected"]
    end

    "onmousedown" --> "handleStart"
    "onwheel" --> "setScroll"
    "handleStart" --> "isDragging"
    "setScroll" --> "translateY"
    "translateY" --> "calcTransform"
    "translateY" --> "isSelected"
    "snapTo" --> "commitValue"
    "commitValue" --> "val_update"["Update $bindable value"]
```

**Sources:**
* [src/lib/components/ui/wheel-picker/wheel-picker.svelte:12-32]()
* [src/lib/components/ui/wheel-picker/wheel-picker-group.svelte:100-245]()
* [src/lib/components/ui/wheel-picker/wheel-picker-item.svelte:33-73]()
* [src/lib/components/ui/wheel-picker/ctx.svelte.ts:1-32]()

---

## 3. Integration with Entity List

The Date Dropper is heavily utilized within the `FiltersPanel` for filtering entity records by date or datetime fields.

### 3.1 Date Normalization and Formatting
When displaying dates in the `EntityListTable`, the system differentiates between the browser's local time and the time stored in the record (if an IANA timezone field is present).

*   **`formatDatetimeIanaListCell`**: This function determines whether to format the date using the user's browser locale or a specific IANA timezone defined in the record's metadata [src/lib/entity-list/format-datetime-iana-cell.ts:6-24]().
*   **`datetimeIanaToggle`**: A configuration in the `MetaColumn` that indicates if a column should support switching between local and record-specific timezones [src/lib/entity-list/format-datetime-iana-cell.ts:12-14]().

### Date Processing Architecture
This diagram shows the relationship between the raw data from the API and the UI components.

Title: Date Processing and Rendering Pipeline
```mermaid
graph LR
    subgraph "Data Layer"
        "API_Row"["API Row Record"]
        "MetaColumn"["MetaColumn Config"]
    end

    subgraph "Formatting Logic"
        "formatDatetimeIanaListCell"["formatDatetimeIanaListCell()"]
        "formatUiDateTimeInTimeZone"["formatUiDateTimeInTimeZone()"]
    end

    subgraph "UI Components"
        "DateDropper"["DateDropper Component"]
        "FiltersPanel"["FiltersPanel (Inputs)"]
        "TableCell"["EntityListTable Cell"]
    end

    "API_Row" --> "formatDatetimeIanaListCell"
    "MetaColumn" --> "formatDatetimeIanaListCell"
    "formatDatetimeIanaListCell" --> "formatUiDateTimeInTimeZone"
    "formatUiDateTimeInTimeZone" --> "TableCell"
    "DateDropper" -- "produces" --> "CalendarDateTime"
    "CalendarDateTime" -- "filter input" --> "FiltersPanel"
```

**Sources:**
* [src/lib/entity-list/format-datetime-iana-cell.ts:1-50]()
* [src/lib/entity-list/index.ts:1-4]()

---
