Skip to content

Conversation

isBatak
Copy link
Contributor

@isBatak isBatak commented Aug 29, 2025

📝 Description

Implements date picker segments functionality to allow inline editing of date components (day, month, year, etc.) for improved user experience. This feature enables users to navigate between date segments using keyboard and edit individual parts of the date without opening the calendar popup.

⛳️ Current behaviour (updates)

Currently, the date picker only supports input through a single text field or calendar selection. Users cannot navigate between individual date components (segments) like day, month, year using keyboard navigation or edit them individually.

🚀 New behaviour

  • Adds segmented date input functionality where date components are rendered as individual editable segments
  • Implements keyboard navigation between segments (arrow keys, tab)
  • Supports direct input and editing of individual date segments

💣 Is this a breaking change (Yes/No): No

This is an additive feature that doesn't break existing functionality.

📝 Additional Information

TODO:

  • Add date-picker-segment example
  • Render segment input wrapper (getSegmentInputProps)
  • Render segments (getSegments, getSegmentProps)
  • Render placeholder date when there is no default value
  • Focus on each segment
  • Basic segment structure and types
  • Segment state management in machine context
  • Date formatting and segment processing (processSegments)
  • ARIA attributes for accessibility
  • Arrow Up/Down for incrementing/decrementing values (basic implementation)
  • Segment value management infrastructure
  • Segment formatter and locale support
  • Valid segments computation
  • Segment events handling structure
  • Complete segment value increment/decrement functionality
  • Implement Page Up/Down for larger increments in segments
  • Complete keyboard navigation between segments (Arrow Left/Right)
  • Add Home/End keys for jumping to first/last segment
  • Implement Backspace/Delete handling for segments
  • Implement Escape key handling for segments
  • Add text input handling for numeric segments
  • Implement input validation and constraints per segment
  • Add auto-advance to next segment after valid input
  • Add invalid input rejection logic
  • Implement respect for min/max values per segment type
  • Add overflow handling (e.g., month 13 → month 1, year++)
  • Implement date validation after segment changes
  • Implement automatic segment completion (e.g., typing "3" in day moves to "03")
  • Implement copy/paste support for segments
  • Add screen reader announcements for value changes
  • Implement proper role descriptions for each segment type
  • Implement proper aria-labelledby attribute for segments
  • Add live region updates for invalid states
  • Handle invalid date scenarios (e.g., Feb 30)
  • Implement leap year validation
  • Implement getSegmentState
  • Fix segment index tracking in machine context
  • Add segment performance optimisations
  • Implement segment testing coverage

Copy link

changeset-bot bot commented Aug 29, 2025

⚠️ No Changeset found

Latest commit: ed687a3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

vercel bot commented Aug 29, 2025

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

Project Deployment Preview Updated (UTC)
zag-nextjs Ready Ready Preview Sep 2, 2025 9:01pm
zag-solid Ready Ready Preview Sep 2, 2025 9:01pm
zag-svelte Ready Ready Preview Sep 2, 2025 9:01pm
zag-vue Ready Ready Preview Sep 2, 2025 9:01pm
zag-website Ready Ready Preview Sep 2, 2025 9:01pm

@@ -803,6 +810,138 @@ export function connect<T extends PropTypes>(
})
},

getSegmentInputProps() {
Copy link
Member

Choose a reason for hiding this comment

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

You can pass the index as props here

</output>

<div {...api.getControlProps()}>
<div {...api.getSegmentInputProps()}>
Copy link
Member

Choose a reason for hiding this comment

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

Let's rename this part to segmentGroup instead of segmentInput (since it's not technically an input)

inputMode:
disabled || segment.type === "dayPeriod" || segment.type === "era" || !isEditable ? undefined : "numeric",
enterKeyHint: "next",
"aria-labelledby": dom.getInputId(scope, 0), // FIXIT: figure out the index
Copy link
Member

Choose a reason for hiding this comment

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

You can also pass the index from props. set the default to 0

"data-editable": dataAttr(segment.isEditable && !readOnly && !disabled),
"data-placeholder": dataAttr(segment.isPlaceholder),
style: {
"caret-color": "transparent",
Copy link
Member

Choose a reason for hiding this comment

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

Should this be caretColor?

Comment on lines 897 to 920
ArrowLeft() {
send({ type: "SEGMENT.ARROW_LEFT", focus: true })
},
ArrowRight() {
send({ type: "SEGMENT.ARROW_RIGHT", focus: true })
},
ArrowUp() {
send({ type: "SEGMENT.ARROW_UP", segment, focus: true })
},
ArrowDown() {
send({ type: "SEGMENT.ARROW_DOWN", segment, focus: true })
},
PageUp(event) {
send({ type: "SEGMENT.PAGE_UP", larger: event.shiftKey, focus: true })
},
PageDown(event) {
send({ type: "SEGMENT.PAGE_DOWN", larger: event.shiftKey, focus: true })
},
Home() {
send({ type: "SEGMENT.HOME", focus: true })
},
End() {
send({ type: "SEGMENT.END", focus: true })
},
Copy link
Member

Choose a reason for hiding this comment

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

After you get this working, I wonder if we can bundle these into a SEGMENT.CYCLE or SEGMENT.INC/DEC event to reduce the repetition here and in the machine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants