diff --git a/airbyte-webapp/src/components/connectorBuilder/StreamTestingPanel/StreamSelector.tsx b/airbyte-webapp/src/components/connectorBuilder/StreamTestingPanel/StreamSelector.tsx index bfad00ad7418..20d3e8189a48 100644 --- a/airbyte-webapp/src/components/connectorBuilder/StreamTestingPanel/StreamSelector.tsx +++ b/airbyte-webapp/src/components/connectorBuilder/StreamTestingPanel/StreamSelector.tsx @@ -1,5 +1,3 @@ -import { faSortDown } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import classNames from "classnames"; import capitalize from "lodash/capitalize"; import { useIntl } from "react-intl"; @@ -9,6 +7,7 @@ import { ListBox, ListBoxControlButtonProps } from "components/ui/ListBox"; import { useConnectorBuilderState } from "services/connectorBuilder/ConnectorBuilderStateService"; +import { ReactComponent as CaretDownIcon } from "../../ui/ListBox/CaretDownIcon.svg"; import styles from "./StreamSelector.module.scss"; interface StreamSelectorProps { @@ -21,7 +20,7 @@ const ControlButton: React.FC> = ({ selectedOp {selectedOption.label} - + ); }; diff --git a/airbyte-webapp/src/components/ui/DropDown/index.stories.tsx b/airbyte-webapp/src/components/ui/DropDown/index.stories.tsx new file mode 100644 index 000000000000..a467f7369291 --- /dev/null +++ b/airbyte-webapp/src/components/ui/DropDown/index.stories.tsx @@ -0,0 +1,33 @@ +import { ComponentStory, ComponentMeta } from "@storybook/react"; + +import { DropDown } from "./DropDown"; + +const listOptions = [ + { + label: "one", + value: "value", + }, + { + label: "two", + value: "value", + }, + { + label: "three", + value: "value", + }, +]; + +export default { + title: "Ui/DropDown", + component: DropDown, + argTypes: { + options: listOptions, + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ; + +export const Primary = Template.bind({}); +Primary.args = { + options: listOptions, +}; diff --git a/airbyte-webapp/src/components/ui/ListBox/CaretDownIcon.svg b/airbyte-webapp/src/components/ui/ListBox/CaretDownIcon.svg new file mode 100644 index 000000000000..12639caa2e8e --- /dev/null +++ b/airbyte-webapp/src/components/ui/ListBox/CaretDownIcon.svg @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/airbyte-webapp/src/components/ui/ListBox/ListBox.module.scss b/airbyte-webapp/src/components/ui/ListBox/ListBox.module.scss index d4ea0a51b4c6..b6ac3c3231ba 100644 --- a/airbyte-webapp/src/components/ui/ListBox/ListBox.module.scss +++ b/airbyte-webapp/src/components/ui/ListBox/ListBox.module.scss @@ -3,8 +3,21 @@ .button { width: 100%; - height: 100%; cursor: pointer; + border: 1px solid colors.$grey-50; + background-color: colors.$grey-50; + border-radius: variables.$border-radius-xs; + text-align: left; + display: flex; + justify-content: space-between; + align-items: center; + font-size: 14px; + line-height: 20px; + min-height: 36px; + + &:hover { + border-color: colors.$grey-100; + } } .optionsContainer { @@ -25,15 +38,33 @@ z-index: 1; } +.caret { + color: colors.$grey-300; +} + .option { list-style-type: none; } +.icon { + padding-right: variables.$spacing-md; + + & svg { + max-width: 18px; + max-height: 18px; + } +} + +.label { + padding: variables.$spacing-lg 0; +} + .optionValue { - padding: variables.$spacing-lg variables.$spacing-md; - border-radius: variables.$border-radius-lg; + padding: 0 variables.$spacing-md; + border-radius: variables.$border-radius-md; cursor: pointer; - overflow: auto; + display: flex; + align-items: center; } .active { diff --git a/airbyte-webapp/src/components/ui/ListBox/ListBox.tsx b/airbyte-webapp/src/components/ui/ListBox/ListBox.tsx index 2addb2069c3f..298e6696f09d 100644 --- a/airbyte-webapp/src/components/ui/ListBox/ListBox.tsx +++ b/airbyte-webapp/src/components/ui/ListBox/ListBox.tsx @@ -2,6 +2,7 @@ import { Listbox } from "@headlessui/react"; import classNames from "classnames"; import React from "react"; +import { ReactComponent as CaretDownIcon } from "./CaretDownIcon.svg"; import styles from "./ListBox.module.scss"; export interface ListBoxControlButtonProps { @@ -9,12 +10,18 @@ export interface ListBoxControlButtonProps { } const DefaultControlButton = ({ selectedOption }: ListBoxControlButtonProps) => { - return <>{selectedOption.label}; + return ( + <> + {selectedOption.label} + + + ); }; export interface Option { label: string; value: T; + icon?: React.ReactNode; } interface ListBoxProps { @@ -48,13 +55,14 @@ export const ListBox = ({ {/* wrap in div to make `position: absolute` on Listbox.Options result in correct vertical positioning */}
- {options.map(({ label, value }) => ( + {options.map(({ label, value, icon }) => ( {({ active, selected }) => (
- {label} + {icon && {icon}} + {label}
)}
diff --git a/airbyte-webapp/src/components/ui/ListBox/index.stories.tsx b/airbyte-webapp/src/components/ui/ListBox/index.stories.tsx new file mode 100644 index 000000000000..f6ce6344b73e --- /dev/null +++ b/airbyte-webapp/src/components/ui/ListBox/index.stories.tsx @@ -0,0 +1,36 @@ +import { faEdit } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { ComponentMeta } from "@storybook/react"; +import { useState } from "react"; + +import { ListBox } from "./ListBox"; + +const listOptions = [ + { + label: "one", + value: 1, + icon: , + }, + { + label: "two", + value: 2, + }, + { + label: "three", + value: 3, + }, +]; + +export default { + title: "Ui/ListBox", + component: ListBox, + argTypes: { + options: listOptions, + }, +} as ComponentMeta; + +export const Primary = () => { + const [selectedOption, setSelectedOption] = useState(1); + + return ; +};