bigbuffet-rw/app/soapbox/components/ui/streamfield/streamfield.tsx

70 lines
1.7 KiB
TypeScript
Raw Normal View History

2022-05-02 19:10:47 -07:00
import React from 'react';
import Button from '../button/button';
2022-05-02 19:38:15 -07:00
import HStack from '../hstack/hstack';
import IconButton from '../icon-button/icon-button';
2022-05-02 19:10:47 -07:00
import Stack from '../stack/stack';
interface IStreamfield {
values: any[],
onAddItem?: () => void,
2022-05-02 19:38:15 -07:00
onRemoveItem?: (i: number) => void,
2022-05-02 19:10:47 -07:00
onChange: (values: any[]) => void,
component: React.ComponentType<{ onChange: (value: any) => void, value: any }>,
maxItems?: number,
}
/** List of inputs that can be added or removed. */
const Streamfield: React.FC<IStreamfield> = ({
values,
onAddItem,
2022-05-02 19:38:15 -07:00
onRemoveItem,
2022-05-02 19:10:47 -07:00
onChange,
component: Component,
maxItems = Infinity,
}) => {
const handleChange = (i: number) => {
return (value: any) => {
const newData = [...values];
newData[i] = value;
onChange(newData);
};
};
return (
<Stack space={4}>
<Stack>
2022-05-02 19:38:15 -07:00
{values.map((value, i) => (
<HStack space={2} alignItems='center'>
2022-05-02 19:10:47 -07:00
<Component key={i} onChange={handleChange(i)} value={value} />
2022-05-02 19:38:15 -07:00
{onRemoveItem && (
<IconButton
iconClassName='w-4 h-4'
className='bg-transparent text-gray-400 hover:text-gray-600'
src={require('@tabler/icons/icons/x.svg')}
onClick={() => onRemoveItem(i)}
/>
)}
</HStack>
))}
2022-05-02 19:10:47 -07:00
</Stack>
{onAddItem && (
<Button
icon={require('@tabler/icons/icons/plus.svg')}
onClick={onAddItem}
disabled={values.length >= maxItems}
theme='ghost'
block
>
Add
</Button>
)}
</Stack>
);
};
export default Streamfield;