Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Mitigate need for users to keep @internationalized/date version in sync with NextUI #4567

Open
jrr opened this issue Jan 15, 2025 · 10 comments · May be fixed by #4655
Open
Assignees
Labels
✨ Type: Enhancement New enhancement on existing codebase

Comments

@jrr
Copy link

jrr commented Jan 15, 2025

Is your feature request related to a problem? Please describe.

Today, in order to use<DatePicker>, users of NextUI also have to take on a dependency on the @internationalized/date package.

It's also necessary to keep your version of this library exactly in sync with NextUI. (for example, a version mismatch can cause an error like Type 'ZonedDateTime' is not assignable to type 'CalendarDate | CalendarDateTime | ZonedDateTime | null | undefined'., seen in the screenshot below)

(I'm guessing this isn't a surprise, as the docs provide instructions to install 3.6.0 specifically)

Describe the solution you'd like

What if NextUI re-exported symbols from their own version of @internationlized/date? So users could switch from this:

import { DatePicker, DatePickerProps } from "@nextui-org/date-picker";
import { CalendarDate, parseDate } from "@internationalized/date";

To something like this:

import { DatePicker, DatePickerProps } from "@nextui-org/date-picker";
import { CalendarDate, parseDate } from "@nextui-org/date-picker/internalized-date";

Then, if I'm only using @internationalized/date for NextUI, then I won't need to add it to my package.json (and won't accidentally update it).

Or, if I am using it elsewhere, I'll have a chance of being able to update it without breaking NextUI. (though I'd probably run into version conflicts elsewhere)

Describe alternatives you've considered

Another issue suggests not requiring @internationalized/date at all: #4401

Screenshots or Videos

image

@J4v4Scr1pt
Copy link

I also have this issue going from 3.6.0 -> 3.7.0 on @internationalized/date package.
But I do not have any issues using this packages or any opinion on how to import it.
The only thing I would not like is to get to far behind on versions, like keeping my packages up to date 😅

@wingkwong wingkwong self-assigned this Jan 16, 2025
@wingkwong wingkwong added the ✨ Type: Enhancement New enhancement on existing codebase label Jan 16, 2025
@wingkwong
Copy link
Member

will export those packages in next minor release

@wingkwong wingkwong added this to the v2.7.0 milestone Jan 16, 2025
@mengxi-ream
Copy link

mengxi-ream commented Jan 19, 2025

After migration, I got the error:

Type 'DateRangePicker' is not assignable to type 'RangeValue<DateValue>'.
  Types of property 'start' are incompatible.
    Type 'CalendarDate' is not assignable to type 'DateValue'.
      Type 'CalendarDate' is not assignable to type 'ZonedDateTime'.
        Property '#private' in type 'CalendarDate' refers to a different member that cannot be accessed from within type 'ZonedDateTime'.

Here is my code:

import { type CalendarDate, parseDate } from "@internationalized/date";

export const dateRangeAtom = atom<[Date, Date]>([
  new Date(new Date().setFullYear(new Date().getFullYear() - 2)),
  new Date(),
]);

type DateRangePicker = {
  start: CalendarDate;
  end: CalendarDate;
};

function dateValueToDate(dateValue: CalendarDate): Date {
  return new Date(dateValue.year, dateValue.month - 1, dateValue.day);
}

export const dateRangePickerAtom = atom<
  DateRangePicker,
  DateRangePicker[],
  void
>(
  (get) => {
    const [startDate, endDate] = get(dateRangeAtom);
    return {
      start: parseDate(format(startDate, "yyyy-MM-dd")),
      end: parseDate(format(endDate, "yyyy-MM-dd")),
    };
  },
  (_get, set, newVal) => {
    set(dateRangeAtom, [
      dateValueToDate(newVal.start),
      dateValueToDate(newVal.end),
    ]);
  },
);

// in React
    <DateRangePicker
      label="Pick Date Range"
      className="w-auto max-w-xs"
      value={dateRangePicker}
      onChange={setDateRangePicker}
    />

// type error from value={dateRangePicker}

@wingkwong
Copy link
Member

@mengxi-ream are you using @internationalized/[email protected]?

@mengxi-ream
Copy link

@mengxi-ream are you using @internationalized/[email protected]?

I'm using 3.7.0, but version ^3.5.5 also has the same error

@mengxi-ream
Copy link

@mengxi-ream are you using @internationalized/[email protected]?

fixed when I changed the version to 3.6.0

@wingkwong
Copy link
Member

@mengxi-ream Internally we are using 3.6.0. Please use the fixed version at this moment. In the future, we will export the package from our side so that users can use the exact same version to avoid incompatible issues.

@ahoedt
Copy link

ahoedt commented Jan 20, 2025

I also have the same type of issue with the "maxValue" parameter:
maxValue={today(getLocalTimeZone())}

Error: Type 'CalendarDate' is not assignable to type 'DateValue | null | undefined'.

I am using the following versions:
"@heroui/date-picker": "^2.3.10",
"@heroui/react": "^2.6.14",
"@heroui/system": "^2.4.7",
"@heroui/theme": "^2.4.6",
"@internationalized/date": "3.6.0"

@twickstrom
Copy link

twickstrom commented Jan 28, 2025

I also have the same type of issue with the "maxValue" parameter: maxValue={today(getLocalTimeZone())}

Error: Type 'CalendarDate' is not assignable to type 'DateValue | null | undefined'.

I am using the following versions: "@heroui/date-picker": "^2.3.10", "@heroui/react": "^2.6.14", "@heroui/system": "^2.4.7", "@heroui/theme": "^2.4.6", "@internationalized/date": "3.6.0"

After fighting with this issue for the better part of a day I was only able to validate two solutions for this issue both have their downsides and hopefully the HeroUI team will have a permanent fix for this issue from their side sooner than later.

I can confirm this minVal issue is effecting Calendar, Date Picker, Date Range Picker, and Time Input. My hunch is the other date/time components are also effected.

Solution 1:
Define override/resolution in your package.json file. Why i personally don't like this is that without exhaustive testing I'm not sure if this will break other dependencies in my app.

Solution 2:
In your component:

import { Calendar, type DateValue } from '@heroui/react'
import {
  type CalendarDate,
  getLocalTimeZone,
  today,
} from '@internationalized/date'

export interface DateSelectProps {
  value: CalendarDate | null
  children?: React.ReactNode
  onChange?: (date: CalendarDate) => void
}

export default function MyDateSelect({ value, children, onChange }: Readonly<DateSelectProps>) {
  const zonedToday = today(getLocalTimeZone())
  const fakeDateValue = {
    year: zonedToday.year,
    month: zonedToday.month,
    day: zonedToday.day,
  } as DateValue

  return (
    <Calendar
      aria-label='Date Picker'
      value={value}
      onChange={handleDateChange}
      minValue={fakeDateValue}
    />
  )
}

I don't love the bloated code in #2 but I like that the solution is isolated to to the problem area and not a sweeping global change.

And guys, I love what your doing with NextUI/HeroUI but but as a paying Pro member this level of a bug should have never made it into a stable release branch. Hopefully we can add a bit more testing around this going forward.

@wingkwong wingkwong removed this from the v2.7.0 milestone Jan 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ Type: Enhancement New enhancement on existing codebase
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants