From 0d96a4f973796322e6f5041fbc3b9424910ff8d1 Mon Sep 17 00:00:00 2001 From: Katalina Okano Date: Sat, 22 Jan 2022 22:07:11 -0500 Subject: [PATCH] feat(editor): add permalink section in editor --- .../atoms/copy-area/CopyArea.stories.tsx | 11 +++++ .../atoms/copy-area/CopyArea.styled.ts | 19 ++++++++ .../atoms/copy-area/CopyArea.tsx | 47 +++++++++++++++++++ .../design-system/atoms/copy-area/index.ts | 1 + .../atoms/text-input/TextInput.tsx | 3 +- .../EditorInviteLink.stories.tsx | 12 +++++ .../EditorInviteLink.styled.ts | 2 + .../editor-invite-link/EditorInviteLink.tsx | 26 ++++++++++ .../molecules/editor-invite-link/index.ts | 1 + .../organisms/editor-shell/EditorShell.tsx | 3 ++ packages/web/src/pages/servers.tsx | 2 +- 11 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 packages/design-system/atoms/copy-area/CopyArea.stories.tsx create mode 100644 packages/design-system/atoms/copy-area/CopyArea.styled.ts create mode 100644 packages/design-system/atoms/copy-area/CopyArea.tsx create mode 100644 packages/design-system/atoms/copy-area/index.ts create mode 100644 packages/design-system/molecules/editor-invite-link/EditorInviteLink.stories.tsx create mode 100644 packages/design-system/molecules/editor-invite-link/EditorInviteLink.styled.ts create mode 100644 packages/design-system/molecules/editor-invite-link/EditorInviteLink.tsx create mode 100644 packages/design-system/molecules/editor-invite-link/index.ts diff --git a/packages/design-system/atoms/copy-area/CopyArea.stories.tsx b/packages/design-system/atoms/copy-area/CopyArea.stories.tsx new file mode 100644 index 0000000..0a0b834 --- /dev/null +++ b/packages/design-system/atoms/copy-area/CopyArea.stories.tsx @@ -0,0 +1,11 @@ +import { CopyArea } from './CopyArea'; + +export default { + title: 'Atoms/Copy Area', + component: CopyArea, + args: { + value: 'Hello world', + }, +}; + +export const copyArea = (args) => ; diff --git a/packages/design-system/atoms/copy-area/CopyArea.styled.ts b/packages/design-system/atoms/copy-area/CopyArea.styled.ts new file mode 100644 index 0000000..8b804b4 --- /dev/null +++ b/packages/design-system/atoms/copy-area/CopyArea.styled.ts @@ -0,0 +1,19 @@ +import { palette } from '@roleypoly/design-system/atoms/colors'; +import { StyledTextInput } from '@roleypoly/design-system/atoms/text-input'; +import styled, { css } from 'styled-components'; + +export const CopyAreaStyled = styled.div` + cursor: pointer; +`; + +export const CopyAreaTextInput = styled(StyledTextInput)<{ copied?: boolean }>` + margin: 0.5em 0; + cursor: pointer; + font-size: 1em; + ${({ copied }) => + copied && + css` + border-color: ${palette.green400} !important; + box-shadow: inset 0 0 2px ${palette.green200} !important; + `} +`; diff --git a/packages/design-system/atoms/copy-area/CopyArea.tsx b/packages/design-system/atoms/copy-area/CopyArea.tsx new file mode 100644 index 0000000..3435abf --- /dev/null +++ b/packages/design-system/atoms/copy-area/CopyArea.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import ReactTooltip from 'react-tooltip'; +import { CopyAreaStyled, CopyAreaTextInput } from './CopyArea.styled'; + +type CopyAreaProps = { + value: string; +}; + +enum CopyState { + NotCopied = 0, + Copied = 1, +} + +export const CopyArea = (props: CopyAreaProps) => { + const [copied, setCopied] = React.useState(CopyState.NotCopied); + + const inputRef = React.useRef(null); + + const handleClick = () => { + inputRef.current?.setSelectionRange(0, 99999); + + if (navigator.clipboard) { + navigator.clipboard.writeText(props.value); + setCopied(CopyState.Copied); + } + }; + + const strings = { + [CopyState.NotCopied]: `Press ⌘/Ctrl+C to copy`, + [CopyState.Copied]: 'Copied to clipboard!', + }; + + return ( + + setCopied(CopyState.NotCopied)} + copied={copied === CopyState.Copied} + data-tip={strings[copied]} + data-for={'copy-area'} + /> + + + ); +}; diff --git a/packages/design-system/atoms/copy-area/index.ts b/packages/design-system/atoms/copy-area/index.ts new file mode 100644 index 0000000..56e15c7 --- /dev/null +++ b/packages/design-system/atoms/copy-area/index.ts @@ -0,0 +1 @@ +export * from './CopyArea'; diff --git a/packages/design-system/atoms/text-input/TextInput.tsx b/packages/design-system/atoms/text-input/TextInput.tsx index 9bfbec3..e19c5bd 100644 --- a/packages/design-system/atoms/text-input/TextInput.tsx +++ b/packages/design-system/atoms/text-input/TextInput.tsx @@ -40,7 +40,7 @@ const common = css` } `; -const StyledTextInput = styled.input` +export const StyledTextInput = styled.input` ${common}; `; @@ -89,6 +89,7 @@ export const TextInputWithIcon = (props: TextInputWithIconProps) => { const StyledTextarea = styled.textarea` ${common}; ${fontCSS}; + margin: 0.5em 0; `; export const MultilineTextInput = ( diff --git a/packages/design-system/molecules/editor-invite-link/EditorInviteLink.stories.tsx b/packages/design-system/molecules/editor-invite-link/EditorInviteLink.stories.tsx new file mode 100644 index 0000000..e2cdea4 --- /dev/null +++ b/packages/design-system/molecules/editor-invite-link/EditorInviteLink.stories.tsx @@ -0,0 +1,12 @@ +import { mastheadSlugs } from '../../fixtures/storyData'; +import { EditorInviteLink } from './EditorInviteLink'; + +export default { + title: 'Molecules/Editor Invite Link', + component: EditorInviteLink, + args: { + guild: mastheadSlugs[0], + }, +}; + +export const editorInviteLink = (args) => ; diff --git a/packages/design-system/molecules/editor-invite-link/EditorInviteLink.styled.ts b/packages/design-system/molecules/editor-invite-link/EditorInviteLink.styled.ts new file mode 100644 index 0000000..13e9543 --- /dev/null +++ b/packages/design-system/molecules/editor-invite-link/EditorInviteLink.styled.ts @@ -0,0 +1,2 @@ +import styled from 'styled-components'; +export const EditorInviteLinkStyled = styled.div``; diff --git a/packages/design-system/molecules/editor-invite-link/EditorInviteLink.tsx b/packages/design-system/molecules/editor-invite-link/EditorInviteLink.tsx new file mode 100644 index 0000000..9ba2f48 --- /dev/null +++ b/packages/design-system/molecules/editor-invite-link/EditorInviteLink.tsx @@ -0,0 +1,26 @@ +import { palette } from '@roleypoly/design-system/atoms/colors'; +import { CopyArea } from '@roleypoly/design-system/atoms/copy-area'; +import { AmbientLarge } from '@roleypoly/design-system/atoms/typography'; +import { MessageBox } from '@roleypoly/design-system/organisms/role-picker/RolePicker.styled'; +import { Guild } from '@roleypoly/types'; +import { GoInfo } from 'react-icons/go'; + +export const EditorInviteLink = (props: { guild: Guild }) => { + const currentURL = new URL(location.href); + currentURL.pathname = `/s/${props.guild.id}`; + currentURL.search = ''; + + const inviteLink = currentURL.toString(); + + return ( + + Share this link with your server members, or ping{' '} + @roleypoly in your server. + + + +  This link will never change. Share it with anyone! + + + ); +}; diff --git a/packages/design-system/molecules/editor-invite-link/index.ts b/packages/design-system/molecules/editor-invite-link/index.ts new file mode 100644 index 0000000..7ff1745 --- /dev/null +++ b/packages/design-system/molecules/editor-invite-link/index.ts @@ -0,0 +1 @@ +export * from './EditorInviteLink'; diff --git a/packages/design-system/organisms/editor-shell/EditorShell.tsx b/packages/design-system/organisms/editor-shell/EditorShell.tsx index 4f6575c..ba28f60 100644 --- a/packages/design-system/organisms/editor-shell/EditorShell.tsx +++ b/packages/design-system/organisms/editor-shell/EditorShell.tsx @@ -1,5 +1,6 @@ import { LinedSpace, Space } from '@roleypoly/design-system/atoms/space'; import { EditableServerMessage } from '@roleypoly/design-system/molecules/editable-server-message'; +import { EditorInviteLink } from '@roleypoly/design-system/molecules/editor-invite-link'; import { ServerMasthead } from '@roleypoly/design-system/molecules/server-masthead'; import { ServerUtilities } from '@roleypoly/design-system/molecules/server-utilities/ServerUtilities'; import { SecondaryEditing } from '@roleypoly/design-system/organisms/masthead'; @@ -60,6 +61,8 @@ export const EditorShell = (props: EditorShellProps) => { + + { return ( <> - + <Title title={'Your Servers - Roleypoly'} /> <ServersTemplate {...appShellProps} /> </> );