Skip to content

feat: add native date picker prompt#1057

Merged
chhoumann merged 3 commits intomasterfrom
288
Dec 20, 2025
Merged

feat: add native date picker prompt#1057
chhoumann merged 3 commits intomasterfrom
288

Conversation

@chhoumann
Copy link
Copy Markdown
Owner

@chhoumann chhoumann commented Dec 20, 2025

CleanShot 2025-12-20 at 18 44 13

Summary

  • add native calendar picker to VDATE prompts and One Page Input date fields
  • normalize @Date:ISO handling in formatter and prompt flow
  • add QuickAdd API datePrompt helper and date picker styles

Reproduction

  1. Trigger a VDATE prompt (e.g. {{VDATE:due,YYYY-MM-DD}}).
  2. Pick a date from the calendar and submit.
  3. Use One Page Input with a date requirement (preflight or quickAddApi.requestInputs).

Testing

  • bun run build-with-lint

Summary by CodeRabbit

  • New Features

    • Interactive calendar date picker with live preview and synchronized input.
    • QuickAdd API: added datePrompt for scripted date entry with optional formatting.
  • Bug Fixes / Behavior

    • Preserves special @Date: inputs; only parses/normalizes when parsing succeeds to avoid incorrect storage.
  • Tests

    • Added tests and mocks covering @Date: handling and prompt behavior.
  • Style

    • New styles for date input and picker UI.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Copy Markdown

vercel Bot commented Dec 20, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
quickadd Ready Ready Preview Dec 20, 2025 5:57pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 20, 2025

Walkthrough

Adds a date-picker UI and integrations across prompts and modal inputs, updates formatter to treat @date:-prefixed values as already normalized, exposes a QuickAdd API datePrompt, adds tests/mocks and styles, and wires picker ↔ input synchronization and submit-time transformation.

Changes

Cohort / File(s) Summary
Date Picker Component
src/gui/date-picker/datePicker.ts
New interactive calendar widget with factory createDatePicker, DatePickerController API, ISO/date parsing and formatting, month navigation, 6-week grid rendering, selection/clear/today actions, and accessibility attributes.
VDate Input Prompt
src/gui/VDateInputPrompt/VDateInputPrompt.ts
Integrates date picker, adds picker state (selectedIso, lastPickerDisplayValue), sync/apply/clear helpers, ISO formatting for input, preview rendering from ISO or natural language, input change handling, and protected transformInputOnSubmit to emit @date:ISO when appropriate.
Generic Input Prompt Base
src/gui/GenericInputPrompt/GenericInputPrompt.ts
inputComponent visibility relaxed to protected; added protected transformInputOnSubmit(input: string): string; submit() now applies transformer before storing input.
One-page Modal Date Field
src/preflight/OnePageInputModal.ts
Replaces plain date input with picker-enabled container, wires createDatePicker, supports @date:ISO defaults, live parsing/preview, and picker-driven selection/clear behavior with helper functions for sync/render.
Formatter Behavior
src/formatters/formatter.ts
Date handling changed: values starting with @date: are stored as-is (parser skipped); non-@date: values parsed only if parser exists and parsing succeeds; unconditional raw storage removed and errors thrown on parse failure.
QuickAdd API
src/quickAddApi.ts
Adds QuickAddApi.datePrompt(app, header, options) and exposes datePrompt on public API (GetApi), supporting placeholder, defaultValue, dateFormat, and existing cancellation semantics.
Styles
src/styles.css
New CSS for date input and picker UI (qa-date-input, qa-date-picker-container, navigation, day grid, states, actions).
Tests / Mocks
src/gui/VDateInputPrompt/vdate-default.test.ts, src/engine/MacroChoiceEngine.entry.test.ts
New test verifying @date: default handling bypasses parser; engine tests add a mock for VDateInputPrompt to stub prompt behavior.

Sequence Diagram

