diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index 610b8a40facfae88eb7bd12c344d47a0928db5ad..4128933494bb8968736f6738c0eb397e5ba515b8 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -5,6 +5,7 @@ import { disabledBg, disabledCursor } from "./utils/classes.ts"; type CheckboxProps = { isDisabled?: boolean; + isRequired?: boolean; isSelected: boolean; setIsSelected?: Dispatch<SetStateAction<boolean>>; label?: string; @@ -12,12 +13,14 @@ type CheckboxProps = { const Checkbox = ({ isDisabled = false, + isRequired = false, isSelected, setIsSelected, label, }: CheckboxProps) => { return ( <NextCheckbox + isRequired={isRequired} isDisabled={isDisabled} isSelected={isSelected} onValueChange={setIsSelected} diff --git a/src/components/DateInput.tsx b/src/components/DateInput.tsx index aef10f6c84a0e4dbd0a9c9933a56d7900aa8a0ab..67764dc660f9c092e212d0319b0b6a77c7a93e0b 100644 --- a/src/components/DateInput.tsx +++ b/src/components/DateInput.tsx @@ -8,6 +8,7 @@ import Typography from "./Typography.tsx"; import { textColor } from "./utils/colors.ts"; type DateInputProps = { + isRequired?: boolean; label: string; value?: Date; onValueChange: Dispatch<SetStateAction<Date | undefined>>; @@ -16,6 +17,7 @@ type DateInputProps = { }; const DateInput = ({ + isRequired = false, label, value, onValueChange, @@ -25,13 +27,14 @@ const DateInput = ({ const dateFormat = "dd/MM/yyyy"; type inputProps = { + isRequired: boolean; value?: string; onClick?: () => void; }; const CustomInput = forwardRef( ( - { value, onClick }: inputProps, + { isRequired, value, onClick }: inputProps, // @ts-expect-error the "ref" prop is needed to avoid console errors. // eslint-disable-next-line @typescript-eslint/no-unused-vars ref @@ -39,6 +42,7 @@ const DateInput = ({ return ( <div onClick={onClick}> <BaseInput + isRequired={isRequired} label={label} endContent={ <Icon @@ -91,7 +95,7 @@ const DateInput = ({ selected={value} onSelect={(date) => onValueChange(date)} onChange={(date) => !!date && onValueChange(date)} - customInput={<CustomInput />} + customInput={<CustomInput isRequired={isRequired} />} showPopperArrow={false} calendarStartDay={1} formatWeekDay={(day) => <div>{day.charAt(0)}</div>} diff --git a/src/components/Dropdown.tsx b/src/components/Dropdown.tsx index 253133f224f290da0ecba73cdbf8fb7442ba116d..9ccd75c211738b20abd29c9ba01b38c3def1f891 100644 --- a/src/components/Dropdown.tsx +++ b/src/components/Dropdown.tsx @@ -4,6 +4,7 @@ import { baseInputClassNames } from "./utils/baseComponents.tsx"; import Icon from "./Icon.tsx"; type DropdownProps = { + isRequired?: boolean; label?: string; valueOptions: { value: string; label: string }[]; value?: string; @@ -11,6 +12,7 @@ type DropdownProps = { }; const Dropdown = ({ + isRequired = false, label, valueOptions, value, @@ -18,6 +20,7 @@ const Dropdown = ({ }: DropdownProps) => { return ( <Autocomplete + isRequired={isRequired} label={label} selectedKey={value} onSelectionChange={(key) => onValueChange(key as string)} @@ -28,6 +31,7 @@ const Dropdown = ({ inputProps={{ classNames: baseInputClassNames(false), variant: "bordered", + isRequired: isRequired, }} // use the same props as BaseInput selectorIcon={<Icon name="dropdown" />} isClearable={false} // so the "cross" button does not show diff --git a/src/components/Radio.tsx b/src/components/Radio.tsx index d3a1f870ea10890e8acd1860aa5671c00a1e4fce..ad9faedf63d9e2845bd4f86455188ded274b3413 100644 --- a/src/components/Radio.tsx +++ b/src/components/Radio.tsx @@ -3,15 +3,27 @@ import { Dispatch, SetStateAction } from "react"; import { disabledBg, disabledCursor } from "./utils/classes.ts"; type RadioProps = { + isRequired?: boolean; label?: string; valueOptions: { value: string; label: string; isDisabled?: boolean }[]; value?: string; onValueChange?: Dispatch<SetStateAction<string | undefined>>; }; -const Radio = ({ label, valueOptions, value, onValueChange }: RadioProps) => { +const Radio = ({ + isRequired = false, + label, + valueOptions, + value, + onValueChange, +}: RadioProps) => { return ( - <RadioGroup label={label} value={value} onValueChange={onValueChange}> + <RadioGroup + isRequired={isRequired} + label={label} + value={value} + onValueChange={onValueChange} + > {valueOptions.map((option) => ( <NextRadio isDisabled={option.isDisabled || false} diff --git a/src/components/TextInput.tsx b/src/components/TextInput.tsx index 31d27e15bca737533513954da52528912907a5d6..10c7b1274e0e273c24be9a4ceaaa36bde23e5082 100644 --- a/src/components/TextInput.tsx +++ b/src/components/TextInput.tsx @@ -2,6 +2,7 @@ import { Dispatch, ReactNode, SetStateAction } from "react"; import { BaseInput } from "./utils/baseComponents.tsx"; type TextInputProps = { + isRequired?: boolean; label?: string; endContent?: ReactNode; // such as units (as text element e.g. <span>) isClearable?: boolean; @@ -13,6 +14,7 @@ type TextInputProps = { }; const TextInput = ({ + isRequired = false, label = "", endContent, isClearable = false, @@ -24,6 +26,7 @@ const TextInput = ({ }: TextInputProps) => { return ( <BaseInput + isRequired={isRequired} label={label} endContent={endContent} placeholder=" " diff --git a/src/components/Toggle.tsx b/src/components/Toggle.tsx index d8dce9f4ec42f2ea8c2b4934f2f060a77ffaf607..5666fc4ad614ec2af1484af25c26600220e053a0 100644 --- a/src/components/Toggle.tsx +++ b/src/components/Toggle.tsx @@ -13,6 +13,7 @@ const Toggle = ({ isSelected, setIsSelected, label }: ToggleProps) => { : "ml-[11px] bg-grey"; return ( <Switch + // Does not support "isRequired": https://github.com/nextui-org/nextui/issues/1610 isSelected={isSelected} onValueChange={setIsSelected} color="default" diff --git a/src/components/utils/baseComponents.tsx b/src/components/utils/baseComponents.tsx index 2a8e1caa9a0a6aa53f02d3e9902b72872cb82626..0baa9f1235109b57ad573fc07b57afae61b5a21b 100644 --- a/src/components/utils/baseComponents.tsx +++ b/src/components/utils/baseComponents.tsx @@ -15,7 +15,8 @@ type BaseInputProps = { isInvalid: boolean; errorMessage: string; // interaction - isDisabled: boolean; + isRequired?: boolean; + isDisabled?: boolean; }; type baseInputClassNamesObj = { [key in InputSlots]: string }; @@ -59,7 +60,8 @@ export const BaseInput = ({ onValueChange, isInvalid, errorMessage, - isDisabled, + isRequired = false, + isDisabled = false, }: BaseInputProps) => { return ( <Input @@ -72,6 +74,7 @@ export const BaseInput = ({ onValueChange={onValueChange} isInvalid={isInvalid} errorMessage={errorMessage} + isRequired={isRequired} isDisabled={isDisabled} // appearance labelPlacement="outside"