|
1 | | -import { GetApp, Refresh, Share } from "@mui/icons-material"; |
2 | | -import { |
3 | | - Box, |
4 | | - Button, |
5 | | - createTheme, |
6 | | - IconButton, |
7 | | - Link, |
8 | | - Stack, |
9 | | - ThemeProvider, |
10 | | - Tooltip, |
11 | | - Typography, |
12 | | - type IconButtonProps, |
13 | | - type ThemeOptions, |
14 | | -} from "@mui/material"; |
| 1 | +import { Box, createTheme, Stack, ThemeProvider, type ThemeOptions } from "@mui/material"; |
15 | 2 | import { merge } from "lodash"; |
16 | 3 | import { useEffect, useState } from "react"; |
| 4 | +import { BottomControls } from "./components/BottomControls/BottomControls"; |
17 | 5 | import { InfoPanel } from "./components/InfoPanel/InfoPanel"; |
18 | 6 | import { MockApp } from "./components/MockApp/MockApp"; |
19 | 7 | import { ToolsPanel } from "./components/ToolsPanel/ToolsPanel"; |
20 | | -import { generateTheme } from "./generateTheme"; |
21 | 8 | import { InnerThemeContext } from "./hooks/useInnerTheme"; |
22 | | -import { deleteKeys, saveObjectToClipboard } from "./utils"; |
| 9 | +import { deleteKeys } from "./utils"; |
23 | 10 |
|
24 | 11 | const LOCAL_STORAGE_KEY = "themeOptions"; |
25 | 12 |
|
26 | | -const SHARED_ICONBUTTON_PROPS: IconButtonProps = { |
27 | | - size: "large", |
28 | | - sx: { |
29 | | - bgcolor: "primary.main", |
30 | | - "&:hover": { bgcolor: "primary.dark" }, |
31 | | - "&:disabled": { bgcolor: "primary.main", opacity: 0.5, color: "primary.contrastText" }, |
32 | | - color: "primary.contrastText", |
33 | | - }, |
34 | | -}; |
35 | | - |
36 | | -const shareSite = async () => { |
37 | | - try { |
38 | | - await navigator.share({ |
39 | | - title: "MUI Theme Builder", |
40 | | - text: "Modern MUI theme builder", |
41 | | - url: "https://google.com", |
42 | | - }); |
43 | | - } catch (err: any) { |
44 | | - if (err.name === "AbortError") return; |
45 | | - try { |
46 | | - await navigator.clipboard.writeText("https://google.com"); |
47 | | - alert("Site URL copied to clipboard"); |
48 | | - } catch (error) { |
49 | | - alert("Failed to share URL"); |
50 | | - console.error(error); |
51 | | - throw error; |
52 | | - } |
53 | | - } |
54 | | -}; |
55 | | - |
56 | 13 | function App() { |
57 | 14 | const [themeOptions, setThemeOptions] = useState<ThemeOptions>(JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY) ?? "{}")); |
58 | 15 | const innerTheme = createTheme(themeOptions); |
59 | 16 | const mergeThemeOptions = (partialThemeOptions: ThemeOptions) => |
60 | 17 | setThemeOptions(merge(structuredClone(themeOptions), partialThemeOptions)); |
61 | 18 | const deleteThemeOptionKey = (keyPath: Array<string>) => setThemeOptions(deleteKeys(themeOptions, keyPath)); |
62 | | - const hasEditedTheme = Object.keys(themeOptions).length !== 0; |
63 | 19 |
|
64 | 20 | useEffect(() => { |
65 | 21 | localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(themeOptions)); |
@@ -107,72 +63,7 @@ function App() { |
107 | 63 | <MockApp /> |
108 | 64 | </ThemeProvider> |
109 | 65 | </Box> |
110 | | - <Stack gap={2} sx={{ p: { xs: 2, sm: 3, md: 4 }, pt: { xs: 0, sm: 0, md: 0 } }} alignItems="center"> |
111 | | - <Stack gap={1.5} direction="row"> |
112 | | - <Button |
113 | | - size="large" |
114 | | - variant="contained" |
115 | | - onClick={() => setThemeOptions(generateTheme())} |
116 | | - sx={{ |
117 | | - border: "2px solid transparent", |
118 | | - borderImage: "conic-gradient(from 0deg, red, yellow, lime, aqua, blue, magenta, red) 1", |
119 | | - borderImageSlice: 1, |
120 | | - transition: "all 0.3s ease", |
121 | | - fontWeight: "bold", |
122 | | - }} |
123 | | - > |
124 | | - Randomize! |
125 | | - </Button> |
126 | | - <Tooltip title="Export theme"> |
127 | | - <IconButton disabled={!hasEditedTheme} onClick={() => saveObjectToClipboard(themeOptions)} {...SHARED_ICONBUTTON_PROPS}> |
128 | | - <GetApp /> |
129 | | - </IconButton> |
130 | | - </Tooltip> |
131 | | - <Tooltip title="Reset"> |
132 | | - <IconButton |
133 | | - disabled={!hasEditedTheme} |
134 | | - onClick={() => { |
135 | | - if (!confirm("Reset all settings to default?")) return; |
136 | | - setThemeOptions({}); |
137 | | - }} |
138 | | - {...SHARED_ICONBUTTON_PROPS} |
139 | | - > |
140 | | - <Refresh /> |
141 | | - </IconButton> |
142 | | - </Tooltip> |
143 | | - <Tooltip title="Share"> |
144 | | - <IconButton onClick={shareSite} {...SHARED_ICONBUTTON_PROPS}> |
145 | | - <Share /> |
146 | | - </IconButton> |
147 | | - </Tooltip> |
148 | | - {/* <Tooltip title={hasEditedTheme ? "Share..." : "Share"}> |
149 | | - <IconButton |
150 | | - {...(hasEditedTheme ? { popoverTarget: "share-popover" } : { onClick: shareSite })} |
151 | | - {...SHARED_ICONBUTTON_PROPS} |
152 | | - > |
153 | | - <Share /> |
154 | | - </IconButton> |
155 | | - </Tooltip> |
156 | | - {hasEditedTheme && ( |
157 | | - <Paper |
158 | | - popover="auto" |
159 | | - id="share-popover" |
160 | | - sx={{ bottom: "anchor(top)", insetInlineEnd: "anchor(end)", bgcolor: "primary.dark", p: 0 }} |
161 | | - > |
162 | | - <MenuList> |
163 | | - <MenuItem onClick={shareSite}>Share site</MenuItem> |
164 | | - <MenuItem onClick={() => {}}>Share this theme</MenuItem> |
165 | | - </MenuList> |
166 | | - </Paper> |
167 | | - )} */} |
168 | | - </Stack> |
169 | | - <Typography color="#ddd" sx={{ display: { sm: "none" } }}> |
170 | | - View on a larger screen to edit | |
171 | | - <Link href="https://github.com/PeterTYLiu/mui-theme-builder" target="_blank"> |
172 | | - Github |
173 | | - </Link> |
174 | | - </Typography> |
175 | | - </Stack> |
| 66 | + <BottomControls /> |
176 | 67 | </Stack> |
177 | 68 | <ToolsPanel /> |
178 | 69 | </Box> |
|
0 commit comments