Skip to content

Added Calendar component and used for filtering#27657

Merged
kevinansfield merged 3 commits intomainfrom
weyland-ber-3598-date-picker-ux-issues-in-member-filtering
May 7, 2026
Merged

Added Calendar component and used for filtering#27657
kevinansfield merged 3 commits intomainfrom
weyland-ber-3598-date-picker-ux-issues-in-member-filtering

Conversation

@weylandswart
Copy link
Copy Markdown
Contributor

Ref https://linear.app/ghost/issue/BER-3598/date-picker-ux-issues-in-member-filtering

Adding a Shade calendar component and replacing the existing native datepicker for filtering with it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

A Calendar UI component and CalendarDayButton were added (with date-fns and react-day-picker deps), exported from the shade components barrel, and documented with Storybook stories (Default and DatePicker). The filters feature gained parse/format helpers and a FilterDatePicker component that replaces native date inputs for single date and daterange filters. Unit tests and a small posts comment-fields formatting tweak were also added.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly summarizes the main changes: adding a Calendar component and using it for filtering, which matches the core objectives of the PR.
Description check ✅ Passed The description is related to the changeset, referencing the Linear issue and explaining the purpose of adding a Calendar component to replace the native datepicker for filtering.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch weyland-ber-3598-date-picker-ux-issues-in-member-filtering

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
Contributor

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/shade/src/components/ui/filters.tsx`:
- Around line 671-676: FilterDatePickerProps/FilterDatePicker currently takes
value/onChange but never calls field.onInputChange, breaking consumers that rely
on FilterFieldConfig.onInputChange for committed edits; update
FilterDatePickerProps to accept field?: FilterFieldConfig and inside the
FilterDatePicker component invoke field.onInputChange(newValue) at the same
point you call onChange (or when the date selection is committed) so date and
daterange flows behave like other input branches; make sure to reference the
existing field parameter and call its onInputChange method with the string value
used by onChange.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5387ef4d-8f6f-468b-9c39-1db4ec5a08d6

📥 Commits

Reviewing files that changed from the base of the PR and between 2897659 and 877e674.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • apps/posts/src/views/comments/components/comments-filters.tsx
  • apps/shade/package.json
  • apps/shade/src/components.ts
  • apps/shade/src/components/ui/calendar.stories.tsx
  • apps/shade/src/components/ui/calendar.tsx
  • apps/shade/src/components/ui/filters.tsx
💤 Files with no reviewable changes (1)
  • apps/posts/src/views/comments/components/comments-filters.tsx

Comment thread apps/shade/src/components/features/filters/filters.tsx
@codecov
Copy link
Copy Markdown

codecov Bot commented May 4, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.69%. Comparing base (bbc3981) to head (059db79).
⚠️ Report is 16 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #27657      +/-   ##
==========================================
+ Coverage   73.18%   73.69%   +0.51%     
==========================================
  Files        1561     1512      -49     
  Lines      127215   125820    -1395     
  Branches    15391    15129     -262     
==========================================
- Hits        93103    92724     -379     
+ Misses      33133    32150     -983     
+ Partials      979      946      -33     
Flag Coverage Δ
admin-tests 53.07% <ø> (+3.18%) ⬆️
e2e-tests 73.69% <ø> (+0.51%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@weylandswart weylandswart force-pushed the weyland-ber-3598-date-picker-ux-issues-in-member-filtering branch from 877e674 to cea3c8a Compare May 6, 2026 20:04
Copy link
Copy Markdown
Contributor

@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.

♻️ Duplicate comments (1)
apps/shade/src/components/features/filters/filters.tsx (1)

671-676: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

field.onInputChange still not invoked for date / daterange.

FilterDatePickerProps doesn't include onInputChange, and handleInputBlur/handleSelect only call the local onChange. Every other input-like branch (time, datetime, text/number, email/url/tel) still forwards field.onInputChange, so committed edits on date/daterange filters silently stop reaching consumers that listen to that callback through FilterFieldConfig. Same applies to both daterange call sites (1888-1893, 1900-1905) and the single-date site (1975-1980).

🛠️ Suggested wiring
 interface FilterDatePickerProps<T = unknown> {
     field?: FilterFieldConfig<T>;
     value: string;
     onChange: (value: string) => void;
+    onInputChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
     className?: string;
 }
@@
-function FilterDatePicker<T = unknown>({
-    field,
-    value,
-    onChange,
-    className
-}: FilterDatePickerProps<T>) {
+function FilterDatePicker<T = unknown>({
+    field,
+    value,
+    onChange,
+    onInputChange,
+    className
+}: FilterDatePickerProps<T>) {
@@
     const handleInputBlur = (e: React.FocusEvent<HTMLInputElement>) => {
         if (e.target.value !== value) {
             onChange(e.target.value);
+            onInputChange?.(e as unknown as React.ChangeEvent<HTMLInputElement>);
         }
     };
@@
     const handleSelect = (date: Date | undefined) => {
         if (!date) {
             setLocalValue('');
             onChange('');
+            onInputChange?.({target: {value: ''}} as React.ChangeEvent<HTMLInputElement>);
             return;
         }
         const formatted = formatFilterDateValue(date);
         setMonth(date);
         setLocalValue(formatted);
         onChange(formatted);
+        onInputChange?.({target: {value: formatted}} as React.ChangeEvent<HTMLInputElement>);
         setOpen(false);
     };

And forward at the three usage sites, e.g.:

 <FilterDatePicker
     className={field.className}
     field={field}
     value={(values[0] as string) || ''}
     onChange={v => onChange([v] as T[])}
+    onInputChange={field.onInputChange}
 />

Also applies to: 716-737, 1888-1905, 1975-1980

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/shade/src/components/features/filters/filters.tsx` around lines 671 -
676, FilterDatePickerProps is missing onInputChange so committed edits for
date/daterange never call field.onInputChange; add onInputChange?: (value:
string) => void to FilterDatePickerProps (or accept it via field?.onInputChange)
and update the handlers (handleInputBlur and handleSelect inside the
date/daterange picker components) to call field.onInputChange(value) in addition
to the local onChange, mirroring how other input branches do it; ensure the
three usage sites that render the daterange and single-date pickers forward the
field.onInputChange through props (or rely on field) so consumers of
FilterFieldConfig receive the callback.
🧹 Nitpick comments (1)
apps/shade/src/components/ui/calendar.stories.tsx (1)

