typescript src/input (#487)
This commit is contained in:
@@ -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<HTMLInputElement> {
|
||||
id: string;
|
||||
label: string;
|
||||
avatarUrl: string;
|
||||
displayName: string;
|
||||
onRemoveAvatar: () => void;
|
||||
}
|
||||
|
||||
export const AvatarInputField = forwardRef<HTMLInputElement, Props>(
|
||||
(
|
||||
{ id, label, className, avatarUrl, displayName, onRemoveAvatar, ...rest },
|
||||
ref
|
||||
) => {
|
||||
const [removed, setRemoved] = useState(false);
|
||||
const [objUrl, setObjUrl] = useState(null);
|
||||
const [objUrl, setObjUrl] = useState<string>(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<HTMLInputElement>;
|
||||
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(
|
||||
<div className={classNames(styles.avatarInputField, className)}>
|
||||
<div className={styles.avatarContainer}>
|
||||
<Avatar
|
||||
size="xl"
|
||||
size={Size.XL}
|
||||
src={removed ? null : objUrl || avatarUrl}
|
||||
fallback={displayName.slice(0, 1).toUpperCase()}
|
||||
/>
|
||||
@@ -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 (
|
||||
<div
|
||||
className={classNames(
|
||||
@@ -33,11 +44,42 @@ export function FieldRow({ children, rightAlign, className, ...rest }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function Field({ children, className, ...rest }) {
|
||||
interface FieldProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function Field({ children, className }: FieldProps): JSX.Element {
|
||||
return <div className={classNames(styles.field, className)}>{children}</div>;
|
||||
}
|
||||
|
||||
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<HTMLInputElement> | HTMLAttributes<HTMLTextAreaElement>`
|
||||
// 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" ? (
|
||||
<textarea
|
||||
id={id}
|
||||
{...rest}
|
||||
ref={ref}
|
||||
type={type}
|
||||
ref={ref as React.ForwardedRef<HTMLTextAreaElement>}
|
||||
disabled={disabled}
|
||||
{...rest}
|
||||
/>
|
||||
) : (
|
||||
<input
|
||||
id={id}
|
||||
{...rest}
|
||||
ref={ref}
|
||||
ref={ref as React.ForwardedRef<HTMLInputElement>}
|
||||
type={type}
|
||||
checked={checked}
|
||||
disabled={disabled}
|
||||
{...rest}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -99,6 +140,10 @@ export const InputField = forwardRef(
|
||||
}
|
||||
);
|
||||
|
||||
export function ErrorMessage({ children }) {
|
||||
export function ErrorMessage({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
}): JSX.Element {
|
||||
return <p className={styles.errorMessage}>{children}</p>;
|
||||
}
|
||||
@@ -15,16 +15,21 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useRef } from "react";
|
||||
import { HiddenSelect, useSelect } from "@react-aria/select";
|
||||
import { AriaSelectOptions, HiddenSelect, useSelect } from "@react-aria/select";
|
||||
import { useButton } from "@react-aria/button";
|
||||
import { useSelectState } from "@react-stately/select";
|
||||
import classNames from "classnames";
|
||||
|
||||
import { Popover } from "../popover/Popover";
|
||||
import { ListBox } from "../ListBox";
|
||||
import styles from "./SelectInput.module.css";
|
||||
import classNames from "classnames";
|
||||
import { ReactComponent as ArrowDownIcon } from "../icons/ArrowDown.svg";
|
||||
|
||||
export function SelectInput(props) {
|
||||
interface Props extends AriaSelectOptions<object> {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function SelectInput(props: Props): JSX.Element {
|
||||
const state = useSelectState(props);
|
||||
|
||||
const ref = useRef();
|
||||
@@ -15,22 +15,37 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useRef } from "react";
|
||||
import styles from "./Toggle.module.css";
|
||||
import { useToggleButton } from "@react-aria/button";
|
||||
import classNames from "classnames";
|
||||
|
||||
import styles from "./Toggle.module.css";
|
||||
import { Field } from "./Input";
|
||||
|
||||
export function Toggle({ id, label, className, onChange, isSelected }) {
|
||||
const buttonRef = useRef();
|
||||
interface Props {
|
||||
id: string;
|
||||
label: string;
|
||||
onChange: (selected: boolean) => void;
|
||||
isSelected: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function Toggle({
|
||||
id,
|
||||
label,
|
||||
className,
|
||||
onChange,
|
||||
isSelected,
|
||||
}: Props): JSX.Element {
|
||||
const buttonRef = useRef<HTMLButtonElement>();
|
||||
const toggle = useCallback(() => {
|
||||
onChange(!isSelected);
|
||||
});
|
||||
const { buttonProps } = useToggleButton(
|
||||
}, [isSelected, onChange]);
|
||||
|
||||
const buttonProps = useToggleButton(
|
||||
{ isSelected },
|
||||
{ toggle },
|
||||
{ isSelected: isSelected, setSelected: undefined, toggle },
|
||||
buttonRef
|
||||
);
|
||||
|
||||
return (
|
||||
<Field
|
||||
className={classNames(
|
||||
Reference in New Issue
Block a user