diff --git a/README.md b/README.md index 98c84a3..5e50f95 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ onRemove(selectedList, removedItem) { | `showArrow` | `bool` | `false` | For multiselect dropdown by default arrow wont show at the end, If required based on flag we can display | `keepSearchTerm` | `bool` | `false` | Whether or not to keep the search value after selecting or removing an item | `customCloseIcon` | `ReactNode or string` | `undefined` | Custom close icon and can be string or react component(Check demo for reference) +| `required` | `boolean` | `false` | Marks the input field as required to prevent form submission with missing values. **Form validation is required to ensure the field is populated before submitting.** ---- diff --git a/src/multiselect/interface.ts b/src/multiselect/interface.ts index 632a43c..d899da3 100644 --- a/src/multiselect/interface.ts +++ b/src/multiselect/interface.ts @@ -24,5 +24,6 @@ export interface IMultiselectProps { hidePlaceholder?: boolean, showArrow?: boolean, keepSearchTerm?: boolean, - customCloseIcon?: React.ReactNode | string + customCloseIcon?: React.ReactNode | string, + required?: boolean } diff --git a/src/multiselect/multiselect.component.tsx b/src/multiselect/multiselect.component.tsx index 3755a8f..2e39571 100644 --- a/src/multiselect/multiselect.component.tsx +++ b/src/multiselect/multiselect.component.tsx @@ -16,7 +16,7 @@ const closeIconTypes = { }; export class Multiselect extends React.Component { - static defaultProps: { options: never[]; disablePreSelectedValues: boolean; selectedValues: never[]; isObject: boolean; displayValue: string; showCheckbox: boolean; selectionLimit: number; placeholder: string; groupBy: string; style: {}; emptyRecordMsg: string; onSelect: () => void; onRemove: () => void; closeIcon: string; singleSelect: boolean; caseSensitiveSearch: boolean; id: string; closeOnSelect: boolean; avoidHighlightFirstOption: boolean; hidePlaceholder: boolean; showArrow: boolean; keepSearchTerm: boolean; }; + static defaultProps: { options: never[]; disablePreSelectedValues: boolean; selectedValues: never[]; isObject: boolean; displayValue: string; showCheckbox: boolean; selectionLimit: number; placeholder: string; groupBy: string; style: {}; emptyRecordMsg: string; onSelect: () => void; onRemove: () => void; closeIcon: string; singleSelect: boolean; caseSensitiveSearch: boolean; id: string; closeOnSelect: boolean; avoidHighlightFirstOption: boolean; hidePlaceholder: boolean; showArrow: boolean; keepSearchTerm: boolean; required: boolean; }; constructor(props) { super(props); this.state = { @@ -505,9 +505,10 @@ export class Multiselect extends React.Component { renderMultiselectContainer() { const { inputValue, toggleOptionsList, selectedValues } = this.state; - const { placeholder, style, singleSelect, id, hidePlaceholder, disable, showArrow} = this.props; + const { placeholder, style, singleSelect, id, hidePlaceholder, disable, showArrow, required} = this.props; + const hasRequiredError = required && selectedValues.length === 0; return ( -
+
{}} @@ -572,5 +573,6 @@ Multiselect.defaultProps = { hidePlaceholder: false, showArrow: false, keepSearchTerm: false, - customCloseIcon: '' + customCloseIcon: '', + required: false }; diff --git a/src/multiselect/styles.css b/src/multiselect/styles.css index 94eb459..cd3c92b 100644 --- a/src/multiselect/styles.css +++ b/src/multiselect/styles.css @@ -18,6 +18,14 @@ min-height: 22px; position: relative; } +.hasRequiredError .searchWrapper { + border-color: red; +} +.hasRequiredError::after { + color: red; + content: "Please select a value"; + font-style: italic; +} .multiSelectContainer input { border: none; margin-top: 3px; diff --git a/stories/basic.stories.tsx b/stories/basic.stories.tsx index 08e9312..d302720 100644 --- a/stories/basic.stories.tsx +++ b/stories/basic.stories.tsx @@ -27,6 +27,16 @@ export default { } as Meta; const Template: Story = (args) => ; +const SubmitTemplate: Story = args => { + return ( + <> +
+ + {}} /> + + + ) +} export const FlatArray = Template.bind({}); FlatArray.args = { @@ -106,4 +116,12 @@ CustomCloseIcon.args = { displayValue: 'key', customCloseIcon: <>🍑, selectedValues -}; \ No newline at end of file +}; + +export const RequiredField = SubmitTemplate.bind({}); +RequiredField.args = { + options, + displayValue: 'key', + selectedValues, + required: true, +};