feat(DatePicker): add allowOnlyDatesList prop to DatePicker#994
feat(DatePicker): add allowOnlyDatesList prop to DatePicker#994vickiwyang wants to merge 11 commits intomainfrom
Conversation
🦋 Changeset detectedLatest commit: 12b8f01 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Claude finished @vickiwyang's task in 1m 3s —— View job Code ReviewNice, clean implementation! The logic in ♿ Accessibility
💡 Suggestions (non-blocking)
|
hoorayimhelping
left a comment
There was a problem hiding this comment.
Two things:
1: Can you add a story to this please?
1: Would it be easier if we had a blacklist rather than a whitelist? It seems like the list of dates we want to allow would be very large compared to the list of dates we want to block
| const isPresent = isSameDate(today, fullDate); | ||
| const isDisabled = futureDatesDisabled ? fullDate > today : false; | ||
| const isNotAllowed = | ||
| allowOnlyDatesList && allowOnlyDatesList.length > 0 |
There was a problem hiding this comment.
Nit: this can be simplified to
Array.isArray(allowOnlyDateList) && !allowOnlyDatesList.some(d => isSameDate(d, fullDate))Or even:
(allowOnlyDatesList && allowOnlyDatesList.length > 0) && !allowOnlyDatesList.some(d => isSameDate(d, fullDate))Basically anytime we explicitly return a boolean value from an if or a ternary, it means it can be simplified into a single expression
There was a problem hiding this comment.
| `; | ||
|
|
||
| interface CalendarProps { | ||
| allowOnlyDatesList?: Date[]; |
There was a problem hiding this comment.
For consistency with the rest of the DatePickers, let's use Array<Date>
There was a problem hiding this comment.
This is actually better for simple types.
As mentioned in the previous discussion, the TypeScript team encourages T[]. For example, in the official documentation, compiler, and language server, you'll generally only find T[].
Obs: In the demo, the TypeScript language server will show T[], even if the author writes Array<T]>.
We can still fall back to Array for declaring complex types, which we happen not to have at the moment, the ones you have there:
src/components/DatePicker/DatePicker.tsx:70: const dayRefs = useRef<Array<HTMLTableCellElement | null>>([]);
src/components/DatePicker/Common.tsx:601: const monthGridRef = useRef<Array<HTMLButtonElement | null>>([]);
src/components/DatePicker/Common.tsx:602: const yearGridRef = useRef<Array<HTMLButtonElement | null>>([]);
src/components/DatePicker/Common.tsx:603: const headerNavRefs = useRef<Array<HTMLButtonElement | null>>([null, null, null]);
src/components/DatePicker/Common.tsx:818: const years: Array<number> = [];
If the author finds writing useRef<Array>([]) better than useRef<T[]>([]), that's completely fine.
In contrast, in the same component group, you find T[]:
src/components/DatePicker/utils.ts:62:): DateRange[] => {
src/components/DatePicker/utils.ts:66: const lastSixMonths: DateRange[] = [];
src/components/DatePicker/utils.ts:81: const nextSixMonths: DateRange[] = [];
That said, the shorthand is concise and more idiomatic, which is great too. I wouldn't bother going back and forth with comments on these:
src/components/DatePicker/Common.tsx:818: const years: number[] = [];
This is exactly why linter rules exist. Enforcing one style over the other (which was proposed in a past PR) was already voted down.
There was a problem hiding this comment.
@punkbit I've already changed this and the other place to Array<Date> following @hoorayimhelping's comments, but I'm happy to make any changes if needed.
|
@vickiwyang - in real life, for this scenario, how many dates would the users have that they can pick from? |
punkbit
left a comment
There was a problem hiding this comment.
@vickiwyang Thanks for your contribution! Let's introduce a Storybook story for this new state, please.
Co-authored-by: Helder Oliveira <helder.oliveira@clickhouse.com>
|
Claude finished @vickiwyang's task in 1m 26s —— View job Code ReviewNice implementation overall — the allowlist logic is clean and the new tests cover the important interaction cases well. A few things need attention before merge: 🚨 Must Fix
♿ Accessibility
💡 Suggestions (non-blocking)
|
…github.com/ClickHouse/click-ui into bil-5134-add-allowlist-param-to-DatePicker
|
Claude finished @vickiwyang's task in 1m 26s —— View job Code ReviewThe implementation is clean and the new tests cover the important cases well. A few things need attention before merge. 🚨 Must Fix
♿ Accessibility
💡 Suggestions (non-blocking)
|
|
Claude finished @vickiwyang's task in 1m 17s —— View job Code ReviewGood progress since the last round — the 🚨 Must Fix
♿ Accessibility
Already addressed from previous rounds ✅
|
There was a problem hiding this comment.
@hoorayimhelping Added a story and implemented your suggestions.
@crisalbu @hoorayimhelping Grouping two related comments from the two of you:
in real life, for this scenario, how many dates would the users have that they can pick from?
Would it be easier if we had a blacklist rather than a whitelist? It seems like the list of dates we want to allow would be very large compared to the list of dates we want to block
For the bill date change use case, the users will have 30 days to pick from (starting from the day after tomorrow—April 17 given today's date of April 15—until but not including the same day on the subsequent month—May 16).
It's easier to define the whitelist than the blacklist for our use case, but maybe for other use cases, a blacklist would be easier. I also thought about defining the whitelist as a date range (using only start and end dates), but decided on an explicit array of dates for the flexibility of having non-contiguous dates. (@crisalbu For the bill date change use case, we could disable the organization's current bill date from the selection.)
| `; | ||
|
|
||
| interface CalendarProps { | ||
| allowOnlyDatesList?: Date[]; |
There was a problem hiding this comment.
@punkbit I've already changed this and the other place to Array<Date> following @hoorayimhelping's comments, but I'm happy to make any changes if needed.
| const isPresent = isSameDate(today, fullDate); | ||
| const isDisabled = futureDatesDisabled ? fullDate > today : false; | ||
| const isNotAllowed = | ||
| allowOnlyDatesList && allowOnlyDatesList.length > 0 |
There was a problem hiding this comment.
|
Claude finished @vickiwyang's task in 1m 6s —— View job Code ReviewGood progress this round — the changeset is now properly closed and the description sentence is in place. Two items remain before merge. 🚨 Must Fix
♿ Accessibility
Already fixed ✅
|
|
Claude finished @vickiwyang's task in 1m 11s —— View job Code ReviewGood progress since the last round — the changeset is now properly closed and the 🚨 Must Fix
♿ Accessibility
Already fixed ✅
|
📚 Storybook Preview Deployed✅ Preview URL: https://click-qcx2650to-clickhouse.vercel.app Built from commit: |
That's ok, the stories are changing during the migration process from styled components to CSS modules. |
punkbit
left a comment
There was a problem hiding this comment.
@vickiwyang Tested, seem to be working correctly. Thank you!


Why?
DatePickercomponent to allow users to select a new bill date for an organization. Only some dates are eligible, and we'd like to be able to disable all non-eligible dates in the UI.How?
allowOnlyDatesListprop toDatePicker: when provided with a non-empty list, dates not in the list will be disabled in the calendarTickets?
Contribution checklist?
buildcommand runs locallySecurity checklist?
dangerouslySetInnerHTMLPreview?
Screen.Recording.2026-04-14.at.3.20.01.PM.mov