From ac77a0ada25b927744114e7c6492a7d817b8d13d Mon Sep 17 00:00:00 2001
From: Szymon Szlachtowicz <38212223+Szymx95@users.noreply.github.com>
Date: Wed, 3 Nov 2021 00:43:06 +0100
Subject: [PATCH] Refactor dropdowns (#109)
---
.../src/components/Form/ChannelMenu.tsx | 116 ++++--------------
.../src/components/Form/DropdownMenu.tsx | 61 +++++++++
.../src/components/Form/ImageMenu.tsx | 56 +++------
.../src/components/Icons/CopyIcon.tsx | 23 +++-
.../src/components/Icons/DownloadIcon.tsx | 23 +++-
5 files changed, 136 insertions(+), 143 deletions(-)
create mode 100644 packages/react-chat/src/components/Form/DropdownMenu.tsx
diff --git a/packages/react-chat/src/components/Form/ChannelMenu.tsx b/packages/react-chat/src/components/Form/ChannelMenu.tsx
index 06fece52..bfd1d3ce 100644
--- a/packages/react-chat/src/components/Form/ChannelMenu.tsx
+++ b/packages/react-chat/src/components/Form/ChannelMenu.tsx
@@ -1,5 +1,4 @@
import React from "react";
-import styled from "styled-components";
import { useMessengerContext } from "../../contexts/messengerProvider";
import { useNarrow } from "../../contexts/narrowProvider";
@@ -9,22 +8,8 @@ import { CheckSvg } from "../Icons/CheckIcon";
import { ClearSvg } from "../Icons/ClearIcon";
import { MembersSmallSvg } from "../Icons/MembersSmallIcon";
import { MuteSvg } from "../Icons/MuteIcon";
-import { textSmallStyles } from "../Text";
-type MenuItemProps = {
- Svg: ({ width, height }: { width: number; height: number }) => JSX.Element;
- text: string;
- onClick: () => void;
-};
-
-function MenuItem({ Svg, text, onClick }: MenuItemProps) {
- return (
- -
-
- {text}
-
- );
-}
+import { DropdownMenu, MenuItem, MenuText } from "./DropdownMenu";
interface ChannelMenuProps {
channel: ChannelData;
@@ -43,82 +28,35 @@ export const ChannelMenu = ({
const { clearNotifications } = useMessengerContext();
return (
-
-
- {narrow && (
-
-
+ >
+
+ View Members
+
+ )}
+ {
+ channel.isMuted = true;
+ setShowChannelMenu(false);
+ }}
+ >
+
+ Mute Chat
+
+ clearNotifications(channel.id)}>
+
+ Mark as Read
+
+ messages.length === 0}>
+
+ Clear History
+
+
);
};
-
-const MenuBlock = styled.div`
- width: 207px;
- background: ${({ theme }) => theme.bodyBackgroundColor};
- box-shadow: 0px 2px 4px rgba(0, 34, 51, 0.16),
- 0px 4px 12px rgba(0, 34, 51, 0.08);
- borderradius: 8px;
- padding: 8px 0;
- position: absolute;
- right: 8px;
- top: calc(100% - 8px);
- z-index: 2;
-`;
-
-const MenuList = styled.ul`
- list-style: none;
-`;
-
-const Item = styled.li`
- width: 100%;
- display: flex;
- align-items: center;
- padding: 8px 14px;
- cursor: pointer;
- color: ${({ theme }) => theme.primary};
-
- &:hover {
- background: ${({ theme }) => theme.tertiary};
- color: ${({ theme }) => theme.bodyBackgroundColor};
- }
-
- & > svg {
- fill: ${({ theme }) => theme.tertiary};
- }
-
- &:hover > svg {
- fill: ${({ theme }) => theme.bodyBackgroundColor};
- }
-`;
-
-const MenuText = styled.span`
- margin-left: 6px;
-
- ${textSmallStyles}
-`;
diff --git a/packages/react-chat/src/components/Form/DropdownMenu.tsx b/packages/react-chat/src/components/Form/DropdownMenu.tsx
new file mode 100644
index 00000000..5d468225
--- /dev/null
+++ b/packages/react-chat/src/components/Form/DropdownMenu.tsx
@@ -0,0 +1,61 @@
+import React, { ReactNode } from "react";
+import styled from "styled-components";
+
+import { textSmallStyles } from "../Text";
+
+type DropdownMenuProps = {
+ children: ReactNode;
+ className?: string;
+};
+
+export function DropdownMenu({ children, className }: DropdownMenuProps) {
+ return (
+
+ {children}
+
+ );
+}
+
+export const MenuItem = styled.li`
+ width: 100%;
+ display: flex;
+ align-items: center;
+ padding: 8px 14px;
+ cursor: pointer;
+ color: ${({ theme }) => theme.primary};
+
+ &:hover {
+ background: ${({ theme }) => theme.tertiary};
+ color: ${({ theme }) => theme.bodyBackgroundColor};
+ }
+
+ & > svg {
+ fill: ${({ theme }) => theme.tertiary};
+ }
+
+ &:hover > svg {
+ fill: ${({ theme }) => theme.bodyBackgroundColor};
+ }
+`;
+
+export const MenuText = styled.span`
+ margin-left: 6px;
+
+ ${textSmallStyles}
+`;
+const MenuBlock = styled.div`
+ width: 207px;
+ background: ${({ theme }) => theme.bodyBackgroundColor};
+ box-shadow: 0px 2px 4px rgba(0, 34, 51, 0.16),
+ 0px 4px 12px rgba(0, 34, 51, 0.08);
+ border-radius: 8px;
+ padding: 8px 0;
+ position: absolute;
+ right: 8px;
+ top: calc(100% - 8px);
+ z-index: 2;
+`;
+
+const MenuList = styled.ul`
+ list-style: none;
+`;
diff --git a/packages/react-chat/src/components/Form/ImageMenu.tsx b/packages/react-chat/src/components/Form/ImageMenu.tsx
index 7b2400c1..e50a8c65 100644
--- a/packages/react-chat/src/components/Form/ImageMenu.tsx
+++ b/packages/react-chat/src/components/Form/ImageMenu.tsx
@@ -4,9 +4,10 @@ import styled from "styled-components";
import { useContextMenu } from "../../hooks/useContextMenu";
import { copyImg } from "../../utils/copyImg";
import { downloadImg } from "../../utils/downloadImg";
-import { CopyIcon } from "../Icons/CopyIcon";
-import { DownloadIcon } from "../Icons/DownloadIcon";
-import { textSmallStyles } from "../Text";
+import { CopySvg } from "../Icons/CopyIcon";
+import { DownloadSvg } from "../Icons/DownloadIcon";
+
+import { DropdownMenu, MenuItem, MenuText } from "./DropdownMenu";
interface ImageMenuProps {
imageId: string;
@@ -16,51 +17,22 @@ export const ImageMenu = ({ imageId }: ImageMenuProps) => {
const { showMenu } = useContextMenu(imageId);
return showMenu ? (
-
-
- copyImg(imageId)}>
- Copy image
-
- downloadImg(imageId)}>
-
- Download image
-
-
-
+
+ copyImg(imageId)}>
+ Copy image
+
+ downloadImg(imageId)}>
+
+ Download image
+
+
) : (
<>>
);
};
-const MenuBlock = styled.div`
+const ImageDropdown = styled(DropdownMenu)`
width: 176px;
- height: 84px;
- background: ${({ theme }) => theme.bodyBackgroundColor};
- box-shadow: 0px 2px 4px rgba(0, 34, 51, 0.16),
- 0px 4px 12px rgba(0, 34, 51, 0.08);
- border-radius: 8px;
- padding: 8px 0;
- position: absolute;
left: 120px;
top: 46px;
- z-index: 2;
-`;
-
-const MenuList = styled.ul`
- list-style: none;
-`;
-
-const MenuItem = styled.li`
- width: 100%;
- display: flex;
- align-items: center;
- padding: 8px 14px;
- cursor: pointer;
-`;
-
-const MenuText = styled.span`
- margin-left: 6px;
- color: ${({ theme }) => theme.primary};
-
- ${textSmallStyles}
`;
diff --git a/packages/react-chat/src/components/Icons/CopyIcon.tsx b/packages/react-chat/src/components/Icons/CopyIcon.tsx
index 3455faa4..1f4a901b 100644
--- a/packages/react-chat/src/components/Icons/CopyIcon.tsx
+++ b/packages/react-chat/src/components/Icons/CopyIcon.tsx
@@ -1,13 +1,20 @@
import React from "react";
import styled from "styled-components";
-export const CopyIcon = () => {
+type CopySvgProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function CopySvg({ width, height, className }: CopySvgProps) {
return (
-
{
clipRule="evenodd"
d="M6.00016 4.00065C6.00016 2.52789 7.19407 1.33398 8.66683 1.33398H12.0002C13.4729 1.33398 14.6668 2.52789 14.6668 4.00065V7.33398C14.6668 8.80674 13.4729 10.0007 12.0002 10.0007H8.66683C7.19407 10.0007 6.00016 8.80674 6.00016 7.33398V4.00065ZM8.66683 2.33398H12.0002C12.9206 2.33398 13.6668 3.08018 13.6668 4.00065V7.33398C13.6668 8.25446 12.9206 9.00065 12.0002 9.00065H8.66683C7.74636 9.00065 7.00016 8.25446 7.00016 7.33398V4.00065C7.00016 3.08018 7.74636 2.33398 8.66683 2.33398Z"
/>
-
+
);
+}
+
+export const CopyIcon = () => {
+ return ;
};
-const Icon = styled.svg`
+const Icon = styled(CopySvg)`
& > path {
fill: ${({ theme }) => theme.tertiary};
}
diff --git a/packages/react-chat/src/components/Icons/DownloadIcon.tsx b/packages/react-chat/src/components/Icons/DownloadIcon.tsx
index c1afdaa8..3d63c1af 100644
--- a/packages/react-chat/src/components/Icons/DownloadIcon.tsx
+++ b/packages/react-chat/src/components/Icons/DownloadIcon.tsx
@@ -1,21 +1,32 @@
import React from "react";
import styled from "styled-components";
-export const DownloadIcon = () => {
+type DownloadSvgProps = {
+ width: number;
+ height: number;
+ className?: string;
+};
+
+export function DownloadSvg({ width, height, className }: DownloadSvgProps) {
return (
-
-
+
);
+}
+
+export const DownloadIcon = () => {
+ return ;
};
-const Icon = styled.svg`
+const Icon = styled(DownloadSvg)`
& > path {
fill: ${({ theme }) => theme.tertiary};
}