Skip to content

Commit

Permalink
feat: allow the NDSOption type to be extended
Browse files Browse the repository at this point in the history
  • Loading branch information
haideralsh committed Dec 30, 2024
1 parent 502ecc0 commit 3ec894a
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 23 deletions.
18 changes: 17 additions & 1 deletion src/Select/Select.story.fixture.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import { GroupBase } from "react-select";
import styled from "styled-components";
import { SelectOption, SelectOptionProps } from "./SelectOption";
import { NDSOption } from "./Select";
Expand Down Expand Up @@ -65,7 +66,7 @@ const Indicator = styled.span(() => ({
marginRight: "5px",
}));

export const CustomOption = ({ children, ...props }: SelectOptionProps) => {
export const CustomOption = ({ children, ...props }: SelectOptionProps<NDSOption, true, GroupBase<NDSOption>>) => {
const newChildren = (
<>
<Indicator />
Expand All @@ -74,3 +75,18 @@ export const CustomOption = ({ children, ...props }: SelectOptionProps) => {
);
return <SelectOption {...props}>{newChildren}</SelectOption>;
};

export interface DescriptiveOption extends NDSOption {
description: string;
}

export const CustomFieldsOption = ({
...props
}: SelectOptionProps<DescriptiveOption, true, GroupBase<DescriptiveOption>>) => {
return (
<SelectOption {...props}>
<span>{props.data.label}</span>
<span>{props.data.description}</span>
</SelectOption>
);
};
21 changes: 20 additions & 1 deletion src/Select/Select.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
wrappingOptions,
PCNList,
errorList,
CustomFieldsOption,
} from "./Select.story.fixture";

const SelectWithManyOptions = ({ multiselect, labelText, ...props }: Partial<NDSSelectProps>) => {
Expand Down Expand Up @@ -336,7 +337,7 @@ WithSmallerMaxHeight.story = {
export const WithWrappingText = () => (
<Select
initialIsOpen
value={options[0].value}
value={wrappingOptions[0].value}
placeholder="Please select inventory status"
options={wrappingOptions}
labelText="Inventory status"
Expand Down Expand Up @@ -538,3 +539,21 @@ export const WithCustomStyles = () => {
/>
);
};

export const WithCustomOptionFields = () => {
const descriptiveOptions = [
{ value: "accepted", label: "Accepted", description: "This item has been accepted" },
{ value: "assigned", label: "Assigned to a line", description: "This item is assigned to a production line" },
];

return (
<Select
defaultValue={descriptiveOptions[0].value}
options={descriptiveOptions}
components={{
Option: CustomFieldsOption,
}}
labelText="Inventory status"
/>
);
};
52 changes: 32 additions & 20 deletions src/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,37 +31,43 @@ export interface NDSOption {
value: NDSOptionValue;
}

interface CustomProps<IsMulti extends boolean, Group extends GroupBase<NDSOption>> extends StyledProps {
autocomplete?: Props<NDSOption, IsMulti, Group>["isSearchable"];
interface CustomProps<Option extends NDSOption, IsMulti extends boolean, Group extends GroupBase<Option>>
extends StyledProps {
autocomplete?: Props<Option, IsMulti, Group>["isSearchable"];
labelText?: string;
size?: ComponentVariant;
requirementText?: string;
helpText?: ReactNode;
disabled?: Props<NDSOption, IsMulti, Group>["isDisabled"];
disabled?: Props<Option, IsMulti, Group>["isDisabled"];
errorMessage?: string;
errorList?: string[];
initialIsOpen?: Props<NDSOption, IsMulti, Group>["defaultMenuIsOpen"];
multiselect?: Props<NDSOption, IsMulti, Group>["isMulti"];
initialIsOpen?: Props<Option, IsMulti, Group>["defaultMenuIsOpen"];
multiselect?: Props<Option, IsMulti, Group>["isMulti"];
maxHeight?: string;
defaultValue?: PropsValue<NDSOptionValue>;
value?: PropsValue<NDSOptionValue>;
options: NDSOption[];
onChange?: (newValue: PropsValue<NDSOptionValue>) => void;
defaultValue?: PropsValue<Option["value"]>;
value?: PropsValue<Option["value"]>;
options: readonly Option[];
onChange?: (newValue: PropsValue<Option["value"]>) => void;
windowThreshold?: number;
styles?: (selectStyles: StylesConfig<NDSOption, IsMulti, Group>) => StylesConfig<NDSOption, IsMulti, Group>;
styles?: (selectStyles: StylesConfig<Option, IsMulti, Group>) => StylesConfig<Option, IsMulti, Group>;
}

export type NDSSelectProps<
Option extends NDSOption = NDSOption,
IsMulti extends boolean = boolean,
Group extends GroupBase<NDSOption> = GroupBase<NDSOption>,
Group extends GroupBase<Option> = GroupBase<Option>,
> = Omit<
Props<NDSOption, IsMulti, Group>,
keyof CustomProps<IsMulti, Group> | "isSearchable" | "isDisabled" | "defaultMenuIsOpen" | "isMulti" | "styles"
Props<Option, IsMulti, Group>,
keyof CustomProps<Option, IsMulti, Group> | "isSearchable" | "isDisabled" | "defaultMenuIsOpen" | "isMulti" | "styles"
> &
CustomProps<IsMulti, Group>;
CustomProps<Option, IsMulti, Group>;

const NDSSelect = forwardRef(
<IsMulti extends boolean = boolean, Group extends GroupBase<NDSOption> = GroupBase<NDSOption>>(
<
Option extends NDSOption = NDSOption,
IsMulti extends boolean = boolean,
Group extends GroupBase<Option> = GroupBase<Option>,
>(
{
autocomplete,
value,
Expand All @@ -85,10 +91,10 @@ const NDSSelect = forwardRef(
options,
styles,
...props
}: NDSSelectProps<IsMulti, Group>,
}: NDSSelectProps<Option, IsMulti, Group>,
ref:
| ((instance: Select<NDSOption, IsMulti, Group> | null) => void)
| MutableRefObject<Select<NDSOption, IsMulti, Group> | null>
| ((instance: Select<Option, IsMulti, Group> | null) => void)
| MutableRefObject<Select<Option, IsMulti, Group> | null>
| null
) => {
const { t } = useTranslation();
Expand All @@ -105,7 +111,7 @@ const NDSSelect = forwardRef(
optionsRef.current = options;
}, [options]);

const stylesConfig = customStyles<NDSOption, IsMulti, Group>({
const stylesConfig = customStyles<Option, IsMulti, Group>({
theme: theme,
error,
maxHeight,
Expand Down Expand Up @@ -160,6 +166,12 @@ const NDSSelect = forwardRef(
</Field>
);
}
);
) as <
Option extends NDSOption = NDSOption,
IsMulti extends boolean = false,
Group extends GroupBase<Option> = GroupBase<Option>,
>(
props: NDSSelectProps<Option, IsMulti, Group> & React.RefAttributes<Select<Option, IsMulti, Group>>
) => React.ReactElement;

export default NDSSelect;
2 changes: 1 addition & 1 deletion src/Select/lib.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from "react";
import { Options, PropsValue } from "react-select";
import { NDSOption, NDSOptionValue } from "./Select";
import * as React from "react";

export function calcOptionsLength(options) {
options = options || [];
Expand Down

0 comments on commit 3ec894a

Please sign in to comment.