Checkout DatePicker - Disabled Date Visually Appears Enabled (Recurring Observation)

Hi everyone,

We’re encountering a recurring visual bug with the DatePicker component from @shopify/ui-extensions-react/checkout.

Issue:
Dates that are explicitly included in the disabled prop array are sometimes visually rendering in the calendar as if they were enabled. They do not consistently have the distinct visual styling typically associated with disabled dates.

Details:

  • We are passing an array of date strings in YYYY-MM-DD format, and sometimes date range objects, to the disabled prop of the DatePicker component.

  • We’ve confirmed via console logging immediately before rendering the DatePicker that the problematic date (e.g., 2025-06-28 in the example below) is indeed present in the disabledDates array being passed to the component.

  • Example disabledDates array logged when visibleMonth is {year: 2025, month: 6} and 2025-06-28 appeared enabled:

[{"start":"1970-01-01","end":"2025-05-20"},{"start":"2025-07-21","end":"2999-12-31"},"2025-06-01","2025-06-04","2025-06-05","2025-06-06","2025-06-07","2025-06-08","2025-06-11","2025-06-12","2025-06-13","2025-06-14","2025-06-15","2025-06-18","2025-06-19","2025-06-20","2025-06-21","2025-06-22","2025-06-25","2025-06-26","2025-06-27","2025-06-28","2025-06-29"]

  • As you can see, 2025-06-28 is part of this array.

  • Functional Behavior: If the user clicks on such a visually “enabled” (but technically disabled) date like 2025-06-28, the onChange event fires with that date. Our application logic then correctly identifies it as an invalid selection (because it’s in our master list of disabled dates) and auto-corrects to a valid date. This confirms the date is functionally disabled by our broader app logic, but the DatePicker’s initial visual representation is misleading.

  • Expected Behavior: The date 2025-06-28 (and others in the array) should visually appear disabled in the calendar (e.g., greyed out, different cursor, not appearing as a clickable target) because its string representation is included in the disabled prop array.

Example Scenario & Recurring Nature:

  • The disabledDates prop is set to the array shown above.

  • The calendar for June 2025 is displayed.

  • 2025-06-28 (a Saturday) visually appears enabled, similar to selectable Mondays/Tuesdays (e.g., June 30th, which is not in the disabled array).

  • User clicks 2025-06-28.

  • onChange fires with 2025-06-28. Our app logic then intervenes to correct the selection.

  • We have observed this behavior before (I am co-founder of Flare: Delivery Date Picker - Flare - Delivery Date Picker App on Shopify | Shopify App Store - we use the datepicker for 500+ merchants), where other random dates, confirmed to be in the disabled prop array, also incorrectly appear as enabled in the calendar. This behavior usually occurs when the disabled array contains a larger amount of disabled dates. When it contains just one or two disabled dates, it never happens.

Could you please investigate why a date passed in the disabled prop array might not be receiving the correct visual styling to indicate it’s disabled? This can lead to user confusion as they might attempt to select dates that are not actually available according to our business logic.

Let me know if any further details or a minimal reproduction case would be helpful.

Screenshot of this occurring in checkout:

Thanks!

Is anyone from Shopify able to assist here? We’re still seeing this issue - we’re explicitly passing dates to be disabled in the calendar, but on month change, dates we’re disabling are showing as enabled. This is causing some headaches for our merchants.

Hey Alex - digging into this on my side, will come back with more info asap!

Thanks Liam - appreciate it :flexed_biceps:

Hey @Alex_Hooper, thanks for reporting the issue. We’ve tried reproducing the issue with the date range you’ve shared, but so far unable to. Our code snippet:

function Extension() {
  const disabledDates = [
    { start: "1970-01-01", end: "2025-05-20" },
    { start: "2025-07-21", end: "2999-12-31" },
    "2025-06-01",
    "2025-06-04",
    "2025-06-05",
    "2025-06-06",
    "2025-06-07",
    "2025-06-08",
    "2025-06-11",
    "2025-06-12",
    "2025-06-13",
    "2025-06-14",
    "2025-06-15",
    "2025-06-18",
    "2025-06-19",
    "2025-06-20",
    "2025-06-21",
    "2025-06-22",
    "2025-06-25",
    "2025-06-26",
    "2025-06-27",
    "2025-06-28",
    "2025-06-29",
  ];
  return (
    <DatePicker
      selected="2025-06-28"
      disabled={disabledDates}
      onChange={(date) => {
        console.log(date);
      }}
    />
  );
}

