@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
`;
|
||||
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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')};
|
||||
`;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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} />)
|
||||
);
|
||||
|
||||
@@ -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')};
|
||||
`;
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ function Highlight({
|
||||
|
||||
const Mark = styled.mark`
|
||||
background: ${props => props.theme.yellow};
|
||||
border-radius: 2px;
|
||||
padding: 0 4px;
|
||||
`;
|
||||
|
||||
export default Highlight;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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;
|
||||
`;
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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)`
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
`;
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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} />;
|
||||
|
||||
@@ -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
25
app/components/Theme.js
Normal 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));
|
||||
@@ -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: *) {
|
||||
|
||||
Reference in New Issue
Block a user