diff --git a/airbyte-webapp/src/components/ui/StepsIndicator/StepsIndicator.module.scss b/airbyte-webapp/src/components/ui/StepsIndicator/StepsIndicator.module.scss new file mode 100644 index 0000000000000..37f20661ea4ff --- /dev/null +++ b/airbyte-webapp/src/components/ui/StepsIndicator/StepsIndicator.module.scss @@ -0,0 +1,31 @@ +@use "scss/colors"; +@use "scss/variables"; + +.steps { + display: flex; + align-items: center; + gap: variables.$spacing-md; +} + +.tooltip { + display: flex; +} + +.step { + display: inline-block; + width: 35px; + height: 4px; + border-radius: 3px; + background-color: colors.$grey-300; + + // Give the element a bit larger hover area for the tooltip to show + margin: 8px 0; + + &.completed { + background-color: colors.$blue-200; + } + + &.current { + background-color: colors.$blue; + } +} diff --git a/airbyte-webapp/src/components/ui/StepsIndicator/StepsIndicator.tsx b/airbyte-webapp/src/components/ui/StepsIndicator/StepsIndicator.tsx new file mode 100644 index 0000000000000..435b1ee7de6fa --- /dev/null +++ b/airbyte-webapp/src/components/ui/StepsIndicator/StepsIndicator.tsx @@ -0,0 +1,51 @@ +import classNames from "classnames"; +import { FormattedMessage } from "react-intl"; + +import { Tooltip } from "components/ui/Tooltip"; + +import styles from "./StepsIndicator.module.scss"; + +interface Step { + id: string; + name: string; +} + +interface StepIndicatorProps { + step: Step; + isCurrent: boolean; + isCompleted: boolean; +} + +interface StepsIndicatorProps { + steps: Step[]; + activeStep: string; + className?: string; +} + +const StepIndicator: React.FC = ({ step, isCurrent, isCompleted }) => { + return ( + + } + > + {step.name} {isCurrent && } + + ); +}; + +export const StepsIndicator: React.FC = ({ className, steps, activeStep }) => { + const activeIndex = steps.findIndex((step) => step.id === activeStep); + return ( +
+ {steps.map((step, index) => ( + + ))} +
+ ); +}; diff --git a/airbyte-webapp/src/components/ui/StepsIndicator/index.stories.tsx b/airbyte-webapp/src/components/ui/StepsIndicator/index.stories.tsx new file mode 100644 index 0000000000000..02cd5e33cb25e --- /dev/null +++ b/airbyte-webapp/src/components/ui/StepsIndicator/index.stories.tsx @@ -0,0 +1,30 @@ +import { ComponentMeta, ComponentStory } from "@storybook/react"; + +import { StepsIndicator } from "./StepsIndicator"; + +export default { + title: "UI/StepsIndicator", + component: StepsIndicator, + argTypes: {}, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ; + +export const Primary = Template.bind({}); +Primary.args = { + steps: [ + { + id: "source", + name: "Create source", + }, + { + id: "destination", + name: "Create destination", + }, + { + id: "connection", + name: "Create connection", + }, + ], + activeStep: "destination", +}; diff --git a/airbyte-webapp/src/components/ui/StepsIndicator/index.ts b/airbyte-webapp/src/components/ui/StepsIndicator/index.ts new file mode 100644 index 0000000000000..9cc8dadf17404 --- /dev/null +++ b/airbyte-webapp/src/components/ui/StepsIndicator/index.ts @@ -0,0 +1 @@ +export { StepsIndicator } from "./StepsIndicator"; diff --git a/airbyte-webapp/src/components/ui/Tooltip/Tooltip.tsx b/airbyte-webapp/src/components/ui/Tooltip/Tooltip.tsx index a07ced3e56dec..662857acb6113 100644 --- a/airbyte-webapp/src/components/ui/Tooltip/Tooltip.tsx +++ b/airbyte-webapp/src/components/ui/Tooltip/Tooltip.tsx @@ -20,7 +20,16 @@ const FLOATING_OPTIONS: UseFloatingProps = { }; export const Tooltip: React.FC> = (props) => { - const { children, control, className, disabled, cursor, theme = "dark", placement = "bottom" } = props; + const { + children, + control, + className, + containerClassName, + disabled, + cursor, + theme = "dark", + placement = "bottom", + } = props; const [isMouseOver, setIsMouseOver] = useState(false); const [isVisible, setIsVisible] = useState(false); @@ -59,7 +68,7 @@ export const Tooltip: React.FC> = (props) <>
{ useTrackPage(PageTrackingCodes.CONNECTIONS_NEW); const location = useLocation(); + const { formatMessage } = useIntl(); // exp-signup-selected-source-definition const state = useLocationState<{ sourceDefinitionId?: string }>(); @@ -185,30 +186,28 @@ export const CreationFormPage: React.FC = () => { ? [ { id: StepsTypes.CREATE_ENTITY, - name: , + name: formatMessage({ id: "onboarding.createSource" }), }, { id: StepsTypes.CREATE_CONNECTOR, - name: , + name: formatMessage({ id: "onboarding.createDestination" }), }, { id: StepsTypes.CREATE_CONNECTION, - name: , + name: formatMessage({ id: "onboarding.setUpConnection" }), }, ] : [ { id: StepsTypes.CREATE_ENTITY, name: - type === "destination" ? ( - - ) : ( - - ), + type === "destination" + ? formatMessage({ id: "onboarding.createDestination" }) + : formatMessage({ id: "onboarding.createSource" }), }, { id: StepsTypes.CREATE_CONNECTION, - name: , + name: formatMessage({ id: "onboarding.setUpConnection" }), }, ]; @@ -226,7 +225,7 @@ export const CreationFormPage: React.FC = () => { } - middleComponent={} + middleComponent={} /> {currentStep !== StepsTypes.CREATE_CONNECTION && (!!source || !!destination) && (