Skip to content

Commit

Permalink
feat(calendar): update day picker and add dropdown for months and yea…
Browse files Browse the repository at this point in the history
…rs (#129)

* chore: udpate day picker to v9

* chore: update v9 classes

* fix: update props as per new calendar

* fix: styling issue

* feat: add dropdown for months and year

* docs: add preview for calendar dropdown

* chore: add text and icon props in select

* chore: update select and scroll-area package

* fix: create dropdown component and fix its style issues

* ci: add dependency in turbo and remove caching from ci tasks

* fix: typo

* chore: remove build dependency in source code

* chore: remove turbo.json file

* chore: add tubo.json file back

* chore: update turbo

* ci: disable build cache

* ci: add installCommand to vercel

* chore: update nextjs version

* docs: update rangepicker example

* fix: add max height for the dropdown

* fix: add border to dropdown content
  • Loading branch information
rsbh authored Jul 26, 2024
1 parent a7b20e4 commit 0bbbfc9
Show file tree
Hide file tree
Showing 13 changed files with 9,191 additions and 10,100 deletions.
11 changes: 10 additions & 1 deletion apps/www/content/primitives/components/calendar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,23 @@ links:
<Calendar numberOfMonths={2} />
</Preview>

## Dropdown

<Preview>
<Flex gap="medium">
<Calendar captionLayout="dropdown" />
<Calendar captionLayout="dropdown-years" />
</Flex>
</Preview>

## DatePicker

<Preview>
<Flex direction="column" gap="medium">

<DatePicker textFieldProps={{ size: "medium" }} />

<RangePicker textFieldProps={{ size: "medium" }} />
<RangePicker textFieldProps={{ size: "medium" }} calendarProps={{ captionLayout: "dropdown-years" }}/>

</Flex>
</Preview>
2 changes: 1 addition & 1 deletion apps/www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"copy-to-clipboard": "^3.3.3",
"dayjs": "^1.11.11",
"framer-motion": "^10.12.16",
"next": "13.2.4",
"next": "14.2.5",
"react-live": "^4.1.6",
"react-loading-skeleton": "^3.4.0",
"tslib": "^2.5.0"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"eslint-config-custom": "workspace:*",
"prettier": "^2.5.1",
"process": "^0.11.10",
"turbo": "2.0.6",
"turbo": "2.0.9",
"typescript": "4.7"
},
"packageManager": "[email protected]",
Expand Down
129 changes: 85 additions & 44 deletions packages/raystack/calendar/calendar.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
background: var(--background-base);
}

.caption {
display: flex;
justify-content: center;
align-items: center;
position: relative;
margin-bottom: var(--mr-12);
}