53-73: ⚡ Quick win

Consider expanding story coverage to mirror shadcn's calendar examples.

Only Default (single) and a popover composition are demonstrated. The shadcn calendar docs cover several common variants worth showing here so consumers see the supported props and states at a glance: mode="range", mode="multiple", captionLayout="dropdown" (already used by FilterDatePicker), and a disabled example. As per coding guidelines: "Add a sibling *.stories.tsx file for new UI components with ... stories showing different use cases/variants (sizes, states, important props)" and "For ShadCN components, copy the examples from the ShadCN component documentation".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/shade/src/components/ui/calendar.stories.tsx` around lines 53 - 73, Add
additional Story exports to mirror shadcn calendar variants: create Range,
Multiple, CaptionDropdown, and Disabled stories alongside Default and DatePicker
by reusing or creating example components (e.g., SingleCalendarExample ->
RangeCalendarExample/MultipleCalendarExample or render SingleCalendarExample
with props mode="range" and mode="multiple"), add a CaptionDropdown story
demonstrating captionLayout="dropdown" (see existing FilterDatePicker for
usage), and add Disabled story showing the calendar with disabled prop; follow
shadcn examples for markup/props and include descriptive docs.description.story
for each export.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@apps/shade/src/components/features/filters/filters.tsx`:
- Around line 671-676: FilterDatePickerProps is missing onInputChange so
committed edits for date/daterange never call field.onInputChange; add
onInputChange?: (value: string) => void to FilterDatePickerProps (or accept it
via field?.onInputChange) and update the handlers (handleInputBlur and
handleSelect inside the date/daterange picker components) to call
field.onInputChange(value) in addition to the local onChange, mirroring how
other input branches do it; ensure the three usage sites that render the
daterange and single-date pickers forward the field.onInputChange through props
(or rely on field) so consumers of FilterFieldConfig receive the callback.

---

Nitpick comments:
In `@apps/shade/src/components/ui/calendar.stories.tsx`:
- Around line 53-73: Add additional Story exports to mirror shadcn calendar
variants: create Range, Multiple, CaptionDropdown, and Disabled stories
alongside Default and DatePicker by reusing or creating example components
(e.g., SingleCalendarExample -> RangeCalendarExample/MultipleCalendarExample or
render SingleCalendarExample with props mode="range" and mode="multiple"), add a
CaptionDropdown story demonstrating captionLayout="dropdown" (see existing
FilterDatePicker for usage), and add Disabled story showing the calendar with
disabled prop; follow shadcn examples for markup/props and include descriptive
docs.description.story for each export.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d1cf1ca7-9969-4eea-bd1e-3465de6f04fa

