From 5e997044ed3a8b9818a2421e8880fd58e24c1ce6 Mon Sep 17 00:00:00 2001 From: muzam1l Date: Mon, 2 May 2022 21:05:18 +0530 Subject: [PATCH] alert dialog component --- components/AlertDialog/index.tsx | 72 +++++++++++++++++++ .../primitive.tsx} | 2 +- components/EditorNavigation.tsx | 71 +++++++----------- components/index.tsx | 2 +- pages/_app.tsx | 2 + pages/test/[[...slug]].tsx | 2 + state/actions/showAlert.ts | 19 +++++ 7 files changed, 124 insertions(+), 46 deletions(-) create mode 100644 components/AlertDialog/index.tsx rename components/{AlertDialog.tsx => AlertDialog/primitive.tsx} (97%) create mode 100644 state/actions/showAlert.ts diff --git a/components/AlertDialog/index.tsx b/components/AlertDialog/index.tsx new file mode 100644 index 0000000..f273d1d --- /dev/null +++ b/components/AlertDialog/index.tsx @@ -0,0 +1,72 @@ +import { FC, ReactNode } from "react"; +import { proxy, useSnapshot } from "valtio"; +import Button from "../Button"; +import Flex from "../Flex"; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogTitle, +} from "./primitive"; + +export interface AlertState { + isOpen: boolean; + title?: string; + body?: ReactNode; + cancelText?: string; + confirmNode?: ReactNode; + onConfirm?: () => any; + onCancel?: () => any; +} + +export const alertState = proxy({ + isOpen: false, +}); + +const Alert: FC = () => { + const { + title = "Are you sure?", + isOpen, + body, + cancelText, + confirmNode = "Ok", + onCancel, + onConfirm, + } = useSnapshot(alertState); + return ( + (alertState.isOpen = value)} + > + + {title} + {body} + + {cancelText && ( + + + + )} + + + + + + + ); +}; + +export default Alert; diff --git a/components/AlertDialog.tsx b/components/AlertDialog/primitive.tsx similarity index 97% rename from components/AlertDialog.tsx rename to components/AlertDialog/primitive.tsx index 4b38493..36b2e45 100644 --- a/components/AlertDialog.tsx +++ b/components/AlertDialog/primitive.tsx @@ -1,7 +1,7 @@ import React from "react"; import { blackA } from "@radix-ui/colors"; import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"; -import { styled, keyframes } from "../stitches.config"; +import { styled, keyframes } from "../../stitches.config"; const overlayShow = keyframes({ "0%": { opacity: 0 }, diff --git a/components/EditorNavigation.tsx b/components/EditorNavigation.tsx index b2cc15e..f99e3e1 100644 --- a/components/EditorNavigation.tsx +++ b/components/EditorNavigation.tsx @@ -50,15 +50,8 @@ import Stack from "./Stack"; import { Input, Label } from "./Input"; import Text from "./Text"; import Tooltip from "./Tooltip"; -import { - AlertDialog, - AlertDialogContent, - AlertDialogTitle, - AlertDialogDescription, - AlertDialogCancel, - AlertDialogAction, -} from "./AlertDialog"; import { styled } from "../stitches.config"; +import { showAlert } from "../state/actions/showAlert"; const ErrorText = styled(Text, { color: "$error", @@ -68,7 +61,6 @@ const ErrorText = styled(Text, { const EditorNavigation = ({ showWat }: { showWat?: boolean }) => { const snap = useSnapshot(state); - const [createNewAlertOpen, setCreateNewAlertOpen] = useState(false); const [editorSettingsOpen, setEditorSettingsOpen] = useState(false); const [isNewfileDialogOpen, setIsNewfileDialogOpen] = useState(false); const [newfileError, setNewfileError] = useState(null); @@ -87,13 +79,32 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => { setNewfileError(null); }, [filename, setNewfileError]); + const showNewGistAlert = () => { + showAlert("Are you sure?", { + body: ( + <> + This action will create new public Github Gist from + your current saved files. You can delete gist anytime from your GitHub + Gists page. + + ), + cancelText: "Cancel", + confirmNode: ( + <> + Create new Gist + + ), + onConfirm: () => syncToGist(session, true), + }); + }; + const validateFilename = useCallback( (filename: string): { error: string | null } => { // check if filename already exists if (!filename) { return { error: "You need to add filename" }; } - if (snap.files.find((file) => file.name === filename)) { + if (snap.files.find(file => file.name === filename)) { return { error: "Filename already exists." }; } @@ -225,8 +236,8 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => { setFilename(e.target.value)} - onKeyPress={(e) => { + onChange={e => setFilename(e.target.value)} + onKeyPress={e => { if (e.key === "Enter") { handleConfirm(); } @@ -416,7 +427,7 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => { if (snap.gistOwner === session?.user.username) { syncToGist(session); } else { - setCreateNewAlertOpen(true); + showNewGistAlert(); } }} > @@ -466,7 +477,7 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => { { - setCreateNewAlertOpen(true); + showNewGistAlert(); }} > Create as a new Gist @@ -486,34 +497,6 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => { ) : null} - setCreateNewAlertOpen(value)} - > - - Are you sure? - - This action will create new public Github Gist from - your current saved files. You can delete gist anytime from your - GitHub Gists page. - - - - - - - - - - - @@ -529,8 +512,8 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => { type="number" min="1" value={editorSettings.tabSize} - onChange={(e) => - setEditorSettings((curr) => ({ + onChange={e => + setEditorSettings(curr => ({ ...curr, tabSize: Number(e.target.value), })) diff --git a/components/index.tsx b/components/index.tsx index 6a17267..1fd4f87 100644 --- a/components/index.tsx +++ b/components/index.tsx @@ -7,7 +7,7 @@ export { default as Text } from "./Text"; export { default as Input, Label } from "./Input"; export { default as Select } from "./Select"; export * from "./Tabs"; -export * from "./AlertDialog"; +export * from "./AlertDialog/primitive"; export { default as Box } from "./Box"; export { default as Button } from "./Button"; export { default as Pre } from "./Pre"; diff --git a/pages/_app.tsx b/pages/_app.tsx index 8da9d51..773cc5d 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -16,6 +16,7 @@ import state from "../state"; import TimeAgo from "javascript-time-ago"; import en from "javascript-time-ago/locale/en.json"; import { useSnapshot } from "valtio"; +import Alert from '../components/AlertDialog'; TimeAgo.setDefaultLocale(en.locale); TimeAgo.addLocale(en); @@ -140,6 +141,7 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) { })(), }} /> + diff --git a/pages/test/[[...slug]].tsx b/pages/test/[[...slug]].tsx index 63e750b..7361a14 100644 --- a/pages/test/[[...slug]].tsx +++ b/pages/test/[[...slug]].tsx @@ -6,6 +6,8 @@ import Transaction from "../../components/Transaction"; import state from "../../state"; import { getSplit, saveSplit } from "../../state/actions/persistSplits"; import { transactionsState, modifyTransaction } from "../../state"; +import { useEffect } from 'react'; +import { showAlert } from '../../state/actions/showAlert'; const DebugStream = dynamic(() => import("../../components/DebugStream"), { ssr: false, diff --git a/state/actions/showAlert.ts b/state/actions/showAlert.ts new file mode 100644 index 0000000..dea2be9 --- /dev/null +++ b/state/actions/showAlert.ts @@ -0,0 +1,19 @@ +import { ref } from 'valtio'; +import { AlertState, alertState } from "../../components/AlertDialog"; + +export const showAlert = (title: string, opts: Partial = {}) => { + const { body: _body, confirmNode: _confirmNode, ...rest } = opts + const body = (_body && typeof _body === 'object') ? ref(_body) : _body + const confirmNode = (_confirmNode && typeof _confirmNode === 'object') ? ref(_confirmNode) : _confirmNode + + const nwState = { + isOpen: true, + title, + body, + confirmNode, + ...rest + } + Object.entries(nwState).forEach(([key, value]) => { + (alertState as any)[key] = value + }) +} \ No newline at end of file