From e8f220448ee1cb7730caff1458230b4a4585090f Mon Sep 17 00:00:00 2001 From: Haider Alshamma Date: Wed, 15 May 2024 15:56:47 -0400 Subject: [PATCH] feat: remove react-windowed-select --- package.json | 7 +- src/AsyncSelect/AsyncSelect.tsx | 1 - src/AsyncSelect/AsyncSelectComponents.tsx | 2 +- src/Select/Select.story.tsx | 156 ++++++++++------------ src/Select/Select.tsx | 128 ++++++++---------- src/Select/SelectComponents.tsx | 47 ++++--- src/Select/SelectOption.tsx | 5 +- src/Select/lib.ts | 52 ++++++++ yarn.lock | 20 +-- 9 files changed, 221 insertions(+), 197 deletions(-) create mode 100644 src/Select/lib.ts diff --git a/package.json b/package.json index 3da3f04cf..31b09f4f5 100644 --- a/package.json +++ b/package.json @@ -142,6 +142,7 @@ "@nulogy/tokens": "^5.4.0", "@styled-system/prop-types": "^5.1.4", "@styled-system/theme-get": "^5.1.2", + "@types/styled-system": "5.1.22", "body-scroll-lock": "^3.1.5", "core-js": "3", "create-react-context": "^0.3.0", @@ -160,11 +161,9 @@ "react-popper": "1.3.11", "react-popper-2": "npm:react-popper@2.2.4", "react-resize-detector": "^9.1.0", - "react-windowed-select": "^5.2.0", - "smoothscroll-polyfill": "^0.4.4", "react-select": "^5.8.0", - "styled-system": "^5.1.4", - "@types/styled-system": "5.1.22" + "smoothscroll-polyfill": "^0.4.4", + "styled-system": "^5.1.4" }, "husky": { "hooks": { diff --git a/src/AsyncSelect/AsyncSelect.tsx b/src/AsyncSelect/AsyncSelect.tsx index 34ffe9697..4b17faca8 100644 --- a/src/AsyncSelect/AsyncSelect.tsx +++ b/src/AsyncSelect/AsyncSelect.tsx @@ -128,7 +128,6 @@ const AsyncSelect = forwardRef( onMenuClose={onMenuClose} menuPosition={menuPosition} onInputChange={onInputChange} - theme={theme as any} components={{ Option: (props) => ( diff --git a/src/AsyncSelect/AsyncSelectComponents.tsx b/src/AsyncSelect/AsyncSelectComponents.tsx index 4c8725b6c..8f13e47e6 100644 --- a/src/AsyncSelect/AsyncSelectComponents.tsx +++ b/src/AsyncSelect/AsyncSelectComponents.tsx @@ -10,7 +10,7 @@ import { MultiValueProps, } from "react-select"; import { components, GroupBase } from "react-select"; -import { OptionProps } from "react-windowed-select"; +import { OptionProps } from "react-select"; import { ComponentSize, useComponentSize } from "../NDSProvider/ComponentSizeContext"; import { StyledOption } from "../Select/SelectOption"; diff --git a/src/Select/Select.story.tsx b/src/Select/Select.story.tsx index 802904603..4920cbc5a 100644 --- a/src/Select/Select.story.tsx +++ b/src/Select/Select.story.tsx @@ -1,16 +1,17 @@ -import React, { useEffect, useState, useRef } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { action } from "@storybook/addon-actions"; import styled from "styled-components"; -import { text, boolean, select } from "@storybook/addon-knobs"; -import { GroupBase, OptionProps } from "react-windowed-select"; -import { Button, Heading2, Select, SelectOption } from "../index"; +import { boolean, select, text } from "@storybook/addon-knobs"; +import { PropsValue } from "react-select"; import { Box } from "../Box"; import { Flex } from "../Flex"; -import { NDSSelectProps } from "./Select"; +import { Button, Heading2, SelectOption } from "../index"; +import Select, { NDSOption, NDSOptionValue, NDSSelectProps } from "./Select"; +import { SelectOptionProps } from "./SelectOption"; const errorList = ["Error message 1", "Error message 2"]; -const options = [ +const options: NDSOption[] = [ { value: "accepted", label: "Accepted" }, { value: "assigned", label: "Assigned to a line" }, { value: "hold", label: "On hold" }, @@ -54,17 +55,13 @@ const getPhotos = async () => { // returns 5000 items const data = await fetch("https://jsonplaceholder.typicode.com/photos"); const json = await data.json(); - const results = json.map(({ title, id }) => ({ + return json.map(({ title, id }) => ({ label: title, value: id, })); - return results; }; -const SelectWithManyOptions = >({ - multiselect, - labelText, -}: Pick, "multiselect" | "labelText">) => { +const SelectWithManyOptions = ({ multiselect, labelText, ...props }: Partial) => { const [photoList, setPhotoList] = useState([]); const setOptions = async () => { @@ -76,35 +73,46 @@ const SelectWithManyOptions = ; + return - - - ); + clearSelection() { + this.setState({ selectedValue: "" }); + } + + render() { + const { selectedValue } = this.state; + return ( + + { /> { Multi-select "No options"} placeholder="Please select inventory status" @@ -202,7 +209,7 @@ export const WithDifferentSizes = () => { /> - - ); -}; diff --git a/src/Select/Select.tsx b/src/Select/Select.tsx index dd3122103..c19059eef 100644 --- a/src/Select/Select.tsx +++ b/src/Select/Select.tsx @@ -1,7 +1,7 @@ import React, { forwardRef, ReactNode, MutableRefObject } from "react"; import Select from "react-select/base"; -import WindowedSelect from "react-windowed-select"; -import type { Props as SelectProps } from "react-select"; +import ReactSelect, { PropsValue } from "react-select"; +import type { GroupBase, Props } from "react-select"; import { useTranslation } from "react-i18next"; import { useTheme } from "styled-components"; import propTypes from "@styled-system/prop-types"; @@ -12,49 +12,55 @@ import customStyles from "../Select/customReactSelectStyles"; import { getSubset } from "../utils/subset"; import { ComponentSize, useComponentSize } from "../NDSProvider/ComponentSizeContext"; import { + SelectControl, SelectMultiValue, SelectClearIndicator, SelectContainer, SelectInput, SelectDropdownIndicator, SelectMenu, - SelectControl, -} from "./SelectComponents"; -import { SelectOption } from "./SelectOption"; -import { checkOptionsAreValid, getReactSelectValue } from "./lib"; + SelectOption, +} from "../AsyncSelect/AsyncSelectComponents"; +import { checkOptionsAreValid, extractValue, getReactSelectValue } from "./lib"; + +export type NDSOptionValue = string | number | boolean | null; -interface WindowedSelectProps extends SelectProps { - windowThreshold: number; +export interface NDSOption { + label: string; + value: NDSOptionValue; } -type CustomProps = { - autocomplete?: WindowedSelectProps["isSearchable"]; +type CustomProps> = { + autocomplete?: Props["isSearchable"]; labelText?: string; size?: ComponentSize; requirementText?: string; helpText?: ReactNode; - disabled?: WindowedSelectProps["isDisabled"]; + disabled?: Props["isDisabled"]; errorMessage?: string; errorList?: string[]; - initialIsOpen?: WindowedSelectProps["defaultMenuIsOpen"]; - multiselect?: WindowedSelectProps["isMulti"]; + initialIsOpen?: Props["defaultMenuIsOpen"]; + multiselect?: Props["isMulti"]; maxHeight?: string; - defaultValue?: WindowedSelectProps["defaultInputValue"]; - value?: string; + defaultValue?: PropsValue; + value?: PropsValue; + options: NDSOption[]; + onChange?: (newValue: PropsValue) => void; + windowThreshold?: number; }; -export type NDSSelectProps = Omit< - WindowedSelectProps, - "isSearchable" | "isDisabled" | "isMulti" | "defaultMenuIsOpen" | "defaultInputValue" | "value" -> & - CustomProps; +export type NDSSelectProps< + IsMulti extends boolean = boolean, + Group extends GroupBase = GroupBase +> = Omit, keyof CustomProps> & CustomProps; const NDSSelect = forwardRef( - ( + = GroupBase>( { - size, autocomplete, - options, + value, + onChange, + defaultValue, labelText, required, requirementText, @@ -65,35 +71,24 @@ const NDSSelect = forwardRef( id, initialIsOpen, maxHeight, - isClearable, - onChange, multiselect, placeholder, - value, - defaultValue, - noOptionsMessage, - menuPosition, - name, - className, - classNamePrefix, - onBlur, - menuIsOpen, - onMenuOpen, - onMenuClose, - onInputChange, components, - "aria-label": ariaLabel, - windowThreshold = 100, + size, + windowThreshold, + options, ...props - }: NDSSelectProps, - ref: ((instance: Select | null) => void) | MutableRefObject