Here’s how it looks. We’ve tried month changes as well but so far 06-28 appears to have the desired disabled behaviour.

Could you help us identify what might be missing?

Hi @avocadomayo, I’m so sorry for the slow response!

We’re still seeing a rendering mismatch with the DatePicker where some dates present in the disabled prop do not get the disabled styling in the grid.

Why your minimal example may not reproduce:

  • Our production flow exercises the DatePicker more heavily:

  • We pass two broad ranges plus 10–30 individual date strings per visible month.

  • disabled is recomputed frequently (address, selected rate, and month changes), often producing a new array identity even when the content is the same.

  • We switch yearMonth and immediately supply a large disabled list for the new month.

  • We notice this happens more frequently once the users selects a new month (i.e they go from Sep → Oct)- once October renders in the picker, we often see the odd date that we’ve fed to disable, be enabled

Could you try a closer reproduction?

  • Use two wide ranges + many single-day strings (weekends triplets).

  • Rapidly change months and recompute disabled (new array identity each time).

Example (closer to our conditions):

import {DatePicker} from '@shopify/ui-extensions-react/checkout';
import * as React from 'react';

function FlakyRepro() {
  const [ym, setYm] = React.useState({year: 2025, month: 10});
  const baseSingles = [
    "2025-10-04","2025-10-05","2025-10-06",
    "2025-10-11","2025-10-12","2025-10-13",
    "2025-10-18","2025-10-19","2025-10-20",
    "2025-10-25","2025-10-26","2025-10-27"
  ];
  const [tick, setTick] = React.useState(0);

  React.useEffect(() => {
    const id = setInterval(() => setTick(t => t + 1), 800); // simulate frequent prop churn
    return () => clearInterval(id);
  }, []);

  const disabled = React.useMemo(() => ([
    {start: "1970-01-01", end: "2025-09-04"},
    {start: "2026-09-05", end: "2999-12-31"},
    ...baseSingles
  ]), [tick]); // new identity, same content

  return (
    <DatePicker
      yearMonth={ym}
      selected="2025-10-09"
      disabled={disabled}
      onYearMonthChange={setYm}
      onChange={() => {}}
    />
  );
}

If this still doesn’t reproduce on your end, we can provide a private test build of our extension that logs the DatePicker props and captures a DOM snapshot of the affected cell for your review.

Happy to also try mitigations on our side to help isolate (memoizing disabled, collapsing consecutive singles into ranges, deferring yearMonth updates until the month’s disabled is finalised) if you think any of those would meaningfully affect the DatePicker’s behaviour.

Thanks for taking another look.

Best,

Alex

Hi team,

We’ve got a large number of Shopify Plus brands chasing us on this. From all of our testing, this isn’t a code issue on our end, it’s the DatePicker not correctly rendering accurate disabled dates (usually caused when a user selects / changes month and the picker has to re render).

Any support would be hugely appreciated.

Thanks,

Alex

Hi @Alex_Hooper, sorry for the late response; I was out of office.

Thank you for providing additional details! I followed your code instructions (wide date ranges + many single-day strings) and rapidly changed months and still no luck reproducing. I may still be missing something. A few questions for you: which API version, and extension target are you using?

A test build with logs or a video with instructions definitely helpful as well. Thanks in advance

@Alex_Hooper I know this has been open for a while, but did you ever find a solve for this? The easiest way that I was able to reproduce was by randomly hiding and showing delivery options using a delivery customization function. Essentially, when those options completely change in the checkout, the entire extension gets reloaded and does not properly hydrate the component with previously stored state.

For example, let’s say I only want to show certain delivery options for Saturday. If my carrier service returns all the options that are possible (because of the Shopify cache), I can use the delivery customization function, to hide 1, 2, and 3 to 5 day ground shipping options, but continue to show the more expensive Saturday option when I select Saturday via the date picker component.

This almost always triggers some sort of weird UX as the internals of the date picker cannot be updated on a full refresh.