feat: dark-mode completed :)

This commit is contained in:
Anoop M D 2022-10-23 11:26:16 +05:30
parent 2ba6e4823d
commit 96f50b0c6d
25 changed files with 253 additions and 85 deletions

View File

@ -25,6 +25,7 @@ const Wrapper = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0.35rem 0.6rem; padding: 0.35rem 0.6rem;
background-color: ${(props) => props.theme.dropdown.labelBg};
} }
.dropdown-item { .dropdown-item {

View File

@ -8,7 +8,7 @@ const Wrapper = styled.div`
thead, thead,
td { td {
border: 1px solid ${(props) => props.theme.table.border}; border: 1px solid ${(props) => props.theme.collection.environment.settings.gridBorder};
} }
thead { thead {
@ -29,6 +29,7 @@ const Wrapper = styled.div`
width: 100%; width: 100%;
border: solid 1px transparent; border: solid 1px transparent;
outline: none !important; outline: none !important;
background-color: transparent;
&:focus { &:focus {
outline: none !important; outline: none !important;

View File

@ -4,8 +4,11 @@ const StyledWrapper = styled.div`
margin-inline: -1rem; margin-inline: -1rem;
margin-block: -1.5rem; margin-block: -1.5rem;
background-color: ${(props) => props.theme.collection.environment.settings.bg};
.environments-sidebar { .environments-sidebar {
background-color: #eaeaea; background-color: ${(props) => props.theme.collection.environment.settings.sidebar.bg};
border-right: solid 1px ${(props) => props.theme.collection.environment.settings.sidebar.borderRight};
min-height: 400px; min-height: 400px;
} }
@ -20,15 +23,15 @@ const StyledWrapper = styled.div`
&:hover { &:hover {
text-decoration: none; text-decoration: none;
background-color: #e4e4e4; background-color: ${(props) => props.theme.collection.environment.settings.item.hoverBg};
} }
} }
.active { .active {
background-color: #dcdcdc !important; background-color: ${(props) => props.theme.collection.environment.settings.item.active.bg} !important;
border-left: solid 2px var(--color-brand); border-left: solid 2px ${(props) => props.theme.collection.environment.settings.item.border};
&:hover { &:hover {
background-color: #dcdcdc !important; background-color: ${(props) => props.theme.collection.environment.settings.item.active.hoverBg} !important;
} }
} }
@ -36,7 +39,7 @@ const StyledWrapper = styled.div`
padding: 8px 10px; padding: 8px 10px;
cursor: pointer; cursor: pointer;
border-bottom: none; border-bottom: none;
color: var(--color-text-link); color: ${(props) => props.theme.textLink};
&:hover { &:hover {
span { span {

View File

@ -110,6 +110,10 @@ const Wrapper = styled.div`
outline: none !important; outline: none !important;
} }
} }
.bruno-form {
color: ${(props) => props.theme.modal.body.color};
}
} }
.bruno-modal-backdrop { .bruno-modal-backdrop {
@ -126,7 +130,7 @@ const Wrapper = styled.div`
height: 100%; height: 100%;
width: 100%; width: 100%;
left: 0; left: 0;
opacity: 0.4; opacity: ${(props) => props.theme.modal.backdrop.opacity};
top: 0; top: 0;
background: black; background: black;
position: fixed; position: fixed;

View File

@ -2,7 +2,7 @@ import styled from 'styled-components';
const Wrapper = styled.div` const Wrapper = styled.div`
.menu-icon { .menu-icon {
color: rgb(110 110 110); color: ${(props) => props.theme.sidebar.dropdownIcon.color};
.dropdown { .dropdown {
div[aria-expanded='true'] { div[aria-expanded='true'] {
@ -62,9 +62,9 @@ const Wrapper = styled.div`
} }
div.dropdown-item.delete-item { div.dropdown-item.delete-item {
color: var(--color-text-danger); color: ${(props) => props.theme.colors.danger};
&:hover { &:hover {
background-color: var(--color-background-danger); background-color: ${(props) => props.theme.colors.bg.danger};
color: white; color: white;
} }
} }

View File

@ -24,7 +24,7 @@ const Wrapper = styled.div`
svg { svg {
height: 22px; height: 22px;
color: rgb(110 110 110); color: ${(props) => props.theme.sidebar.dropdownIcon.color};
} }
} }
@ -45,9 +45,9 @@ const Wrapper = styled.div`
} }
div.dropdown-item.delete-collection { div.dropdown-item.delete-collection {
color: var(--color-text-danger); color: ${(props) => props.theme.colors.text.danger};
&:hover { &:hover {
background-color: var(--color-background-danger); background-color: ${(props) => props.theme.colors.bg.danger};
color: white; color: white;
} }
} }

