From f554afd6b1b6598785a1a02fac14e991b9f2eccc Mon Sep 17 00:00:00 2001 From: Timo <16718859+toger5@users.noreply.github.com> Date: Tue, 9 Aug 2022 11:44:46 +0200 Subject: [PATCH] typescript `src/input` (#487) --- src/ListBox.tsx | 4 +- src/auth/RegisterPage.tsx | 9 ++- ...tarInputField.jsx => AvatarInputField.tsx} | 36 ++++++---- src/input/{Input.jsx => Input.tsx} | 65 ++++++++++++++++--- .../{SelectInput.jsx => SelectInput.tsx} | 11 +++- src/input/{Toggle.jsx => Toggle.tsx} | 29 +++++++-- src/profile/ProfileModal.tsx | 4 +- src/room/GroupCallInspector.tsx | 3 +- 8 files changed, 120 insertions(+), 41 deletions(-) rename src/input/{AvatarInputField.jsx => AvatarInputField.tsx} (73%) rename src/input/{Input.jsx => Input.tsx} (62%) rename src/input/{SelectInput.jsx => SelectInput.tsx} (90%) rename src/input/{Toggle.jsx => Toggle.tsx} (76%) diff --git a/src/ListBox.tsx b/src/ListBox.tsx index a57d440..16b7f05 100644 --- a/src/ListBox.tsx +++ b/src/ListBox.tsx @@ -23,10 +23,10 @@ import classNames from "classnames"; import styles from "./ListBox.module.css"; interface ListBoxProps extends AriaListBoxOptions { - className: string; optionClassName: string; - listBoxRef: React.MutableRefObject; state: ListState; + className?: string; + listBoxRef?: React.MutableRefObject; } export function ListBox({ diff --git a/src/auth/RegisterPage.tsx b/src/auth/RegisterPage.tsx index 768c3c1..0f908be 100644 --- a/src/auth/RegisterPage.tsx +++ b/src/auth/RegisterPage.tsx @@ -15,6 +15,7 @@ limitations under the License. */ import React, { + ChangeEvent, FC, FormEvent, useCallback, @@ -166,7 +167,9 @@ export const RegisterPage: FC = () => { required name="password" type="password" - onChange={(e) => setPassword(e.target.value)} + onChange={(e: ChangeEvent) => + setPassword(e.target.value) + } value={password} placeholder="Password" label="Password" @@ -177,7 +180,9 @@ export const RegisterPage: FC = () => { required type="password" name="passwordConfirmation" - onChange={(e) => setPasswordConfirmation(e.target.value)} + onChange={(e: ChangeEvent) => + setPasswordConfirmation(e.target.value) + } value={passwordConfirmation} placeholder="Confirm Password" label="Confirm Password" diff --git a/src/input/AvatarInputField.jsx b/src/input/AvatarInputField.tsx similarity index 73% rename from src/input/AvatarInputField.jsx rename to src/input/AvatarInputField.tsx index 0977388..8f0aa4d 100644 --- a/src/input/AvatarInputField.jsx +++ b/src/input/AvatarInputField.tsx @@ -15,42 +15,52 @@ limitations under the License. */ import { useObjectRef } from "@react-aria/utils"; -import React, { useEffect } from "react"; +import React, { AllHTMLAttributes, useEffect } from "react"; import { useCallback } from "react"; import { useState } from "react"; import { forwardRef } from "react"; -import { Avatar } from "../Avatar"; -import { Button } from "../button"; import classNames from "classnames"; + +import { Avatar, Size } from "../Avatar"; +import { Button } from "../button"; import { ReactComponent as EditIcon } from "../icons/Edit.svg"; import styles from "./AvatarInputField.module.css"; -export const AvatarInputField = forwardRef( +interface Props extends AllHTMLAttributes { + id: string; + label: string; + avatarUrl: string; + displayName: string; + onRemoveAvatar: () => void; +} + +export const AvatarInputField = forwardRef( ( { id, label, className, avatarUrl, displayName, onRemoveAvatar, ...rest }, ref ) => { const [removed, setRemoved] = useState(false); - const [objUrl, setObjUrl] = useState(null); + const [objUrl, setObjUrl] = useState(null); const fileInputRef = useObjectRef(ref); useEffect(() => { - const onChange = (e) => { - if (e.target.files.length > 0) { - setObjUrl(URL.createObjectURL(e.target.files[0])); + const currentInput = fileInputRef.current; + + const onChange = (e: Event) => { + const inputEvent = e as unknown as React.ChangeEvent; + if (inputEvent.target.files.length > 0) { + setObjUrl(URL.createObjectURL(inputEvent.target.files[0])); setRemoved(false); } else { setObjUrl(null); } }; - fileInputRef.current.addEventListener("change", onChange); + currentInput.addEventListener("change", onChange); return () => { - if (fileInputRef.current) { - fileInputRef.current.removeEventListener("change", onChange); - } + currentInput?.removeEventListener("change", onChange); }; }); @@ -63,7 +73,7 @@ export const AvatarInputField = forwardRef(
diff --git a/src/input/Input.jsx b/src/input/Input.tsx similarity index 62% rename from src/input/Input.jsx rename to src/input/Input.tsx index 820956b..5b6ec66 100644 --- a/src/input/Input.jsx +++ b/src/input/Input.tsx @@ -14,12 +14,23 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { forwardRef } from "react"; +import React, { ChangeEvent, forwardRef, ReactNode } from "react"; import classNames from "classnames"; + import styles from "./Input.module.css"; import { ReactComponent as CheckIcon } from "../icons/Check.svg"; -export function FieldRow({ children, rightAlign, className, ...rest }) { +interface FieldRowProps { + children: ReactNode; + rightAlign?: boolean; + className?: string; +} + +export function FieldRow({ + children, + rightAlign, + className, +}: FieldRowProps): JSX.Element { return (
{children}
; } -export const InputField = forwardRef( +interface InputFieldProps { + label: string; + type: string; + prefix?: string; + suffix?: string; + id?: string; + checked?: boolean; + className?: string; + description?: string; + disabled?: boolean; + required?: boolean; + // this is a hack. Those variables should be part of `HTMLAttributes | HTMLAttributes` + // but extending from this union type does not work + name?: string; + autoComplete?: string; + autoCorrect?: string; + autoCapitalize?: string; + value?: string; + placeholder?: string; + defaultChecked?: boolean; + onChange?: (event: ChangeEvent) => void; +} + +export const InputField = forwardRef< + HTMLInputElement | HTMLTextAreaElement, + InputFieldProps +>( ( { id, @@ -68,19 +110,18 @@ export const InputField = forwardRef( {type === "textarea" ? (