new design implementations

This commit is contained in:
AykutSarac 2022-09-01 21:04:00 +03:00
parent 5ca31703a6
commit 4f74321303
18 changed files with 102 additions and 62 deletions

View File

@ -28,14 +28,31 @@ const StyledButton = styled.button<{
color: #ffffff;
padding: 8px 16px;
min-width: 60px;
min-height: 32px;
border-radius: 3px;
font-size: 14px;
font-weight: 500;
font-family: "Catamaran", sans-serif;
width: ${({ block }) => (block ? "100%" : "fit-content")};
height: 40px;
background-image: none;
:disabled {
cursor: not-allowed;
opacity: 0.5;
}
div {
white-space: normal;
margin: 0 auto;
text-overflow: ellipsis;
overflow: hidden;
}
&:hover {
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
@media only screen and (max-width: 768px) {
font-size: 14px;
}

View File

@ -12,6 +12,7 @@ const StyledErrorWrapper = styled.div`
`;
const StyledErrorExpand = styled.button<{ error: boolean }>`
position: relative;
display: flex;
width: 100%;
padding: 4px 16px;
@ -25,10 +26,10 @@ const StyledErrorExpand = styled.button<{ error: boolean }>`
background: ${({ theme }) => theme.BACKGROUND_SECONDARY};
box-shadow: 0 1px 0px ${({ theme }) => theme.BACKGROUND_TERTIARY};
cursor: pointer;
z-index: 100;
&:hover {
color: ${({ theme }) => theme.TEXT_DANGER};
box-shadow: none;
}
`;

View File

@ -24,6 +24,9 @@ const StyledEditorWrapper = styled.div<{ isWidget: boolean }>`
width: 100%;
height: ${({ isWidget }) => (isWidget ? "100vh" : "calc(100vh - 36px)")};
background: ${({ theme }) => theme.BACKGROUND_SECONDARY};
background-image: ${({ theme }) => `radial-gradient(#505050 0.5px, ${theme.BACKGROUND_SECONDARY} 0.5px)`};
background-size: 10px 10px;
z-index: 0;
:active {
cursor: move;

View File

@ -15,7 +15,7 @@ export const ModalWrapper = styled.div`
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.85);
z-index: 36;
z-index: 100;
* {
box-sizing: border-box;

View File

@ -13,6 +13,7 @@ import {
AiOutlineLink,
AiOutlineEdit,
} from "react-icons/ai";
import { FiDownload } from "react-icons/fi";
import { Tooltip } from "src/components/Tooltip";
import { useRouter } from "next/router";
@ -24,6 +25,7 @@ import { HiHeart } from "react-icons/hi";
import shallow from "zustand/shallow";
import { MdCenterFocusWeak } from "react-icons/md";
import { getNextLayout } from "src/utils/getNextLayout";
import { DownloadModal } from "src/containers/Modals/DownloadModal";
const StyledSidebar = styled.div`
display: flex;
@ -41,19 +43,19 @@ const StyledSidebar = styled.div`
}
`;
const StyledElement = styled.div<{ beta?: boolean }>`
const StyledElement = styled.button`
position: relative;
display: flex;
justify-content: center;
text-align: center;
font-size: 26px;
font-weight: 600;
width: 100%;
color: ${({ theme }) => theme.INTERACTIVE_NORMAL};
width: fit-content;
color: ${({ theme }) => theme.SIDEBAR_ICONS};
cursor: pointer;
svg {
padding: 8px;
padding: 12px 8px;
vertical-align: middle;
}
@ -64,11 +66,20 @@ const StyledElement = styled.div<{ beta?: boolean }>`
&:hover :is(a, svg) {
color: ${({ theme }) => theme.INTERACTIVE_HOVER};
}
@media only screen and (max-width: 768px) {
font-size: 22px;
svg {
padding: 8px 4px;
vertical-align: middle;
}
}
`;
const StyledText = styled.span<{ secondary?: boolean }>`
color: ${({ theme, secondary }) =>
secondary ? theme.INTERACTIVE_NORMAL : theme.ORANGE};
secondary ? theme.INTERACTIVE_HOVER : theme.ORANGE};
`;
const StyledFlowIcon = styled(TiFlowMerge)<{ rotate: number }>`
@ -82,21 +93,14 @@ const StyledTopWrapper = styled.nav`
align-items: center;
width: 100%;
& > div:nth-child(n + 1) {
border-bottom: 1px solid ${({ theme }) => theme.BACKGROUND_MODIFIER_ACCENT};
}
.mobile {
display: none;
}
@media only screen and (max-width: 768px) {
justify-content: space-evenly;
flex-direction: row;
& > div:nth-child(n + 1) {
border-bottom: none;
}
.mobile {
display: initial;
}
@ -114,18 +118,19 @@ const StyledBottomWrapper = styled.nav`
align-items: center;
width: 100%;
& > div,
a:nth-child(0) {
border-top: 1px solid ${({ theme }) => theme.BACKGROUND_MODIFIER_ACCENT};
}
@media only screen and (max-width: 768px) {
display: none;
}
`;
const StyledLogo = styled.div`
const StyledLogo = styled.a`
color: ${({ theme }) => theme.FULL_WHITE};
padding: 8px 4px;
border-bottom: 1px solid ${({ theme }) => theme.BACKGROUND_MODIFIER_ACCENT};
@media only screen and (max-width: 768px) {
border-bottom: 0;
}
`;
function rotateLayout(layout: "LEFT" | "RIGHT" | "DOWN" | "UP") {
@ -142,6 +147,7 @@ export const Sidebar: React.FC = () => {
const [uploadVisible, setUploadVisible] = React.useState(false);
const [clearVisible, setClearVisible] = React.useState(false);
const [shareVisible, setShareVisible] = React.useState(false);
const [isDownloadVisible, setDownloadVisible] = React.useState(false);
const { push } = useRouter();
const [expand, layout, hideEditor] = useConfig(
@ -215,6 +221,11 @@ export const Sidebar: React.FC = () => {
<AiOutlineSave />
</StyledElement>
</Tooltip>
<Tooltip className="mobile" title="Download Image">
<StyledElement onClick={() => setDownloadVisible(true)}>
<FiDownload />
</StyledElement>
</Tooltip>
<Tooltip title="Clear JSON">
<StyledElement onClick={() => setClearVisible(true)}>
<AiOutlineDelete />
@ -252,6 +263,10 @@ export const Sidebar: React.FC = () => {
<ImportModal visible={uploadVisible} setVisible={setUploadVisible} />
<ClearModal visible={clearVisible} setVisible={setClearVisible} />
<ShareModal visible={shareVisible} setVisible={setShareVisible} />
<DownloadModal
visible={isDownloadVisible}
setVisible={setDownloadVisible}
/>
</StyledSidebar>
);
};

View File

@ -7,7 +7,7 @@ interface TooltipProps extends React.ComponentPropsWithoutRef<"div"> {
const StyledTooltipWrapper = styled.div`
position: relative;
width: 100%;
width: fit-content;
height: 100%;
`;
@ -15,7 +15,7 @@ const StyledTooltip = styled.div<{ visible: boolean }>`
position: absolute;
top: 0;
right: 0;
transform: translate(calc(100% + 15px), 10%);
transform: translate(calc(100% + 15px), 25%);
z-index: 5;
background: ${({ theme }) => theme.BACKGROUND_PRIMARY};
color: ${({ theme }) => theme.TEXT_NORMAL};

View File

@ -1,5 +1,5 @@
// Example taken from https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json
export const defaultJson = {
export const defaultJson = JSON.stringify({
squadName: "Super hero squad",
homeTown: "Metro City",
formed: 2016,
@ -35,4 +35,4 @@ export const defaultJson = {
],
},
],
};
});

View File

@ -35,26 +35,14 @@ const GlobalStyle = createGlobalStyle`
}
button {
min-height: 32px;
border: none;
border-radius: 3px;
outline: none;
font-family: 'Catamaran', sans-serif;
font-weight: 500;
font-size: 14px;
background-image: none;
-webkit-tap-highlight-color: transparent;
background: transparent;
width: fit-content;
margin: 0;
padding: 0;
cursor: pointer;
div {
white-space: normal;
margin: 0 auto;
text-overflow: ellipsis;
overflow: hidden;
}
&:hover {
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
}
#carbonads * {

View File

@ -24,6 +24,7 @@ export const darkTheme: DefaultTheme = {
SILVER_DARK: "#4D4D4D",
NODE_KEY: "#FAA81A",
OBJECT_KEY: "#59b8ff",
SIDEBAR_ICONS: "#8B8E90",
INTERACTIVE_NORMAL: "#b9bbbe",
INTERACTIVE_HOVER: "#dcddde",
@ -44,6 +45,7 @@ export const lightTheme: DefaultTheme = {
SILVER_DARK: "#CCCCCC",
NODE_KEY: "#DC3790",
OBJECT_KEY: "#0260E8",
SIDEBAR_ICONS: "#6D6E70",
INTERACTIVE_NORMAL: "#4f5660",
INTERACTIVE_HOVER: "#2e3338",

View File

@ -1,8 +1,7 @@
import React from "react";
import styled from "styled-components";
import Editor from "@monaco-editor/react";
import parseJson from "parse-json";
import { loader } from "@monaco-editor/react";
import MonacoEditor, { loader } from "@monaco-editor/react";
import { ErrorContainer } from "src/components/ErrorContainer/ErrorContainer";
import useConfig from "src/hooks/store/useConfig";
import { Loading } from "src/components/Loading";
@ -76,7 +75,7 @@ export const JsonEditor: React.FC = () => {
<StyledEditorWrapper>
<ErrorContainer error={error} />
<StyledWrapper>
<Editor
<MonacoEditor
height="100%"
defaultLanguage="json"
value={value}

View File

@ -5,18 +5,16 @@ import {
AiOutlinePlus,
} from "react-icons/ai";
import { FiDownload } from "react-icons/fi";
import { HiOutlineSun, HiOutlineMoon } from "react-icons/hi";
import { MdCenterFocusWeak } from "react-icons/md";
import { SearchInput } from "src/components/SearchInput";
import styled from "styled-components";
import useConfig from "src/hooks/store/useConfig";
import shallow from "zustand/shallow";
import { DownloadModal } from "../Modals/DownloadModal";
import useStored from "src/hooks/store/useStored";
import { TbSettings } from "react-icons/tb";
import { Settings } from "./Settings";
import { SettingsModal } from "src/containers/Modals/SettingsModal";
export const StyledTools = styled.div`
position: relative;
display: flex;
align-items: center;
gap: 4px;
@ -26,6 +24,7 @@ export const StyledTools = styled.div`
background: ${({ theme }) => theme.BACKGROUND_PRIMARY};
color: ${({ theme }) => theme.SILVER};
box-shadow: 0 1px 0px ${({ theme }) => theme.BACKGROUND_TERTIARY};
z-index: 36;
@media only screen and (max-width: 768px) {
display: none;
@ -38,6 +37,12 @@ const StyledToolElement = styled.button`
font-size: 20px;
background: none;
color: ${({ theme }) => theme.INTERACTIVE_NORMAL};
padding: 6px;
border-radius: 3px;
&:hover {
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
&:hover {
color: ${({ theme }) => theme.INTERACTIVE_HOVER};
@ -49,8 +54,6 @@ const StyledToolElement = styled.button`
export const Tools: React.FC = () => {
const [settingsVisible, setSettingsVisible] = React.useState(false);
const [isDownloadVisible, setDownloadVisible] = React.useState(false);
const lightmode = useStored((state) => state.lightmode);
const setLightTheme = useStored((state) => state.setLightTheme);
const hideEditor = useConfig((state) => state.hideEditor);
const setConfig = useConfig((state) => state.setConfig);
@ -59,7 +62,6 @@ export const Tools: React.FC = () => {
const zoomOut = useConfig((state) => state.zoomOut);
const centerView = useConfig((state) => state.centerView);
const toggleEditor = () => setConfig("hideEditor", !hideEditor);
const toggleTheme = () => setLightTheme(!lightmode);
return (
<StyledTools>
@ -72,9 +74,6 @@ export const Tools: React.FC = () => {
>
<TbSettings />
</StyledToolElement>
<StyledToolElement aria-label="switch theme" onClick={toggleTheme}>
{lightmode ? <HiOutlineMoon /> : <HiOutlineSun />}
</StyledToolElement>
<SearchInput />
<StyledToolElement
aria-label="save"
@ -95,7 +94,10 @@ export const Tools: React.FC = () => {
visible={isDownloadVisible}
setVisible={setDownloadVisible}
/>
<Settings visible={settingsVisible} setVisible={setSettingsVisible} />
<SettingsModal
visible={settingsVisible}
setVisible={setSettingsVisible}
/>
</StyledTools>
);
};

View File

@ -53,6 +53,7 @@ export const NodeModal = ({
},
2
)}
readOnly
/>
</Modal.Content>
<Modal.Controls setVisible={closeModal}>

View File

@ -16,10 +16,12 @@ const StyledModalWrapper = styled.div`
gap: 20px;
`;
export const Settings: React.FC<{
export const SettingsModal: React.FC<{
visible: boolean;
setVisible: React.Dispatch<React.SetStateAction<boolean>>;
}> = ({ visible, setVisible }) => {
const lightmode = useStored((state) => state.lightmode);
const setLightTheme = useStored((state) => state.setLightTheme);
const [toggleHideCollapse, hideCollapse] = useStored(
(state) => [state.toggleHideCollapse, state.hideCollapse],
shallow
@ -33,6 +35,12 @@ export const Settings: React.FC<{
<StyledToggle onChange={toggleHideCollapse} checked={hideCollapse}>
Hide Collapse/Expand Button
</StyledToggle>
<StyledToggle
onChange={() => setLightTheme(!lightmode)}
checked={lightmode}
>
Enable Light Theme
</StyledToggle>
</StyledModalWrapper>
</Modal.Content>
<Modal.Controls setVisible={setVisible} />

View File

@ -22,7 +22,7 @@ export interface Config {
}
const initialStates: Config = {
json: JSON.stringify(defaultJson),
json: defaultJson,
cursorMode: "move",
layout: "RIGHT",
expand: true,

View File

@ -36,9 +36,9 @@ const useStored = create(
users: [],
nextDate: Date.now(),
},
setLightTheme: (enabled: boolean) =>
setLightTheme: (value: boolean) =>
set({
lightmode: enabled,
lightmode: value,
}),
setSponsors: (users) =>
set({

View File

@ -8,6 +8,7 @@ import {
import useConfig from "./store/useConfig";
export const useFocusNode = () => {
const setConfig = useConfig((state) => state.setConfig);
const zoomPanPinch = useConfig((state) => state.zoomPanPinch);
const [selectedNode, setSelectedNode] = React.useState(0);
const [content, setContent] = React.useState({
@ -18,12 +19,14 @@ export const useFocusNode = () => {
const skip = () => setSelectedNode((current) => current + 1);
React.useEffect(() => {
setConfig("performanceMode", !content.value.length);
const debouncer = setTimeout(() => {
setContent((val) => ({ ...val, debounced: content.value }));
}, 1500);
return () => clearTimeout(debouncer);
}, [content.value]);
}, [content.value, setConfig]);
React.useEffect(() => {
if (!zoomPanPinch) return;

View File

@ -43,7 +43,7 @@ const WidgetPage = () => {
React.useEffect(() => {
if (!query.json) {
setJson(JSON.stringify(defaultJson));
setJson(defaultJson);
} else {
const jsonURI = decodeURIComponent(query.json as string);
const isJsonValid = isValidJson(jsonURI);

View File

@ -20,6 +20,7 @@ declare module "styled-components" {
PRIMARY: string;
NODE_KEY: string;
OBJECT_KEY: string;
SIDEBAR_ICONS: string;
INTERACTIVE_NORMAL: string;
INTERACTIVE_HOVER: string;