📥 Commits

Reviewing files that changed from the base of the PR and between 877e674 and cea3c8a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • apps/posts/src/views/comments/comment-fields.ts
  • apps/shade/package.json
  • apps/shade/src/components.ts
  • apps/shade/src/components/features/filters/filters.tsx
  • apps/shade/src/components/ui/calendar.stories.tsx
  • apps/shade/src/components/ui/calendar.tsx

@weylandswart weylandswart force-pushed the weyland-ber-3598-date-picker-ux-issues-in-member-filtering branch from cea3c8a to 62dc518 Compare May 6, 2026 20:31
Copy link
Copy Markdown
Contributor

@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.

🧹 Nitpick comments (6)
apps/shade/src/components/features/filters/filters.tsx (4)

649-659: 💤 Low value

parseFilterDateValue accepts overflow dates.

new Date(year, month - 1, day) silently normalizes out-of-range parts, so '2024-02-30' parses to Mar 1 and '2024-13-01' to Jan 2025. Native <input type="date"> won't typically produce such values, but consumers can call this with arbitrary strings (URL roundtrip, programmatic init). Consider validating the round-trip:

🛡️ Proposed validation
 const parseFilterDateValue = (value: string): Date | undefined => {
     if (!value) {
         return undefined;
     }
     const parts = value.split('-').map(Number);
     if (parts.length !== 3 || parts.some(n => Number.isNaN(n))) {
         return undefined;
     }
     const [year, month, day] = parts;
-    return new Date(year, month - 1, day);
+    const date = new Date(year, month - 1, day);
+    if (
+        date.getFullYear() !== year ||
+        date.getMonth() !== month - 1 ||
+        date.getDate() !== day
+    ) {
+        return undefined;
+    }
+    return date;
 };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/shade/src/components/features/filters/filters.tsx` around lines 649 -
659, parseFilterDateValue currently lets overflow dates silently normalize
(e.g., "2024-02-30" -> Mar 1); after parsing parts and constructing the Date,
validate that the resulting Date's year, month and day match the original
components (compare d.getFullYear() === year, d.getMonth() + 1 === month,
d.getDate() === day) and return undefined if any mismatch; update the function
(parseFilterDateValue) to perform this round-trip check so only exact,
non-overflow dates are accepted.

1888-1905: 🏗️ Heavy lift

Daterange: start/end share the same Calendar popover with no cross-field constraints.

Both pickers render an independent single-date calendar; nothing prevents picking endDate < startDate, and there's no visual range highlight (which react-day-picker's mode="range" would give for free). Consider migrating to a single Calendar with mode="range" for daterange, or at minimum pass disabled={{before: startDate}} to the end picker and disabled={{after: endDate}} to the start picker.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/shade/src/components/features/filters/filters.tsx` around lines 1888 -
1905, The two FilterDatePicker instances (rendering startDate and endDate)
currently each open independent single-date calendars so users can pick end <
start and there's no range highlight; update the implementation to either
(preferred) switch to a single Calendar with mode="range" wired to the
component's onChange to produce [startDate,endDate], or (minimal) pass
cross-field disable rules to the existing pickers—i.e., give the end
FilterDatePicker a disabled prop like {before: startDate} and the start
FilterDatePicker a disabled prop like {after: endDate} so selections are
constrained; ensure onChange still emits [startDate,endDate] via the existing
onChange handler.

691-714: 💤 Low value

Stale calendar selection when value is cleared externally.

When the parent clears the filter (e.g. "Clear filters" or operator switch), value becomes '', parsed becomes undefined, and the if (parsed) setMonth(parsed) guard at line 703 leaves month pointing at the previously viewed month. That's usually fine, but combine it with selected={parsed} (line 787) being undefined while the popover is open, and the calendar shows no selection in a possibly-unrelated month. Consider also resetting the state in the cleared branch or using setMonth(parsed ?? new Date()) to recenter.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/shade/src/components/features/filters/filters.tsx` around lines 691 -
714, The month state isn't cleared when value becomes '' because the effect only
sets month when parsed is truthy; update the useEffect that currently reads if
(parsed) setMonth(parsed) to handle the cleared case by calling setMonth(parsed
?? new Date()) (or setMonth(undefined) if you prefer to collapse to no
selection) so month is recentered/reset when parsed is undefined; this involves
modifying the effect that uses parsed and setMonth (the parsed variable from
parseFilterDateValue, the month state and setMonth setter) to set the fallback
state when parsed is falsy.