sequenceDiagram
    participant User
    participant QuickAddAPI
    participant VDateInputPrompt
    participant DatePicker
    participant Formatter

    User->>QuickAddAPI: datePrompt(header, options)
    QuickAddAPI->>VDateInputPrompt: show prompt
    VDateInputPrompt->>DatePicker: createDatePicker(container)
    DatePicker-->>VDateInputPrompt: ready

    alt User selects date in picker
        User->>DatePicker: click date
        DatePicker->>VDateInputPrompt: onSelect(iso,"picker")
        VDateInputPrompt->>VDateInputPrompt: syncPickerSelection(iso)
        VDateInputPrompt->>VDateInputPrompt: renderPreviewFromIso(iso)
    else User types input
        User->>VDateInputPrompt: type input
        VDateInputPrompt->>VDateInputPrompt: renderPreviewFromInput(value)
        VDateInputPrompt->>DatePicker: setSelectedIso(iso?)
    end

    User->>VDateInputPrompt: submit
    VDateInputPrompt->>VDateInputPrompt: transformInputOnSubmit(input) -> value
    VDateInputPrompt->>Formatter: store value
    Formatter->>Formatter: if startsWith("@date:") skip parse else parse/normalize (or error)

    VDateInputPrompt-->>QuickAddAPI: return value / cancel
    QuickAddAPI-->>User: promise resolved/rejected
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Focus review on:
    • src/gui/date-picker/datePicker.ts — date math, ISO conversions, render loop, ARIA and DOM cleanup.
    • src/gui/VDateInputPrompt/VDateInputPrompt.ts and src/preflight/OnePageInputModal.ts — state sync between input, parser, and picker; transformInputOnSubmit behavior.
    • src/formatters/formatter.ts — correct @date: detection, conditional parsing, and error paths.
    • src/quickAddApi.ts — API surface changes and cancellation semantics.

Possibly related PRs

Poem

🐰 I hop through months and tiny squares,

I nudge an ISO into your snares,
Pickers hum and inputs sing,
Press submit — the organized spring! ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add native date picker prompt' directly and concisely describes the main feature addition—a native date picker integrated into the prompt system.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 288

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
src/preflight/OnePageInputModal.ts (1)

193-200: Missing cleanup for date picker controller.

The datePicker is created via createDatePicker() but there's no corresponding destroy() call when the modal closes. While Obsidian modals typically clean up their DOM, the date picker may hold references or event listeners that should be explicitly released.

Consider storing the controller and calling destroy() in the modal's close handler.

🔎 Suggested approach

Store date picker references and clean them up:

// Add field to class
private datePickerControllers: DatePickerController[] = [];

// In renderField for date type:
this.datePickerControllers.push(datePicker);

// Override onClose:
onClose() {
  this.datePickerControllers.forEach(dp => dp.destroy());
  super.onClose();
}
src/gui/VDateInputPrompt/VDateInputPrompt.ts (1)

19-21: Missing cleanup for date picker controller.

Similar to OnePageInputModal, the datePicker controller is created but destroy() is never called. Add cleanup in onClose():

🔎 Suggested fix
 onClose() {
   // Prevent any pending debounced updates
   this.isOpen = false;

   // Cancel any pending debounced calls
   this.updatePreviewDebounced.cancel();

+  // Clean up date picker
+  this.datePicker?.destroy();
+
   // If input is empty and we have a default, use the default
   if (!this.input.trim() && this.defaultValue) {
     this.input = this.defaultValue;
   }

   super.onClose();
 }
src/gui/date-picker/datePicker.ts (3)

176-181: Consider creating the ARIA formatter once.

The ariaFormatter is recreated on every render, which is called whenever the selection or view month changes. Since the formatter options are static, creating it once outside the render function would improve efficiency.

🔎 Suggested refactor

Move the formatter creation to line 75 (after weekdayLabels):

 	const weekStartsOn = getWeekStartsOn(options.weekStartsOn);
 	const weekdayLabels = getWeekdayLabels(weekStartsOn);
