Dark Mode (#912)

closes #704
This commit is contained in:
Tom Moor
2019-03-12 21:35:35 -07:00
committed by GitHub
parent 6445da33db
commit 59c82f1f06
46 changed files with 648 additions and 252 deletions

View File

@@ -20,7 +20,7 @@ export const Separator = styled.div`
margin-left: 12px;
width: 1px;
height: 20px;
background: ${props => props.theme.slateLight};
background: ${props => props.theme.divider};
`;
const Actions = styled(Flex)`
@@ -29,7 +29,7 @@ const Actions = styled(Flex)`
right: 0;
left: 0;
border-radius: 3px;
background: rgba(255, 255, 255, 0.9);
background: ${props => props.theme.background};
padding: 12px;
-webkit-backdrop-filter: blur(20px);

View File

@@ -26,7 +26,7 @@ class Alert extends React.Component<Props> {
const Container = styled(Flex)`
height: $headerHeight;
color: #ffffff;
color: ${props => props.theme.white};
font-size: 14px;
line-height: 1;

View File

@@ -39,7 +39,7 @@ const CircleImg = styled.img`
width: ${props => props.size}px;
height: ${props => props.size}px;
border-radius: 50%;
border: 2px solid ${props => props.theme.white};
border: 2px solid ${props => props.theme.background};
flex-shrink: 0;
`;

View File

@@ -8,8 +8,8 @@ const RealButton = styled.button`
margin: 0;
padding: 0;
border: 0;
background: ${props => props.theme.blackLight};
color: ${props => props.theme.white};
background: ${props => props.theme.buttonBackground};
color: ${props => props.theme.buttonText};
box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px;
border-radius: 4px;
font-size: 12px;
@@ -28,26 +28,26 @@ const RealButton = styled.button`
}
&:hover {
background: ${props => darken(0.05, props.theme.blackLight)};
background: ${props => darken(0.05, props.theme.buttonBackground)};
}
&:disabled {
cursor: default;
pointer-events: none;
color: ${props => lighten(0.2, props.theme.blackLight)};
color: ${props => lighten(0.2, props.theme.buttonText)};
}
${props =>
props.neutral &&
`
background: ${props.theme.white};
color: ${props.theme.text};
background: ${props.theme.buttonNeutralBackground};
color: ${props.theme.buttonNeutralText};
box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 2px;
border: 1px solid ${props.theme.slateLight};
border: 1px solid ${darken(0.1, props.theme.buttonNeutralBackground)};
&:hover {
background: ${darken(0.05, props.theme.white)};
border: 1px solid ${darken(0.05, props.theme.slateLight)};
background: ${darken(0.05, props.theme.buttonNeutralBackground)};
border: 1px solid ${darken(0.15, props.theme.buttonNeutralBackground)};
}
`} ${props =>
props.danger &&

View File

@@ -4,6 +4,7 @@ import { observer } from 'mobx-react';
import { Link } from 'react-router-dom';
import Document from 'models/Document';
import styled, { withTheme } from 'styled-components';
import { darken } from 'polished';
import Flex from 'shared/components/Flex';
import Highlight from 'components/Highlight';
import { StarredIcon } from 'outline-icons';
@@ -20,7 +21,7 @@ type Props = {
};
const StyledStar = withTheme(styled(({ solid, theme, ...props }) => (
<StarredIcon color={solid ? theme.black : theme.text} {...props} />
<StarredIcon color={theme.text} {...props} />
))`
flex-shrink: 0;
opacity: ${props => (props.solid ? '1 !important' : 0)};
@@ -59,8 +60,8 @@ const DocumentLink = styled(Link)`
&:hover,
&:active,
&:focus {
background: ${props => props.theme.smokeLight};
border: 2px solid ${props => props.theme.smoke};
background: ${props => props.theme.listItemHoverBackground};
border: 2px solid ${props => props.theme.listItemHoverBorder};
outline: none;
${StyledStar}, ${StyledDocumentMenu} {
@@ -73,7 +74,7 @@ const DocumentLink = styled(Link)`
}
&:focus {
border: 2px solid ${props => props.theme.slateDark};
border: 2px solid ${props => darken(0.5, props.theme.listItemHoverBorder)};
}
`;
@@ -102,7 +103,7 @@ const Title = styled(Highlight)`
const ResultContext = styled(Highlight)`
display: block;
color: ${props => props.theme.slateDark};
color: ${props => props.theme.textTertiary};
font-size: 14px;
margin-top: -0.25em;
margin-bottom: 0.25em;

View File

@@ -7,13 +7,13 @@ import Flex from 'shared/components/Flex';
import Time from 'shared/components/Time';
const Container = styled(Flex)`
color: ${props => props.theme.slate};
color: ${props => props.theme.textTertiary};
font-size: 13px;
`;
const Modified = styled.span`
color: ${props =>
props.highlight ? props.theme.slateDark : props.theme.slate};
props.highlight ? props.theme.text : props.theme.textTertiary};
font-weight: ${props => (props.highlight ? '600' : '400')};
`;

View File

@@ -3,8 +3,8 @@ import * as React from 'react';
import invariant from 'invariant';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import styled from 'styled-components';
import { PortalWithState } from 'react-portal';
import styled from 'styled-components';
import Flex from 'shared/components/Flex';
import { fadeAndScaleIn } from 'shared/styles/animations';
@@ -89,14 +89,13 @@ const Menu = styled.div`
right: ${({ right }) => right}px;
top: ${({ top }) => top}px;
z-index: 1000;
border: ${props => props.theme.slateLight};
background: ${props => props.theme.white};
background: ${props => props.theme.menuBackground};
border-radius: 2px;
padding: 0.5em 0;
min-width: 180px;
overflow: hidden;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 4px 8px rgba(0, 0, 0, 0.08),
0 2px 4px rgba(0, 0, 0, 0.08);
box-shadow: ${props => props.theme.menuShadow};
@media print {
display: none;

View File

@@ -23,13 +23,13 @@ const MenuItem = styled.a`
height: 32px;
color: ${props =>
props.disabled ? props.theme.slate : props.theme.slateDark};
props.disabled ? props.theme.textTertiary : props.theme.textSecondary};
justify-content: left;
align-items: center;
font-size: 15px;
cursor: default;
svg {
svg:not(:last-child) {
margin-right: 8px;
}

View File

@@ -3,6 +3,7 @@ import * as React from 'react';
import { Redirect } from 'react-router-dom';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import { withTheme } from 'styled-components';
import RichMarkdownEditor from 'rich-markdown-editor';
import { uploadFile } from 'utils/uploadFile';
import isInternalUrl from 'utils/isInternalUrl';
@@ -89,7 +90,7 @@ class Editor extends React.Component<Props> {
}
}
// $FlowIssue - https://github.com/facebook/flow/issues/6103
export default React.forwardRef((props, ref) => (
<Editor {...props} forwardedRef={ref} />
));
export default withTheme(
// $FlowIssue - https://github.com/facebook/flow/issues/6103
React.forwardRef((props, ref) => <Editor {...props} forwardedRef={ref} />)
);

View File

@@ -3,7 +3,7 @@ import styled from 'styled-components';
const HelpText = styled.p`
margin-top: 0;
color: ${props => props.theme.slateDark};
color: ${props => props.theme.textSecondary};
font-size: ${props => (props.small ? '13px' : 'inherit')};
`;

View File

@@ -39,6 +39,8 @@ function Highlight({
const Mark = styled.mark`
background: ${props => props.theme.yellow};
border-radius: 2px;
padding: 0 4px;
`;
export default Highlight;

View File

@@ -1,5 +1,7 @@
// @flow
import * as React from 'react';
import { observer } from 'mobx-react';
import { observable } from 'mobx';
import styled from 'styled-components';
import Flex from 'shared/components/Flex';
@@ -9,10 +11,11 @@ const RealTextarea = styled.textarea`
padding: 8px 12px;
outline: none;
background: none;
color: ${props => props.theme.text};
&:disabled,
&::placeholder {
color: ${props => props.theme.slate};
color: ${props => props.theme.placeholder};
}
`;
@@ -22,10 +25,11 @@ const RealInput = styled.input`
padding: 8px 12px;
outline: none;
background: none;
color: ${props => props.theme.text};
&:disabled,
&::placeholder {
color: ${props => props.theme.slate};
color: ${props => props.theme.placeholder};
}
&::-webkit-search-cancel-button {
@@ -46,13 +50,14 @@ export const Outline = styled(Flex)`
color: inherit;
border-width: 1px;
border-style: solid;
border-color: ${props => (props.hasError ? 'red' : props.theme.slateLight)};
border-color: ${props =>
props.hasError
? 'red'
: props.focused
? props.theme.inputBorderFocused
: props.theme.inputBorder};
border-radius: 4px;
font-weight: normal;
&:focus {
border-color: ${props => props.theme.slate};
}
`;
export const LabelText = styled.div`
@@ -68,26 +73,39 @@ export type Props = {
short?: boolean,
};
export default function Input({
type = 'text',
label,
className,
short,
...rest
}: Props) {
const InputComponent = type === 'textarea' ? RealTextarea : RealInput;
@observer
class Input extends React.Component<Props> {
@observable focused: boolean = false;
return (
<Wrapper className={className} short={short}>
<label>
{label && <LabelText>{label}</LabelText>}
<Outline>
<InputComponent
type={type === 'textarea' ? undefined : type}
{...rest}
/>
</Outline>
</label>
</Wrapper>
);
handleBlur = () => {
this.focused = false;
};
handleFocus = () => {
this.focused = true;
};
render() {
const { type = 'text', label, className, short, ...rest } = this.props;
const InputComponent = type === 'textarea' ? RealTextarea : RealInput;
return (
<Wrapper className={className} short={short}>
<label>
{label && <LabelText>{label}</LabelText>}
<Outline focused={this.focused}>
<InputComponent
onBlur={this.handleBlur}
onFocus={this.handleFocus}
type={type === 'textarea' ? undefined : type}
{...rest}
/>
</Outline>
</label>
</Wrapper>
);
}
}
export default Input;

View File

@@ -2,7 +2,7 @@
import * as React from 'react';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import styled from 'styled-components';
import styled, { withTheme } from 'styled-components';
import Input, { LabelText, Outline } from 'components/Input';
type Props = {
@@ -15,11 +15,20 @@ type Props = {
@observer
class InputRich extends React.Component<Props> {
@observable editorComponent: *;
@observable focused: boolean = false;
componentDidMount() {
this.loadEditor();
}
handleBlur = () => {
this.focused = false;
};
handleFocus = () => {
this.focused = true;
};
loadEditor = async () => {
const EditorImport = await import('./Editor');
this.editorComponent = EditorImport.default;
@@ -33,8 +42,16 @@ class InputRich extends React.Component<Props> {
<React.Fragment>
<LabelText>{label}</LabelText>
{Editor ? (
<StyledOutline maxHeight={maxHeight} minHeight={minHeight}>
<Editor {...rest} />
<StyledOutline
maxHeight={maxHeight}
minHeight={minHeight}
focused={this.focused}
>
<Editor
onBlur={this.handleBlur}
onFocus={this.handleFocus}
{...rest}
/>
</StyledOutline>
) : (
<Input
@@ -60,4 +77,4 @@ const StyledOutline = styled(Outline)`
}
`;
export default InputRich;
export default withTheme(InputRich);

View File

@@ -7,7 +7,7 @@ const Key = styled.kbd`
font: 11px 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier,
monospace;
line-height: 10px;
color: ${props => props.theme.text};
color: ${props => props.theme.almostBlack};
vertical-align: middle;
background-color: ${props => props.theme.smokeLight};
border: solid 1px ${props => props.theme.slateLight};

View File

@@ -21,7 +21,7 @@ export const Label = styled(Flex)`
font-size: 13px;
font-weight: 500;
text-transform: uppercase;
color: #9fa6ab;
color: ${props => props.theme.textTertiary};
letter-spacing: 0.04em;
`;

View File

@@ -2,7 +2,7 @@
import * as React from 'react';
import { Switch, Route, Redirect } from 'react-router-dom';
import { Helmet } from 'react-helmet';
import styled from 'styled-components';
import styled, { withTheme } from 'styled-components';
import breakpoint from 'styled-components-breakpoint';
import { observable } from 'mobx';
import { observer, inject } from 'mobx-react';
@@ -35,6 +35,7 @@ type Props = {
auth: AuthStore,
ui: UiStore,
notifications?: React.Node,
theme: Object,
};
@observer
@@ -42,12 +43,23 @@ class Layout extends React.Component<Props> {
scrollable: ?HTMLDivElement;
@observable redirectTo: ?string;
componentWillMount() {
this.updateBackground();
}
componentDidUpdate() {
this.updateBackground();
if (this.redirectTo) {
this.redirectTo = undefined;
}
}
updateBackground() {
// ensure the wider page color always matches the theme
window.document.body.style.background = this.props.theme.background;
}
@keydown(['/', 't', 'meta+k'])
goToSearch(ev) {
ev.preventDefault();
@@ -124,6 +136,7 @@ class Layout extends React.Component<Props> {
}
const Container = styled(Flex)`
background: ${props => props.theme.background};
position: relative;
width: 100vw;
min-height: 100%;
@@ -142,4 +155,4 @@ const Content = styled(Flex)`
`};
`;
export default inject('auth', 'ui', 'documents')(Layout);
export default inject('auth', 'ui', 'documents')(withTheme(Layout));

View File

@@ -29,7 +29,7 @@ const Wrapper = styled.li`
display: flex;
padding: ${props => (props.compact ? '8px' : '12px')} 0;
margin: 0;
border-bottom: 1px solid ${props => props.theme.smokeDark};
border-bottom: 1px solid ${props => props.theme.divider};
`;
const Image = styled(Flex)`

View File

@@ -25,7 +25,7 @@ const Redacted = styled(Flex)`
width: ${props => (props.header ? props.width / 2 : props.width)}%;
height: ${props => (props.height ? props.height : props.header ? 24 : 18)}px;
margin-bottom: 6px;
background-color: ${props => props.theme.smokeDark};
background-color: ${props => props.theme.divider};
animation: ${pulsate} 1.3s infinite;
&:last-child {

View File

@@ -4,6 +4,7 @@ import { observer } from 'mobx-react';
import styled, { createGlobalStyle } from 'styled-components';
import breakpoint from 'styled-components-breakpoint';
import ReactModal from 'react-modal';
import { transparentize } from 'polished';
import { CloseIcon } from 'outline-icons';
import { fadeAndScaleIn } from 'shared/styles/animations';
import Flex from 'shared/components/Flex';
@@ -17,6 +18,8 @@ type Props = {
const GlobalStyles = createGlobalStyle`
.ReactModal__Overlay {
background-color: ${props =>
transparentize(0.25, props.theme.background)} !important;
z-index: 100;
}
@@ -76,7 +79,7 @@ const StyledModal = styled(ReactModal)`
align-items: flex-start;
overflow-x: hidden;
overflow-y: auto;
background: white;
background: ${props => props.theme.background};
padding: 13vh 2rem 2rem;
outline: none;
`;
@@ -93,7 +96,7 @@ const Close = styled.a`
top: 16px;
right: 16px;
opacity: 0.5;
color: ${props => props.theme.text};
color: ${props => props.theme.textSecondary};
&:hover {
opacity: 1;

View File

@@ -6,10 +6,12 @@ import styled from 'styled-components';
import breakpoint from 'styled-components-breakpoint';
import { observer, inject } from 'mobx-react';
import { CloseIcon, MenuIcon } from 'outline-icons';
import Fade from 'components/Fade';
import Flex from 'shared/components/Flex';
import UiStore from 'stores/UiStore';
let firstRender = true;
type Props = {
children: React.Node,
location: Location,
@@ -30,8 +32,7 @@ class Sidebar extends React.Component<Props> {
render() {
const { children, ui } = this.props;
return (
const content = (
<Container
editMode={ui.editMode}
mobileSidebarVisible={ui.mobileSidebarVisible}
@@ -46,6 +47,14 @@ class Sidebar extends React.Component<Props> {
{children}
</Container>
);
// Fade in the sidebar on first render after page load
if (firstRender) {
firstRender = false;
return <Fade>{content}</Fade>;
}
return content;
}
}
@@ -55,7 +64,7 @@ const Container = styled(Flex)`
bottom: 0;
left: ${props => (props.editMode ? `-${props.theme.sidebarWidth}` : 0)};
width: 100%;
background: ${props => props.theme.smoke};
background: ${props => props.theme.sidebarBackground};
transition: left 100ms ease-out;
margin-left: ${props => (props.mobileSidebarVisible ? 0 : '-100%')};
z-index: 2;
@@ -68,7 +77,7 @@ const Container = styled(Flex)`
&:before,
&:after {
content: '';
background: ${props => props.theme.smoke};
background: ${props => props.theme.sidebarBackground};
position: absolute;
top: -50vh;
left: 0;

View File

@@ -6,7 +6,7 @@ const Header = styled(Flex)`
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
color: ${props => props.theme.slateDark};
color: ${props => props.theme.sidebarText};
letter-spacing: 0.04em;
margin: 4px 16px;
`;

View File

@@ -46,7 +46,7 @@ const Subheading = styled.div`
font-size: 11px;
text-transform: uppercase;
font-weight: 500;
color: ${props => props.theme.slateDark};
color: ${props => props.theme.sidebarText};
`;
const TeamName = styled.div`

View File

@@ -34,7 +34,7 @@ class SidebarLink extends React.Component<Props> {
activeStyle = {
color: this.props.theme.text,
background: 'rgba(0, 0, 0, 0.05)',
background: this.props.theme.sidebarItemBackground,
fontWeight: 600,
...this.style,
};
@@ -115,7 +115,7 @@ const StyledNavLink = styled(NavLink)`
text-overflow: ellipsis;
padding: 4px 16px;
border-radius: 4px;
color: ${props => props.theme.slateDark};
color: ${props => props.theme.sidebarText};
font-size: 15px;
cursor: pointer;
@@ -128,7 +128,7 @@ const Action = styled.span`
position: absolute;
top: 4px;
right: 4px;
color: ${props => props.theme.slate};
color: ${props => props.theme.textTertiary};
svg {
opacity: 0.75;

View File

@@ -5,9 +5,9 @@ const Subheading = styled.h3`
font-size: 11px;
font-weight: 500;
text-transform: uppercase;
color: ${props => props.theme.slate};
color: ${props => props.theme.textTertiary};
letter-spacing: 0.04em;
border-bottom: 1px solid ${props => props.theme.slateLight};
border-bottom: 1px solid ${props => props.theme.textTertiary};
padding-bottom: 8px;
margin-top: 30px;
margin-bottom: 10px;

View File

@@ -8,21 +8,21 @@ const NavItem = styled(NavLink)`
font-size: 11px;
font-weight: 500;
text-transform: uppercase;
color: ${props => props.theme.slate};
color: ${props => props.theme.textTertiary};
letter-spacing: 0.04em;
margin-right: 24px;
padding-bottom: 8px;
&:hover {
color: ${props => props.theme.slateDark};
color: ${props => props.theme.text};
}
`;
function Tab(props: *) {
const activeStyle = {
paddingBottom: '5px',
borderBottom: `3px solid ${props.theme.slateLight}`,
color: props.theme.slate,
borderBottom: `3px solid ${props.theme.textTertiary}`,
color: props.theme.textTertiary,
};
return <NavItem {...props} activeStyle={activeStyle} />;

View File

@@ -2,7 +2,7 @@
import styled from 'styled-components';
const Tabs = styled.nav`
border-bottom: 1px solid ${props => props.theme.slateLight};
border-bottom: 1px solid ${props => props.theme.textTertiary};
margin-top: 22px;
margin-bottom: 10px;
`;

25
app/components/Theme.js Normal file
View File

@@ -0,0 +1,25 @@
// @flow
import * as React from 'react';
import { inject, observer } from 'mobx-react';
import { ThemeProvider } from 'styled-components';
import { dark, light } from 'shared/styles/theme';
import GlobalStyles from 'shared/styles/globals';
import UiStore from 'stores/UiStore';
type Props = {
ui: UiStore,
children: React.Node,
};
function Theme({ children, ui }: Props) {
return (
<ThemeProvider theme={ui.theme === 'dark' ? dark : light} key={ui.theme}>
<React.Fragment>
<GlobalStyles />
{children}
</React.Fragment>
</ThemeProvider>
);
}
export default inject('ui')(observer(Theme));

View File

@@ -4,7 +4,194 @@ import { TooltipTrigger } from 'pui-react-tooltip';
import { createGlobalStyle } from 'styled-components';
const GlobalStyles = createGlobalStyle`
.tooltip:hover .tooltip-container:not(.tooltip-container-hidden){visibility:visible;opacity:1}.tooltip-container{visibility:hidden;-webkit-transition:opacity ease-out 0.2s;transition:opacity ease-out 0.2s;z-index:10;position:absolute;bottom:100%;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);margin:0 0 8px 0;text-align:left}.tooltip-container.tooltip-container-visible{visibility:visible}.tooltip-container.tooltip-hoverable:after{content:"";position:absolute;width:calc(100% + 16px);height:calc(100% + 16px);top:50%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%)}.tooltip-container .tooltip-content{white-space:nowrap;padding:4px 8px;font-size:12px;line-height:16px;font-weight:400;letter-spacing:0;text-transform:none;background-color:#243641;color:#fff;border-radius:2px;border:1px solid #243641;box-shadow:0px 2px 2px 0px rgba(36, 54, 65, .1),0px 0px 2px 0px rgba(36, 54, 65, .1)}.tooltip-container .tooltip-content:before{content:"";z-index:1;position:absolute;bottom:-4px;left:50%;-webkit-transform:translateX(-50%) rotateZ(45deg);transform:translateX(-50%) rotateZ(45deg);background-color:#243641;border-bottom:1px solid #243641;border-right:1px solid #243641;width:8px;height:8px}.tooltip-container .tooltip-content:after{content:"";box-sizing:content-box;z-index:-1;position:absolute;bottom:-4px;left:50%;-webkit-transform:translateX(-50%) rotateZ(45deg);transform:translateX(-50%) rotateZ(45deg);background-color:#243641;box-shadow:0px 2px 2px 0px rgba(36, 54, 65, .1),0px 0px 2px 0px rgba(36, 54, 65, .1);width:8px;height:8px}.tooltip{position:relative;display:inline-block}.tooltip.tooltip-light .tooltip-content{background-color:#fff;color:#243641;border:1px solid #DFE5E8}.tooltip.tooltip-light .tooltip-content:before{background-color:#fff;border-bottom:1px solid #DFE5E8;border-right:1px solid #DFE5E8}.tooltip.tooltip-light .tooltip-content:after{background-color:#fff}.tooltip.tooltip-bottom .tooltip-container{top:100%;bottom:auto;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);margin:8px 0 0 0}.tooltip.tooltip-bottom .tooltip-container .tooltip-content:before{bottom:auto;top:-4px;border-top:1px solid #243641;border-right:none;border-bottom:none;border-left:1px solid #243641}.tooltip.tooltip-bottom .tooltip-container .tooltip-content:after{bottom:auto;top:-4px}.tooltip.tooltip-bottom.tooltip-light .tooltip-content:before{border-top:1px solid #DFE5E8;border-left:1px solid #DFE5E8}.tooltip.tooltip-right .tooltip-container{top:50%;bottom:auto;left:100%;-webkit-transform:translatey(-50%);transform:translatey(-50%);margin:0 0 0 8px}.tooltip.tooltip-right .tooltip-container .tooltip-content:before{bottom:auto;left:-4px;top:50%;-webkit-transform:translatey(-50%) rotateZ(45deg);transform:translatey(-50%) rotateZ(45deg);border-top:none;border-right:none;border-bottom:1px solid #243641;border-left:1px solid #243641}.tooltip.tooltip-right .tooltip-container .tooltip-content:after{bottom:auto;left:-4px;top:50%;-webkit-transform:translatey(-50%) rotateZ(45deg);transform:translatey(-50%) rotateZ(45deg)}.tooltip.tooltip-right.tooltip-light .tooltip-content:before{border-bottom:1px solid #DFE5E8;border-left:1px solid #DFE5E8}.tooltip.tooltip-left .tooltip-container{top:50%;bottom:auto;right:100%;left:auto;-webkit-transform:translatey(-50%);transform:translatey(-50%);margin:0 8px 0 0}.tooltip.tooltip-left .tooltip-container .tooltip-content:before{bottom:auto;right:-4px;left:auto;top:50%;-webkit-transform:translatey(-50%) rotateZ(45deg);transform:translatey(-50%) rotateZ(45deg);border-top:1px solid #243641;border-right:1px solid #243641;border-bottom:none;border-left:none}.tooltip.tooltip-left .tooltip-container .tooltip-content:after{bottom:auto;right:-4px;left:auto;top:50%;-webkit-transform:translatey(-50%) rotateZ(45deg);transform:translatey(-50%) rotateZ(45deg)}.tooltip.tooltip-left.tooltip-light .tooltip-content:before{border-top:1px solid #DFE5E8;border-right:1px solid #DFE5E8}.tooltip-sm.tooltip-container{width:120px}.tooltip-sm.tooltip-container .tooltip-content{white-space:normal}.tooltip-md.tooltip-container{width:240px}.tooltip-md.tooltip-container .tooltip-content{white-space:normal}.tooltip-lg.tooltip-container{width:360px}.tooltip-lg.tooltip-container .tooltip-content{white-space:normal}.tether-element{z-index:99}.overlay-trigger{color:#1B78B3;-webkit-transition:all 300ms ease-out;transition:all 300ms ease-out;-webkit-transition-property:background-color, color, opacity;transition-property:background-color, color, opacity}.overlay-trigger:hover,.overlay-trigger:focus{color:#1f8ace;cursor:pointer;outline:none;text-decoration:none}.overlay-trigger:active,.overlay-trigger.active{color:#176698}
.tooltip:hover .tooltip-container:not(.tooltip-container-hidden){
visibility:visible;
opacity:1
}
.tooltip-container{
visibility:hidden;
-webkit-transition:opacity ease-out 0.2s;
transition:opacity ease-out 0.2s;
z-index:10;
position:absolute;
bottom:100%;
left:50%;
-webkit-transform:translateX(-50%);
transform:translateX(-50%);
margin:0 0 8px 0;
text-align:left
}
.tooltip-container.tooltip-container-visible{
visibility:visible
}
.tooltip-container.tooltip-hoverable:after{
content:"";
position:absolute;
width:calc(100% + 16px);
height:calc(100% + 16px);
top:50%;
left:50%;
-webkit-transform:translateX(-50%) translateY(-50%);
transform:translateX(-50%) translateY(-50%)
}
.tooltip-container .tooltip-content{
white-space:nowrap;
padding:4px 8px;
font-size:12px;
line-height:16px;
font-weight:400;
letter-spacing:0;
text-transform:none;
background-color:${props => props.theme.tooltipBackground};
color: ${props => props.theme.tooltipText};
border-radius:2px;
border:1px solid ${props => props.theme.tooltipBackground};
box-shadow:0px 2px 2px 0px rgba(36, 54, 65, .1),0px 0px 2px 0px rgba(36, 54, 65, .1)
}
.tooltip-container .tooltip-content:before{
content:"";
z-index:1;
position:absolute;
bottom:-4px;
left:50%;
-webkit-transform:translateX(-50%) rotateZ(45deg);
transform:translateX(-50%) rotateZ(45deg);
background-color:${props => props.theme.tooltipBackground};
border-bottom:1px solid ${props => props.theme.tooltipBackground};
border-right:1px solid ${props => props.theme.tooltipBackground};
width:8px;
height:8px
}
.tooltip-container .tooltip-content:after{
content:"";
box-sizing:content-box;
z-index:-1;
position:absolute;
bottom:-4px;
left:50%;
-webkit-transform:translateX(-50%) rotateZ(45deg);
transform:translateX(-50%) rotateZ(45deg);
background-color:${props => props.theme.tooltipBackground};
box-shadow:0px 2px 2px 0px rgba(36, 54, 65, .1),0px 0px 2px 0px rgba(36, 54, 65, .1);
width:8px;
height:8px
}
.tooltip{
position:relative;
display:inline-block
}
.tooltip.tooltip-bottom .tooltip-container{
top:100%;
bottom:auto;
left:50%;
-webkit-transform:translateX(-50%);
transform:translateX(-50%);
margin:8px 0 0 0
}
.tooltip.tooltip-bottom .tooltip-container .tooltip-content:before{
bottom:auto;
top:-4px;
border-top:1px solid ${props => props.theme.tooltipBackground};
border-right:none;
border-bottom:none;
border-left:1px solid ${props => props.theme.tooltipBackground}
}
.tooltip.tooltip-bottom .tooltip-container .tooltip-content:after{
bottom:auto;
top:-4px
}
.tooltip.tooltip-right .tooltip-container{
top:50%;
bottom:auto;
left:100%;
-webkit-transform:translatey(-50%);
transform:translatey(-50%);
margin:0 0 0 8px
}
.tooltip.tooltip-right .tooltip-container .tooltip-content:before{
bottom:auto;
left:-4px;
top:50%;
-webkit-transform:translatey(-50%) rotateZ(45deg);
transform:translatey(-50%) rotateZ(45deg);
border-top:none;
border-right:none;
border-bottom:1px solid ${props => props.theme.tooltipBackground};
border-left:1px solid ${props => props.theme.tooltipBackground}
}
.tooltip.tooltip-right .tooltip-container .tooltip-content:after{
bottom:auto;
left:-4px;
top:50%;
-webkit-transform:translatey(-50%) rotateZ(45deg);
transform:translatey(-50%) rotateZ(45deg)
}
.tooltip.tooltip-left .tooltip-container{
top:50%;
bottom:auto;
right:100%;
left:auto;
-webkit-transform:translatey(-50%);
transform:translatey(-50%);
margin:0 8px 0 0
}
.tooltip.tooltip-left .tooltip-container .tooltip-content:before{
bottom:auto;
right:-4px;
left:auto;
top:50%;
-webkit-transform:translatey(-50%) rotateZ(45deg);
transform:translatey(-50%) rotateZ(45deg);
border-top:1px solid ${props => props.theme.tooltipBackground};
border-right:1px solid ${props => props.theme.tooltipBackground};
border-bottom:none;
border-left:none
}
.tooltip.tooltip-left .tooltip-container .tooltip-content:after{
bottom:auto;
right:-4px;
left:auto;
top:50%;
-webkit-transform:translatey(-50%) rotateZ(45deg);
transform:translatey(-50%) rotateZ(45deg)
}
.tooltip-sm.tooltip-container{
width:120px
}
.tooltip-sm.tooltip-container .tooltip-content{
white-space:normal
}
.tooltip-md.tooltip-container{
width:240px
}
.tooltip-md.tooltip-container .tooltip-content{
white-space:normal
}
.tooltip-lg.tooltip-container{
width:360px
}
.tooltip-lg.tooltip-container .tooltip-content{
white-space:normal
}
.tether-element{
z-index:99
}
.overlay-trigger{
color:#1B78B3;
-webkit-transition:all 300ms ease-out;
transition:all 300ms ease-out;
-webkit-transition-property:background-color, color, opacity;
transition-property:background-color, color, opacity
}
.overlay-trigger:hover,.overlay-trigger:focus{
color:#1f8ace;
cursor:pointer;
outline:none;
text-decoration:none
}
.overlay-trigger:active,.overlay-trigger.active{
color:#176698
}
`;
const Tooltip = function(props: *) {

View File

@@ -70,7 +70,7 @@ const Rounded = styled.div`
const Iframe = styled.iframe`
border: 1px solid;
border-color: #ddd #ddd #ccc;
border-color: ${props => props.theme.embedBorder};
border-radius: 3px;
`;

View File

@@ -2,17 +2,15 @@
import * as React from 'react';
import { render } from 'react-dom';
import { Provider } from 'mobx-react';
import { ThemeProvider } from 'styled-components';
import { BrowserRouter as Router } from 'react-router-dom';
import stores from 'stores';
import theme from 'shared/styles/theme';
import GlobalStyles from 'shared/styles/globals';
import 'shared/styles/prism.css';
import ErrorBoundary from 'components/ErrorBoundary';
import ScrollToTop from 'components/ScrollToTop';
import Toasts from 'components/Toasts';
import Theme from 'components/Theme';
import Routes from './routes';
let DevTools;
@@ -25,10 +23,9 @@ const element = document.getElementById('root');
if (element) {
render(
<React.Fragment>
<GlobalStyles />
<ThemeProvider theme={theme}>
<ErrorBoundary>
<Provider {...stores}>
<ErrorBoundary>
<Provider {...stores}>
<Theme>
<Router>
<React.Fragment>
<ScrollToTop>
@@ -37,9 +34,9 @@ if (element) {
<Toasts />
</React.Fragment>
</Router>
</Provider>
</ErrorBoundary>
</ThemeProvider>
</Theme>
</Provider>
</ErrorBoundary>
{DevTools && <DevTools position={{ bottom: 0, right: 0 }} />}
</React.Fragment>,
element

View File

@@ -3,8 +3,11 @@ import * as React from 'react';
import { Redirect } from 'react-router-dom';
import { observable } from 'mobx';
import { inject, observer } from 'mobx-react';
import { MoonIcon } from 'outline-icons';
import styled, { withTheme } from 'styled-components';
import UiStore from 'stores/UiStore';
import AuthStore from 'stores/AuthStore';
import Flex from 'shared/components/Flex';
import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu';
import {
developers,
@@ -18,6 +21,7 @@ type Props = {
label: React.Node,
ui: UiStore,
auth: AuthStore,
theme: Object,
};
@observer
@@ -42,6 +46,8 @@ class AccountMenu extends React.Component<Props> {
render() {
if (this.redirectTo) return <Redirect to={this.redirectTo} push />;
const { ui, theme } = this.props;
const isLightTheme = ui.theme === 'light';
return (
<DropdownMenu
@@ -72,9 +78,22 @@ class AccountMenu extends React.Component<Props> {
</DropdownMenuItem>
<hr />
<DropdownMenuItem onClick={this.handleLogout}>Logout</DropdownMenuItem>
<hr />
<DropdownMenuItem onClick={ui.toggleDarkMode}>
<NightMode justify="space-between">
Night Mode{' '}
<MoonIcon
color={isLightTheme ? theme.textSecondary : theme.primary}
/>
</NightMode>
</DropdownMenuItem>
</DropdownMenu>
);
}
}
export default inject('ui', 'auth')(AccountMenu);
const NightMode = styled(Flex)`
width: 100%;
`;
export default inject('ui', 'auth')(withTheme(AccountMenu));

View File

@@ -4,7 +4,7 @@ import { observable } from 'mobx';
import { observer, inject } from 'mobx-react';
import { Redirect, Link, Switch, Route } from 'react-router-dom';
import styled from 'styled-components';
import styled, { withTheme } from 'styled-components';
import {
CollectionIcon,
PrivateCollectionIcon,
@@ -43,6 +43,7 @@ type Props = {
documents: DocumentsStore,
collections: CollectionsStore,
match: Object,
theme: Object,
};
@observer
@@ -115,7 +116,7 @@ class CollectionScene extends React.Component<Props> {
}
render() {
const { documents } = this.props;
const { documents, theme } = this.props;
if (this.redirectTo) return <Redirect to={this.redirectTo} push />;
if (!this.isFetching && !this.collection) return <Search notFound />;
@@ -139,7 +140,7 @@ class CollectionScene extends React.Component<Props> {
</HelpText>
<Wrapper>
<Link to={newDocumentUrl(collection)}>
<Button icon={<NewDocumentIcon color="#FFF" />}>
<Button icon={<NewDocumentIcon color={theme.buttonText} />}>
Create a document
</Button>
</Link>&nbsp;&nbsp;
@@ -184,6 +185,7 @@ class CollectionScene extends React.Component<Props> {
id={collection.id}
key={collection.description}
defaultValue={collection.description}
theme={theme}
readOnly
/>
)}
@@ -289,4 +291,6 @@ const Wrapper = styled(Flex)`
margin: 10px 0;
`;
export default inject('collections', 'documents', 'ui')(CollectionScene);
export default inject('collections', 'documents', 'ui')(
withTheme(CollectionScene)
);

View File

@@ -7,6 +7,7 @@ import { Redirect } from 'react-router-dom';
import styled from 'styled-components';
import breakpoint from 'styled-components-breakpoint';
import { NewDocumentIcon } from 'outline-icons';
import { transparentize } from 'polished';
import Document from 'models/Document';
import AuthStore from 'stores/AuthStore';
import { documentEditUrl } from 'utils/routeHelpers';
@@ -227,9 +228,9 @@ const Actions = styled(Flex)`
right: 0;
left: 0;
z-index: 1;
background: rgba(255, 255, 255, 0.9);
background: ${props => transparentize(0.1, props.theme.background)};
border-bottom: 1px solid
${props => (props.isCompact ? props.theme.smoke : 'transparent')};
${props => (props.isCompact ? props.theme.background : 'transparent')};
padding: 12px;
transition: all 100ms ease-out;
transform: translate3d(0, 0, 0);

View File

@@ -1,6 +1,5 @@
// @flow
import * as React from 'react';
import { lighten } from 'polished';
import styled, { withTheme } from 'styled-components';
import { SearchIcon } from 'outline-icons';
import Flex from 'shared/components/Flex';
@@ -26,8 +25,8 @@ class SearchField extends React.Component<Props> {
<Field align="center">
<StyledIcon
type="Search"
size={48}
color={lighten(0.1, this.props.theme.slate)}
size={46}
color={this.props.theme.textTertiary}
onClick={this.focusInput}
/>
<StyledInput
@@ -56,24 +55,25 @@ const StyledInput = styled.input`
font-weight: 400;
outline: none;
border: 0;
background: ${props => props.theme.smoke};
background: ${props => props.theme.sidebarBackground};
border-radius: 4px;
color: ${props => props.theme.text};
::-webkit-search-cancel-button {
-webkit-appearance: searchfield-cancel-button;
}
::-webkit-input-placeholder {
color: ${props => props.theme.slate};
color: ${props => props.theme.placeholder};
}
:-moz-placeholder {
color: ${props => props.theme.slate};
color: ${props => props.theme.placeholder};
}
::-moz-placeholder {
color: ${props => props.theme.slate};
color: ${props => props.theme.placeholder};
}
:-ms-input-placeholder {
color: ${props => props.theme.slate};
color: ${props => props.theme.placeholder};
}
`;

View File

@@ -126,7 +126,7 @@ class Profile extends React.Component<Props> {
}
const DangerZone = styled.div`
background: #fff;
background: ${props => props.theme.background};
position: absolute;
bottom: 16px;
`;

View File

@@ -8,6 +8,7 @@ import AuthStore from 'stores/AuthStore';
import ShareListItem from './components/ShareListItem';
import List from 'components/List';
import CenteredContent from 'components/CenteredContent';
import Subheading from 'components/Subheading';
import PageTitle from 'components/PageTitle';
import HelpText from 'components/HelpText';
@@ -46,6 +47,7 @@ class Shares extends React.Component<Props> {
sharing in <Link to="/settings/security">security settings</Link>.
</HelpText>
)}
<Subheading>Shared Documents</Subheading>
<List>
{shares.orderedData.map(share => (
<ShareListItem key={share.id} share={share} />

View File

@@ -7,6 +7,8 @@ import Collection from 'models/Collection';
import type { Toast } from '../types';
class UiStore {
@observable
theme: 'light' | 'dark' = window.localStorage.getItem('theme') || 'light';
@observable activeModalName: ?string;
@observable activeModalProps: ?Object;
@observable activeDocumentId: ?string;
@@ -16,6 +18,12 @@ class UiStore {
@observable mobileSidebarVisible: boolean = false;
@observable toasts: Map<string, Toast> = new Map();
@action
toggleDarkMode = () => {
this.theme = this.theme === 'dark' ? 'light' : 'dark';
window.localStorage.setItem('theme', this.theme);
};
@action
setActiveModal = (name: string, props: ?Object): void => {
this.activeModalName = name;

View File

@@ -122,7 +122,7 @@
"mobx-react": "^5.4.2",
"natural-sort": "^1.0.0",
"nodemailer": "^4.4.0",
"outline-icons": "^1.6.0",
"outline-icons": "^1.7.0",
"oy-vey": "^0.10.0",
"pg": "^6.1.5",
"pg-hstore": "2.3.2",

View File

@@ -20,21 +20,15 @@
flex: 1;
min-height: 100vh;
}
#sidebar-placeholder {
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 280px;
background: #F4F7FA;
}
</style>
</head>
<body>
<div id="root">
<div id="sidebar-placeholder"></div>
</div>
<div id="root"></div>
<script>
if (window.localStorage.getItem("theme") === "dark") {
window.document.querySelector('#root').style.background = "#111319";
}
</script>
<script src="/static/bundle.js"></script>
</body>
</html>

View File

@@ -23,21 +23,15 @@
flex: 1;
min-height: 100vh;
}
#sidebar-placeholder {
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 280px;
background: #F4F7FA;
}
</style>
</head>
<body>
<div id="root">
<div id="sidebar-placeholder"></div>
</div>
<div id="root"></div>
<script>
if (window.localStorage.getItem("theme") === "dark") {
window.document.querySelector('#root').style.background = "#111319";
}
</script>
<script src="//d2wy8f7a9ursnm.cloudfront.net/bugsnag-3.min.js" data-apikey="<%= BUGSNAG_KEY %>"></script>
</body>
</html>

View File

@@ -8,7 +8,7 @@ import {
ThemeProvider,
} from 'styled-components';
import Layout from '../pages/components/Layout';
import theme from '../../shared/styles/theme';
import { light } from '../../shared/styles/theme';
const sheet = new ServerStyleSheet();
@@ -28,7 +28,7 @@ export default function renderpage(ctx: Object, children: React.Node) {
const html = ReactDOMServer.renderToString(
<StyleSheetManager sheet={sheet.instance}>
<ThemeProvider theme={theme}>
<ThemeProvider theme={light}>
<Layout sessions={sessions} loggedIn={loggedIn}>
{children}
</Layout>

View File

@@ -1,12 +1,13 @@
// @flow
import styled from 'styled-components';
import { darken } from 'polished';
const TeamLogo = styled.img`
width: 38px;
height: 38px;
border-radius: 4px;
background: ${props => props.theme.white};
border: 1px solid ${props => props.theme.slateLight};
border: 1px solid ${props => darken(0.1, props.theme.sidebarBackground)};
`;
export default TeamLogo;

View File

@@ -1,84 +0,0 @@
// @flow
import theme from './theme';
export default `
@font-face {
font-family: 'Lato';
src: url('/fonts/LatoLatin-Semibold.woff') format('woff');
}
* {
box-sizing: border-box;
}
html,
body {
width: 100%;
min-height: 100vh;
margin: 0;
padding: 0;
}
body,
button,
input,
optgroup,
select,
textarea {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
body {
font-size: 16px;
line-height: 1.5;
color: ${theme.text};
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
a {
color: ${theme.blue};
text-decoration: none;
cursor: pointer;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Lato',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen, Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;
font-weight: 500;
line-height: 1.25;
margin-top: 1em;
margin-bottom: 0.5em;
color: ${theme.text};
}
h1 { font-size: 2.25em; }
h2 { font-size: 1.5em; }
h3 { font-size: 1.25em; }
h4 { font-size: 1em; }
h5 { font-size: 0.875em; }
h6 { font-size: 0.75em; }
p,
dl,
ol,
ul,
pre,
blockquote {
margin-top: 1em;
margin-bottom: 1em;
}
hr {
border: 0;
height: 0;
border-top: 1px solid rgba(0, 0, 0, 0.1);
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}
`;

View File

@@ -1,9 +1,86 @@
// @flow
import styledNormalize from 'styled-normalize';
import { createGlobalStyle } from 'styled-components';
import base from './base';
export default createGlobalStyle`
${styledNormalize}
${base}
@font-face {
font-family: 'Lato';
src: url('/fonts/LatoLatin-Semibold.woff') format('woff');
}
* {
box-sizing: border-box;
}
html,
body {
width: 100%;
min-height: 100vh;
margin: 0;
padding: 0;
}
body,
button,
input,
optgroup,
select,
textarea {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
body {
font-size: 16px;
line-height: 1.5;
color: ${props => props.theme.text};
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
a {
color: ${props => props.theme.primary};
text-decoration: none;
cursor: pointer;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Lato',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen, Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;
font-weight: 500;
line-height: 1.25;
margin-top: 1em;
margin-bottom: 0.5em;
color: ${props => props.theme.text};
}
h1 { font-size: 2.25em; }
h2 { font-size: 1.5em; }
h3 { font-size: 1.25em; }
h4 { font-size: 1em; }
h5 { font-size: 0.875em; }
h6 { font-size: 0.75em; }
p,
dl,
ol,
ul,
pre,
blockquote {
margin-top: 1em;
margin-bottom: 1em;
}
hr {
border: 0;
height: 0;
border-top: 1px solid ${props => props.theme.divider};
}
`;

View File

@@ -1,18 +1,10 @@
// @flow
const theme = {
fontFamily:
"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen, Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif",
monospaceFontFamily: `Menlo, Consolas, 'Liberation Mono', monospace;`,
fontWeight: 400,
import { darken, lighten } from 'polished';
text: '#171B35',
link: '#1AB6FF',
primary: '#1AB6FF',
placeholder: '#b1becc',
danger: '#D0021B',
warning: '#f08a24',
success: '#2f3336',
info: '#a0d3e8',
const colors = {
almostBlack: '#111319',
lightBlack: '#2F3336',
almostWhite: '#E6E6E6',
slate: '#9BA6B2',
slateLight: '#DAE1E9',
@@ -22,19 +14,131 @@ const theme = {
smokeLight: '#F9FBFC',
smokeDark: '#E8EBED',
white: '#FFFFFF',
blue: '#1AB6FF',
black: '#000000',
blackLight: '#2f3336',
white: '#FFF',
white10: 'rgba(255, 255, 255, 0.1)',
black: '#000',
black05: 'rgba(0, 0, 0, 0.05)',
black10: 'rgba(0, 0, 0, 0.1)',
black50: 'rgba(0, 0, 0, 0.50)',
primary: '#1AB6FF',
yellow: '#FBCA04',
danger: '#D0021B',
warning: '#f08a24',
success: '#2f3336',
info: '#a0d3e8',
};
const spacing = {
padding: '1.5vw 1.875vw',
vpadding: '1.5vw',
hpadding: '1.875vw',
sidebarWidth: '280px',
sidebarMinWidth: '250px',
sidebarMaxWidth: '350px',
contentHeaderBackground: 'hsl(180, 58%, 85%)',
};
export default theme;
export const base = {
...colors,
...spacing,
fontFamily:
"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen, Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif",
fontWeight: 400,
link: colors.primary,
};
export const light = {
...base,
background: colors.white,
text: colors.almostBlack,
textSecondary: colors.slateDark,
textTertiary: colors.slate,
placeholder: '#B1BECC',
sidebarBackground: 'rgb(244, 247, 250)',
sidebarItemBackground: colors.black05,
sidebarText: 'rgb(78, 92, 110)',
menuBackground: colors.white,
menuShadow:
'0 0 0 1px rgba(0, 0, 0, 0.05), 0 4px 8px rgba(0, 0, 0, 0.08), 0 2px 4px rgba(0, 0, 0, 0.08)',
divider: colors.slateLight,
inputBorder: colors.slateLight,
inputBorderFocused: colors.slate,
listItemHoverBackground: colors.smoke,
listItemHoverBorder: colors.smokeDark,
toolbarBackground: colors.lightBlack,
toolbarInput: colors.white10,
toolbarItem: colors.white,
buttonBackground: colors.lightBlack,
buttonText: colors.white,
buttonNeutralBackground: colors.white,
buttonNeutralText: colors.almostBlack,
tooltipBackground: colors.almostBlack,
tooltipText: colors.white,
blockToolbarBackground: colors.smoke,
blockToolbarTrigger: colors.slate,
blockToolbarTriggerIcon: colors.white,
blockToolbarItem: colors.almostBlack,
quote: colors.slateLight,
codeBackground: colors.smoke,
codeBorder: colors.smokeDark,
embedBorder: '#DDD #DDD #CCC',
horizontalRule: colors.smokeDark,
};
export const dark = {
...base,
background: colors.almostBlack,
text: colors.almostWhite,
textSecondary: lighten(0.2, colors.slate),
textTertiary: colors.slate,
placeholder: darken(0.5, '#B1BECC'),
sidebarBackground: colors.black50,
sidebarItemBackground: colors.black50,
sidebarText: colors.slate,
menuBackground: lighten(0.015, colors.almostBlack),
menuShadow:
'0 0 0 1px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.08)',
divider: colors.slate,
inputBorder: colors.slateDark,
inputBorderFocused: colors.slate,
listItemHoverBackground: colors.black10,
listItemHoverBorder: colors.black50,
toolbarBackground: colors.white,
toolbarInput: colors.black10,
toolbarItem: colors.lightBlack,
buttonBackground: colors.white,
buttonText: colors.lightBlack,
buttonNeutralBackground: colors.almostBlack,
buttonNeutralText: colors.white,
tooltipBackground: colors.white,
tooltipText: colors.lightBlack,
blockToolbarBackground: colors.white,
blockToolbarTrigger: colors.almostWhite,
blockToolbarTriggerIcon: colors.almostBlack,
blockToolbarItem: colors.lightBlack,
quote: colors.almostWhite,
codeBackground: colors.almostBlack,
codeBorder: colors.black50,
embedBorder: colors.black50,
horizontalRule: colors.almostWhite,
};
export default light;

View File

@@ -7038,6 +7038,10 @@ outline-icons@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/outline-icons/-/outline-icons-1.6.0.tgz#6c7897d354e6bd77ca5498cd3a989b8cb9482574"
outline-icons@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/outline-icons/-/outline-icons-1.7.0.tgz#093f2f18c80bf5577bc31a6ff41460f2feb76fb7"
oy-vey@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/oy-vey/-/oy-vey-0.10.0.tgz#16160f837f0ea3d0340adfc2377ba93d1ed9ce76"