Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@nordcloud/gnui",
"description": "Nordcloud Design System - a collection of reusable React components used in Nordcloud's SaaS products",
"version": "11.5.3",
"version": "11.6.0",
"license": "MIT",
"repository": {
"type": "git",
Expand Down
1 change: 1 addition & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export default {
],
plugins: [
typescript({
include: ["src/**/*.{ts,tsx}"],
useTsconfigDeclarationDir: true,
tsconfigOverride: {
exclude: [
Expand Down
25 changes: 16 additions & 9 deletions src/components/timeRangePicker/TimeRangePicker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import * as TimeRangePickerStories from "./TimeRangePicker.stories";

## TimeRangePicker properties

| properties | required | type | description |
| ------------: | :------: | :-------------------------------------------- | :-------------------------------------------------------------------------------------------------------- |
| initTimeRange | false | Interval | Start date and end date should be within the same day, current date will be used otherwise and by default |
| type | false | <code>Days</code>, <code>Hours</code> | Type of time selected in component |
| weekCounts | false | DailyCount\[] | Item counts in each time range (Type "Hours" only) |
| countsLoading | false | boolean | Loading state of week counts (Type "Hours" only) |
| disabledDays | false | Matcher\[] | Dates not allowed to select |
| onChange | true | <code>(newTimeRange: Interval) => void</code> | Function to handle timeRange change |
| onWeekChange | false | <code>(monday: Date) => void</code> | Function to submit when showing week updates (Type "Hours" only) |
| properties | required | type | description |
| ------------------: | :------: | :-------------------------------------------- | :-------------------------------------------------------------------------------------------------------- |
| initTimeRange | false | Interval | Start date and end date should be within the same day, current date will be used otherwise and by default |
| type | false | <code>Days</code>, <code>Hours</code> | Type of time selected in component |
| weekCounts | false | DailyCount\[] | Item counts in each time range (Type "Hours" only) |
| countsLoading | false | boolean | Loading state of week counts (Type "Hours" only) |
| disabledDays | false | Matcher\[] | Dates not allowed to select |
| keepSelectedWeekday | false | boolean | Whether to preserve week day selection when changing week (Type "Hours" only) |
| onChange | true | <code>(newTimeRange: Interval) => void</code> | Function to handle timeRange change |
| onWeekChange | false | <code>(monday: Date) => void</code> | Function to submit when showing week updates (Type "Hours" only) |

```typescript
import { Interval } from "date-fns";
Expand Down Expand Up @@ -49,6 +50,12 @@ type Matcher = (boolean | (date: Date)) => boolean | Date | Date[] | DateRange |
<Story of={TimeRangePickerStories.TimerangepickerOfHours} />
</Canvas>

## Type "Hours" with preserved day selection

<Canvas>
<Story of={TimeRangePickerStories.TimerangepickerOfHoursWithKeepSelectedWeekday} />
</Canvas>

## Type "Hours" with Histogram

<Canvas>
Expand Down
202 changes: 111 additions & 91 deletions src/components/timeRangePicker/TimeRangePicker.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,113 +1,133 @@
import { useState } from "react";
import { Meta, StoryObj } from "@storybook/react";
import { previousMonday, addDays } from "date-fns";
import { addDays, previousMonday } from "date-fns";
import { Spacer } from "../spacer";
import { TimeRangePicker } from "./TimeRangePicker";

const meta: Meta = {
const meta: Meta<typeof TimeRangePicker> = {
title: "Forms/TimeRangePicker",
component: TimeRangePicker,
};

export default meta;

export const TimerangepickerOfDays: StoryObj = {
render: () => {
const initValue = {
start: new Date(),
end: new Date(),
};

const [value, setValue] = useState<{
start: Date | number;
end: Date | number;
}>(initValue);

return (
<>
<TimeRangePicker
type="Days"
initTimeRange={initValue}
onChange={(newValue) => setValue(newValue)}
/>
<Spacer height="20rem" />
<div id="result-days">Current Value:{JSON.stringify(value)}</div>
</>
);
},
type TimeRangeValue = {
start: Date | number;
end: Date | number;
};

function TimerangepickerOfDaysComponent() {
const initValue = {
start: new Date(),
end: new Date(),
};

const [value, setValue] = useState<TimeRangeValue>(initValue);

return (
<>
<TimeRangePicker
type="Days"
initTimeRange={initValue}
onChange={(newValue) => setValue(newValue)}
/>
<Spacer height="20rem" />
<div id="result-days">Current Value:{JSON.stringify(value)}</div>
</>
);
}

export const TimerangepickerOfDays: StoryObj<typeof TimeRangePicker> = {
render: () => <TimerangepickerOfDaysComponent />,
name: "timerangepicker of days",
};

export const TimerangepickerOfHours: StoryObj = {
render: () => {
const [value, setValue] = useState<{
start: Date | number;
end: Date | number;
}>();

return (
<>
<TimeRangePicker onChange={setValue} />
<Spacer height="20rem" />
<div id="result-hours">Current Value:{JSON.stringify(value)}</div>
</>
);
},
function TimerangepickerOfHoursComponent() {
const [value, setValue] = useState<TimeRangeValue>();

return (
<>
<TimeRangePicker onChange={setValue} />
<Spacer height="20rem" />
<div id="result-hours">Current Value:{JSON.stringify(value)}</div>
</>
);
}

export const TimerangepickerOfHours: StoryObj<typeof TimeRangePicker> = {
render: () => <TimerangepickerOfHoursComponent />,
name: "timerangepicker of hours ",
};

export const TimerangepickerOfHoursWithHistogram: StoryObj = {
render: () => {
const [value, setValue] = useState<{
start: Date | number;
end: Date | number;
}>();
const monday = previousMonday(new Date());

return (
<>
<TimeRangePicker
weekCounts={[
{
date: monday,
counts: [1, 2, 3, 4],
},
{
date: addDays(monday, 1),
counts: [0, 2, 3, 4],
},
{
date: addDays(monday, 2),
counts: [1, 0, 3, 4],
},
{
date: addDays(monday, 3),
counts: [1, 2, 0, 4],
},
{
date: addDays(monday, 4),
counts: [1, 2, 3, 0],
},
{
date: addDays(monday, 5),
counts: [0, 0, 0, 0],
},
{
date: addDays(monday, 6),
counts: [0, 0, 0, 0],
},
]}
onChange={setValue}
/>
<Spacer height="20rem" />
<div id="result-hours-with-histogram">
Current Value:{JSON.stringify(value)}
</div>
</>
);
},
function TimerangepickerOfHoursWithKeepSelectedWeekdayComponent() {
const [value, setValue] = useState<TimeRangeValue>();

return (
<>
<TimeRangePicker keepSelectedWeekday onChange={setValue} />
<Spacer height="20rem" />
<div id="result-hours">Current Value:{JSON.stringify(value)}</div>
</>
);
}

export const TimerangepickerOfHoursWithKeepSelectedWeekday: StoryObj<
typeof TimeRangePicker
> = {
render: () => <TimerangepickerOfHoursWithKeepSelectedWeekdayComponent />,
name: "timerangepicker of hours with preserved day",
};

function TimerangepickerOfHoursWithHistogramComponent() {
const [value, setValue] = useState<TimeRangeValue>();
const monday = previousMonday(new Date());

return (
<>
<TimeRangePicker
weekCounts={[
{
date: monday,
counts: [1, 2, 3, 4],
},
{
date: addDays(monday, 1),
counts: [0, 2, 3, 4],
},
{
date: addDays(monday, 2),
counts: [1, 0, 3, 4],
},
{
date: addDays(monday, 3),
counts: [1, 2, 0, 4],
},
{
date: addDays(monday, 4),
counts: [1, 2, 3, 0],
},
{
date: addDays(monday, 5),
counts: [0, 0, 0, 0],
},
{
date: addDays(monday, 6),
counts: [0, 0, 0, 0],
},
]}
onChange={setValue}
/>
<Spacer height="20rem" />
<div id="result-hours-with-histogram">
Current Value:{JSON.stringify(value)}
</div>
</>
);
}

export const TimerangepickerOfHoursWithHistogram: StoryObj<
typeof TimeRangePicker
> = {
render: () => <TimerangepickerOfHoursWithHistogramComponent />,
name: "timerangepicker of hours with histogram",
};
3 changes: 3 additions & 0 deletions src/components/timeRangePicker/TimeRangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { DatesPicker, DateHourPicker } from "./components";
type Props = Omit<ComponentProps<typeof DateHourPicker>, "initTimeRange"> & {
initTimeRange?: Interval;
type?: "Days" | "Hours";
keepSelectedWeekday?: boolean;
};

const DEFAULT_TIME_RANGE: Interval = {
Expand All @@ -17,6 +18,7 @@ export function TimeRangePicker({
weekCounts,
countsLoading = false,
disabledDays,
keepSelectedWeekday = false,
onChange,
onWeekChange,
}: Props) {
Expand All @@ -35,6 +37,7 @@ export function TimeRangePicker({
weekCounts={weekCounts}
countsLoading={countsLoading}
disabledDays={disabledDays}
keepSelectedWeekday={keepSelectedWeekday}
onChange={onChange}
onWeekChange={onWeekChange}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ import {
getMonday,
getTimeRangeDate,
isSameTimeRange,
getNewSelectedDate,
} from "../utils";
import { DateSelector, HourSelector } from "./components";

type Props = DatesPickerProps & {
weekCounts?: DailyCount[];
countsLoading?: boolean;
keepSelectedWeekday?: boolean;
onWeekChange?: (monday: Date) => void;
};

Expand All @@ -29,11 +31,12 @@ export function DateHourPicker({
weekCounts,
countsLoading = false,
disabledDays,
keepSelectedWeekday = false,
onChange,
onWeekChange,
}: Props) {
const [selectedDate, setSelectedDate] = useState<Date>(
getTimeRangeDate(initTimeRange)
getTimeRangeDate(initTimeRange, "Hours")
);
const [dateOptions, setDateOptions] = useState<DateOption[]>(
getDateOptions(getMonday(initTimeRange.start))
Expand Down Expand Up @@ -93,6 +96,15 @@ export function DateHourPicker({
if (onWeekChange) {
onWeekChange(newMonday);
}
if (keepSelectedWeekday) {
const newSeletedDate = getNewSelectedDate(
selectedDate,
currentMonday,
newMonday
);
setSelectedDate(newSeletedDate);
submitDateHour(newSeletedDate, selectedTimeRange);
}
};

// Function to update time range options
Expand Down
Loading
Loading