Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade React Select #16027

Merged
merged 4 commits into from
Sep 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
657 changes: 263 additions & 394 deletions airbyte-webapp/package-lock.json

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions airbyte-webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"react-query": "^3.39.1",
"react-reflex": "^4.0.9",
"react-router-dom": "^6.3.0",
"react-select": "^4.3.1",
"react-select": "^5.4.0",
"react-table": "^7.8.0",
"react-use": "^15.3.8",
"react-use-intercom": "^1.5.2",
Expand Down Expand Up @@ -95,7 +95,6 @@
"@types/react-dom": "^17.0.11",
"@types/react-helmet": "^6.1.5",
"@types/react-lazylog": "^4.5.1",
"@types/react-select": "^4.0.16",
"@types/react-table": "^7.7.12",
"@types/react-widgets": "^4.4.7",
"@types/sanitize-html": "^2.6.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const CustomSelect = styled(Select)<

& .react-select__value-container {
overflow: visible;
display: flex;
}
}
`;
27 changes: 16 additions & 11 deletions airbyte-webapp/src/components/base/DropDown/DropDown.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React from "react";
import { Props } from "react-select";
import { SelectComponentsConfig } from "react-select/src/components";
import { CSSObject } from "styled-components";
import { CSSObjectWithLabel, GroupBase, Props, SelectComponentsConfig, StylesConfig } from "react-select";
import Select from "react-select/dist/declarations/src/Select";

import { equal, naturalComparatorBy } from "utils/objects";

import DropdownIndicator from "./components/DropdownIndicator";
import { DropdownIndicator } from "./components/DropdownIndicator";
import Menu from "./components/Menu";
import Option, { IDataItem } from "./components/Option";
import SingleValue from "./components/SingleValue";
Expand All @@ -15,16 +14,22 @@ import { SelectContainer } from "./SelectContainer";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type OptionType = any;

export interface DropdownProps extends Props<OptionType> {
export interface DropdownProps<T = unknown> extends Props<OptionType> {
withBorder?: boolean;
$withBorder?: boolean;
fullText?: boolean;
error?: boolean;
selectProps?: T;
}

export const DropDown: React.FC<DropdownProps> = React.forwardRef((props, ref) => {
// eslint-disable-next-line react/function-component-definition
function DropDownInner<T = unknown>(
props: DropdownProps<T>,
ref: React.ForwardedRef<Select<unknown, boolean, GroupBase<unknown>>>
) {
const propsComponents = props.components;

const components = React.useMemo<SelectComponentsConfig<OptionType, boolean>>(
const components = React.useMemo<SelectComponentsConfig<OptionType, boolean, GroupBase<unknown>>>(
() =>
({
DropdownIndicator,
Expand All @@ -49,10 +54,10 @@ export const DropDown: React.FC<DropdownProps> = React.forwardRef((props, ref) =
: props.options?.find((op) => equal(op.value, props.value))
: null;

const styles = {
const styles: StylesConfig = {
...(props.styles ?? {}),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
menuPortal: (base: CSSObject, menuPortalProps: any) => ({
menuPortal: (base: CSSObjectWithLabel, menuPortalProps: any) => ({
...(props.styles?.menuPortal?.(base, menuPortalProps) ?? { ...base }),
zIndex: 9999,
}),
Expand All @@ -76,8 +81,8 @@ export const DropDown: React.FC<DropdownProps> = React.forwardRef((props, ref) =
components={components}
/>
);
});
}

export const defaultDataItemSort = naturalComparatorBy<IDataItem>((dataItem) => dataItem.label || "");

export default DropDown;
export const DropDown = React.forwardRef(DropDownInner);
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ import { components, ContainerProps } from "react-select";

import { OptionType } from "./DropDown";

export const SelectContainer: React.FC<ContainerProps<OptionType, false>> = (props) => {
export const SelectContainer: React.FC<
ContainerProps<OptionType, false> & {
selectProps: {
"data-testid": string;
krishnaglick marked this conversation as resolved.
Show resolved Hide resolved
role: string;
};
}
> = (props) => {
const wrapperProps = {
"data-testid": props.selectProps["data-testid"],
role: props.selectProps["role"] || "combobox",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { faSortDown } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React from "react";
import { components, IndicatorProps, OptionTypeBase } from "react-select";
import { components, DropdownIndicatorProps } from "react-select";
import styled from "styled-components";

const Arrow = styled(FontAwesomeIcon)`
margin-top: -6px;
`;

const DropdownIndicator: React.FC<IndicatorProps<OptionTypeBase, false>> = (props) => (
export const DropdownIndicator: React.FC<DropdownIndicatorProps> = (props) => (
<components.DropdownIndicator {...props}>
<Arrow icon={faSortDown} />
</components.DropdownIndicator>
);

export default DropdownIndicator;
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React from "react";
import { components, OptionProps, OptionTypeBase } from "react-select";
import { components, OptionProps } from "react-select";
import styled from "styled-components";

import CheckBox from "components/base/CheckBox";

import { OptionType } from "../DropDown";
import Text from "./Text";

export type IProps = {
data: { disabled: boolean; index: number; fullText?: boolean } & IDataItem;
} & OptionProps<OptionTypeBase, false>;
} & OptionProps<OptionType, boolean>;

export interface IDataItem {
label?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from "react";
import { components, SingleValueProps, OptionTypeBase } from "react-select";
import { components, SingleValueProps } from "react-select";
import styled from "styled-components";

import { IDataItem } from "./Option";
import Text from "./Text";

export type IProps = {
export type IProps<T> = {
data?: IDataItem;
} & SingleValueProps<OptionTypeBase>;
} & SingleValueProps<T>;

export const ItemView = styled.div`
display: flex;
Expand All @@ -21,7 +21,7 @@ export const Icon = styled.div`
display: inline-block;
`;