View File

@ -10,7 +10,7 @@ const StyledWrapper = styled.div`
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background-color: #f4f4f4; background-color: ${(props) => props.theme.plainGrid.hoverBg};;
} }
} }
`; `;

View File

@ -13,6 +13,11 @@ const Wrapper = styled.div`
} }
} }
.muted-message {
color: ${(props) => props.theme.sidebar.muted};
border-top: solid 1px ${(props) => props.theme.dropdown.seperator};
}
div[data-tippy-root] { div[data-tippy-root] {
width: calc(100% - 1rem); width: calc(100% - 1rem);
} }

View File

@ -60,7 +60,7 @@ const LocalCollections = ({ searchText }) => {
<span>Open Collection</span> <span>Open Collection</span>
</div> </div>
<div className="px-2 pt-2 text-gray-600" style={{ fontSize: 10, borderTop: 'solid 1px #e7e7e7' }}> <div className="px-2 pt-2 muted-message" style={{ fontSize: 10 }}>
Note: Local collections are not tied to a workspace Note: Local collections are not tied to a workspace
</div> </div>
</Dropdown> </Dropdown>

View File

@ -8,7 +8,7 @@ import { IconCode, IconFiles, IconMoon, IconChevronsLeft, IconLifebuoy } from '@
import Link from 'next/link'; import Link from 'next/link';
import StyledWrapper from './StyledWrapper'; import StyledWrapper from './StyledWrapper';
import BrunoSupport from 'components/BrunoSupport'; import BrunoSupport from 'components/BrunoSupport';
import ThemeSupport from 'components/ThemeSupport/index'; import SwitchTheme from 'components/SwitchTheme';
const MenuBar = () => { const MenuBar = () => {
const router = useRouter(); const router = useRouter();
@ -23,6 +23,9 @@ const MenuBar = () => {
return ( return (
<StyledWrapper className="h-full flex flex-col"> <StyledWrapper className="h-full flex flex-col">
{openBrunoSupport && <BrunoSupport onClose={() => setOpenBrunoSupport(false)} />}
{openTheme && <SwitchTheme onClose={() => setOpenTheme(false)} />}
<div className="flex flex-col"> <div className="flex flex-col">
<Link href="/"> <Link href="/">
<div className={getClassName('/')}> <div className={getClassName('/')}>
@ -46,18 +49,16 @@ const MenuBar = () => {
<IconUser size={28} strokeWidth={1.5}/> <IconUser size={28} strokeWidth={1.5}/>
</div> </div>
</Link> */} </Link> */}
<div className="menu-item"> <div className="menu-item" onClick={() => setOpenBrunoSupport(true)}>
<IconLifebuoy size={28} strokeWidth={1.5} onClick={() => setOpenBrunoSupport(true)} /> <IconLifebuoy size={28} strokeWidth={1.5}/>
</div> </div>
<div className="menu-item"> <div className="menu-item" onClick={() => setOpenTheme(true)}>
<IconMoon size={28} strokeWidth={1.5} onClick={() => setOpenTheme(true)} /> <IconMoon size={28} strokeWidth={1.5}/>
</div> </div>
<div className="menu-item" onClick={() => dispatch(toggleLeftMenuBar())}> <div className="menu-item" onClick={() => dispatch(toggleLeftMenuBar())}>
<IconChevronsLeft size={28} strokeWidth={1.5} /> <IconChevronsLeft size={28} strokeWidth={1.5} />
</div> </div>
</div> </div>
{openBrunoSupport && <BrunoSupport onClose={() => setOpenBrunoSupport(false)} />}
{openTheme && <ThemeSupport onClose={() => setOpenTheme(false)} />}
</StyledWrapper> </StyledWrapper>
); );
}; };

View File

@ -1,17 +1,14 @@
import styled from 'styled-components'; import styled from 'styled-components';
const StyledWrapper = styled.div` const StyledWrapper = styled.div`
.local-collection-label {
background-color: var(--color-sidebar-background);
}
.local-collections-unavailable { .local-collections-unavailable {
padding: 0.35rem 0.6rem; padding: 0.35rem 0.6rem;
color: ${(props) => props.theme.sidebar.muted};
border-top: solid 1px ${(props) => props.theme.dropdown.seperator}; border-top: solid 1px ${(props) => props.theme.dropdown.seperator};
font-size: 11px; font-size: 11px;
} }
.collection-dropdown { .collection-dropdown {
color: rgb(110 110 110); color: ${(props) => props.theme.sidebar.dropdownIcon.color};
&:hover { &:hover {
color: inherit; color: inherit;

View File

@ -135,7 +135,7 @@ const TitleBar = () => {
</div> </div>
</> </>
) : ( ) : (
<div className="flex items-center select-none text-gray-400 text-xs local-collections-unavailable"> <div className="flex items-center select-none text-xs local-collections-unavailable">
Note: Local collections are only available on the desktop app. Note: Local collections are only available on the desktop app.
</div> </div>
)} )}

View File

@ -0,0 +1,67 @@
import React from 'react';
import { useFormik } from 'formik';
import * as Yup from 'yup';
import Modal from 'components/Modal/index';
import StyledWrapper from './StyledWrapper';
import { useTheme } from 'providers/Theme';
const SwitchTheme = ({ onClose }) => {
const { storedTheme, setStoredTheme } = useTheme();
const formik = useFormik({
enableReinitialize: true,
initialValues: {
theme: storedTheme
},
validationSchema: Yup.object({
theme: Yup.string().oneOf(['light', 'dark']).required('theme is required')
}),
onSubmit: (values) => {
setStoredTheme(values.theme);
}
});
return (
<StyledWrapper>
<Modal size="sm" title={'Switch Theme'} handleCancel={onClose} hideFooter={true}>
<div className='bruno-form'>
<div className="flex items-center mt-2">
<input
id="light-theme"
className="cursor-pointer"
type="radio"
name="theme"
onChange={(e) => {
formik.handleChange(e);
formik.handleSubmit()
}}
value="light"
checked={formik.values.theme === 'light'}
/>
<label htmlFor="light-theme" className="ml-1 cursor-pointer select-none">
Light
</label>
<input
id="dark-theme"
className="ml-4 cursor-pointer"
type="radio"
name="theme"
onChange={(e) => {
formik.handleChange(e);
formik.handleSubmit()
}}
value="dark"
checked={formik.values.theme === 'dark'}
/>
<label htmlFor="dark-theme" className="ml-1 cursor-pointer select-none">
Dark
</label>
</div>
</div>
</Modal>
</StyledWrapper>
);
};
export default SwitchTheme;

View File

@ -1,34 +0,0 @@
import React from 'react';
import Modal from 'components/Modal/index';
import StyledWrapper from './StyledWrapper';
import { useTheme } from 'providers/Theme';
const ThemeSupport = ({ onClose }) => {
const { storedTheme, themeOptions, setStoredTheme } = useTheme();
console.log(themeOptions);
const handleThemeChange = (e) => {
setStoredTheme(e.target.value);
};
return (
<StyledWrapper>
<Modal size="sm" title={'Support'} handleCancel={onClose} hideFooter={true}>
<div className="collection-options">
<select name="theme_switcher" onChange={handleThemeChange} defaultValue={storedTheme}>
{themeOptions.map((tk, index) => {
return (
<option value={tk} key={index}>
{tk}
</option>
);
})}
</select>
</div>
</Modal>
</StyledWrapper>
);
};
export default ThemeSupport;

View File

@ -2,12 +2,12 @@ import styled from 'styled-components';
const StyledWrapper = styled.div` const StyledWrapper = styled.div`
.heading { .heading {
color: ${(props) => props.theme.welcome.heading}; color: ${(props) => props.theme.welcome.heading};
font-size: 0.75rem; font-size: 0.75rem;
} }
.muted { .muted {
color: ${(props) => props.theme.welcome.muted}; color: ${(props) => props.theme.welcome.muted};
} }
.collection-options { .collection-options {

View File

@ -10,7 +10,7 @@ const Wrapper = styled.div`
} }
div:hover { div:hover {
background-color: #f4f4f4; background-color: ${(props) => props.theme.plainGrid.hoverBg};
} }
`; `;

View File

@ -66,9 +66,9 @@ const GlobalStyle = createGlobalStyle`
} }
&:disabled { &:disabled {
color: #545454; color: ${(props) => props.theme.button.disabled.color};
background: #efefef; background: ${(props) => props.theme.button.disabled.bg};
border: solid 1px rgb(234, 234, 234); border: solid 1px ${(props) => props.theme.button.disabled.border};
cursor: not-allowed; cursor: not-allowed;
} }

View File

@ -17,7 +17,7 @@ const Wrapper = styled.div`
border-radius: 3px; border-radius: 3px;
&:hover { &:hover {
background-color: #f4f4f4; background-color: ${(props) => props.theme.plainGrid.hoverBg};
margin-left: -8px; margin-left: -8px;
margin-right: -8px; margin-right: -8px;
padding-left: 8px; padding-left: 8px;

View File

@ -28,7 +28,7 @@ const Wrapper = styled.div`
} }
a { a {
color: var(--color-text-link); color: ${(props) => props.theme.textLink};
} }
.error-msg { .error-msg {

View File

@ -28,7 +28,7 @@ const Wrapper = styled.div`
} }
a { a {
color: var(--color-text-link); color: ${(props) => props.theme.textLink};
} }
.or { .or {

View File

@ -1,7 +1,6 @@
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { Toaster } from 'react-hot-toast';
import { AppProvider } from 'providers/App'; import { AppProvider } from 'providers/App';
import { AuthProvider } from 'providers/Auth'; import { ToastProvider } from 'providers/Toaster';
import { HotkeysProvider } from 'providers/Hotkeys'; import { HotkeysProvider } from 'providers/Hotkeys';
import ReduxStore from 'providers/ReduxStore'; import ReduxStore from 'providers/ReduxStore';
@ -34,12 +33,13 @@ function MyApp({ Component, pageProps }) {
<NoSsr> <NoSsr>
<Provider store={ReduxStore}> <Provider store={ReduxStore}>
<ThemeProvider> <ThemeProvider>
<AppProvider> <ToastProvider>
<HotkeysProvider> <AppProvider>
<Toaster toastOptions={{ duration: 2000 }} /> <HotkeysProvider>
<Component {...pageProps} /> <Component {...pageProps} />
</HotkeysProvider> </HotkeysProvider>
</AppProvider> </AppProvider>
</ToastProvider>
</ThemeProvider> </ThemeProvider>
</Provider> </Provider>
</NoSsr> </NoSsr>

View File

@ -0,0 +1,31 @@
import React from 'react';
import { Toaster } from 'react-hot-toast';
import { useTheme } from 'providers/Theme';
export const ToastContext = React.createContext();
export const ToastProvider = (props) => {
const {
storedTheme
} = useTheme();
const toastOptions = { duration: 2000 };
if(storedTheme === 'dark') {
toastOptions.style = {
borderRadius: '10px',
background: '#3d3d3d',
color: '#fff'
};
}
return (
<ToastContext.Provider {...props} value="toastProvider">
<Toaster toastOptions={toastOptions} />
<div>
{props.children}
</div>
</ToastContext.Provider>
);
};
export default ToastProvider;

View File

@ -4,12 +4,22 @@ const darkTheme = {
textLink: '#569cd6', textLink: '#569cd6',
bg: '#1e1e1e', bg: '#1e1e1e',
colors: {
text: {
danger: '#f06f57'
},
bg: {
danger: '#d03544'
}
},
menubar: { menubar: {
bg: '#333333', bg: '#333333',
}, },
sidebar: { sidebar: {
color: '#ccc', color: '#ccc',
muted: '#9d9d9d',
workspace: { workspace: {
bg: '#3D3D3D' bg: '#3D3D3D'
@ -29,6 +39,10 @@ const darkTheme = {
indentBorder: 'solid 1px #4c4c4c' indentBorder: 'solid 1px #4c4c4c'
} }
} }
},
dropdownIcon: {
color: '#ccc'
} }
}, },
@ -43,7 +57,8 @@ const darkTheme = {
bg: 'rgb(48, 48, 49)', bg: 'rgb(48, 48, 49)',
hoverBg: '#0F395E', hoverBg: '#0F395E',
shadow: 'rgb(0 0 0 / 36%) 0px 2px 8px', shadow: 'rgb(0 0 0 / 36%) 0px 2px 8px',
seperator: '#444' seperator: '#444',
labelBg: '#4a4949'
}, },
request: { request: {
@ -75,7 +90,24 @@ const darkTheme = {
collection: { collection: {
environment: { environment: {
bg: '#3D3D3D' bg: '#3D3D3D',
settings: {
bg: '#3D3D3D',
sidebar: {
bg: '#3D3D3D',
borderRight: '#4f4f4f'
},
item: {
border: '#569cd6',
hoverBg: 'transparent',
active: {
bg: 'transparent',
hoverBg: 'transparent'
},
},
gridBorder: '#4f4f4f'
}
} }
}, },
@ -93,6 +125,9 @@ const darkTheme = {
bg: 'rgb(65, 65, 65)', bg: 'rgb(65, 65, 65)',
border: 'rgb(65, 65, 65)', border: 'rgb(65, 65, 65)',
focusBorder: 'rgb(65, 65, 65)' focusBorder: 'rgb(65, 65, 65)'
},
backdrop: {
opacity: 0.2
} }
}, },
@ -108,6 +143,11 @@ const darkTheme = {
bg: 'transparent', bg: 'transparent',
border: 'transparent', border: 'transparent',
hoverBorder: '' hoverBorder: ''
},
disabled: {
color: '#a5a5a5',
bg: '#626262',
border: '#626262'
} }
}, },
@ -154,6 +194,10 @@ const darkTheme = {
striped: '#2A2D2F' striped: '#2A2D2F'
}, },
plainGrid: {
hoverBg: '#3D3D3D'
},
'primary-text': '#ffffff', 'primary-text': '#ffffff',
'secondary-text': '#929292', 'secondary-text': '#929292',
'sidebar-collection-item-active-background': '#e1e1e1', 'sidebar-collection-item-active-background': '#e1e1e1',

View File

@ -4,12 +4,22 @@ const lightTheme = {
textLink: '#1663bb', textLink: '#1663bb',
bg: '#fff', bg: '#fff',
colors: {
text: {
danger: 'rgb(185, 28, 28)'
},
bg: {
danger: '#dc3545'
}
},
menubar: { menubar: {
bg: 'rgb(44, 44, 44)', bg: 'rgb(44, 44, 44)',
}, },
sidebar: { sidebar: {
color: 'rgb(52, 52, 52)', color: 'rgb(52, 52, 52)',
muted: '#4b5563',
workspace: { workspace: {
bg: '#e1e1e1' bg: '#e1e1e1'
@ -29,6 +39,10 @@ const lightTheme = {
indentBorder: 'solid 1px #d0d0d0' indentBorder: 'solid 1px #d0d0d0'
} }
} }
},
dropdownIcon: {
color: 'rgb(110 110 110)'
} }
}, },
@ -43,7 +57,8 @@ const lightTheme = {
bg: '#fff', bg: '#fff',
hoverBg: '#e9e9e9', hoverBg: '#e9e9e9',
shadow: 'rgb(50 50 93 / 25%) 0px 6px 12px -2px, rgb(0 0 0 / 30%) 0px 3px 7px -3px', shadow: 'rgb(50 50 93 / 25%) 0px 6px 12px -2px, rgb(0 0 0 / 30%) 0px 3px 7px -3px',
seperator: '#e7e7e7' seperator: '#e7e7e7',
labelBg: '#f3f3f3'
}, },
request: { request: {
@ -75,7 +90,28 @@ const lightTheme = {
collection: { collection: {
environment: { environment: {
bg: '#efefef' bg: '#efefef',
settings: {
bg: 'white',
sidebar: {
bg: '#eaeaea',
borderRight: 'transparent'
},
item: {
border: '#546de5',
hoverBg: '#e4e4e4',
active: {
bg: '#dcdcdc',
hoverBg: '#dcdcdc'
},
},
gridBorder: '#f4f4f4'
}
},
sidebar: {
bg: '#eaeaea'
} }
}, },
@ -86,13 +122,16 @@ const lightTheme = {
iconColor: 'black' iconColor: 'black'
}, },
body: { body: {
color: '#ccc', color: 'rgb(52, 52, 52)',
bg: 'white', bg: 'white',
}, },
input : { input : {
bg: 'white', bg: 'white',
border: '#ccc', border: '#ccc',
focusBorder: '#8b8b8b' focusBorder: '#8b8b8b'
},
backdrop: {
opacity: 0.4
} }
}, },
@ -108,6 +147,11 @@ const lightTheme = {
bg: 'white', bg: 'white',
border: 'white', border: 'white',
hoverBorder: '' hoverBorder: ''
},
disabled: {
color: '#9f9f9f',
bg: '#efefef',
border: 'rgb(234, 234, 234)'
} }
}, },
@ -154,6 +198,10 @@ const lightTheme = {
striped: '#f3f3f3' striped: '#f3f3f3'
}, },
plainGrid: {
hoverBg: '#f4f4f4'
},
'primary-text': 'rgb(52 52 52)', 'primary-text': 'rgb(52 52 52)',
'secondary-text': '#929292', 'secondary-text': '#929292',
'sidebar-collection-item-active-background': '#e1e1e1', 'sidebar-collection-item-active-background': '#e1e1e1',