better looking dropdown component
This commit is contained in:
parent
d2051a67ab
commit
577b279108
|
@ -4,11 +4,7 @@
|
||||||
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import {
|
import { faEllipsis } from "@fortawesome/free-solid-svg-icons";
|
||||||
faPenToSquare,
|
|
||||||
faTrashCan,
|
|
||||||
faEllipsis,
|
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { CollectionIncludingMembers } from "@/types/global";
|
import { CollectionIncludingMembers } from "@/types/global";
|
||||||
import useLinkStore from "@/store/links";
|
import useLinkStore from "@/store/links";
|
||||||
|
@ -50,12 +46,12 @@ export default function ({
|
||||||
<div className="bg-gradient-to-tr from-sky-100 from-10% via-gray-100 via-20% self-stretch min-h-[12rem] rounded-md shadow duration-100 hover:shadow-none group relative">
|
<div className="bg-gradient-to-tr from-sky-100 from-10% via-gray-100 via-20% self-stretch min-h-[12rem] rounded-md shadow duration-100 hover:shadow-none group relative">
|
||||||
<div
|
<div
|
||||||
onClick={() => setExpandDropdown(!expandDropdown)}
|
onClick={() => setExpandDropdown(!expandDropdown)}
|
||||||
id="edit-dropdown"
|
id={"expand-dropdown" + collection.id}
|
||||||
className="inline-flex absolute top-5 right-5 rounded-md cursor-pointer hover:bg-white hover:border-sky-500 border-sky-100 border duration-100 p-1"
|
className="inline-flex absolute top-5 right-5 rounded-md cursor-pointer hover:bg-white hover:border-sky-500 border-sky-100 border duration-100 p-1"
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={faEllipsis}
|
icon={faEllipsis}
|
||||||
id="edit-dropdown"
|
id={"expand-dropdown" + collection.id}
|
||||||
className="w-5 h-5 text-gray-500"
|
className="w-5 h-5 text-gray-500"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -100,7 +96,6 @@ export default function ({
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
name: "Edit Collection",
|
name: "Edit Collection",
|
||||||
icon: <FontAwesomeIcon icon={faPenToSquare} />,
|
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
toggleEditCollectionModal();
|
toggleEditCollectionModal();
|
||||||
setExpandDropdown(false);
|
setExpandDropdown(false);
|
||||||
|
@ -108,7 +103,6 @@ export default function ({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Delete Collection",
|
name: "Delete Collection",
|
||||||
icon: <FontAwesomeIcon icon={faTrashCan} />,
|
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
toggleDeleteCollectionModal();
|
toggleDeleteCollectionModal();
|
||||||
setExpandDropdown(false);
|
setExpandDropdown(false);
|
||||||
|
@ -117,9 +111,10 @@ export default function ({
|
||||||
]}
|
]}
|
||||||
onClickOutside={(e: Event) => {
|
onClickOutside={(e: Event) => {
|
||||||
const target = e.target as HTMLInputElement;
|
const target = e.target as HTMLInputElement;
|
||||||
if (target.id !== "edit-dropdown") setExpandDropdown(false);
|
if (target.id !== "expand-dropdown" + collection.id)
|
||||||
|
setExpandDropdown(false);
|
||||||
}}
|
}}
|
||||||
className="absolute top-[3.2rem] right-5 z-10 w-44"
|
className="absolute top-[3.2rem] right-5 z-10 w-36"
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,6 @@ import {
|
||||||
faFolder,
|
faFolder,
|
||||||
faArrowUpRightFromSquare,
|
faArrowUpRightFromSquare,
|
||||||
faEllipsis,
|
faEllipsis,
|
||||||
faPenToSquare,
|
|
||||||
faTrashCan,
|
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import { faFileImage, faFilePdf } from "@fortawesome/free-regular-svg-icons";
|
import { faFileImage, faFilePdf } from "@fortawesome/free-regular-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
@ -124,14 +122,14 @@ export default function ({ link, count }: Props) {
|
||||||
<div className="flex flex-col justify-between items-end relative">
|
<div className="flex flex-col justify-between items-end relative">
|
||||||
<div
|
<div
|
||||||
onClick={() => setExpandDropdown(!expandDropdown)}
|
onClick={() => setExpandDropdown(!expandDropdown)}
|
||||||
id="edit-dropdown"
|
id="expand-dropdown"
|
||||||
className="text-gray-500 inline-flex rounded-md cursor-pointer hover:bg-white hover:outline outline-sky-100 outline-1 duration-100 p-1"
|
className="text-gray-500 inline-flex rounded-md cursor-pointer hover:bg-white hover:outline outline-sky-100 outline-1 duration-100 p-1"
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={faEllipsis}
|
icon={faEllipsis}
|
||||||
title="More"
|
title="More"
|
||||||
className="w-6 h-6"
|
className="w-6 h-6"
|
||||||
id="edit-dropdown"
|
id="expand-dropdown"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
|
@ -168,7 +166,6 @@ export default function ({ link, count }: Props) {
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
name: "Edit",
|
name: "Edit",
|
||||||
icon: <FontAwesomeIcon icon={faPenToSquare} />,
|
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setEditModal(true);
|
setEditModal(true);
|
||||||
setExpandDropdown(false);
|
setExpandDropdown(false);
|
||||||
|
@ -176,7 +173,6 @@ export default function ({ link, count }: Props) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Delete",
|
name: "Delete",
|
||||||
icon: <FontAwesomeIcon icon={faTrashCan} />,
|
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
removeLink(link);
|
removeLink(link);
|
||||||
setExpandDropdown(false);
|
setExpandDropdown(false);
|
||||||
|
@ -185,7 +181,7 @@ export default function ({ link, count }: Props) {
|
||||||
]}
|
]}
|
||||||
onClickOutside={(e: Event) => {
|
onClickOutside={(e: Event) => {
|
||||||
const target = e.target as HTMLInputElement;
|
const target = e.target as HTMLInputElement;
|
||||||
if (target.id !== "edit-dropdown") setExpandDropdown(false);
|
if (target.id !== "expand-dropdown") setExpandDropdown(false);
|
||||||
}}
|
}}
|
||||||
className="absolute top-8 right-0 w-36"
|
className="absolute top-8 right-0 w-36"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -4,15 +4,20 @@
|
||||||
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import React, { MouseEventHandler, ReactElement } from "react";
|
import React, { MouseEventHandler } from "react";
|
||||||
import ClickAwayHandler from "./ClickAwayHandler";
|
import ClickAwayHandler from "./ClickAwayHandler";
|
||||||
|
|
||||||
type MenuItem = {
|
type MenuItem =
|
||||||
name: string;
|
| {
|
||||||
icon: ReactElement;
|
name: string;
|
||||||
onClick?: MouseEventHandler;
|
onClick: MouseEventHandler;
|
||||||
href?: string;
|
href?: string;
|
||||||
};
|
}
|
||||||
|
| {
|
||||||
|
name: string;
|
||||||
|
onClick?: MouseEventHandler;
|
||||||
|
href: string;
|
||||||
|
};
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onClickOutside: Function;
|
onClickOutside: Function;
|
||||||
|
@ -20,20 +25,17 @@ type Props = {
|
||||||
items: MenuItem[];
|
items: MenuItem[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ({ onClickOutside, className, items }: Props) {
|
export default function Dropdown({ onClickOutside, className, items }: Props) {
|
||||||
return (
|
return (
|
||||||
<ClickAwayHandler
|
<ClickAwayHandler
|
||||||
onClickOutside={onClickOutside}
|
onClickOutside={onClickOutside}
|
||||||
className={`${className} border border-sky-100 shadow-md mb-5 bg-gray-50 rounded-md flex flex-col z-10`}
|
className={`${className} border border-sky-100 py-1 shadow-md bg-gray-50 rounded-md flex flex-col z-10`}
|
||||||
>
|
>
|
||||||
{items.map((e, i) => {
|
{items.map((e, i) => {
|
||||||
const inner = (
|
const inner = (
|
||||||
<div className="cursor-pointer rounded-md hover:bg-white hover:outline outline-sky-100 outline-1 duration-100">
|
<div className="cursor-pointer rounded-md">
|
||||||
<div className="flex items-center gap-2 p-2 rounded-md hover:opacity-60 duration-100">
|
<div className="flex items-center gap-2 py-1 px-2 hover:bg-sky-200 duration-100">
|
||||||
{React.cloneElement(e.icon, {
|
<p className="text-sky-900 select-none">{e.name}</p>
|
||||||
className: "text-sky-500 w-5 h-5",
|
|
||||||
})}
|
|
||||||
<p className="text-sky-900">{e.name}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,8 +8,6 @@ import {
|
||||||
faFolder,
|
faFolder,
|
||||||
faArrowUpRightFromSquare,
|
faArrowUpRightFromSquare,
|
||||||
faEllipsis,
|
faEllipsis,
|
||||||
faPenToSquare,
|
|
||||||
faTrashCan,
|
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import { faFileImage, faFilePdf } from "@fortawesome/free-regular-svg-icons";
|
import { faFileImage, faFilePdf } from "@fortawesome/free-regular-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
@ -124,14 +122,14 @@ export default function ({ link, count }: Props) {
|
||||||
<div className="flex flex-col justify-between items-end relative">
|
<div className="flex flex-col justify-between items-end relative">
|
||||||
<div
|
<div
|
||||||
onClick={() => setExpandDropdown(!expandDropdown)}
|
onClick={() => setExpandDropdown(!expandDropdown)}
|
||||||
id="edit-dropdown"
|
id={"expand-dropdown" + link.id}
|
||||||
className="text-gray-500 inline-flex rounded-md cursor-pointer hover:bg-white hover:outline outline-sky-100 outline-1 duration-100 p-1"
|
className="text-gray-500 inline-flex rounded-md cursor-pointer hover:bg-white hover:outline outline-sky-100 outline-1 duration-100 p-1"
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={faEllipsis}
|
icon={faEllipsis}
|
||||||
title="More"
|
title="More"
|
||||||
className="w-5 h-5"
|
className="w-5 h-5"
|
||||||
id="edit-dropdown"
|
id={"expand-dropdown" + link.id}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
|
@ -168,7 +166,6 @@ export default function ({ link, count }: Props) {
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
name: "Edit",
|
name: "Edit",
|
||||||
icon: <FontAwesomeIcon icon={faPenToSquare} />,
|
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setEditModal(true);
|
setEditModal(true);
|
||||||
setExpandDropdown(false);
|
setExpandDropdown(false);
|
||||||
|
@ -176,7 +173,6 @@ export default function ({ link, count }: Props) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Delete",
|
name: "Delete",
|
||||||
icon: <FontAwesomeIcon icon={faTrashCan} />,
|
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
removeLink(link);
|
removeLink(link);
|
||||||
setExpandDropdown(false);
|
setExpandDropdown(false);
|
||||||
|
@ -185,9 +181,10 @@ export default function ({ link, count }: Props) {
|
||||||
]}
|
]}
|
||||||
onClickOutside={(e: Event) => {
|
onClickOutside={(e: Event) => {
|
||||||
const target = e.target as HTMLInputElement;
|
const target = e.target as HTMLInputElement;
|
||||||
if (target.id !== "edit-dropdown") setExpandDropdown(false);
|
if (target.id !== "expand-dropdown" + link.id)
|
||||||
|
setExpandDropdown(false);
|
||||||
}}
|
}}
|
||||||
className="absolute top-8 right-0 w-36"
|
className="absolute top-7 right-0 w-36"
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,8 +8,6 @@ import { signOut } from "next-auth/react";
|
||||||
import {
|
import {
|
||||||
faPlus,
|
faPlus,
|
||||||
faCircleUser,
|
faCircleUser,
|
||||||
faSliders,
|
|
||||||
faArrowRightFromBracket,
|
|
||||||
faChevronDown,
|
faChevronDown,
|
||||||
faBars,
|
faBars,
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
@ -104,7 +102,6 @@ export default function () {
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
name: "Settings",
|
name: "Settings",
|
||||||
icon: <FontAwesomeIcon icon={faSliders} />,
|
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
toggleSettingsModal();
|
toggleSettingsModal();
|
||||||
setProfileDropdown(!profileDropdown);
|
setProfileDropdown(!profileDropdown);
|
||||||
|
@ -112,7 +109,6 @@ export default function () {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Logout",
|
name: "Logout",
|
||||||
icon: <FontAwesomeIcon icon={faArrowRightFromBracket} />,
|
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
signOut();
|
signOut();
|
||||||
setProfileDropdown(!profileDropdown);
|
setProfileDropdown(!profileDropdown);
|
||||||
|
|
|
@ -13,12 +13,9 @@ import useCollectionStore from "@/store/collections";
|
||||||
import useLinkStore from "@/store/links";
|
import useLinkStore from "@/store/links";
|
||||||
import { CollectionIncludingMembers } from "@/types/global";
|
import { CollectionIncludingMembers } from "@/types/global";
|
||||||
import {
|
import {
|
||||||
faAdd,
|
|
||||||
faEllipsis,
|
faEllipsis,
|
||||||
faFolder,
|
faFolder,
|
||||||
faPenToSquare,
|
|
||||||
faSort,
|
faSort,
|
||||||
faTrashCan,
|
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
@ -231,12 +228,12 @@ export default function () {
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div
|
<div
|
||||||
onClick={() => setExpandDropdown(!expandDropdown)}
|
onClick={() => setExpandDropdown(!expandDropdown)}
|
||||||
id="edit-dropdown"
|
id="expand-dropdown"
|
||||||
className="inline-flex rounded-md cursor-pointer hover:bg-white hover:border-sky-500 border-sky-100 border duration-100 p-1"
|
className="inline-flex rounded-md cursor-pointer hover:bg-white hover:border-sky-500 border-sky-100 border duration-100 p-1"
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={faEllipsis}
|
icon={faEllipsis}
|
||||||
id="edit-dropdown"
|
id="expand-dropdown"
|
||||||
title="More"
|
title="More"
|
||||||
className="w-5 h-5 text-gray-500"
|
className="w-5 h-5 text-gray-500"
|
||||||
/>
|
/>
|
||||||
|
@ -246,7 +243,6 @@ export default function () {
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
name: "Add Link Here",
|
name: "Add Link Here",
|
||||||
icon: <FontAwesomeIcon icon={faAdd} />,
|
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
toggleLinkModal();
|
toggleLinkModal();
|
||||||
setExpandDropdown(false);
|
setExpandDropdown(false);
|
||||||
|
@ -254,7 +250,17 @@ export default function () {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Edit Collection",
|
name: "Edit Collection",
|
||||||
icon: <FontAwesomeIcon icon={faPenToSquare} />,
|
onClick: () => {
|
||||||
|
toggleEditCollectionModal();
|
||||||
|
setExpandDropdown(false);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: `${
|
||||||
|
activeCollection?.ownerId === data?.user.id
|
||||||
|
? "Manage"
|
||||||
|
: "View"
|
||||||
|
} Team`,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
toggleEditCollectionModal();
|
toggleEditCollectionModal();
|
||||||
setExpandDropdown(false);
|
setExpandDropdown(false);
|
||||||
|
@ -262,7 +268,6 @@ export default function () {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Delete Collection",
|
name: "Delete Collection",
|
||||||
icon: <FontAwesomeIcon icon={faTrashCan} />,
|
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
toggleDeleteCollectionModal();
|
toggleDeleteCollectionModal();
|
||||||
setExpandDropdown(false);
|
setExpandDropdown(false);
|
||||||
|
@ -271,10 +276,10 @@ export default function () {
|
||||||
]}
|
]}
|
||||||
onClickOutside={(e: Event) => {
|
onClickOutside={(e: Event) => {
|
||||||
const target = e.target as HTMLInputElement;
|
const target = e.target as HTMLInputElement;
|
||||||
if (target.id !== "edit-dropdown")
|
if (target.id !== "expand-dropdown")
|
||||||
setExpandDropdown(false);
|
setExpandDropdown(false);
|
||||||
}}
|
}}
|
||||||
className="absolute top-8 right-0 z-10 w-44"
|
className="absolute top-8 right-0 z-10 w-36"
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
import useCollectionStore from "@/store/collections";
|
import useCollectionStore from "@/store/collections";
|
||||||
import {
|
import {
|
||||||
faAdd,
|
|
||||||
faBox,
|
faBox,
|
||||||
faEllipsis,
|
faEllipsis,
|
||||||
faPlus,
|
faPlus,
|
||||||
|
@ -95,12 +94,12 @@ export default function () {
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div
|
<div
|
||||||
onClick={() => setExpandDropdown(!expandDropdown)}
|
onClick={() => setExpandDropdown(!expandDropdown)}
|
||||||
id="edit-dropdown"
|
id="expand-dropdown"
|
||||||
className="inline-flex rounded-md cursor-pointer hover:bg-white hover:border-sky-500 border-sky-100 border duration-100 p-1"
|
className="inline-flex rounded-md cursor-pointer hover:bg-white hover:border-sky-500 border-sky-100 border duration-100 p-1"
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={faEllipsis}
|
icon={faEllipsis}
|
||||||
id="edit-dropdown"
|
id="expand-dropdown"
|
||||||
className="w-5 h-5 text-gray-500"
|
className="w-5 h-5 text-gray-500"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -109,8 +108,7 @@ export default function () {
|
||||||
<Dropdown
|
<Dropdown
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
name: "New",
|
name: "New Collection",
|
||||||
icon: <FontAwesomeIcon icon={faAdd} />,
|
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
toggleCollectionModal();
|
toggleCollectionModal();
|
||||||
setExpandDropdown(false);
|
setExpandDropdown(false);
|
||||||
|
@ -119,7 +117,8 @@ export default function () {
|
||||||
]}
|
]}
|
||||||
onClickOutside={(e: Event) => {
|
onClickOutside={(e: Event) => {
|
||||||
const target = e.target as HTMLInputElement;
|
const target = e.target as HTMLInputElement;
|
||||||
if (target.id !== "edit-dropdown") setExpandDropdown(false);
|
if (target.id !== "expand-dropdown")
|
||||||
|
setExpandDropdown(false);
|
||||||
}}
|
}}
|
||||||
className="absolute top-8 left-0 w-36"
|
className="absolute top-8 left-0 w-36"
|
||||||
/>
|
/>
|
||||||
|
|
Ŝarĝante…
Reference in New Issue