const SingleValue: React.FC<IProps> = (props) => {
const SingleValue = <T extends { data: { img: string } }>(props: React.PropsWithChildren<IProps<T>>) => {
return (
<ItemView>
{props.data.img ? <Icon>{props.data.img}</Icon> : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ const Text = styled.div<IProps>`
font-family: ${({ theme }) => theme.regularFont};
font-style: normal;
font-weight: normal;
max-width: 94%;
color: ${(props) => setColor(props)};

.rw-list-option.rw-state-selected & {
Expand Down
2 changes: 0 additions & 2 deletions airbyte-webapp/src/components/base/DropDown/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import * as DropDownRow from "./components/Option";
import DropDown from "./DropDown";

export * from "./DropDown";
export { DropDownRow };
export default DropDown;
3 changes: 2 additions & 1 deletion airbyte-webapp/src/components/base/Popout/Popout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const OutsideClickListener = styled.div`
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Value = any;

const ControlComponent = (props: ControlProps<Value, false>) => (
const ControlComponent = (props: ControlProps & { selectProps: Value }) => (
<div ref={props.innerRef}>
{props.selectProps.selectProps.targetComponent({
onOpen: props.selectProps.selectProps.onOpen,
Expand All @@ -30,6 +30,7 @@ const ControlComponent = (props: ControlProps<Value, false>) => (

interface PopoutProps extends DropdownProps {
targetComponent: (props: { onOpen: () => void; isOpen?: boolean; value: Value }) => ReactNode;
title?: string;
}

const Popout: React.FC<PopoutProps> = ({ onChange, targetComponent, ...props }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useMemo } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { components } from "react-select";
import { MenuListComponentProps } from "react-select/src/components/Menu";
import { components, MenuListProps } from "react-select";
import styled from "styled-components";

import { Popout } from "components";
Expand Down Expand Up @@ -67,7 +66,7 @@ const List = styled.div`
}
`;

type MenuWithRequestButtonProps = MenuListComponentProps<IDataItem, false> & {
type MenuWithRequestButtonProps = MenuListProps<IDataItem, boolean> & {
selectedWorkspace: string;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ export const PathPopout: React.FC<PathPopoutProps> = (props) => {
<Popout
options={options}
value={props.path}
// @ts-expect-error need to solve issue with typings
isMulti={props.isMulti}
isSearchable
onChange={(options: PathPopoutProps["isMulti"] extends true ? Array<{ value: Path }> : { value: Path }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ const Separator = styled.div`
padding: 0 5px;
`;

const SingleValue: React.FC<IProps> = (props) => {
const { syncMode, destinationSyncMode } = props.data.value;
const SingleValue: React.FC<IProps<unknown>> = (props) => {
const { syncMode, destinationSyncMode } = props.data?.value;
return (
<Text>
<ValueView {...props}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useField } from "formik";
import React, { useCallback, useEffect, useMemo } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { components } from "react-select";
import { MenuListComponentProps } from "react-select/src/components/Menu";
import { MenuListProps } from "react-select";
import styled from "styled-components";

import { ControlLabels, DropDown, DropDownRow } from "components";
Expand Down Expand Up @@ -79,7 +79,8 @@ const SingleValueContent = styled(components.SingleValue)`
align-items: center;
`;

type MenuWithRequestButtonProps = MenuListComponentProps<IDataItem, false>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type MenuWithRequestButtonProps = MenuListProps<IDataItem, false> & { selectProps: any };

/**
* Returns the order for a specific release stage label. This will define
Expand Down Expand Up @@ -139,7 +140,8 @@ const Option: React.FC<OptionProps> = (props) => {
);
};

const SingleValue: React.FC<SingleValueProps> = (props) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const SingleValue: React.FC<SingleValueProps<any>> = (props) => {
return (
<SingleValueView>
{props.data.img && <SingleValueIcon>{props.data.img}</SingleValueIcon>}
Expand Down