# Custom Dropdowns & Date Pickers Design **Goal:** Replace all native `` elements with custom Vue 3 components that match ZeroClock's dark UI. **Architecture:** Two reusable components (`AppSelect`, `AppDatePicker`) using `` for overflow-safe positioning. Drop-in replacements — no store or logic changes needed. --- ## Inventory ### Native `` (6 instances) 1. **Entries.vue** — Start Date filter 2. **Entries.vue** — End Date filter 3. **Reports.vue** — Start Date 4. **Reports.vue** — End Date 5. **Invoices.vue** — Invoice Date (required) 6. **Invoices.vue** — Due Date (optional) --- ## Component 1: AppSelect ### Trigger - Styled like existing inputs: `bg-bg-inset`, `border-border-subtle`, `rounded-xl` - Shows selected label or placeholder in `text-text-tertiary` - `ChevronDown` icon (Lucide) on right, rotates 180deg when open - Disabled state: `opacity-40`, `cursor-not-allowed` ### Dropdown Panel - Teleported to ``, positioned via `getBoundingClientRect()` - `bg-bg-surface`, `border border-border-visible`, `rounded-xl`, shadow - Max-height with overflow-y scroll - Options: hover `bg-bg-elevated`, selected item shows `Check` icon in accent color - Animate in: scale + fade (150ms) ### API ```vue ``` ### Behavior - Click trigger toggles open/close - Click option selects and closes - Click outside closes - Keyboard: Arrow keys navigate, Enter selects, Escape closes - Tab moves focus away and closes --- ## Component 2: AppDatePicker ### Trigger - Text input showing formatted date ("Feb 17, 2026") or placeholder - `Calendar` icon (Lucide) on right - Same input styling as AppSelect trigger ### Calendar Popover - Teleported to ``, positioned below trigger - Header: `ChevronLeft`/`ChevronRight` arrows, center "Month Year" label - 7-column grid: Mon-Sun header row, day cells - Prev/next month padding days in `text-text-tertiary` - Today: ring/border in amber accent - Selected: solid amber accent background, white text - Hover: `bg-bg-elevated` - Click day: selects, closes popover, updates model ### API ```vue ``` ### Behavior - v-model is `YYYY-MM-DD` string (same format as native date input) - Click trigger opens calendar - Click outside closes - Keyboard: Arrow keys navigate days, Enter selects, Escape closes - Month navigation via chevron buttons --- ## Integration Pure visual swap — replace each native element with the custom component, keep the same `v-model` binding. No store or routing changes. **Files created:** `src/components/AppSelect.vue`, `src/components/AppDatePicker.vue` **Files modified:** Timer.vue, Projects.vue, Entries.vue, Invoices.vue, Reports.vue The `datetime-local` input in Entries.vue edit dialog stays as-is (not in scope).