From 242149c402667d50e5a479c37164b9d7c5d3b509 Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Thu, 14 Jul 2022 11:15:17 -0700 Subject: [PATCH 1/7] Cleanup LabeledInput props and prop assignment --- .../components/LabeledInput/LabeledInput.tsx | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/airbyte-webapp/src/components/LabeledInput/LabeledInput.tsx b/airbyte-webapp/src/components/LabeledInput/LabeledInput.tsx index a55c19c0182c..c287c50e269a 100644 --- a/airbyte-webapp/src/components/LabeledInput/LabeledInput.tsx +++ b/airbyte-webapp/src/components/LabeledInput/LabeledInput.tsx @@ -1,24 +1,26 @@ import React from "react"; import { Input, InputProps } from "components/base"; -import { ControlLabels } from "components/LabeledControl"; +import { ControlLabels, ControlLabelsProps } from "components/LabeledControl"; -type IProps = { - success?: boolean; - message?: React.ReactNode; - label?: React.ReactNode; - labelAdditionLength?: number; -} & InputProps; +type LabeledInputProps = Pick & InputProps; -const LabeledInput: React.FC = (props) => ( +const LabeledInput: React.FC = ({ + error, + success, + message, + label, + labelAdditionLength, + ...inputProps +}) => ( - + ); From badc038dab624c680499c99f56a56a23ebfc1d2a Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Thu, 14 Jul 2022 11:37:48 -0700 Subject: [PATCH 2/7] Fix Input component focus and blur handlers --- .../src/components/base/Input/Input.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/airbyte-webapp/src/components/base/Input/Input.tsx b/airbyte-webapp/src/components/base/Input/Input.tsx index dde749132783..010b7b669b3b 100644 --- a/airbyte-webapp/src/components/base/Input/Input.tsx +++ b/airbyte-webapp/src/components/base/Input/Input.tsx @@ -82,9 +82,7 @@ const VisibilityButton = styled(Button)` border: none; `; -const Input: React.FC = (props) => { - const { defaultFocus = false } = props; - +const Input: React.FC = ({ defaultFocus = false, onFocus, onBlur, ...props }) => { const { formatMessage } = useIntl(); const inputRef = useRef(null); const [isContentVisible, setIsContentVisible] = useToggle(false); @@ -93,7 +91,6 @@ const Input: React.FC = (props) => { const isPassword = props.type === "password"; const isVisibilityButtonVisible = isPassword && !props.disabled; const type = isPassword ? (isContentVisible ? "text" : "password") : props.type; - const onInputFocusChange = () => toggleFocused(); useEffect(() => { if (defaultFocus && inputRef.current !== null) { @@ -109,8 +106,14 @@ const Input: React.FC = (props) => { ref={inputRef} type={type} isPassword={isPassword} - onFocus={onInputFocusChange} - onBlur={onInputFocusChange} + onFocus={(event) => { + toggleFocused(); + onFocus?.(event); + }} + onBlur={(event) => { + toggleFocused(); + onBlur?.(event); + }} /> {isVisibilityButtonVisible ? ( Date: Thu, 14 Jul 2022 11:38:11 -0700 Subject: [PATCH 3/7] Disable validateOnChange for signin and signup form --- .../cloud/views/auth/SignupPage/components/SignupForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airbyte-webapp/src/packages/cloud/views/auth/SignupPage/components/SignupForm.tsx b/airbyte-webapp/src/packages/cloud/views/auth/SignupPage/components/SignupForm.tsx index df3525c67496..1e3ce316be65 100644 --- a/airbyte-webapp/src/packages/cloud/views/auth/SignupPage/components/SignupForm.tsx +++ b/airbyte-webapp/src/packages/cloud/views/auth/SignupPage/components/SignupForm.tsx @@ -218,7 +218,7 @@ export const SignupForm: React.FC = () => { }) } validateOnBlur - validateOnChange + validateOnChange={false} > {({ isValid, isSubmitting, values, status }) => (
From 2f90d68321d5948b08e160e1cc8e212226d5dfb1 Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Thu, 14 Jul 2022 11:45:36 -0700 Subject: [PATCH 4/7] Fix error wording for empty and email input errors --- airbyte-webapp/src/locales/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/airbyte-webapp/src/locales/en.json b/airbyte-webapp/src/locales/en.json index 15470e7f5381..768a0e12874f 100644 --- a/airbyte-webapp/src/locales/en.json +++ b/airbyte-webapp/src/locales/en.json @@ -26,8 +26,8 @@ "form.continue": "Continue", "form.yourEmail": "Your email", "form.email.placeholder": "you@company.com", - "form.email.error": "This email address doesn’t seem correct.", - "form.empty.error": "Field is required", + "form.email.error": "Enter a valid email", + "form.empty.error": "Required", "form.selectConnector": "Type to search for a connector", "form.searchName": "search by name...", "form.noResult": "No result", From 094104a185680a4aa1ae9dfd5721f4f1bf4f2c13 Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Thu, 14 Jul 2022 11:58:18 -0700 Subject: [PATCH 5/7] Add focus / blur tests to Input test --- .../src/components/base/Input/Input.test.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/airbyte-webapp/src/components/base/Input/Input.test.tsx b/airbyte-webapp/src/components/base/Input/Input.test.tsx index e08b581411c2..99af97ac6075 100644 --- a/airbyte-webapp/src/components/base/Input/Input.test.tsx +++ b/airbyte-webapp/src/components/base/Input/Input.test.tsx @@ -52,4 +52,22 @@ describe("", () => { fireEvent.change(inputEl, { target: { value: "one more test" } }); expect(onChange).toHaveBeenCalledTimes(1); }); + + test("should trigger onFocus once", async () => { + const onFocus = jest.fn(); + const { getByTestId } = await render(); + const inputEl = getByTestId("input"); + + fireEvent.focus(inputEl); + expect(onFocus).toHaveBeenCalledTimes(1); + }); + + test("should trigger onBlur once", async () => { + const onBlur = jest.fn(); + const { getByTestId } = await render(); + const inputEl = getByTestId("input"); + + fireEvent.blur(inputEl); + expect(onBlur).toHaveBeenCalledTimes(1); + }); }); From 2ca39244c1fb9039d65015cc8b74c061021ef7bd Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Thu, 14 Jul 2022 12:31:31 -0700 Subject: [PATCH 6/7] Update focused from toggle to state in Input component --- airbyte-webapp/src/components/base/Input/Input.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/airbyte-webapp/src/components/base/Input/Input.tsx b/airbyte-webapp/src/components/base/Input/Input.tsx index 010b7b669b3b..1f7013e99669 100644 --- a/airbyte-webapp/src/components/base/Input/Input.tsx +++ b/airbyte-webapp/src/components/base/Input/Input.tsx @@ -1,6 +1,6 @@ import { faEye, faEyeSlash } from "@fortawesome/free-regular-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import React, { useEffect, useRef } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { useIntl } from "react-intl"; import { useToggle } from "react-use"; import styled from "styled-components"; @@ -86,7 +86,7 @@ const Input: React.FC = ({ defaultFocus = false, onFocus, onBlur, .. const { formatMessage } = useIntl(); const inputRef = useRef(null); const [isContentVisible, setIsContentVisible] = useToggle(false); - const [focused, toggleFocused] = useToggle(false); + const [focused, setFocused] = useState(false); const isPassword = props.type === "password"; const isVisibilityButtonVisible = isPassword && !props.disabled; @@ -107,11 +107,11 @@ const Input: React.FC = ({ defaultFocus = false, onFocus, onBlur, .. type={type} isPassword={isPassword} onFocus={(event) => { - toggleFocused(); + setFocused(true); onFocus?.(event); }} onBlur={(event) => { - toggleFocused(); + setFocused(false); onBlur?.(event); }} /> From 05b97152b2189de39bacfde5c61b228aa501db26 Mon Sep 17 00:00:00 2001 From: Edmundo Ruiz Ghanem Date: Thu, 14 Jul 2022 13:04:44 -0700 Subject: [PATCH 7/7] Add Input tests to verify that focus class is set --- .../src/components/base/Input/Input.test.tsx | 27 +++++++++++++++++-- .../src/components/base/Input/Input.tsx | 6 ++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/airbyte-webapp/src/components/base/Input/Input.test.tsx b/airbyte-webapp/src/components/base/Input/Input.test.tsx index 99af97ac6075..1d7d5cbc586e 100644 --- a/airbyte-webapp/src/components/base/Input/Input.test.tsx +++ b/airbyte-webapp/src/components/base/Input/Input.test.tsx @@ -53,21 +53,44 @@ describe("", () => { expect(onChange).toHaveBeenCalledTimes(1); }); - test("should trigger onFocus once", async () => { + test("has focused class after focus", async () => { + const { getByTestId } = await render(); + const inputEl = getByTestId("input"); + + fireEvent.focus(inputEl); + fireEvent.focus(inputEl); + + expect(getByTestId("input-container")).toHaveClass("input-container--focused"); + }); + + test("does not have focused class after blur", async () => { + const { getByTestId } = await render(); + const inputEl = getByTestId("input"); + + fireEvent.focus(inputEl); + fireEvent.blur(inputEl); + fireEvent.blur(inputEl); + + expect(getByTestId("input-container")).not.toHaveClass("input-container--focused"); + }); + + test("calls onFocus if passed as prop", async () => { const onFocus = jest.fn(); const { getByTestId } = await render(); const inputEl = getByTestId("input"); fireEvent.focus(inputEl); + expect(onFocus).toHaveBeenCalledTimes(1); }); - test("should trigger onBlur once", async () => { + test("calls onBlur if passed as prop", async () => { const onBlur = jest.fn(); const { getByTestId } = await render(); const inputEl = getByTestId("input"); fireEvent.blur(inputEl); + expect(onBlur).toHaveBeenCalledTimes(1); }); }); diff --git a/airbyte-webapp/src/components/base/Input/Input.tsx b/airbyte-webapp/src/components/base/Input/Input.tsx index 1f7013e99669..39e00dc62bf1 100644 --- a/airbyte-webapp/src/components/base/Input/Input.tsx +++ b/airbyte-webapp/src/components/base/Input/Input.tsx @@ -1,5 +1,6 @@ import { faEye, faEyeSlash } from "@fortawesome/free-regular-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import classNames from "classnames"; import React, { useEffect, useRef, useState } from "react"; import { useIntl } from "react-intl"; import { useToggle } from "react-use"; @@ -99,7 +100,10 @@ const Input: React.FC = ({ defaultFocus = false, onFocus, onBlur, .. }, [inputRef, defaultFocus]); return ( - +