Added dropdownAction

This commit is contained in:
Meliora Ho 2024-04-02 21:17:13 +00:00
parent 908cc07683
commit f97783b9b5
5 changed files with 93 additions and 51 deletions

View File

@ -35,13 +35,13 @@ export const Table = () => {
cell: (info) => <RowAction title={info.getValue()} />,
}),
columnHelper.accessor("role", {
cell: (info) => <TagsInput />,
cell: (info) => <TagsInput presetValue={info.getValue()} presetOptions={["Administrator","Employee","Volunteer"]} />,
}),
columnHelper.accessor("email", {
cell: (info) => info.renderValue(),
}),
columnHelper.accessor("program", {
cell: (info) => info.renderValue(),
cell: (info) => <TagsInput presetValue={info.getValue()} presetOptions={["Domestic","Economic","Community"]} />,
}),
];

View File

@ -0,0 +1,41 @@
import { EllipsisHorizontalIcon } from "@heroicons/react/24/solid";
import { useState } from "react";
export const DropdownAction = ({ tag }) => {
const [isVisible, setVisible] = useState(false);
const [inputValue, setInputValue] = useState(tag);
const handleBlur = () => {
setVisible(false);
};
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
};
const handleClick = (event: React.MouseEvent<SVGSVGElement, MouseEvent>) => {
event.stopPropagation(); // This stops the click event from propagating
setVisible(!isVisible); // Toggle visibility
};
return (
<div>
{isVisible ? (
<div className="absolute z-50 bg-white">
<input
type="text"
value={inputValue}
onChange={handleInputChange}
onBlur={handleBlur}
autoFocus
/>
</div>
) : (
<EllipsisHorizontalIcon
className="w-5 text-gray-500"
onClick={handleClick} // Attach the click event handler here
/>
)}
</div>
);
};

View File

@ -1,29 +1,30 @@
// In a file TagsInput.tsx
import { useState } from 'react';
import React, { useState } from 'react';
import 'tailwindcss/tailwind.css';
import {TagsArray} from './TagsArray'; // Assuming this is the correct path
import { TagsArray } from './TagsArray'; // Corrected path assumption
import { TagDropdown } from './TagDropdown';
const TagsInput = () => {
interface TagsInputProps {
presetOptions: string[];
}
const TagsInput: React.FC<TagsInputProps> = ({ presetValue, presetOptions }) => {
const [inputValue, setInputValue] = useState('');
const [cellSelected, setCellSelected] = useState(false);
const [tags, setTags] = useState<string[]>(['Administrator']);
const [options, setOptions] = useState<string[]>(["Administrators", "Employees", "Volunteers"]);
const [tags, setTags] = useState<string[]>([presetValue]);
const [options, setOptions] = useState<string[]>(presetOptions);
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(e.target.value);
};
// Function to handle adding new tags when enter is pressed
const handleAddTag = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter' && inputValue) {
setTags([...tags, inputValue]);
if (e.key === 'Enter' && inputValue.trim()) {
setTags(prevTags => [...prevTags, inputValue]);
setOptions(prevOptions => [...prevOptions, inputValue]);
setInputValue('');
}
};
// Function to handle deleting tags
const handleDeleteTag = (tagToDelete: string) => {
setTags(tags.filter(tag => tag !== tagToDelete));
};
@ -33,34 +34,30 @@ const TagsInput = () => {
};
return (
<div
className="w-full relative items-center cursor-pointer"
onClick={() => setCellSelected(true)}
>
<div className="w-50 cursor-pointer" onClick={() => setCellSelected(true)}>
{!cellSelected ? (
<TagsArray tags={tags} />
<TagsArray tags={tags} />
) : (
<div className="absolute z-50 object-top">
<div className="rounded-md border border-gray-200 shadow">
<div className="flex flex-wrap rounded-t-md items-center gap-2 bg-gray-50 p-2">
<TagsArray active={true} tags={tags} />
<input
type="text"
value={inputValue}
placeholder="Search for an option..."
onChange={handleInputChange}
onKeyDown={handleAddTag}
onBlur={handleBlur}
className="focus:outline-none bg-transparent"
autoFocus
/>
</div>
<div className="flex rounded-b-md bg-white flex-col border-t border-gray-100 text-2xs font-medium text-gray-500 p-2">
Select an option or create one
<TagDropdown tags={options} />
<div className="absolute z-50 -mt-6">
<div className="rounded-md border border-gray-200 shadow">
<div className="flex flex-wrap rounded-t-md items-center gap-2 bg-gray-50 p-2">
<TagsArray active tags={tags} />
<input
type="text"
value={inputValue}
placeholder="Search for an option..."
onChange={handleInputChange}
onKeyDown={handleAddTag}
onBlur={handleBlur}
className="focus:outline-none bg-transparent"
autoFocus
/>
</div>
</div>
<div className="flex rounded-b-md bg-white flex-col border-t border-gray-100 text-2xs font-medium text-gray-500 p-2">
Select an option or create one
<TagDropdown tags={options} />
</div>
</div>
</div>
)}
</div>

View File

@ -1,6 +1,9 @@
import { XMarkIcon } from "@heroicons/react/24/solid"
export const Tag = ({children, active = false}) => {
const handleClick = () => {
}
return (
<span className="font-normal text-gray-800 flex flex-row p-1 px-2 rounded-lg bg-blue-100">{children}
{active && <XMarkIcon className="ml-1 w-3 text-blue-500" />}

View File

@ -1,15 +1,16 @@
import { EllipsisHorizontalIcon } from "@heroicons/react/24/solid"
import { Tag } from "./Tag"
export const TagDropdown = ({tags}) => {
return (
<div className="flex flex-col space-y-2 mt-2">
{tags.map((tag) => {
return <div className="rounded-md p-1 flex flex-row justify-between hover:bg-gray-100"><Tag>{tag}</Tag><EllipsisHorizontalIcon className="w-5 text-gray-500" /></div>
})}
import { Tag } from "./Tag";
import { DropdownAction } from "./DropdownAction";
export const TagDropdown = ({ tags }) => {
return (
<div className="flex flex-col space-y-2 mt-2">
{tags.map((tag, index) => (
<div key={index} className="items-center rounded-md p-1 flex flex-row justify-between hover:bg-gray-100">
<Tag>{tag}</Tag>
<DropdownAction tag={tag} />
</div>
)
}
))}
</div>
);
};