757-766: 💤 Low value

The native type="date" display format is controlled by OS/browser locale, not app-settable user preference.

<input type="date"> always stores values as YYYY-MM-DD per spec but displays the date mask in the browser's locale (e.g., MM/DD/YYYY for en-US, DD/MM/YYYY for en-GB). There is no HTML attribute or API to override this, and Safari/WebKit historically show rendering inconsistencies. Since the popover Calendar is the primary interaction surface (the input's picker UI is hidden), the text input format inconsistency is mitigated. Consider type="text" with explicit format hints and parseFilterDateValue if explicit format control becomes a requirement, but the current approach is pragmatic.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/shade/src/components/features/filters/filters.tsx` around lines 757 -
766, The input uses type="date" which forces browser/OS-local display
formatting; change it to type="text" to control visible format and parsing:
update the JSX input in filters.tsx (the element using inputRef, localValue,
handleInputBlur, handleInputChange) to type="text", add a visible format
hint/placeholer, and modify handleInputChange/handleInputBlur to parse/validate
using the existing parseFilterDateValue utility (or central parse function) and
continue to store values as YYYY-MM-DD for internal state; ensure the popover
calendar remains the primary picker and keep hiding native pickers CSS as-is.
apps/shade/src/components/ui/calendar.stories.tsx (1)

53-73: 💤 Low value

Consider adding stories for range/multiple modes and captionLayout="dropdown".

The Calendar supports mode="range", mode="multiple", and captionLayout="dropdown" (which FilterDatePicker actually uses). Adding stories for those would document the variants consumers will hit and align with the guideline to "demonstrate key variants and states".

As per coding guidelines: "Add a sibling *.stories.tsx file for new UI components with an overview (what/why) and stories showing different use cases/variants (sizes, states, important props)".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/shade/src/components/ui/calendar.stories.tsx` around lines 53 - 73, Add
additional Story exports demonstrating Calendar variants: create new stories
(e.g., Range and Multiple) alongside Default and DatePicker that render examples
like RangeCalendarExample and MultipleCalendarExample using Calendar props
mode="range" and mode="multiple", and add a story (e.g., CaptionDropdown)
showing captionLayout="dropdown" (match FilterDatePicker usage) — ensure each
story has docs.description.story and a descriptive name so consumers can see
these key variants and states.
apps/shade/package.json (1)

130-134: 💤 Low value

Consider dropping date-fns as an unused dependency.

date-fns@4.1.0 is listed in package.json but is not imported or used anywhere in the codebase. react-day-picker@9.14.0 works without it as an optional peer dependency. Both calendar.tsx and the FilterDatePicker component in filters.tsx use native Date APIs and hand-rolled formatting helpers instead. Removing this dependency would reduce bundle size with no functional impact.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/shade/package.json` around lines 130 - 134, The package.json currently
lists date-fns@4.1.0 but the codebase (e.g., calendar.tsx and the
FilterDatePicker component in filters.tsx) does not import or use it; remove the
unused dependency by deleting the "date-fns" entry from package.json, run your
package manager to update the lockfile (npm/yarn/pnpm install), ensure there are
no stray imports of "date-fns" anywhere (search the repo), and run tests/build
to verify nothing breaks (react-day-picker remains as the optional peer
dependency).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/shade/package.json`:
- Around line 130-134: The package.json currently lists date-fns@4.1.0 but the
codebase (e.g., calendar.tsx and the FilterDatePicker component in filters.tsx)
does not import or use it; remove the unused dependency by deleting the
"date-fns" entry from package.json, run your package manager to update the
lockfile (npm/yarn/pnpm install), ensure there are no stray imports of
"date-fns" anywhere (search the repo), and run tests/build to verify nothing
breaks (react-day-picker remains as the optional peer dependency).

