Skip to content

Datetime picker as a form component - #123

Merged
joshunrau merged 9 commits into
DouglasNeuroInformatics:mainfrom
david-roper:datetime-picker
Oct 5, 2026
Merged

joshunrau merged 9 commits into
DouglasNeuroInformatics:mainfrom
david-roper:datetime-picker

Conversation

@david-roper

@david-roper david-roper commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

feat: add DateTimeField form component

Adds a DateTimeField component to src/components/Form. It lets the user pick a calendar date and a time of day, and produces a single Date value. The layout follows the shadcn/ui date picker with time.

Changes

  • DateTimeField.tsx: new component in src/components/Form/DateTimeField/
    • Shows the field label with the usual description popover, then two labelled controls side by side:
      • Date: an outline button showing "Select date" or the chosen date as YYYY-MM-DD. Clicking it opens the existing DatePicker in a Popover.
      • Time: a native <input type="time" step="1"> that shows seconds and hides the browser's picker icon. It starts at 00:00:00.
    • Takes the same props as DateField (BaseFieldComponentProps<Date> plus label, description and disabled).
    • Behaviour:
      • Picking a date sets the value to that day at the current time and closes the popover.
      • Changing the time updates the time of the current value. If no date is picked yet, the time is kept and applied once a date is chosen.
      • Clearing the time or entering an invalid one leaves the value unchanged.
      • Clearing the value from outside, such as with the form's reset button, returns both controls to their empty state.
      • disabled and readOnly turn off both controls.
  • DateTimeField.stories.tsx: four stories: Default, WithInitialValue, Disabled and WithError.
  • DateTimeField.spec.tsx: 10 tests covering the default render, opening the popover, picking a date, setting the time before or after the date, clearing the time, rendering a value passed in, resetting and disabling.
  • libui.json: new translation keys form.date, form.selectDate and form.time (en / es / fr).

Not included

DateTimeField is not yet connected to Form / ScalarField. @douglasneuroinformatics/libui-form-types has no datetime field type yet, so for now the component can only be used on its own. See "Next steps".

Next steps: libui-form-types

For Form to render a DateTimeField from a field config, the form-types package has to describe a datetime field first:

  1. Update libui-form-types. Recommended: add an optional variant to the existing date field:
    export type DateField = FieldMixin<{
      kind: 'date';
      variant?: 'date' | 'datetime'; // defaults to 'date'
    }>;
    The value stays a Date, so ScalarFieldValue and zod schemas don't change. Existing kind: 'date' configs keep working, and any switch (field.kind) in a dependent package stays exhaustive.
    Alternative: a separate kind: 'datetime' (DateTimeFormField) added to ScalarField / AnyScalarFormField. This makes the two fields more clearly distinct, but it is a breaking change for any package that switches over every kind, including ScalarField in this repo.
  2. Publish a new version of libui-form-types: a minor bump for the variant option, or a major bump if we add a new kind.
  3. In libui:
    • Bump the dependency.
    • Change DateTimeFieldProps to come from the updated form type.
    • Route datetime fields to DateTimeField in ScalarField.tsx: check field.variant === 'datetime' inside the 'date' case, or add a 'datetime' case.
    • Add a datetime example to Form.stories.tsx and a test in Form.test.tsx that submits through the reset/submit flow.

Testing

  • pnpm exec vitest run src/components/Form: all tests pass
  • tsc and eslint: clean
  • Checked manually in Storybook: the DateTimeField stories render.

🤖 Generated with Claude Code

Closes issue #122

@david-roper
david-roper requested a review from joshunrau as a code owner October 2, 2026 21:21

@joshunrau joshunrau left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

So, two comments on this:

  1. should we support a 24 hour time (i.e., 13:00) for French?
  2. can we add some way to indicate am vs pm?

Otherwise, looks terrific!

@david-roper
david-roper requested a review from joshunrau October 5, 2026 18:58
@joshunrau
joshunrau merged commit 1069a58 into DouglasNeuroInformatics:main Oct 5, 2026
1 check passed
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 6.17.0 🎉

The release is available on:

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.

2 participants