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/button/Button.tsx b/src/button/Button.tsx index 2c2605f..c29b5f2 100644 --- a/src/button/Button.tsx +++ b/src/button/Button.tsx @@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import React, { forwardRef } from "react"; +import React, { forwardRef, useCallback } from "react"; import { PressEvent } from "@react-types/shared"; import classNames from "classnames"; import { useButton } from "@react-aria/button"; @@ -29,6 +29,8 @@ import { ReactComponent as ScreenshareIcon } from "../icons/Screenshare.svg"; import { ReactComponent as SettingsIcon } from "../icons/Settings.svg"; import { ReactComponent as AddUserIcon } from "../icons/AddUser.svg"; import { ReactComponent as ArrowDownIcon } from "../icons/ArrowDown.svg"; +import { ReactComponent as Fullscreen } from "../icons/Fullscreen.svg"; +import { ReactComponent as FullscreenExit } from "../icons/FullscreenExit.svg"; import { TooltipTrigger } from "../Tooltip"; import { VolumeIcon } from "./VolumeIcon"; @@ -262,3 +264,24 @@ export function AudioButton({ volume, ...rest }: AudioButtonProps) { ); } + +interface FullscreenButtonProps extends Omit { + fullscreen?: boolean; +} + +export function FullscreenButton({ + fullscreen, + ...rest +}: FullscreenButtonProps) { + const getTooltip = useCallback(() => { + return fullscreen ? "Exit full screen" : "Full screen"; + }, [fullscreen]); + + return ( + + + + ); +} diff --git a/src/icons/Fullscreen.svg b/src/icons/Fullscreen.svg new file mode 100644 index 0000000..ad8d2b7 --- /dev/null +++ b/src/icons/Fullscreen.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/FullscreenExit.svg b/src/icons/FullscreenExit.svg new file mode 100644 index 0000000..f7b8044 --- /dev/null +++ b/src/icons/FullscreenExit.svg @@ -0,0 +1,3 @@ + + + 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" ? (