In `@apps/shade/src/components/features/filters/filters.tsx`:
- Around line 649-659: parseFilterDateValue currently lets overflow dates
silently normalize (e.g., "2024-02-30" -> Mar 1); after parsing parts and
constructing the Date, validate that the resulting Date's year, month and day
match the original components (compare d.getFullYear() === year, d.getMonth() +
1 === month, d.getDate() === day) and return undefined if any mismatch; update
the function (parseFilterDateValue) to perform this round-trip check so only
exact, non-overflow dates are accepted.
- Around line 1888-1905: The two FilterDatePicker instances (rendering startDate
and endDate) currently each open independent single-date calendars so users can
pick end < start and there's no range highlight; update the implementation to
either (preferred) switch to a single Calendar with mode="range" wired to the
component's onChange to produce [startDate,endDate], or (minimal) pass
cross-field disable rules to the existing pickers—i.e., give the end
FilterDatePicker a disabled prop like {before: startDate} and the start
FilterDatePicker a disabled prop like {after: endDate} so selections are
constrained; ensure onChange still emits [startDate,endDate] via the existing
onChange handler.
- Around line 691-714: The month state isn't cleared when value becomes ''
because the effect only sets month when parsed is truthy; update the useEffect
that currently reads if (parsed) setMonth(parsed) to handle the cleared case by
calling setMonth(parsed ?? new Date()) (or setMonth(undefined) if you prefer to
collapse to no selection) so month is recentered/reset when parsed is undefined;
this involves modifying the effect that uses parsed and setMonth (the parsed
variable from parseFilterDateValue, the month state and setMonth setter) to set
the fallback state when parsed is falsy.
- Around line 757-766: The input uses type="date" which forces browser/OS-local
display formatting; change it to type="text" to control visible format and
parsing: update the JSX input in filters.tsx (the element using inputRef,
localValue, handleInputBlur, handleInputChange) to type="text", add a visible
format hint/placeholer, and modify handleInputChange/handleInputBlur to
parse/validate using the existing parseFilterDateValue utility (or central parse
function) and continue to store values as YYYY-MM-DD for internal state; ensure
the popover calendar remains the primary picker and keep hiding native pickers
CSS as-is.

In `@apps/shade/src/components/ui/calendar.stories.tsx`:
- Around line 53-73: Add additional Story exports demonstrating Calendar
variants: create new stories (e.g., Range and Multiple) alongside Default and
DatePicker that render examples like RangeCalendarExample and
MultipleCalendarExample using Calendar props mode="range" and mode="multiple",
and add a story (e.g., CaptionDropdown) showing captionLayout="dropdown" (match
FilterDatePicker usage) — ensure each story has docs.description.story and a
descriptive name so consumers can see these key variants and states.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1115b8bf-a30e-4bb0-880c-7cabbd753883

📥 Commits

Reviewing files that changed from the base of the PR and between cea3c8a and 62dc518.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • apps/posts/src/views/comments/comment-fields.ts
  • apps/shade/package.json
  • apps/shade/src/components.ts
  • apps/shade/src/components/features/filters/filters.tsx
  • apps/shade/src/components/ui/calendar.stories.tsx
  • apps/shade/src/components/ui/calendar.tsx

@jonatansberg jonatansberg self-requested a review May 7, 2026 11:51
);
}

if (field.type === 'daterange') {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@weylandswart should we expose this somewhere? I remember us discussing in the mob that we're lacking date ranges, but it seems the filter UI supports it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We probably should? I feel like it'd be nice to do between as a filter operator. I'd add a follow up issue for that, though. Purely to get the better looking calendar shipped as priority numero uno.

@jonatansberg jonatansberg force-pushed the weyland-ber-3598-date-picker-ux-issues-in-member-filtering branch from 62dc518 to 1990f64 Compare May 7, 2026 12:26
Ref https://linear.app/ghost/issue/BER-3598/date-picker-ux-issues-in-member-filtering

Adding a Shade calendar component and replacing the existing native datepicker for filtering with it.
@jonatansberg jonatansberg force-pushed the weyland-ber-3598-date-picker-ux-issues-in-member-filtering branch from 1990f64 to f6ba57a Compare May 7, 2026 12:37
Copy link
Copy Markdown
Member

@jonatansberg jonatansberg left a comment

Choose a reason for hiding this comment

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

@weylandswart I pushed an updated version that fixed some reliability things. With those fixes, I think it looks good enough code wise. The date input is a bit wide though. Maybe we want to make it a bit more narrow?

Image

@weylandswart
Copy link
Copy Markdown
Contributor Author

@jonatansberg Agreed. Fixed in 7e38eef.

no issue

Safari still opened its native date picker from date input text clicks, so the filter date control now uses an editable text field paired with the Shade calendar popover while keeping calendar selections synced into the input.
@kevinansfield kevinansfield force-pushed the weyland-ber-3598-date-picker-ux-issues-in-member-filtering branch from 3dbf079 to 059db79 Compare May 7, 2026 15:13
@kevinansfield kevinansfield merged commit 76982f0 into main May 7, 2026
45 checks passed
@kevinansfield kevinansfield deleted the weyland-ber-3598-date-picker-ux-issues-in-member-filtering branch May 7, 2026 16:11
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.

3 participants