feat: first form field auto focused

This commit is contained in:
Sonny
2023-04-21 19:00:03 +02:00
parent 57317affbe
commit 05ab09f7bc
21 changed files with 1009 additions and 792 deletions

View File

@@ -1,57 +1,59 @@
import { MutableRefObject, useState } from 'react';
import { MutableRefObject, useState } from "react";
interface SelectorProps {
name: string;
label?: string;
labelComponent?: JSX.Element;
disabled?: boolean;
innerRef?: MutableRefObject<any>;
placeholder?: string;
fieldClass?: string;
isChecked?: boolean;
onChangeCallback?: (value, { target }) => void;
name: string;
label?: string;
labelComponent?: JSX.Element;
disabled?: boolean;
innerRef?: MutableRefObject<any>;
placeholder?: string;
fieldClass?: string;
isChecked?: boolean;
onChangeCallback?: (value, { target }) => void;
}
export default function Selector({
name,
label,
labelComponent,
disabled = false,
innerRef = null,
fieldClass = '',
placeholder = 'Type something...',
isChecked,
onChangeCallback
export default function Checkbox({
name,
label,
labelComponent,
disabled = false,
innerRef = null,
fieldClass = "",
placeholder = "Type something...",
isChecked,
onChangeCallback,
}: SelectorProps): JSX.Element {
const [checkboxValue, setCheckboxValue] = useState<boolean>(isChecked);
const [checkboxValue, setCheckboxValue] = useState<boolean>(isChecked);
function onChange({ target }) {
setCheckboxValue(!checkboxValue);
if (onChangeCallback) {
onChangeCallback(!checkboxValue, { target });
}
function onChange({ target }) {
setCheckboxValue(!checkboxValue);
if (onChangeCallback) {
onChangeCallback(!checkboxValue, { target });
}
}
return (<div className={`checkbox-field ${fieldClass}`}>
{label && (
<label htmlFor={name} title={`${name} field`}>
{label}
</label>
)}
{labelComponent && (
<label htmlFor={name} title={`${name} field`}>
{labelComponent}
</label>
)}
<input
type='checkbox'
id={name}
name={name}
onChange={onChange}
checked={checkboxValue}
placeholder={placeholder}
ref={innerRef}
disabled={disabled}
/>
</div>);
}
return (
<div className={`checkbox-field ${fieldClass}`}>
{label && (
<label htmlFor={name} title={`${name} field`}>
{label}
</label>
)}
{labelComponent && (
<label htmlFor={name} title={`${name} field`}>
{labelComponent}
</label>
)}
<input
type="checkbox"
id={name}
name={name}
onChange={onChange}
checked={checkboxValue}
placeholder={placeholder}
ref={innerRef}
disabled={disabled}
/>
</div>
);
}

View File

@@ -7,6 +7,9 @@ import styles from "../styles/create.module.scss";
interface FormProps {
title: string;
categoryId?: string;
errorMessage?: string;
successMessage?: string;
infoMessage?: string;
@@ -21,6 +24,7 @@ interface FormProps {
}
export default function Form({
title,
categoryId = undefined,
errorMessage,
successMessage,
infoMessage,
@@ -45,7 +49,9 @@ export default function Form({
{textBtnConfirm}
</button>
</form>
<Link href="/"> Revenir à l'accueil</Link>
<Link href={categoryId ? `/?categoryId=${categoryId}` : "/"}>
Revenir à l'accueil
</Link>
<MessageManager
info={infoMessage}
error={errorMessage}

View File

@@ -3,6 +3,7 @@ import { AiFillDelete, AiFillEdit } from "react-icons/ai";
import { Category } from "../../../types";
import { useEffect, useRef } from "react";
import styles from "./categories.module.scss";
interface CategoryItemProps {
@@ -11,19 +12,28 @@ interface CategoryItemProps {
handleSelectCategory: (category: Category) => void;
}
let rendered = false;
export default function CategoryItem({
category,
categoryActive,
handleSelectCategory,
}: CategoryItemProps): JSX.Element {
const ref = useRef<HTMLLIElement>();
const className = `${styles["item"]} ${
category.id === categoryActive.id ? styles["active"] : ""
}`;
const onClick = () => handleSelectCategory(category);
useEffect(() => {
if (category.id === categoryActive.id && !rendered) {
rendered = true;
ref.current.scrollIntoView({ behavior: "smooth" });
}
}, [category.id, categoryActive.id]);
return (
<li className={className} onClick={onClick}>
<div className={styles["content"]}>
<li className={className} ref={ref}>
<div className={styles["content"]} onClick={onClick}>
<span className={styles["name"]}>{category.name}</span>
<span className={styles["links-count"]}> {category.links.length}</span>
</div>
@@ -35,12 +45,17 @@ export default function CategoryItem({
function MenuOptions({ id }: { id: number }): JSX.Element {
return (
<div className={styles["menu-item"]}>
<LinkTag href={`/category/edit/${id}`} className={styles["option-edit"]}>
<LinkTag
href={`/category/edit/${id}`}
className={styles["option-edit"]}
onClick={(event) => event.stopPropagation()}
>
<AiFillEdit />
</LinkTag>
<LinkTag
href={`/category/remove/${id}`}
className={styles["option-remove"]}
onClick={(event) => event.stopPropagation()}
>
<AiFillDelete color="red" />
</LinkTag>

View File

@@ -29,7 +29,7 @@ export default function SideMenu({
<BlockWrapper>
<Favorites favorites={favorites} />
</BlockWrapper>
<BlockWrapper style={{ minHeight: "0" }}>
<BlockWrapper style={{ minHeight: "0", flex: "1" }}>
<Categories
categories={categories}
categoryActive={categoryActive}

View File

@@ -1,62 +1,64 @@
import { MutableRefObject, useState } from 'react';
import { MutableRefObject, useState } from "react";
interface InputProps {
name: string;
label?: string;
labelComponent?: JSX.Element;
disabled?: boolean;
type?: string;
multiple?: boolean;
innerRef?: MutableRefObject<any>;
placeholder?: string;
fieldClass?: string;
value?: string;
onChangeCallback?: (value) => void;
name: string;
label?: string;
labelComponent?: JSX.Element;
disabled?: boolean;
type?: string;
multiple?: boolean;
innerRef?: MutableRefObject<any> | ((ref: any) => void);
placeholder?: string;
fieldClass?: string;
value?: string;
onChangeCallback?: (value) => void;
}
export default function TextBox({
name,
label,
labelComponent,
disabled = false,
type = 'text',
multiple = false,
innerRef = null,
placeholder = 'Type something...',
fieldClass = '',
value,
onChangeCallback
name,
label,
labelComponent,
disabled = false,
type = "text",
multiple = false,
innerRef = null,
placeholder = "Type something...",
fieldClass = "",
value,
onChangeCallback,
}: InputProps): JSX.Element {
const [inputValue, setInputValue] = useState<string>(value);
const [inputValue, setInputValue] = useState<string>(value);
function onChange({ target }) {
setInputValue(target.value);
if (onChangeCallback) {
onChangeCallback(target.value);
}
function onChange({ target }) {
setInputValue(target.value);
if (onChangeCallback) {
onChangeCallback(target.value);
}
}
return (<div className={`input-field ${fieldClass}`}>
{label && (
<label htmlFor={name} title={`${name} field`}>
{label}
</label>
)}
{labelComponent && (
<label htmlFor={name} title={`${name} field`}>
{labelComponent}
</label>
)}
<input
id={name}
name={name}
type={type}
onChange={onChange}
value={inputValue}
multiple={multiple}
placeholder={placeholder}
ref={innerRef}
disabled={disabled}
/>
</div>);
}
return (
<div className={`input-field ${fieldClass}`}>
{label && (
<label htmlFor={name} title={`${name} field`}>
{label}
</label>
)}
{labelComponent && (
<label htmlFor={name} title={`${name} field`}>
{labelComponent}
</label>
)}
<input
id={name}
name={name}
type={type}
onChange={onChange}
value={inputValue}
multiple={multiple}
placeholder={placeholder}
ref={innerRef}
disabled={disabled}
/>
</div>
);
}