Skip to content

Commit

Permalink
refactor(date): updated errorMessage story and modified to import pro…
Browse files Browse the repository at this point in the history
…ps (#3112)

* refactor(date): updated errorMessage story and modified to import props

* docs(date): add errorMessageFunction examples

* chore: add changeset

* fix: remove unnecessary props

* fix: typo
  • Loading branch information
ryo-manba authored Jun 15, 2024
1 parent 3da8149 commit df0126f
Show file tree
Hide file tree
Showing 19 changed files with 243 additions and 18 deletions.
6 changes: 6 additions & 0 deletions .changeset/spicy-islands-drum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@nextui-org/date-input": patch
"@nextui-org/date-picker": patch
---

chore(date): update errorMessageFunction story and docs for date libraries
30 changes: 30 additions & 0 deletions apps/docs/content/components/date-input/error-message-function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const App = `import {DateInput} from "@nextui-org/react";
import {CalendarDate, parseDate} from "@internationalized/date";
export default function App() {
return (
<div className="flex w-full flex-wrap md:flex-nowrap gap-4">
<DateInput
label={"Birth date"}
defaultValue={parseDate("2024-04-04")}
placeholderValue={new CalendarDate(1995, 11, 6)}
description={"This is my birth date."}
isInvalid
errorMessage={(value) => {
if (value.isInvalid) {
return "Please enter a valid date.";
}
}}
className="max-w-xs"
/>
</div>
);
}`;

const react = {
"/App.jsx": App,
};

export default {
...react,
};
2 changes: 2 additions & 0 deletions apps/docs/content/components/date-input/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import labelPlacements from "./label-placements";
import description from "./description";
import startEndContent from "./start-end-content";
import errorMessage from "./error-message";
import errorMessageFunction from "./error-message-function";
import controlled from "./controlled";
import timeZones from "./time-zones";
import granularity from "./granularity";
Expand All @@ -25,6 +26,7 @@ export const dateInputContent = {
description,
startEndContent,
errorMessage,
errorMessageFunction,
controlled,
timeZones,
granularity,
Expand Down
26 changes: 26 additions & 0 deletions apps/docs/content/components/date-picker/error-message-function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const App = `import {DatePicker} from "@nextui-org/react";
export default function App() {
return (
<div className="flex w-full flex-wrap md:flex-nowrap gap-4">
<DatePicker
label="Birth date"
className="max-w-[284px]"
isInvalid
errorMessage={(value) => {
if (value.isInvalid) {
return "Please enter a valid date.";
}
}}
/>
</div>
);
}`;

const react = {
"/App.jsx": App,
};

export default {
...react,
};
2 changes: 2 additions & 0 deletions apps/docs/content/components/date-picker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import variants from "./variants";
import labelPlacements from "./label-placements";
import description from "./description";
import errorMessage from "./error-message";
import errorMessageFunction from "./error-message-function";
import withMonthAndYearPickers from "./with-month-and-year-pickers";
import withTimeField from "./with-time-field";
import selectorIcon from "./selector-icon";
Expand All @@ -28,6 +29,7 @@ export const datePickerContent = {
labelPlacements,
description,
errorMessage,
errorMessageFunction,
withMonthAndYearPickers,
withTimeField,
selectorIcon,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const App = `import {DateRangePicker} from "@nextui-org/react";
import {parseDate} from "@internationalized/date";
export default function App() {
return (
<DateRangePicker
isInvalid
label="Stay duration"
variant="bordered"
errorMessage={(value) => {
if (value.isInvalid) {
return "Please enter your stay duration";
}
}}
defaultValue={{
start: parseDate("2024-04-01"),
end: parseDate("2024-04-08"),
}}
className="max-w-xs"
/>
);
}`;

const react = {
"/App.jsx": App,
};

export default {
...react,
};
2 changes: 2 additions & 0 deletions apps/docs/content/components/date-range-picker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import variants from "./variants";
import labelPlacements from "./label-placements";
import description from "./description";
import errorMessage from "./error-message";
import errorMessageFunction from "./error-message-function";
import withTimeField from "./with-time-field";
import selectorIcon from "./selector-icon";
import controlled from "./controlled";
Expand All @@ -28,6 +29,7 @@ export const dateRangePickerContent = {
labelPlacements,
description,
errorMessage,
errorMessageFunction,
withTimeField,
selectorIcon,
controlled,
Expand Down
23 changes: 23 additions & 0 deletions apps/docs/content/components/time-input/error-message-function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const App = `import {TimeInput} from "@nextui-org/react";
export default function App() {
return (
<TimeInput
label="Event Time"
isInvalid
errorMessage={(value) => {
if (value.isInvalid) {
return "Please enter a valid time";
}
}}
/>
);
}`;

const react = {
"/App.jsx": App,
};

export default {
...react,
};
19 changes: 19 additions & 0 deletions apps/docs/content/components/time-input/error-message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const App = `import {TimeInput} from "@nextui-org/react";
export default function App() {
return (
<TimeInput
label="Event Time"
isInvalid
errorMessage="Please enter a valid time"
/>
);
}`;

const react = {
"/App.jsx": App,
};

export default {
...react,
};
4 changes: 4 additions & 0 deletions apps/docs/content/components/time-input/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import disabled from "./disabled";
import readonly from "./read-only";
import withoutLabel from "./without-label";
import withDescription from "./with-description";
import errorMessage from "./error-message";
import errorMessageFunction from "./error-message-function";
import labelPlacement from "./label-placement";
import startContent from "./start-content";
import endContent from "./end-content";
Expand All @@ -23,6 +25,8 @@ export const timeInputContent = {
readonly,
withoutLabel,
withDescription,
errorMessage,
errorMessageFunction,
labelPlacement,
startContent,
endContent,
Expand Down
4 changes: 4 additions & 0 deletions apps/docs/content/docs/components/date-input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ You can combine the `isInvalid` and `errorMessage` properties to show an invalid

<CodeDemo title="With Error Message" files={dateInputContent.errorMessage} />

You can also pass an error message as a function. This allows for dynamic error message handling based on the [ValidationResult]((https://github.com/adobe/react-spectrum/blob/1cacbf1d438675feb3859fee54b17e620b458d9c/packages/%40react-types/shared/src/inputs.d.ts#L44-L51)).

<CodeDemo title="With Error Message Function" files={dateInputContent.errorMessageFunction} />

### Controlled

You can use the `value` and `onChange` properties to control the input value.
Expand Down
4 changes: 4 additions & 0 deletions apps/docs/content/docs/components/date-picker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ You can combine the `isInvalid` and `errorMessage` properties to show an invalid

<CodeDemo title="With Error Message" files={datePickerContent.errorMessage} />

You can also pass an error message as a function. This allows for dynamic error message handling based on the [ValidationResult]((https://github.com/adobe/react-spectrum/blob/1cacbf1d438675feb3859fee54b17e620b458d9c/packages/%40react-types/shared/src/inputs.d.ts#L44-L51)).

<CodeDemo title="With Error Message Function" files={datePickerContent.errorMessageFunction} />

### With Month and Year Pickers

<CodeDemo title="With Month and Year Pickers" files={datePickerContent.withMonthAndYearPickers} />
Expand Down
4 changes: 4 additions & 0 deletions apps/docs/content/docs/components/date-range-picker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ You can combine the `isInvalid` and `errorMessage` properties to show an invalid

<CodeDemo title="With Error Message" files={dateRangePickerContent.errorMessage} />

You can also pass an error message as a function. This allows for dynamic error message handling based on the [ValidationResult]((https://github.com/adobe/react-spectrum/blob/1cacbf1d438675feb3859fee54b17e620b458d9c/packages/%40react-types/shared/src/inputs.d.ts#L44-L51)).

<CodeDemo title="With Error Message Function" files={dateRangePickerContent.errorMessageFunction} />

### With Time Fields

DateRangePicker automatically includes time fields when a `CalendarDateTime` or `ZonedDateTime` object is provided as the value.
Expand Down
11 changes: 11 additions & 0 deletions apps/docs/content/docs/components/time-input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,17 @@ A description for the field. Provides a hint such as specific requirements for w

<CodeDemo title="With Description" files={timeInputContent.withDescription} />

### With Error Message

You can combine the `isInvalid` and `errorMessage` properties to show an invalid input.

<CodeDemo title="With Error Message" files={timeInputContent.errorMessage} />

You can also pass an error message as a function. This allows for dynamic error message handling based on the [ValidationResult]((https://github.com/adobe/react-spectrum/blob/1cacbf1d438675feb3859fee54b17e620b458d9c/packages/%40react-types/shared/src/inputs.d.ts#L44-L51)).

<CodeDemo title="With Error Message Function" files={timeInputContent.errorMessageFunction} />


### Label Placement

The label's overall position relative to the element it is labeling.
Expand Down
18 changes: 2 additions & 16 deletions packages/components/date-input/src/date-input-group.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
import type {HTMLAttributes, ReactElement, ReactNode} from "react";
import type {GroupDOMAttributes} from "@react-types/shared";
import type {GroupDOMAttributes, HelpTextProps, ValidationResult} from "@react-types/shared";

import {useMemo} from "react";
import {forwardRef} from "@nextui-org/system";
import {dataAttr} from "@nextui-org/shared-utils";

// TODO: Use HelpTextProps from "@react-types/shared"; once we upgrade react-aria packages to the latest version.
export interface ValidationResult {
/** Whether the input value is invalid. */
isInvalid: boolean;
/** The current error messages for the input if it is invalid, otherwise an empty array. */
validationErrors: string[];
/** The native validation details for the input. */
validationDetails: ValidityState;
}

export interface DateInputGroupProps extends ValidationResult {
export interface DateInputGroupProps extends ValidationResult, HelpTextProps {
children?: ReactElement | ReactElement[];
shouldLabelBeOutside?: boolean;
label?: ReactNode;
Expand All @@ -27,10 +17,6 @@ export interface DateInputGroupProps extends ValidationResult {
labelProps?: HTMLAttributes<HTMLElement>;
descriptionProps?: HTMLAttributes<HTMLElement>;
errorMessageProps?: HTMLAttributes<HTMLElement>;
/** A description for the field. Provides a hint such as specific requirements for what to choose. */
description?: ReactNode;
/** An error message for the field. */
errorMessage?: ReactNode | ((v: ValidationResult) => ReactNode);
}

export const DateInputGroup = forwardRef<"div", DateInputGroupProps>((props, ref) => {
Expand Down
16 changes: 16 additions & 0 deletions packages/components/date-input/stories/date-input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from "@internationalized/date";
import {CalendarBoldIcon} from "@nextui-org/shared-icons";
import {useDateFormatter, I18nProvider} from "@react-aria/i18n";
import {ValidationResult} from "@react-types/shared";

import {DateInput, DateInputProps} from "../src";

Expand Down Expand Up @@ -254,10 +255,25 @@ export const WithErrorMessage = {

args: {
...defaultProps,
isInvalid: true,
errorMessage: "Please enter a valid date",
},
};

export const WithErrorMessageFunction = {
render: Template,

args: {
...defaultProps,
isInvalid: true,
errorMessage: (value: ValidationResult) => {
if (value.isInvalid) {
return "Please enter a valid date";
}
},
},
};

export const IsInvalid = {
render: Template,

Expand Down
25 changes: 25 additions & 0 deletions packages/components/date-input/stories/time-input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ZonedDateTime,
} from "@internationalized/date";
import {useDateFormatter} from "@react-aria/i18n";
import {ValidationResult} from "@react-types/shared";

import {TimeInput, TimeInputProps, TimeInputValue as TimeValue} from "../src";

Expand Down Expand Up @@ -192,6 +193,30 @@ export const WithDescription = {
},
};

export const WithErrorMessage = {
render: Template,

args: {
...defaultProps,
isInvalid: true,
errorMessage: "Please enter a valid time",
},
};

export const WithErrorMessageFunction = {
render: Template,

args: {
...defaultProps,
isInvalid: true,
errorMessage: (value: ValidationResult) => {
if (value.isInvalid) {
return "Please enter a valid date";
}
},
},
};

export const LabelPlacement = {
render: LabelPlacementTemplate,

Expand Down
16 changes: 16 additions & 0 deletions packages/components/date-picker/stories/date-picker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {I18nProvider, useDateFormatter, useLocale} from "@react-aria/i18n";
import {Button, ButtonGroup} from "@nextui-org/button";
import {Radio, RadioGroup} from "@nextui-org/radio";
import {cn} from "@nextui-org/theme";
import {ValidationResult} from "@react-types/shared";

import {DatePicker, DatePickerProps} from "../src";

Expand Down Expand Up @@ -424,10 +425,25 @@ export const WithErrorMessage = {

args: {
...defaultProps,
isInvalid: true,
errorMessage: "Please enter a valid date",
},
};

export const WithErrorMessageFunction = {
render: Template,

args: {
...defaultProps,
isInvalid: true,
errorMessage: (value: ValidationResult) => {
if (value.isInvalid) {
return "Please enter a valid date";
}
},
},
};

export const IsInvalid = {
render: Template,

Expand Down
Loading

0 comments on commit df0126f

Please sign in to comment.