45 lines
1.4 KiB
TypeScript
45 lines
1.4 KiB
TypeScript
import { Icon } from '@iconify/react/dist/iconify.js';
|
|
import { isEmpty } from 'lodash-es';
|
|
import { useRef, useState } from 'react';
|
|
import styles from './EditableTitle.module.css';
|
|
|
|
type EditableTitleProps = {
|
|
title: string;
|
|
onChange?: (newTitle: string) => void;
|
|
};
|
|
|
|
export function EditableTitle({ title, onChange }: EditableTitleProps) {
|
|
const [isEditing, setIsEditing] = useState(false);
|
|
const formRef = useRef<HTMLFormElement>(null);
|
|
const cancelEdit = () => {
|
|
setIsEditing(false);
|
|
formRef.current?.reset();
|
|
};
|
|
const handleSubmit = (data: FormData) => {
|
|
const newTitle = data.get('title') as string;
|
|
if (!isEmpty(newTitle) && newTitle !== title) {
|
|
onChange?.(newTitle);
|
|
}
|
|
cancelEdit();
|
|
};
|
|
|
|
return isEditing ? (
|
|
<form className={styles.editable_layout} action={handleSubmit} ref={formRef}>
|
|
<input type="text" name="title" defaultValue={title} />
|
|
<div className="action_icon success" onClick={() => formRef.current?.requestSubmit()}>
|
|
<Icon icon="tabler:check" />
|
|
</div>
|
|
<div className="action_icon danger" onClick={cancelEdit}>
|
|
<Icon icon="tabler:x" />
|
|
</div>
|
|
</form>
|
|
) : (
|
|
<div className={styles.editable_layout}>
|
|
<h3>{title}</h3>
|
|
<div className="action_icon" onClick={() => setIsEditing(true)}>
|
|
<Icon icon="tabler:edit" />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|