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

feat(Calendar): implement component #2618

Open
wants to merge 60 commits into
base: v3
Choose a base branch
from
Open

Conversation

hywax
Copy link

@hywax hywax commented Nov 12, 2024

πŸ”— Linked issue

Resolves #1137 and half #2524

❓ Type of change

  • πŸ“– Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • πŸ‘Œ Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

UDatepicker component to use nuxt-ui is sorely lacking. This is the first step towards implementing a UDatepicker. I'll be doing this in my spare time, so it might be a bit of a stretch.

πŸ“ Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@benjamincanac benjamincanac changed the title feat(calendar): implement component feat(Calendar): implement component Nov 12, 2024
@benjamincanac benjamincanac added the v3 #1289 label Nov 12, 2024
@hywax
Copy link
Author

hywax commented Nov 13, 2024

@benjamincanac do you think UCalendar is part of UForm? Or is it an independent component that only becomes part of UDatepicker?

I'm asking to see if I need to get the props part from useFormField

Upd. looked at how other ui's work with the calendar. It's always a separate component, without a form, it's with a model

Copy link
Member

No need to make it work in a form, it's a separate component indeed! Also, it should handle ranges:

src/theme/calendar.ts Outdated Show resolved Hide resolved
@hywax
Copy link
Author

hywax commented Nov 13, 2024

@benjamincanac at the moment it looks like this. It remains to solve the typing problem and write documentation.

Copy link
Member

@benjamincanac benjamincanac left a comment

Choose a reason for hiding this comment

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

You should not duplicate the code to handle range prop but use namespaced imports instead: https://www.radix-vue.com/guides/namespaced-components.html

Take a look at https://github.com/nuxt/ui/blob/v3/src/runtime/components/DropdownMenuContent.vue#L92 for example.

You could have something like const Component = computed(() => props.range ? RangeCalendar : Calendar).

@hywax
Copy link
Author

hywax commented Nov 13, 2024

I was going to do that originally. But I thought that typing on dynamic components might break.

But since you recommend it, I'll do it like this

@hywax
Copy link
Author

hywax commented Nov 14, 2024

@benjamincanac radix uses @internationalized/date for calendars, which internally creates a class. When Vue wraps this class in ref, it hides some of the private properties. The solution to this situation is to use shallowRef.


There is an issue where this problem was discussed: vuejs/core#2981 (comment), but the workaround looks quite unappealing.

I would suggest switching to standard new Date in the models.

Example:

export type DateRange = {
-    start: DateValue | undefined;
-    end: DateValue | undefined;
+    start: Date | undefined;
+    end: Date | undefined;
};

What do you think about this?

PS Even in the example they use computed in the model, not ref because the model is computed inside the class - https://www.radix-vue.com/components/calendar.html#calendar-with-locale-and-calendar-system-selection

@hywax
Copy link
Author

hywax commented Nov 21, 2024

@benjamincanac I think we should transform this component into DatePicker and DateRangePicker at once. I don't think the calendar itself is necessary.

So I'm going to change this PR to a different component

Copy link
Member

Why is that? I can see the use of a Date picker outside of a popover but directly in your page. This is not a really good example but on Airbnb, let's imagine this directly in your page:
CleanShot 2024-11-21 at 17.12.44@2x.png

@hywax
Copy link
Author

hywax commented Nov 21, 2024

Yeah, you're right.

Then to implement Datepicker we will need to take https://www.radix-vue.com/components/date-range-field.html so that you don't have to write a date validator yourself

Copy link
Member

We'll need to create a UDateInput that uses https://www.radix-vue.com/components/date-range-picker.html and we can also make an example in the calendar.md named Within a popover that will act as a DatePicker I guess.

@hywax
Copy link
Author

hywax commented Nov 21, 2024

I fully endorse!

Copy link
Member

Can you make the example in this PR? This would look like https://www.shadcn-vue.com/docs/components/date-picker.html

@hywax
Copy link
Author

hywax commented Nov 21, 2024

@benjamincanac I added CalendarDatePickerExample.vue, is that what you were talking about?

@benjamincanac
Copy link
Member

Could be nice to also have a DateRangePicker: https://www.shadcn-vue.com/docs/components/date-picker.html#date-range-picker

@hywax
Copy link
Author

hywax commented Nov 21, 2024

@benjamincanac done. Also returned the flex styles for body, needed for 2 or more calendars

@hywax
Copy link
Author

hywax commented Nov 21, 2024


@hywax
Copy link
Author

hywax commented Nov 21, 2024

@benjamincanac I switched from the standard new Date to using @internationalized/date. I think this approach is more appropriate.

Pros:

  • It reduced the amount of code
  • All props/events can be used

Cons:

@hywax
Copy link
Author

hywax commented Nov 21, 2024

I don't plan to add or modify the code anymore. You can review it, and if everything looks good, go ahead and merge it 😊

Copy link
Member

Awesome! Will try to make a final review tomorrow and merge it :) In both datepickers examples, would you mind formatting the dates as such: Jan 20, 2022 - Feb 9, 2022? 😬

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v3 #1289
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants