#307 - List field

This commit is contained in:
Elio Struyf
2022-06-02 09:19:06 +02:00
parent daeaf0a59d
commit bd2860e225
7 changed files with 161 additions and 10 deletions
@@ -0,0 +1,126 @@
import { PencilIcon, TrashIcon, ViewListIcon } from '@heroicons/react/outline';
import * as React from 'react';
import { useCallback, useRef } from 'react';
import { VsLabel } from '../VscodeComponents';
export interface IListFieldProps {
label: string;
value: string[] | null;
onChange: (value: string | string[]) => void;
}
export const ListField: React.FunctionComponent<IListFieldProps> = ({ label, value, onChange }: React.PropsWithChildren<IListFieldProps>) => {
const [ text, setText ] = React.useState<string | null>("");
const [ list, setList ] = React.useState<string[] | null>(value);
const [ itemToEdit, setItemToEdit ] = React.useState<number | null>(null);
const inputRef = useRef<HTMLInputElement>(null);
const onTextChange = (txtValue: string) => {
setText(txtValue);
// onChange(txtValue);
};
const onSaveForm = useCallback(() => {
if (itemToEdit !== null) {
if (list && text) {
const newList = [...(list || [])];
newList[itemToEdit] = text;
setList(newList);
onChange(newList);
}
} else {
if (text) {
const newList = list ? [ ...list, text ] : [ text ];
setList(newList);
onChange(newList);
}
}
onCancelForm();
}, [list, text]);
const onEdit = useCallback((index: number) => {
setItemToEdit(index);
setText(list ? list[index] : "");
inputRef.current?.focus();
}, [list]);
const onCancelForm = useCallback(() => {
setText("");
setItemToEdit(null);
}, []);
const onDelete = useCallback((index: number) => {
if (list) {
const newList = [...list];
newList.splice(index, 1);
setList(newList);
onChange(newList);
}
}, [list]);
let isValid = true;
return (
<div className={`list_field`}>
<VsLabel>
<div className={`metadata_field__label`}>
<ViewListIcon style={{ width: "16px", height: "16px" }} /> <span style={{ lineHeight: "16px"}}>{label}</span>
</div>
</VsLabel>
<input
ref={inputRef}
className={`metadata_field__input`}
value={text || ""}
onChange={(e) => onTextChange(e.currentTarget.value)}
onKeyDown={(e) => {
if (e.key === "Enter") {
onSaveForm();
}
}}
style={{
border: isValid ? "1px solid var(--vscode-inputValidation-infoBorder)" : "1px solid var(--vscode-inputValidation-warningBorder)"
}} />
<div className={`list_field__form__buttons`}>
<button
className={`list_field__form__button__save`}
title={`Save`}
onClick={onSaveForm}
disabled={!text}>
{itemToEdit !== null ? `Update` : `Add`}
</button>
<button
className={`list_field__form__button__cancel`}
title={`Cancel`}
onClick={onCancelForm}>
Cancel
</button>
</div>
<ul className='list_field__list'>
{
list && list.map((item, index) => (
<li className='list_field__list__item' key={index}>
<div>
{item}
</div>
<div>
<button title='Edit record' className='list_field__list__button list_field__list__button_edit' onClick={() => onEdit(index)}>
<PencilIcon className='list_field__list__button_icon' />
<span className='sr-only'>Edit</span>
</button>
<button title='Delete record' className='list_field__list__button list_field__list__button_delete' onClick={() => onDelete(index)}>
<TrashIcon className='list_field__list__button_icon' />
<span className='sr-only'>Delete</span>
</button>
</div>
</li>
))
}
</ul>
</div>
);
};
@@ -21,6 +21,7 @@ import { DataFileField } from './DataFileField';
import { DateTimeField } from './DateTimeField';
import { DraftField } from './DraftField';
import { FileField } from './FileField';
import { ListField } from './ListField';
import { NumberField } from './NumberField';
import { PreviewImageField, PreviewImageValue } from './PreviewImageField';
import { TextField } from './TextField';
@@ -360,6 +361,15 @@ export const WrapperField: React.FunctionComponent<IWrapperFieldProps> = ({
onChange={(value => onSendUpdate(field.name, value, parentFields))} />
</FieldBoundary>
);
} else if (field.type === 'list') {
return (
<FieldBoundary key={field.name} fieldName={field.title || field.name}>
<ListField
label={field.title || field.name}
value={fieldValue}
onChange={(value => onSendUpdate(field.name, value, parentFields))} />
</FieldBoundary>
);
} else {
console.warn(`Unknown field type: ${field.type}`);
return null;