diff --git a/package-lock.json b/package-lock.json index c76817a9c776589e67b3fdff070529bd69abc146..44ee6e419252ca4713bee69737e99ddfd3043ec1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "postcss": "^8.4.31", "primereact": "^10.5.1", "react": "^18.2.0", - "react-datepicker": "^4.21.0", + "react-datepicker": "6.2.0", "react-dom": "^18.2.0", "react-slider": "^2.0.6", "react-svg": "^16.1.29", @@ -3041,31 +3041,46 @@ "dev": true }, "node_modules/@floating-ui/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", - "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", "dev": true, "dependencies": { - "@floating-ui/utils": "^0.1.3" + "@floating-ui/utils": "^0.2.1" } }, "node_modules/@floating-ui/dom": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", - "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", "dev": true, "dependencies": { - "@floating-ui/core": "^1.4.2", - "@floating-ui/utils": "^0.1.3" + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.9.tgz", + "integrity": "sha512-p86wynZJVEkEq2BBjY/8p2g3biQ6TlgT4o/3KgFKyTWoJLU1GZ8wpctwRqtkEl2tseYA+kw7dBAIDFcednfI5w==", + "dev": true, + "dependencies": { + "@floating-ui/react-dom": "^2.0.8", + "@floating-ui/utils": "^0.2.1", + "tabbable": "^6.0.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.3.tgz", - "integrity": "sha512-wOoKUw2P24/OXbNr3bbCqWgoltsyY7lFBDPVtjj/V4WDIJ5hja2C/r+CoWmS+Y75Ahndds3wa7eJRhnJxTCJaQ==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", "dev": true, "dependencies": { - "@floating-ui/dom": "^1.5.1" + "@floating-ui/dom": "^1.6.1" }, "peerDependencies": { "react": ">=16.8.0", @@ -3073,9 +3088,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", - "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==", "dev": true }, "node_modules/@formatjs/ecma402-abstract": { @@ -26088,23 +26103,32 @@ } }, "node_modules/react-datepicker": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-4.21.0.tgz", - "integrity": "sha512-z0DtuRrKMz9i7dcTusW29VacbM9pn08g1yw0cG+Y5GpodJDxSWv7zUMxl3IwKN9Ap/AMphiepvmT5P+iNCgEiA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-6.2.0.tgz", + "integrity": "sha512-GzEOiE6yLfp9P6XNkOhXuYtZHzoAx3tirbi7/dj2WHlGM+NGE1lefceqGR0ZrYsYaqsNJhIJFTgwUpzVzA+mjw==", "dev": true, "dependencies": { - "@popperjs/core": "^2.11.8", + "@floating-ui/react": "^0.26.2", "classnames": "^2.2.6", - "date-fns": "^2.30.0", + "date-fns": "^3.3.1", "prop-types": "^15.7.2", - "react-onclickoutside": "^6.13.0", - "react-popper": "^2.3.0" + "react-onclickoutside": "^6.13.0" }, "peerDependencies": { "react": "^16.9.0 || ^17 || ^18", "react-dom": "^16.9.0 || ^17 || ^18" } }, + "node_modules/react-datepicker/node_modules/date-fns": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.3.1.tgz", + "integrity": "sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/react-docgen": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-6.0.4.tgz", @@ -28490,6 +28514,12 @@ "integrity": "sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==", "dev": true }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "dev": true + }, "node_modules/tailwind-merge": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.14.0.tgz", diff --git a/package.json b/package.json index ff818002bfb7b933d26dfc6c015d89d0ab98ded0..acaa9527800d3bf8b63ef601c20db61caa22172a 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "postcss": "^8.4.31", "primereact": "^10.5.1", "react": "^18.2.0", - "react-datepicker": "^4.21.0", + "react-datepicker": "6.2.0", "react-dom": "^18.2.0", "react-slider": "^2.0.6", "react-svg": "^16.1.29", diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index a743ecfbf5debb3a310ed8b56424811afd4d3d37..78f350520d3ad4c78df2fb3f787274971a7920b3 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -3,6 +3,7 @@ import { Dispatch, SetStateAction } from "react"; import { clsx } from "clsx"; import Icon from "./Icon.tsx"; import { formFieldBg, cursorPointer } from "./utils/classes.ts"; +import Typography from "./Typography.tsx"; type CheckboxProps = { isDisabled?: boolean; @@ -10,6 +11,8 @@ type CheckboxProps = { isSelected: boolean; setIsSelected?: Dispatch<SetStateAction<boolean>>; label?: string; + labelClass?: string; + labelCustomColor?: boolean; }; const Checkbox = ({ @@ -18,6 +21,8 @@ const Checkbox = ({ isSelected, setIsSelected, label, + labelClass = "", + labelCustomColor = false, }: CheckboxProps) => { return ( <NextCheckbox @@ -39,7 +44,14 @@ const Checkbox = ({ ), }} > - {label} + {label && ( + <Typography + text={label} + variant="paragraph" + customClass={labelClass} + customColor={labelCustomColor} + /> + )} </NextCheckbox> ); }; diff --git a/src/components/DateInput.tsx b/src/components/DateInput.tsx index 191ea9cb428be588d4729826ae4b3cf1a173516f..024a44d48e73be9bd81b0cc1738cf0fc8e70c03d 100644 --- a/src/components/DateInput.tsx +++ b/src/components/DateInput.tsx @@ -13,8 +13,11 @@ export type DateArray = [DateNull, DateNull]; type DateInputProps = { isRequired?: boolean; + isDisabled?: boolean; label: string; labelPlacement?: LabelPlacement; + labelClass?: string; + labelCustomColor?: boolean; isRange?: boolean; value?: DateNull; startDate?: DateNull; @@ -29,8 +32,11 @@ type DateInputProps = { const DateInput = ({ isRequired = false, + isDisabled = false, label, labelPlacement = "outside", + labelClass = "", + labelCustomColor = false, value, startDate, endDate, @@ -64,8 +70,11 @@ const DateInput = ({ <div onClick={onClick}> <BaseInput isRequired={isRequired} + isDisabled={isDisabled} label={label} labelPlacement={labelPlacement} + labelClass={labelClass} + labelCustomColor={labelCustomColor} endContent={ <Icon name="datepicker" @@ -113,9 +122,9 @@ const DateInput = ({ const datePickerBaseProps: object = { dateFormat: `${dateFormat}${showTimeSelect ? " " + timeFormat : ""}`, + wrapperClassName: "w-full", customInput: <CustomInput isRequired={isRequired} />, showPopperArrow: false, - popperClassName: "!transform-none !relative", calendarStartDay: 1, formatWeekDay: (day: string) => <div>{day.charAt(0)}</div>, weekDayClassName: () => @@ -144,14 +153,15 @@ const DateInput = ({ ), }; - const singleDatePickerProps: object = { openToDate: value || new Date(), selected: value, showTimeSelect: showTimeSelect, timeFormat: timeFormat, - dayClassName: () => "!text-foreground-body !bg-default aria-selected:!bg-lightBlue", - timeClassName: () => "!text-foreground-body !bg-default dark:!bg-mediumGrey aria-selected:!bg-lightBlue dark:aria-selected:!bg-lightBlue", + dayClassName: () => + "!text-foreground-body !bg-default aria-selected:!bg-lightBlue", + timeClassName: () => + "!text-foreground-body !bg-default dark:!bg-mediumGrey aria-selected:!bg-lightBlue dark:aria-selected:!bg-lightBlue", }; const rangeDatePickerProps: object = { @@ -174,6 +184,10 @@ const DateInput = ({ onSelect={(date) => onValueChange(date)} onChange={(date) => !!date && onValueChange(date)} {...datePickerProps} + popperPlacement={ + labelPlacement === "outside-left" ? "bottom-end" : "bottom-start" + } + disabled={isDisabled} /> ); }; diff --git a/src/components/Dropdown.tsx b/src/components/Dropdown.tsx index a0e4796e15bbb711b34b3a92f584e532071cf820..b1362f018c1ded99a50eb5c6a54ea18a918906e7 100644 --- a/src/components/Dropdown.tsx +++ b/src/components/Dropdown.tsx @@ -4,10 +4,15 @@ import { clsx } from "clsx"; import { baseInputClassNames } from "./utils/baseComponents.tsx"; import Icon from "./Icon.tsx"; import { textColor } from "./utils/classes.ts"; +import Typography from "./Typography.tsx"; type DropdownProps = { isRequired?: boolean; + isDisabled?: boolean; label?: string; + labelPlacement?: "outside" | "outside-left"; + labelClass?: string; + labelCustomColor?: boolean; valueOptions: { value: string; label: string }[]; value?: string; onValueChange: Dispatch<SetStateAction<string | undefined>>; @@ -15,7 +20,11 @@ type DropdownProps = { const Dropdown = ({ isRequired = false, + isDisabled = false, label, + labelPlacement = "outside", + labelClass = "", + labelCustomColor = false, valueOptions, value, onValueChange, @@ -27,7 +36,17 @@ const Dropdown = ({ return ( <Autocomplete isRequired={isRequired} - label={label} + isDisabled={isDisabled} + label={ + label && ( + <Typography + text={label} + variant="paragraph" + customClass={labelClass} + customColor={labelCustomColor} + /> + ) + } selectedKey={value} onSelectionChange={(key) => onValueChange(key as string)} labelPlacement="outside" @@ -35,7 +54,7 @@ const Dropdown = ({ disableAnimation disableSelectorIconRotation inputProps={{ - classNames: baseInputClassNames(false), + classNames: baseInputClassNames(isDisabled, labelPlacement), variant: "bordered", isRequired: isRequired, }} // use the same props as BaseInput diff --git a/src/components/Table.tsx b/src/components/Table.tsx index fb098b49ec660a912472bd325a3190b1c3560f31..b5cff8fa581977f26c14138abaf3a8c17442fbc1 100644 --- a/src/components/Table.tsx +++ b/src/components/Table.tsx @@ -1,6 +1,7 @@ import { Dispatch, ReactNode, SetStateAction } from "react"; import { DataTable, type DataTableValueArray } from "primereact/datatable"; import { Column } from "primereact/column"; +import { clsx } from "clsx"; import { textColor } from "./utils/classes.ts"; import Typography from "./Typography.tsx"; @@ -39,7 +40,9 @@ const Table = ({ reorderableRows={isReorderable} onRowReorder={(e) => onReorder && onReorder(e.value)} className="rounded-[8px] bg-lightGrey/30 dark:bg-baseBlack/40 p-[20px] pb-[10px]" - rowClassName={() => "border-t border-grey/50 text-[13px] font-body"} + rowClassName={() => + clsx("border-t border-grey/50 text-[13px] font-body", textColor("body")) + } cellClassName={() => "h-12 pl-[5px]"} > {isSelectable && ( diff --git a/src/components/TextArea.tsx b/src/components/TextArea.tsx index 41708b6522fc598a0ae6c75fecc52c153796f848..e5169ecf672895fd9c7204b781b766f94c631473 100644 --- a/src/components/TextArea.tsx +++ b/src/components/TextArea.tsx @@ -3,12 +3,15 @@ import { Textarea } from "@nextui-org/react"; import { TextInputProps } from "./TextInput"; import { formFieldBg, cursorPointer } from "./utils/classes.ts"; import { LabelPlacement } from "./utils/baseComponents.tsx"; +import Typography from "./Typography.tsx"; interface TextAreaProps extends Omit<TextInputProps, OmittedTextInputProps> { minRows?: number; maxRows?: number; disableAutosize?: boolean; labelPlacement?: LabelPlacement; + labelClass?: string; + labelCustomColor?: boolean; } type OmittedTextInputProps = "isClearable" | "type" | "inputMode"; @@ -35,24 +38,23 @@ const classNames = ( return { base: clsx( - labelPlacement === "outside-left" - ? "flex flex-row justify-between items-start" - : "", + { + "flex flex-row justify-between items-start": + labelPlacement === "outside-left", + }, cursorPointer(isDisabled) ), - label: clsx( - "!text-foreground-body ml-[1px]", - labelPlacement === "outside-left" ? "w-1/3" : "" - ), + label: clsx("!text-foreground-body ml-[1px]", { + "w-1/3": labelPlacement === "outside-left", + }), inputWrapper: clsx( inputWrapperClass(isDisabled), "px-2 rounded-[4px]", formFieldBg(isDisabled) ), - input: clsx( - "!text-foreground-body bg-default", - disableAutosize ? "resize-y" : "" - ), + input: clsx("!text-foreground-body bg-default", { + "resize-y": disableAutosize, + }), }; }; @@ -70,13 +72,24 @@ const TextArea = ({ errorMessage, disableAutosize = false, labelPlacement = "outside", + labelClass = "", + labelCustomColor = false, }: TextAreaProps) => { return ( <Textarea isRequired={isRequired} isDisabled={isDisabled} isReadOnly={isReadOnly} - label={label} + label={ + label && ( + <Typography + text={label} + variant="paragraph" + customClass={labelClass} + customColor={labelCustomColor} + /> + ) + } minRows={minRows} maxRows={maxRows} maxLength={maxLength} diff --git a/src/components/TextInput.tsx b/src/components/TextInput.tsx index 0db64624ce36b81636116bc66016e6dabbe2f654..43c3891c68a323d89a7e33267f1ae354e52b38ee 100644 --- a/src/components/TextInput.tsx +++ b/src/components/TextInput.tsx @@ -5,6 +5,8 @@ type TextInputProps = { isRequired?: boolean; label?: string; labelPlacement?: LabelPlacement; + labelClass?: string; + labelCustomColor?: boolean; endContent?: ReactNode; // such as units (as text element e.g. <span>) isClearable?: boolean; value: string; @@ -37,6 +39,8 @@ const TextInput = ({ isRequired = false, label = "", labelPlacement = "outside", + labelClass = "", + labelCustomColor = false, endContent, isClearable = false, value, @@ -54,6 +58,8 @@ const TextInput = ({ isRequired={isRequired} label={label} labelPlacement={labelPlacement} + labelClass={labelClass} + labelCustomColor={labelCustomColor} endContent={endContent} placeholder=" " isClearable={isClearable} diff --git a/src/components/Toggle.tsx b/src/components/Toggle.tsx index 2890d3e45c9bb6430e249b97623e684011b528b8..20e6cf520b3071bb284a9e43ddd23a4ed2b6423d 100644 --- a/src/components/Toggle.tsx +++ b/src/components/Toggle.tsx @@ -2,6 +2,7 @@ import { Dispatch, SetStateAction } from "react"; import { Switch } from "@nextui-org/react"; import { clsx } from "clsx"; import { cursorPointer } from "./utils/classes.ts"; +import Typography from "./Typography.tsx"; type ToggleProps = { isDisabled?: boolean; @@ -9,6 +10,8 @@ type ToggleProps = { setIsSelected?: Dispatch<SetStateAction<boolean>>; label?: string; labelPlacement?: "right" | "left"; + labelClass?: string; + labelCustomColor?: boolean; width?: "fit" | "full"; }; @@ -18,6 +21,8 @@ const Toggle = ({ setIsSelected, label, labelPlacement = "right", + labelClass = "", + labelCustomColor = false, width = "fit", }: ToggleProps) => { const selectedClass = (isSelected: boolean) => @@ -29,7 +34,14 @@ const Toggle = ({ width === "fit" ? "w-fit" : "w-full" )} > - {labelPlacement === "left" && <div className="mr-2">{label}</div>} + {labelPlacement === "left" && label && ( + <Typography + variant="paragraph" + customClass={clsx("mr-2", labelClass)} + text={label} + customColor={labelCustomColor} + /> + )} <Switch isDisabled={isDisabled} // Does not support "isRequired": https://github.com/nextui-org/nextui/issues/1610 @@ -43,7 +55,14 @@ const Toggle = ({ "h-[8px] w-[25px] p-0 overflow-visible bg-lightGrey dark:bg-mediumGrey", }} /> - {labelPlacement === "right" && label} + {labelPlacement === "right" && label && ( + <Typography + variant="paragraph" + text={label} + customClass={labelClass} + customColor={labelCustomColor} + /> + )} </div> ); }; diff --git a/src/components/Typography.tsx b/src/components/Typography.tsx index 53835edcf34565bc51fd771447d1ca59bcd3a17d..ffc157f203e1f4dc1b823bf88e7be9893045cccf 100644 --- a/src/components/Typography.tsx +++ b/src/components/Typography.tsx @@ -32,6 +32,7 @@ const Typography = ({ customColor = false, customClass = "", }: TypographyProps) => { + // font-body is Inter, font-heading is Montserrat const font = { overtitle: "text-[16px] font-heading font-bold", title: "text-[70px] font-heading font-bold", diff --git a/src/components/utils/baseComponents.tsx b/src/components/utils/baseComponents.tsx index 39764bbbabf609e7304d660b822edb60348d32c4..463c61dbbcbdb8fec6597d24c93721fd9a0ce09e 100644 --- a/src/components/utils/baseComponents.tsx +++ b/src/components/utils/baseComponents.tsx @@ -2,6 +2,7 @@ import { Input } from "@nextui-org/react"; import { Dispatch, ReactNode, SetStateAction } from "react"; import { InputSlots } from "@nextui-org/theme"; import { clsx } from "clsx"; +import Typography from "src/components/Typography.tsx"; import { formFieldBg, cursorPointer } from "./classes.ts"; export type LabelPlacement = "outside" | "outside-left"; @@ -10,6 +11,8 @@ type BaseInputProps = { // basic info label: string; labelPlacement: LabelPlacement; + labelClass: string; + labelCustomColor: boolean; endContent: ReactNode; // such as units or icon // value and validation placeholder: string; @@ -45,7 +48,8 @@ type BaseInputProps = { type baseInputClassNamesObj = { [key in InputSlots]: string }; export const baseInputClassNames = ( - isDisabled: boolean + isDisabled: boolean, + labelPlacement: LabelPlacement ): baseInputClassNamesObj => { // this is the border color (use text-*) const mainWrapperClass = (isDisabled: boolean) => @@ -54,24 +58,29 @@ export const baseInputClassNames = ( : "text-grey dark:text-mediumGrey hover:text-baseBlack focus-within:!text-primary"; const clearButtonClass = (isDisabled: boolean) => { + if (isDisabled) return ""; + // we cannot do "[&>svg]:" + className because Tailwind does not support dynamic class names const clearButtonSvgClass: string = "[&>svg]:w-[30px] [&>svg]:h-[30px] [&>svg]:mt-[-4px] [&>svg]:ml-[-4px]"; const clearButtonBaseClass: string = "bg-mediumGrey text-baseWhite dark:bg-baseWhite dark:text-mediumGrey w-[22px] h-[22px] p-0 !opacity-100"; - - return isDisabled ? "" : clsx(clearButtonSvgClass, clearButtonBaseClass); + return clsx(clearButtonSvgClass, clearButtonBaseClass); }; return { base: clsx("flex flex-row justify-between", cursorPointer(isDisabled)), - label: "!text-foreground-body", input: "!text-foreground-body bg-default", inputWrapper: clsx( "px-2 rounded-[4px] min-h-[33px] max-h-[33px]", formFieldBg(isDisabled) ), - mainWrapper: clsx("w-2/3", mainWrapperClass(isDisabled)), + mainWrapper: clsx( + { + "w-2/3": labelPlacement === "outside-left", + }, + mainWrapperClass(isDisabled) + ), clearButton: clearButtonClass(isDisabled), } as baseInputClassNamesObj; }; @@ -79,6 +88,8 @@ export const baseInputClassNames = ( export const BaseInput = ({ label, labelPlacement = "outside", + labelClass, + labelCustomColor, endContent, placeholder, isClearable = false, @@ -95,7 +106,14 @@ export const BaseInput = ({ }: BaseInputProps) => { return ( <Input - label={label} + label={ + <Typography + text={label} + variant="paragraph" + customClass={labelClass} + customColor={labelCustomColor} + /> + } endContent={endContent} placeholder={placeholder} value={value} @@ -112,7 +130,7 @@ export const BaseInput = ({ // appearance labelPlacement={labelPlacement} variant="bordered" - classNames={baseInputClassNames(isDisabled)} + classNames={baseInputClassNames(isDisabled, labelPlacement)} /> ); }; diff --git a/src/stories/DateInput.stories.tsx b/src/stories/DateInput.stories.tsx index 50e7d9d14a166478a73a1d0fad116920822185f7..7e629a88a519029d92983d968c4c1869220ef301 100644 --- a/src/stories/DateInput.stories.tsx +++ b/src/stories/DateInput.stories.tsx @@ -70,3 +70,28 @@ export const DateRange = () => { /> ); }; + +/** The label occupies one-third of the width of the parent, and the form field two-thirds of it. */ +export const LabelOnTheLeft = () => { + const [date, setDate] = useState<Date>(); + return ( + <div className="max-w-lg p-3 bg-lightGrey/30 dark:bg-baseBlack/40 rounded-[8px]"> + <DateInput + label="When's the party?" + labelPlacement="outside-left" + value={date} + onValueChange={(value) => setDate(value as Date)} + /> + </div> + ); +}; + +export const Disabled = () => { + return ( + <DateInput + label="Can't touch this" + onValueChange={() => {}} + isDisabled={true} + /> + ); +}; diff --git a/src/stories/Dropdown.stories.tsx b/src/stories/Dropdown.stories.tsx index d6d6fc344fb7bb6136a2db99bc72a938cb663b2a..f48b848206d9c9e939f15fcdb894e661e992800a 100644 --- a/src/stories/Dropdown.stories.tsx +++ b/src/stories/Dropdown.stories.tsx @@ -35,3 +35,14 @@ export const SimpleDropdown = () => { </> ); }; + +export const Disabled = () => { + return ( + <Dropdown + label="You can't choose your favourite ice cream." + valueOptions={[]} + onValueChange={() => {}} + isDisabled={true} + /> + ); +};