.caption_label {
.caption_label,
.dropdowns > span,
.dropdown_trigger .dropdown_item_text {
font-size: 14px;
line-height: 20px;
letter-spacing: 0.25px;
font-weight: 500;
color: var(--foreground-base);
user-select: none;
font-family: var(--ff-inter);
}

.caption_label[aria-hidden="true"] {
display: none;
}

.nav_button {
Expand All @@ -28,111 +28,125 @@
color: var(--foreground-base);
background: var(--background-base);
cursor: pointer;
height: 20px;
}

.nav_button_previous {
left: 0;
height: 100%;
}

.nav_button_next {
right: 0;
height: 100%;
}

.head {
color: var(--foreground-muted);
font-size: 12px;
line-height: 16px;
letter-spacing: 0.4px;
font-weight: 500;
.months {
display: flex;
gap: var(--pd-8);
position: relative;
}

.nav {
position: absolute;
width: 100%;
}

.head_cell {
.month_caption {
display: flex;
justify-content: center;
align-items: center;
width: 36px;
height: 36px;
color: var(--foreground-base);
position: relative;
width: fit-content;
margin: 0 auto var(--mr-12) auto;
}

.cell {
.day {
width: 36px;
height: 36px;
background-color: var(--background-base);
border-radius: var(--br-4);
color: var(--foreground-base);
font-size: 13px;
line-height: 16px;
letter-spacing: 0.4px;
display: flex;
justify-content: center;
align-items: center;
}

.cell:hover {
.day:hover {
background-color: var(--background-base-hover);
}

.cell:has([aria-selected="true"]) {
.day[aria-selected="true"]:not(.range_middle) {
background-color: var(--background-highlight);

button {
color: var(--foreground-inverted);
}
}

.cell:has(.day_today):not(:has([aria-selected="true"])) {
background-color: var(--background-subtle);
}

.cell:has(.day_range_middle) {
.range_middle {
border-radius: 0;
background-color: var(--background-base-hover);
button {
color: var(--foreground-base);
}
}

.cell:has(.day_range_start):not(:has(.day_range_end)) {
.range_start:not(.range_end) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}

.cell:has(.day_range_end):not(:has(.day_range_start)) {
.range_end:not(.range_start) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}

.row {
.week {
display: flex;
}

.day {
color: var(--foreground-base);
font-size: 13px;
line-height: 16px;
letter-spacing: 0.4px;
.day_button {
cursor: pointer;
border: none;
background: transparent;
width: 100%;
height: 100%;
padding: unset;
display: grid;
place-content: center;
background: inherit;
color: inherit;
font-weight: inherit;
}

.day_outside {
.outside {
color: var(--foreground-subtle);
}

.day_today {
.today {
font-weight: 600;
}

.day_range_start,
.day_range_end {
.range_start,
.range_end {
color: var(--foreground-inverted);
}

.months {
.weekday {
display: flex;
gap: var(--pd-8);
justify-content: center;
align-items: center;
width: 36px;
height: 36px;
color: var(--foreground-base);
font-size: 12px;
line-height: 16px;
letter-spacing: 0.4px;
}

.hidden {
visibility: hidden;
}

.calendarPopover {
Expand All @@ -144,3 +158,30 @@
.datePickerInput {
cursor: pointer;
}

.dropdowns {
display: flex;
align-items: center;
gap: var(--pd-4);
}

.dropdown_trigger,
.dropdown_trigger:focus {
border: none;
outline: none;
box-shadow: none;
padding: var(--pd-2);
}

.dropdown_trigger:hover {
background-color: var(--background-base-hover);
}

.dropdown_icon {
margin-left: var(--mr-4);
}

.dropdown_content {
max-height: 400px;
border: 1px solid var(--border-base);
}
101 changes: 80 additions & 21 deletions packages/raystack/calendar/calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,66 @@
import { DayPicker, DayPickerProps } from "react-day-picker";
import { DayPicker, DayPickerProps, DropdownProps } from "react-day-picker";
import { cva } from "class-variance-authority";
import { ChevronRightIcon, ChevronLeftIcon } from "@radix-ui/react-icons";

import {
ChevronRightIcon,
ChevronLeftIcon,
ChevronUpIcon,
ChevronDownIcon,
} from "@radix-ui/react-icons";
import styles from "./calendar.module.css";
import { Select } from "~/select";
import { ChangeEvent } from "react";
import { Flex } from "~/flex/flex";

export type CalendarProps = DayPickerProps & {};

const root = cva(styles.calendarRoot);

function DropDown({ options = [], value, onChange }: DropdownProps) {
function handleChange(value: string) {
if (onChange) {
onChange({ target: { value } } as ChangeEvent<HTMLSelectElement>);
}
}
return (
<Select value={value?.toString()} onValueChange={handleChange}>
<Select.Trigger
className={styles.dropdown_trigger}
iconProps={{
className: styles.dropdown_icon,
}}
>
<Select.Value />
</Select.Trigger>
<Select.Content className={styles.dropdown_content}>
<Select.ScrollUpButton asChild>
<Flex justify={"center"}>
<ChevronUpIcon />
</Flex>
</Select.ScrollUpButton>
<Select.Viewport>
{options.map((opt) => (
<Select.Item
value={opt.value.toString()}
key={opt.value}
disabled={opt.disabled}
textProps={{
className: styles.dropdown_item_text,
}}
>
{opt.label}
</Select.Item>
))}
</Select.Viewport>
<Select.ScrollDownButton asChild>
<Flex justify={"center"}>
<ChevronDownIcon />
</Flex>
</Select.ScrollDownButton>
</Select.Content>
</Select>
);
}

export const Calendar = function ({
className,
classNames,
Expand All @@ -18,31 +71,37 @@ export const Calendar = function ({
<DayPicker
showOutsideDays={showOutsideDays}
components={{
IconLeft: () => <ChevronLeftIcon />,
IconRight: () => <ChevronRightIcon />,
Chevron: (props) => {
if (props.orientation === "left") {
return <ChevronLeftIcon {...props} />;
}
return <ChevronRightIcon {...props} />;
},
Dropdown: DropDown,
}}
classNames={{
caption: styles.caption,
caption_label: styles.caption_label,
nav_button: styles.nav_button,
nav_button_previous: styles.nav_button_previous,
nav_button_next: styles.nav_button_next,
head: styles.head,
head_cell: styles.head_cell,
cell: styles.cell,
head_row: styles.row,
row: styles.row,
day: styles.day,
day_outside: styles.day_outside,
day_today: styles.day_today,
day_range_middle: styles.day_range_middle,
day_range_end: styles.day_range_end,
day_range_start: styles.day_range_start,
button_previous: `${styles.nav_button} ${styles.nav_button_previous}`,
button_next: `${styles.nav_button} ${styles.nav_button_next}`,
month_caption: styles.month_caption,
months: styles.months,
// button: styles.button,
nav: styles.nav,
day: styles.day,
today: styles.today,
outside: styles.outside,
week: styles.week,
weekdays: styles.week,
weekday: styles.weekday,
day_button: styles.day_button,
range_middle: styles.range_middle,
range_end: styles.range_end,
range_start: styles.range_start,
hidden: styles.hidden,
dropdowns: styles.dropdowns,
...classNames,
}}
className={root({ className })}
mode="single"
{...props}
/>
);
Expand Down
Loading

0 comments on commit 0bbbfc9

Please sign in to comment.