Skip to content

Commit

Permalink
refactor: date picker inputProps -> getInputProps (#1214)
Browse files Browse the repository at this point in the history
* refactor: date picker

* docs: update changelog

* fix: parse date function

* refactor: machine logic

* test: fix

* fix: use start date for selects
  • Loading branch information
segunadebayo authored Feb 6, 2024
1 parent 1d42e72 commit 36958b5
Show file tree
Hide file tree
Showing 18 changed files with 447 additions and 186 deletions.
8 changes: 8 additions & 0 deletions .changeset/green-lobsters-hide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@zag-js/date-picker": minor
---

- [BREAKING] Change date picker from `inputProps` to `getInputProps` to support multiple inputs.

- Added a new prop `getPresetTriggerProps` to support custom trigger for common date presets (e.g. Last 7 days, Last 30
days, etc.)
41 changes: 27 additions & 14 deletions .xstate/date-picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const fetchMachine = createMachine({
id: "datepicker",
initial: ctx.open ? "open" : "idle",
context: {
"isOpenControlled": false,
"isOpenControlled": false,
"isYearView": false,
"isMonthView": false,
"isYearView": false,
Expand Down Expand Up @@ -68,7 +70,7 @@ const fetchMachine = createMachine({
activities: ["setupLiveRegion"],
on: {
"VALUE.SET": {
actions: ["setSelectedDate", "setFocusedDate"]
actions: ["setDateValue", "setFocusedDate"]
},
"VIEW.SET": {
actions: ["setView"]
Expand All @@ -77,11 +79,31 @@ const fetchMachine = createMachine({
actions: ["setFocusedDate"]
},
"VALUE.CLEAR": {
actions: ["clearSelectedDate", "clearFocusedDate", "focusInputElement"]
actions: ["clearDateValue", "clearFocusedDate", "focusFirstInputElement"]
},
"INPUT.CHANGE": {
actions: ["focusParsedDate"]
},
"INPUT.ENTER": {
actions: ["focusParsedDate", "selectFocusedDate"]
},
"INPUT.FOCUS": {
actions: ["setActiveIndex"]
},
"INPUT.BLUR": [{
cond: "isOpenControlled",
actions: ["setActiveIndexToStart", "selectParsedDate", "invokeOnClose"]
}, {
target: "idle",
actions: ["setActiveIndexToStart", "selectParsedDate"]
}],
"PRESET.CLICK": [{
cond: "isOpenControlled",
actions: ["setDateValue", "setFocusedDate", "invokeOnClose"]
}, {
target: "focused",
actions: ["setDateValue", "setFocusedDate", "focusInputElement"]
}],
"GOTO.NEXT": [{
cond: "isYearView",
actions: ["focusNextDecade", "announceVisibleRange"]
Expand Down Expand Up @@ -114,9 +136,6 @@ const fetchMachine = createMachine({
target: "open",
actions: ["focusFirstSelectedDate", "focusActiveCell"]
},
"INPUT.FOCUS": {
target: "focused"
},
"TRIGGER.CLICK": [{
cond: "isOpenControlled",
actions: ["invokeOnOpen"]
Expand Down Expand Up @@ -147,12 +166,6 @@ const fetchMachine = createMachine({
target: "open",
actions: ["focusFirstSelectedDate", "focusActiveCell", "invokeOnOpen"]
}],
"INPUT.ENTER": {
actions: ["focusParsedDate", "selectFocusedDate"]
},
"INPUT.BLUR": {
target: "idle"
},
OPEN: [{
cond: "isOpenControlled",
actions: ["invokeOnOpen"]
Expand Down Expand Up @@ -186,7 +199,7 @@ const fetchMachine = createMachine({
actions: ["setFocusedYear", "setViewToMonth"]
}, {
cond: "isRangePicker && hasSelectedRange",
actions: ["setActiveIndexToStart", "clearSelectedDate", "setFocusedDate", "setSelectedDate", "setActiveIndexToEnd"]
actions: ["setActiveIndexToStart", "clearDateValue", "setFocusedDate", "setSelectedDate", "setActiveIndexToEnd"]
},
// === Grouped transitions (based on `closeOnSelect` and `isOpenControlled`) ===
{
Expand Down Expand Up @@ -250,7 +263,7 @@ const fetchMachine = createMachine({
actions: "setViewToMonth"
}, {
cond: "isRangePicker && hasSelectedRange",
actions: ["setActiveIndexToStart", "clearSelectedDate", "setSelectedDate", "setActiveIndexToEnd"]
actions: ["setActiveIndexToStart", "clearDateValue", "setSelectedDate", "setActiveIndexToEnd"]
},
// === Grouped transitions (based on `closeOnSelect` and `isOpenControlled`) ===
{
Expand Down Expand Up @@ -389,9 +402,9 @@ const fetchMachine = createMachine({
})
},
guards: {
"isOpenControlled": ctx => ctx["isOpenControlled"],
"isYearView": ctx => ctx["isYearView"],
"isMonthView": ctx => ctx["isMonthView"],
"isOpenControlled": ctx => ctx["isOpenControlled"],
"shouldRestoreFocus && isInteractOutsideEvent": ctx => ctx["shouldRestoreFocus && isInteractOutsideEvent"],
"shouldRestoreFocus": ctx => ctx["shouldRestoreFocus"],
"isRangePicker && hasSelectedRange": ctx => ctx["isRangePicker && hasSelectedRange"],
Expand Down
3 changes: 2 additions & 1 deletion examples/next-app/components/date-range-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export function DateRangePicker(props: Props) {
</output>

<div {...api.controlProps}>
<input {...api.inputProps} />
<input {...api.getInputProps({ index: 0 })} />
<input {...api.getInputProps({ index: 1 })} />
<button {...api.clearTriggerProps}></button>
<button {...api.triggerProps}>🗓</button>
</div>
Expand Down
2 changes: 1 addition & 1 deletion examples/next-ts/pages/date-picker-multi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function Page() {
</output>

<div {...api.controlProps}>
<input {...api.inputProps} />
<input {...api.getInputProps()} />
<button {...api.clearTriggerProps}></button>
<button {...api.triggerProps}>🗓</button>
</div>
Expand Down
19 changes: 15 additions & 4 deletions examples/next-ts/pages/date-picker-range.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default function Page() {
const [state, send] = useMachine(
datePicker.machine({
id: useId(),
name: "date[]",
locale: "en",
numOfMonths: 2,
selectionMode: "range",
Expand All @@ -33,12 +34,13 @@ export default function Page() {
<p>{`Visible range: ${api.visibleRangeText.formatted}`}</p>

<output className="date-output">
<div>Selected: {api.valueAsString ?? "-"}</div>
<div>Selected: {api.valueAsString.join(", ") ?? "-"}</div>
<div>Focused: {api.focusedValueAsString}</div>
</output>

<div {...api.controlProps}>
<input {...api.inputProps} />
<input {...api.getInputProps({ index: 0 })} />
<input {...api.getInputProps({ index: 1 })} />
<button {...api.clearTriggerProps}></button>
<button {...api.triggerProps}>🗓</button>
</div>
Expand Down Expand Up @@ -75,7 +77,7 @@ export default function Page() {
</div>

<div style={{ display: "flex", gap: "24px" }}>
<table {...api.getTableProps({ id: "r1" })}>
<table {...api.getTableProps({ id: useId() })}>
<thead {...api.getTableHeaderProps()}>
<tr {...api.getTableRowProps()}>
{api.weekDays.map((day, i) => (
Expand All @@ -98,7 +100,7 @@ export default function Page() {
</tbody>
</table>

<table {...api.getTableProps({ id: "r2" })}>
<table {...api.getTableProps({ id: useId() })}>
<thead {...api.getTableHeaderProps()}>
<tr {...api.getTableRowProps()}>
{api.weekDays.map((day, i) => (
Expand All @@ -122,6 +124,15 @@ export default function Page() {
))}
</tbody>
</table>

<div style={{ minWidth: "80px", display: "flex", flexDirection: "column", gap: "4px" }}>
<b>Presets</b>
<button {...api.getPresetTriggerProps({ value: "last3Days" })}>Last 3 Days</button>
<button {...api.getPresetTriggerProps({ value: "last7Days" })}>Last 7 Days</button>
<button {...api.getPresetTriggerProps({ value: "last14Days" })}>Last 14 Days</button>
<button {...api.getPresetTriggerProps({ value: "last30Days" })}>Last 30 Days</button>
<button {...api.getPresetTriggerProps({ value: "last90Days" })}>Last 90 Days</button>
</div>
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion examples/next-ts/pages/date-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function Page() {
</output>

<div {...api.controlProps}>
<input {...api.inputProps} />
<input {...api.getInputProps()} />
<button {...api.clearTriggerProps}></button>
<button {...api.triggerProps}>🗓</button>
</div>
Expand Down
1 change: 1 addition & 0 deletions packages/machines/date-picker/src/date-picker.anatomy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const anatomy = createAnatomy("date-picker").parts(
"viewTrigger",
"viewControl",
"yearSelect",
"presetTrigger",
)

export const parts = anatomy.build()
Loading

0 comments on commit 36958b5

Please sign in to comment.