+	const ariaFormatter = new Intl.DateTimeFormat(undefined, {
+		weekday: "long",
+		year: "numeric",
+		month: "long",
+		day: "numeric",
+	});

 	const initialDate =
 		parseIsoToDate(options.initialIso) ?? new Date();

Then remove lines 176-181 from the render function.


183-214: Consider simplifying date calculation in the render loop.

Lines 184-185 compute each cell's date by creating a copy of startDate and then setting the date to startDate.getDate() + i. While correct, this pattern is less idiomatic and slightly inefficient.

🔎 More idiomatic alternative
 		for (let i = 0; i < 42; i += 1) {
-			const date = new Date(startDate);
-			date.setDate(startDate.getDate() + i);
+			const date = new Date(startDate.getTime() + i * 86400000);

 			const dayKey = toDateKey(date);

Or use setDate on the copied date itself:

 		for (let i = 0; i < 42; i += 1) {
 			const date = new Date(startDate);
-			date.setDate(startDate.getDate() + i);
+			date.setDate(date.getDate() + i);

 			const dayKey = toDateKey(date);

85-122: Good accessibility implementation.

The component includes proper ARIA labels for navigation buttons (lines 91, 100) and day buttons (line 197), sets aria-pressed for selected days (line 203), and correctly specifies type="button" to prevent form submission.

Optional enhancement: Consider adding role="grid" to the calendar grid and an aria-live region for month changes to improve screen reader announcements during navigation.

Also applies to: 192-213

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 231e908 and 395bdb8.

📒 Files selected for processing (8)
  • src/formatters/formatter.ts (1 hunks)
  • src/formatters/vdate-default.test.ts (1 hunks)
  • src/gui/GenericInputPrompt/GenericInputPrompt.ts (2 hunks)
  • src/gui/VDateInputPrompt/VDateInputPrompt.ts (7 hunks)
  • src/gui/date-picker/datePicker.ts (1 hunks)
  • src/preflight/OnePageInputModal.ts (3 hunks)
  • src/quickAddApi.ts (3 hunks)
  • src/styles.css (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Source code lives in src/: core logic under engine/, services/, and utils/; Svelte UI in src/gui; shared types in src/types; settings entry in src/quickAddSettingsTab.ts

Files:

  • src/preflight/OnePageInputModal.ts
  • src/formatters/vdate-default.test.ts
  • src/gui/GenericInputPrompt/GenericInputPrompt.ts
  • src/gui/VDateInputPrompt/VDateInputPrompt.ts
  • src/formatters/formatter.ts
  • src/gui/date-picker/datePicker.ts
  • src/quickAddApi.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Biome enforces tab indentation (width 2), LF endings, and an 80-character line guide; align editor settings
Use camelCase for variables and functions
Prefer type-only imports in TypeScript files
Route logging through the logger utilities for consistent output
Structure production code so Obsidian dependencies are injected behind interfaces; unit tests target pure logic and swap in adapters or tests/obsidian-stub.ts

Files:

  • src/preflight/OnePageInputModal.ts
  • src/formatters/vdate-default.test.ts
  • src/gui/GenericInputPrompt/GenericInputPrompt.ts
  • src/gui/VDateInputPrompt/VDateInputPrompt.ts
  • src/formatters/formatter.ts
  • src/gui/date-picker/datePicker.ts
  • src/quickAddApi.ts
src/**/*.{ts,tsx,svelte}

📄 CodeRabbit inference engine (AGENTS.md)

Use PascalCase for classes and Svelte components

Files:

  • src/preflight/OnePageInputModal.ts
  • src/formatters/vdate-default.test.ts
  • src/gui/GenericInputPrompt/GenericInputPrompt.ts
  • src/gui/VDateInputPrompt/VDateInputPrompt.ts
  • src/formatters/formatter.ts
  • src/gui/date-picker/datePicker.ts
  • src/quickAddApi.ts
🧠 Learnings (1)
📚 Learning: 2025-12-09T21:20:52.425Z
Learnt from: CR
Repo: chhoumann/quickadd PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T21:20:52.425Z
Learning: Applies to tests/**/*.{ts,tsx} : Add regression coverage for bug fixes

Applied to files:

  • src/formatters/vdate-default.test.ts
🧬 Code graph analysis (6)
src/preflight/OnePageInputModal.ts (3)
src/utils/dateParser.ts (2)
  • formatISODate (70-85)
  • parseNaturalLanguageDate (21-62)
src/gui/VDateInputPrompt/VDateInputPrompt.ts (4)
  • createDatePicker (99-112)
  • applyPickerSelection (220-231)
  • clearPickerSelection (233-243)
  • updatePreview (165-208)
src/gui/date-picker/datePicker.ts (1)
  • createDatePicker (71-243)
src/gui/GenericInputPrompt/GenericInputPrompt.ts (1)
tests/obsidian-stub.ts (1)
  • TextComponent (122-149)
src/gui/VDateInputPrompt/VDateInputPrompt.ts (2)
src/gui/date-picker/datePicker.ts (2)
  • DatePickerController (3-10)
  • createDatePicker (71-243)
src/utils/dateParser.ts (2)
  • formatISODate (70-85)
  • parseNaturalLanguageDate (21-62)
src/formatters/formatter.ts (2)
src/settingsStore.ts (1)
  • settingsStore (8-21)
src/utils/dateAliases.ts (1)
  • normalizeDateInput (15-30)
src/gui/date-picker/datePicker.ts (2)
tests/obsidian-stub.ts (1)
  • moment (475-475)
src/gui/VDateInputPrompt/VDateInputPrompt.ts (1)
  • createDatePicker (99-112)
src/quickAddApi.ts (2)
src/gui/VDateInputPrompt/VDateInputPrompt.ts (1)
  • VDateInputPrompt (12-324)
src/utils/dateParser.ts (1)
  • formatISODate (70-85)
🪛 GitHub Actions: Test
src/gui/VDateInputPrompt/VDateInputPrompt.ts

[error] 12-12: TypeError: Class extends value # is not a constructor or null. The class VDateInputPrompt extends GenericInputPrompt likely due to an incorrect import or circular dependency.

src/quickAddApi.ts

[error] 19-19: TypeError: Class extends value # is not a constructor or null. Retrieved during test execution; stack may reference VDateInputPrompt.ts.

🔇 Additional comments (13)
src/gui/GenericInputPrompt/GenericInputPrompt.ts (2)

13-13: LGTM - Visibility change enables subclass access.

Changing inputComponent from private to protected allows subclasses like VDateInputPrompt to access the input element for synchronization with the date picker.


177-183: LGTM - Clean hook pattern for input transformation.

The transformInputOnSubmit hook with an identity default enables subclasses to customize submission behavior without modifying the base class logic. The submit flow correctly reads the raw value, transforms it, and assigns the result.

src/formatters/vdate-default.test.ts (1)

192-200: LGTM - Good regression test for @Date: bypass behavior.

This test verifies the critical behavior that values prefixed with @date: bypass date parsing and are formatted directly using the stored ISO string. This aligns with the formatter changes and provides regression coverage. Based on learnings, this adds appropriate coverage for the new feature.

src/styles.css (1)

174-271: LGTM - Well-structured date picker styles.

The new date picker CSS uses appropriate CSS custom properties for theme consistency (e.g., var(--background-modifier-border), var(--interactive-accent)). The grid layout, hover states, and action button styling are clean and follow existing QuickAdd patterns.

src/formatters/formatter.ts (1)

475-499: LGTM - Robust date handling with proper guards.

The logic correctly:

  1. Bypasses parsing for values already prefixed with @date:
  2. Guards against missing dateParser before attempting normalization/parsing
  3. Normalizes input using aliases before parsing
  4. Throws explicit errors when parsing fails, preventing silent failures

This ensures consistent @date:ISO storage and proper error propagation.

src/preflight/OnePageInputModal.ts (1)

263-283: LGTM - Proper default value handling with picker sync.

The updatePreview function correctly handles the default value case by parsing it, storing the ISO string, syncing the picker selection, and rendering the preview. The error path also properly clears state and shows the error message.

src/quickAddApi.ts (1)

555-584: LGTM - Clean datePrompt API implementation.

The implementation correctly:

  1. Delegates to VDateInputPrompt.Prompt with the provided options
  2. Extracts the ISO string from @date: prefixed values
  3. Applies optional dateFormat for user-friendly output
  4. Returns the raw ISO if no format is specified or formatting fails
  5. Follows existing error handling patterns with throwIfPromptCancelled
src/gui/VDateInputPrompt/VDateInputPrompt.ts (3)

99-112: LGTM - Date picker integration is well-structured.

The createDatePicker method properly:

  1. Creates a container with appropriate styling class
  2. Initializes the picker with the current selectedIso
  3. Wires up onSelect to apply or clear selections

The picker controller is stored for later synchronization.


282-308: LGTM - Robust input transformation on submit.

The transformInputOnSubmit method correctly handles all cases:

  1. Already prefixed with @date: → return as-is
  2. Input matches picker selection → convert to @date:ISO
  3. Empty with default value → parse default and convert
  4. Regular input → parse and convert if valid
  5. Fallback → return original input

This ensures consistent @date: prefixed output for downstream processing.


3-12: Import structure is correct—no circular dependency exists.

Investigation confirms the import chain is one-directional: VDateInputPrompt imports GenericInputPrompt, which does not import back from VDateInputPrompt or any module that would create a cycle. GenericInputPrompt properly exports export default class. The originally reported pipeline failure, if real, is not caused by the circular dependency concern described in this comment.

Likely an incorrect or invalid review comment.

src/gui/date-picker/datePicker.ts (3)

1-17: LGTM! Well-structured public API.

The type definitions and interfaces provide a clean, well-typed API surface with clear semantics for selection sources and controller methods.


220-230: LGTM! Correct default behavior.

The updateView !== false check ensures the view updates by default (when updateView is undefined), while allowing explicit opt-out with updateView: false. This provides a good developer experience.


21-28: LGTM! Robust fallback logic.

The function properly validates the explicit weekStartsOn option, falls back to the moment locale setting if available, and defaults to 0 (Sunday). The range checks and optional chaining ensure safe operation.

Comment thread src/gui/date-picker/datePicker.ts
Comment on lines +63 to +69
const toIsoFromParts = (year: number, month: number, day: number): string => {
const moment = window.moment;
if (moment) {
return moment({ year, month, day }).startOf("day").toISOString();
}
return new Date(year, month, day).toISOString();
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Consider using UTC midnight for consistent date handling.

The current implementation creates dates at midnight local time, then converts to ISO UTC. This causes the ISO string's date portion to shift for timezones ahead of UTC.

Example: User in UTC+8 selects January 1, 2024:

  • Line 68 produces: "2023-12-31T16:00:00.000Z"
  • Date portion shows December 31, not January 1

This can lead to confusion if consumers parse the ISO string as a UTC date or if data crosses timezones.

🔎 Proposed fix for consistent UTC midnight
 const toIsoFromParts = (year: number, month: number, day: number): string => {
 	const moment = window.moment;
 	if (moment) {
-		return moment({ year, month, day }).startOf("day").toISOString();
+		return moment.utc({ year, month, day }).toISOString();
 	}
-	return new Date(year, month, day).toISOString();
+	return new Date(Date.UTC(year, month, day)).toISOString();
 };

This ensures the ISO date portion always matches the selected calendar date.

Note: Line 66's .startOf("day") is redundant since moment({ year, month, day }) already creates midnight.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const toIsoFromParts = (year: number, month: number, day: number): string => {
const moment = window.moment;
if (moment) {
return moment({ year, month, day }).startOf("day").toISOString();
}
return new Date(year, month, day).toISOString();
};
const toIsoFromParts = (year: number, month: number, day: number): string => {
const moment = window.moment;
if (moment) {
return moment.utc({ year, month, day }).toISOString();
}
return new Date(Date.UTC(year, month, day)).toISOString();
};
🤖 Prompt for AI Agents
In src/gui/date-picker/datePicker.ts around lines 63 to 69, the function creates
midnight in local time then converts to ISO which shifts the date for non-UTC
timezones; change it to create UTC-midnight instead: when moment is available
use moment.utc({ year, month, day }) (no startOf needed) and otherwise use new
Date(Date.UTC(year, month, day)).toISOString() so the ISO date portion always
matches the selected calendar date.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/gui/date-picker/datePicker.ts (1)

76-78: Consider renaming to reflect date-only format.

The function name toIsoFromParts suggests a full ISO 8601 timestamp, but it returns only the date portion ("YYYY-MM-DD"). Consider renaming to toDateStringFromParts or formatDateFromParts for clarity.

🔎 Proposed rename
-const toIsoFromParts = (year: number, month: number, day: number): string => {
+const toDateStringFromParts = (year: number, month: number, day: number): string => {
 	return formatDateKey(year, month, day);
 };

Then update the call sites at lines 161, 216.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bcd9548 and c91d512.

📒 Files selected for processing (1)
  • src/gui/date-picker/datePicker.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Source code lives in src/: core logic under engine/, services/, and utils/; Svelte UI in src/gui; shared types in src/types; settings entry in src/quickAddSettingsTab.ts

Files:

  • src/gui/date-picker/datePicker.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Biome enforces tab indentation (width 2), LF endings, and an 80-character line guide; align editor settings
Use camelCase for variables and functions
Prefer type-only imports in TypeScript files
Route logging through the logger utilities for consistent output
Structure production code so Obsidian dependencies are injected behind interfaces; unit tests target pure logic and swap in adapters or tests/obsidian-stub.ts

Files:

  • src/gui/date-picker/datePicker.ts
src/**/*.{ts,tsx,svelte}

📄 CodeRabbit inference engine (AGENTS.md)

Use PascalCase for classes and Svelte components

Files:

  • src/gui/date-picker/datePicker.ts
🧬 Code graph analysis (1)
src/gui/date-picker/datePicker.ts (2)
tests/obsidian-stub.ts (1)
  • moment (475-475)
src/gui/VDateInputPrompt/VDateInputPrompt.ts (1)
  • createDatePicker (99-112)
🔇 Additional comments (3)
src/gui/date-picker/datePicker.ts (3)

30-44: Timezone bug fixed—weekday labels now render correctly.

The previous UTC timestamp issue has been resolved. The implementation now creates dates in local time and uses date arithmetic to avoid timezone shifts.


76-78: Approach changed: now returns date-only string.

The previous concern about UTC midnight has been addressed by switching to a simpler approach—returning "YYYY-MM-DD" format instead of a full ISO 8601 string. This avoids timezone complexity entirely.


80-252: Implementation looks solid.

The date picker logic is well-structured:

  • Proper state management for view and selection
  • DST-safe date arithmetic in the rendering loop (lines 193-194)
  • Accessible UI with ARIA labels and button types
  • Clean public API with controller pattern
  • Boundary conversion from internal undefined to external null for cleared selections (lines 150-152) maintains API consistency

@chhoumann chhoumann merged commit 2811c5a into master Dec 20, 2025
4 checks passed
@chhoumann chhoumann deleted the 288 branch December 20, 2025 19:53
@chhoumann chhoumann linked an issue Dec 20, 2025 that may be closed by this pull request
@github-actions
Copy link
Copy Markdown

🎉 This PR is included in version 2.10.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE REQUEST] Date Picker

1 participant