refactor: Move depths and breakpoints out of theme

This commit is contained in:
Tom Moor
2022-04-04 21:20:38 -07:00
parent 20a69b711a
commit 2e41ace386
25 changed files with 73 additions and 79 deletions

View File

@@ -1,6 +1,7 @@
import * as React from "react"; import * as React from "react";
import styled from "styled-components"; import styled from "styled-components";
import breakpoint from "styled-components-breakpoint"; import breakpoint from "styled-components-breakpoint";
import { depths } from "@shared/styles";
import env from "~/env"; import env from "~/env";
import OutlineLogo from "./OutlineLogo"; import OutlineLogo from "./OutlineLogo";
@@ -38,7 +39,7 @@ const Link = styled.a`
} }
${breakpoint("tablet")` ${breakpoint("tablet")`
z-index: ${(props: any) => props.theme.depths.sidebar + 1}; z-index: ${depths.sidebar + 1};
position: fixed; position: fixed;
bottom: 0; bottom: 0;
left: 0; left: 0;

View File

@@ -6,6 +6,7 @@ import { useTranslation } from "react-i18next";
import { Portal } from "react-portal"; import { Portal } from "react-portal";
import styled from "styled-components"; import styled from "styled-components";
import breakpoint from "styled-components-breakpoint"; import breakpoint from "styled-components-breakpoint";
import { depths } from "@shared/styles";
import CommandBarResults from "~/components/CommandBarResults"; import CommandBarResults from "~/components/CommandBarResults";
import SearchActions from "~/components/SearchActions"; import SearchActions from "~/components/SearchActions";
import rootActions from "~/actions/root"; import rootActions from "~/actions/root";
@@ -90,7 +91,7 @@ const Hint = styled(Text)`
`; `;
const Positioner = styled(KBarPositioner)` const Positioner = styled(KBarPositioner)`
z-index: ${(props) => props.theme.depths.commandBar}; z-index: ${depths.commandBar};
`; `;
const SearchInput = styled(KBarSearch)` const SearchInput = styled(KBarSearch)`

View File

@@ -4,6 +4,7 @@ import { Portal } from "react-portal";
import { Menu } from "reakit/Menu"; import { Menu } from "reakit/Menu";
import styled from "styled-components"; import styled from "styled-components";
import breakpoint from "styled-components-breakpoint"; import breakpoint from "styled-components-breakpoint";
import { depths } from "@shared/styles";
import useMenuContext from "~/hooks/useMenuContext"; import useMenuContext from "~/hooks/useMenuContext";
import useMenuHeight from "~/hooks/useMenuHeight"; import useMenuHeight from "~/hooks/useMenuHeight";
import usePrevious from "~/hooks/usePrevious"; import usePrevious from "~/hooks/usePrevious";
@@ -148,7 +149,7 @@ export const Backdrop = styled.div`
right: 0; right: 0;
bottom: 0; bottom: 0;
background: ${(props) => props.theme.backdrop}; background: ${(props) => props.theme.backdrop};
z-index: ${(props) => props.theme.depths.menu - 1}; z-index: ${depths.menu - 1};
${breakpoint("tablet")` ${breakpoint("tablet")`
display: none; display: none;
@@ -157,7 +158,7 @@ export const Backdrop = styled.div`
export const Position = styled.div` export const Position = styled.div`
position: absolute; position: absolute;
z-index: ${(props) => props.theme.depths.menu}; z-index: ${depths.menu};
// overrides make mobile-first coding style challenging // overrides make mobile-first coding style challenging
// so we explicitly define mobile breakpoint here // so we explicitly define mobile breakpoint here

View File

@@ -2,6 +2,7 @@ import { observer } from "mobx-react";
import * as React from "react"; import * as React from "react";
import { Dialog, DialogBackdrop, useDialogState } from "reakit/Dialog"; import { Dialog, DialogBackdrop, useDialogState } from "reakit/Dialog";
import styled from "styled-components"; import styled from "styled-components";
import { depths } from "@shared/styles";
import Scrollable from "~/components/Scrollable"; import Scrollable from "~/components/Scrollable";
import usePrevious from "~/hooks/usePrevious"; import usePrevious from "~/hooks/usePrevious";
@@ -72,7 +73,7 @@ const Backdrop = styled.div`
right: 0; right: 0;
bottom: 0; bottom: 0;
background-color: ${(props) => props.theme.backdrop} !important; background-color: ${(props) => props.theme.backdrop} !important;
z-index: ${(props) => props.theme.depths.modalOverlay}; z-index: ${depths.modalOverlay};
transition: opacity 200ms ease-in-out; transition: opacity 200ms ease-in-out;
opacity: 0; opacity: 0;
@@ -87,7 +88,7 @@ const Scene = styled.div`
right: 0; right: 0;
bottom: 0; bottom: 0;
margin: 12px; margin: 12px;
z-index: ${(props) => props.theme.depths.modal}; z-index: ${depths.modal};
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: flex-start; align-items: flex-start;

View File

@@ -5,6 +5,7 @@ import { transparentize } from "polished";
import * as React from "react"; import * as React from "react";
import styled from "styled-components"; import styled from "styled-components";
import breakpoint from "styled-components-breakpoint"; import breakpoint from "styled-components-breakpoint";
import { depths } from "@shared/styles";
import Button from "~/components/Button"; import Button from "~/components/Button";
import Fade from "~/components/Fade"; import Fade from "~/components/Fade";
import Flex from "~/components/Flex"; import Flex from "~/components/Flex";
@@ -100,7 +101,7 @@ const Actions = styled(Flex)`
const Wrapper = styled(Flex)<{ $passThrough?: boolean }>` const Wrapper = styled(Flex)<{ $passThrough?: boolean }>`
top: 0; top: 0;
z-index: ${(props) => props.theme.depths.header}; z-index: ${depths.header};
position: sticky; position: sticky;
background: ${(props) => props.theme.background}; background: ${(props) => props.theme.background};

View File

@@ -2,6 +2,7 @@ import { transparentize } from "polished";
import * as React from "react"; import * as React from "react";
import { Portal } from "react-portal"; import { Portal } from "react-portal";
import styled from "styled-components"; import styled from "styled-components";
import { depths } from "@shared/styles";
import parseDocumentSlug from "@shared/utils/parseDocumentSlug"; import parseDocumentSlug from "@shared/utils/parseDocumentSlug";
import { isInternalUrl } from "@shared/utils/urls"; import { isInternalUrl } from "@shared/utils/urls";
import HoverPreviewDocument from "~/components/HoverPreviewDocument"; import HoverPreviewDocument from "~/components/HoverPreviewDocument";
@@ -195,7 +196,7 @@ const Card = styled.div`
const Position = styled.div<{ fixed?: boolean; top?: number; left?: number }>` const Position = styled.div<{ fixed?: boolean; top?: number; left?: number }>`
margin-top: 10px; margin-top: 10px;
position: ${({ fixed }) => (fixed ? "fixed" : "absolute")}; position: ${({ fixed }) => (fixed ? "fixed" : "absolute")};
z-index: ${(props) => props.theme.depths.hoverPreview}; z-index: ${depths.hoverPreview};
display: flex; display: flex;
max-height: 75%; max-height: 75%;

View File

@@ -1,5 +1,6 @@
import * as React from "react"; import * as React from "react";
import styled, { keyframes } from "styled-components"; import styled, { keyframes } from "styled-components";
import { depths } from "@shared/styles";
const LoadingIndicatorBar = () => { const LoadingIndicatorBar = () => {
return ( return (
@@ -17,7 +18,7 @@ const loadingFrame = keyframes`
const Container = styled.div` const Container = styled.div`
position: fixed; position: fixed;
top: 0; top: 0;
z-index: ${(props) => props.theme.depths.loadingIndicatorBar}; z-index: ${depths.loadingIndicatorBar};
width: 100%; width: 100%;
animation: ${loadingFrame} 4s ease-in-out infinite; animation: ${loadingFrame} 4s ease-in-out infinite;
animation-delay: 250ms; animation-delay: 250ms;

View File

@@ -6,6 +6,7 @@ import { useTranslation } from "react-i18next";
import { Dialog, DialogBackdrop, useDialogState } from "reakit/Dialog"; import { Dialog, DialogBackdrop, useDialogState } from "reakit/Dialog";
import styled from "styled-components"; import styled from "styled-components";
import breakpoint from "styled-components-breakpoint"; import breakpoint from "styled-components-breakpoint";
import { depths } from "@shared/styles";
import Flex from "~/components/Flex"; import Flex from "~/components/Flex";
import NudeButton from "~/components/NudeButton"; import NudeButton from "~/components/NudeButton";
import Scrollable from "~/components/Scrollable"; import Scrollable from "~/components/Scrollable";
@@ -133,7 +134,7 @@ const Backdrop = styled(Flex)<{ $isCentered?: boolean }>`
props.$isCentered props.$isCentered
? props.theme.modalBackdrop ? props.theme.modalBackdrop
: transparentize(0.25, props.theme.background)} !important; : transparentize(0.25, props.theme.background)} !important;
z-index: ${(props) => props.theme.depths.modalOverlay}; z-index: ${depths.modalOverlay};
transition: opacity 50ms ease-in-out; transition: opacity 50ms ease-in-out;
opacity: 0; opacity: 0;
@@ -150,7 +151,7 @@ const Fullscreen = styled.div<{ $nested: boolean }>`
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
z-index: ${(props) => props.theme.depths.modal}; z-index: ${depths.modal};
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: flex-start; align-items: flex-start;
@@ -240,7 +241,7 @@ const Small = styled.div`
margin: auto auto; margin: auto auto;
min-width: 350px; min-width: 350px;
max-width: 30vw; max-width: 30vw;
z-index: ${(props) => props.theme.depths.modal}; z-index: ${depths.modal};
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: flex-start; align-items: flex-start;

View File

@@ -5,6 +5,7 @@ import { Portal } from "react-portal";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import styled, { useTheme } from "styled-components"; import styled, { useTheme } from "styled-components";
import breakpoint from "styled-components-breakpoint"; import breakpoint from "styled-components-breakpoint";
import { depths } from "@shared/styles";
import Flex from "~/components/Flex"; import Flex from "~/components/Flex";
import useMenuContext from "~/hooks/useMenuContext"; import useMenuContext from "~/hooks/useMenuContext";
import usePrevious from "~/hooks/usePrevious"; import usePrevious from "~/hooks/usePrevious";
@@ -224,7 +225,7 @@ const Backdrop = styled.a`
bottom: 0; bottom: 0;
right: 0; right: 0;
cursor: default; cursor: default;
z-index: ${(props) => props.theme.depths.sidebar - 1}; z-index: ${depths.sidebar - 1};
background: ${(props) => props.theme.backdrop}; background: ${(props) => props.theme.backdrop};
`; `;
@@ -246,7 +247,7 @@ const Container = styled(Flex)<{
transform: translateX( transform: translateX(
${(props) => (props.$mobileSidebarVisible ? 0 : "-100%")} ${(props) => (props.$mobileSidebarVisible ? 0 : "-100%")}
); );
z-index: ${(props) => props.theme.depths.sidebar}; z-index: ${depths.sidebar};
max-width: 70%; max-width: 70%;
min-width: 280px; min-width: 280px;

View File

@@ -1,5 +1,6 @@
import * as React from "react"; import * as React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { depths } from "@shared/styles";
import { id } from "~/components/SkipNavContent"; import { id } from "~/components/SkipNavContent";
export default function SkipNavLink() { export default function SkipNavLink() {
@@ -25,7 +26,7 @@ const Anchor = styled.a`
background: ${(props) => props.theme.background}; background: ${(props) => props.theme.background};
color: ${(props) => props.theme.text}; color: ${(props) => props.theme.text};
outline-color: ${(props) => props.theme.primary}; outline-color: ${(props) => props.theme.primary};
z-index: ${(props) => props.theme.depths.popover}; z-index: ${depths.popover};
width: auto; width: auto;
height: auto; height: auto;
clip: auto; clip: auto;

View File

@@ -1,7 +1,8 @@
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import * as React from "react"; import * as React from "react";
import { ThemeProvider } from "styled-components"; import { ThemeProvider } from "styled-components";
import { dark, light, lightMobile, darkMobile } from "@shared/theme"; import { breakpoints } from "@shared/styles";
import { dark, light, lightMobile, darkMobile } from "@shared/styles/theme";
import useMediaQuery from "~/hooks/useMediaQuery"; import useMediaQuery from "~/hooks/useMediaQuery";
import useStores from "~/hooks/useStores"; import useStores from "~/hooks/useStores";
import GlobalStyles from "~/styles/globals"; import GlobalStyles from "~/styles/globals";
@@ -11,9 +12,7 @@ const Theme: React.FC = ({ children }) => {
const resolvedTheme = ui.resolvedTheme === "dark" ? dark : light; const resolvedTheme = ui.resolvedTheme === "dark" ? dark : light;
const resolvedMobileTheme = const resolvedMobileTheme =
ui.resolvedTheme === "dark" ? darkMobile : lightMobile; ui.resolvedTheme === "dark" ? darkMobile : lightMobile;
const isMobile = useMediaQuery( const isMobile = useMediaQuery(`(max-width: ${breakpoints.tablet}px)`);
`(max-width: ${resolvedTheme.breakpoints.tablet}px)`
);
const isPrinting = useMediaQuery("print"); const isPrinting = useMediaQuery("print");
const theme = isPrinting const theme = isPrinting
? light ? light

View File

@@ -1,6 +1,7 @@
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import * as React from "react"; import * as React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { depths } from "@shared/styles";
import Toast from "~/components/Toast"; import Toast from "~/components/Toast";
import useStores from "~/hooks/useStores"; import useStores from "~/hooks/useStores";
import { Toast as TToast } from "~/types"; import { Toast as TToast } from "~/types";
@@ -27,7 +28,7 @@ const List = styled.ol`
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
z-index: ${(props) => props.theme.depths.toasts}; z-index: ${depths.toasts};
`; `;
export default observer(Toasts); export default observer(Toasts);

View File

@@ -1,6 +1,6 @@
import { base } from "@shared/theme"; import { breakpoints } from "@shared/styles";
import useMediaQuery from "~/hooks/useMediaQuery"; import useMediaQuery from "~/hooks/useMediaQuery";
export default function useMobile(): boolean { export default function useMobile(): boolean {
return useMediaQuery(`(max-width: ${base.breakpoints.tablet - 1}px)`); return useMediaQuery(`(max-width: ${breakpoints.tablet - 1}px)`);
} }

View File

@@ -3,7 +3,7 @@ import * as React from "react";
import styled from "styled-components"; import styled from "styled-components";
import breakpoint from "styled-components-breakpoint"; import breakpoint from "styled-components-breakpoint";
import { MAX_TITLE_LENGTH } from "@shared/constants"; import { MAX_TITLE_LENGTH } from "@shared/constants";
import { light } from "@shared/theme"; import { light } from "@shared/styles/theme";
import { import {
getCurrentDateAsString, getCurrentDateAsString,
getCurrentDateTimeAsString, getCurrentDateTimeAsString,

View File

@@ -3,6 +3,7 @@ import { observer } from "mobx-react";
import * as React from "react"; import * as React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import styled from "styled-components"; import styled from "styled-components";
import { depths } from "@shared/styles";
import useStores from "~/hooks/useStores"; import useStores from "~/hooks/useStores";
const transition = { const transition = {
@@ -50,7 +51,7 @@ const Banner = styled(m.div)<{ $color: string }>`
padding: 6px 6px 1px; padding: 6px 6px 1px;
font-size: 13px; font-size: 13px;
font-weight: 500; font-weight: 500;
z-index: ${(props) => props.theme.depths.header + 1}; z-index: ${depths.header + 1};
color: ${(props) => props.theme.white}; color: ${(props) => props.theme.white};
background: ${(props) => props.$color}; background: ${(props) => props.$color};
border-bottom-left-radius: 4px; border-bottom-left-radius: 4px;

View File

@@ -1,5 +1,5 @@
import { action, autorun, computed, observable } from "mobx"; import { action, autorun, computed, observable } from "mobx";
import { light as defaultTheme } from "@shared/theme"; import { light as defaultTheme } from "@shared/styles/theme";
import Document from "~/models/Document"; import Document from "~/models/Document";
import { ConnectionStatus } from "~/scenes/Document/components/MultiplayerEditor"; import { ConnectionStatus } from "~/scenes/Document/components/MultiplayerEditor";

View File

@@ -1,5 +1,6 @@
import { createGlobalStyle } from "styled-components"; import { createGlobalStyle } from "styled-components";
import styledNormalize from "styled-normalize"; import styledNormalize from "styled-normalize";
import { breakpoints, depths } from "@shared/styles";
export default createGlobalStyle` export default createGlobalStyle`
${styledNormalize} ${styledNormalize}
@@ -36,8 +37,7 @@ export default createGlobalStyle`
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
} }
@media (min-width: ${(props) => @media (min-width: ${breakpoints.tablet}px) and (display-mode: standalone) {
props.theme.breakpoints.tablet}px) and (display-mode: standalone) {
body:after { body:after {
content: ""; content: "";
display: block; display: block;
@@ -47,7 +47,7 @@ export default createGlobalStyle`
right: 0; right: 0;
height: 1px; height: 1px;
background: ${(props) => props.theme.titleBarDivider}; background: ${(props) => props.theme.titleBarDivider};
z-index: ${(props) => props.theme.depths.titleBarDivider}; z-index: ${depths.titleBarDivider};
} }
} }

View File

@@ -116,27 +116,6 @@ declare module "styled-components" {
sidebarMaxWidth: number; sidebarMaxWidth: number;
} }
interface Breakpoints {
mobile: number;
tablet: number;
desktop: number;
desktopLarge: number;
}
interface Depths {
header: number;
sidebar: number;
hoverPreview: number;
modalOverlay: number;
modal: number;
menu: number;
toasts: number;
popover: number;
titleBarDivider: number;
loadingIndicatorBar: number;
commandBar: number;
}
export interface DefaultTheme extends Colors, Spacing, EditorTheme { export interface DefaultTheme extends Colors, Spacing, EditorTheme {
background: string; background: string;
backgroundTransition: string; backgroundTransition: string;
@@ -183,8 +162,5 @@ declare module "styled-components" {
progressBarBackground: string; progressBarBackground: string;
scrollbarBackground: string; scrollbarBackground: string;
scrollbarThumb: string; scrollbarThumb: string;
breakpoints: Breakpoints;
depths: Depths;
} }
} }

View File

@@ -1,6 +1,6 @@
import { Table, TBody, TR, TD } from "oy-vey"; import { Table, TBody, TR, TD } from "oy-vey";
import * as React from "react"; import * as React from "react";
import theme from "@shared/theme"; import theme from "@shared/styles/theme";
const EmailLayout: React.FC = ({ children }) => ( const EmailLayout: React.FC = ({ children }) => (
<Table width="550" padding="40"> <Table width="550" padding="40">

View File

@@ -1,6 +1,6 @@
import { Table, TBody, TR, TD } from "oy-vey"; import { Table, TBody, TR, TD } from "oy-vey";
import * as React from "react"; import * as React from "react";
import theme from "@shared/theme"; import theme from "@shared/styles/theme";
import { twitterUrl } from "@shared/utils/urlHelpers"; import { twitterUrl } from "@shared/utils/urlHelpers";
type Props = { type Props = {

View File

@@ -0,0 +1,11 @@
const breakpoints = {
mobile: 0,
// targeting all devices
tablet: 737,
// targeting devices that are larger than the iPhone 6 Plus (which is 736px in landscape mode)
desktop: 1025,
// targeting devices that are larger than the iPad (which is 1024px in landscape mode)
desktopLarge: 1600,
};
export default breakpoints;

17
shared/styles/depths.ts Normal file
View File

@@ -0,0 +1,17 @@
const depths = {
header: 800,
sidebar: 900,
// Note: editor toolbars are 900
hoverPreview: 998,
// Note: editor lightbox is z-index 999
modalOverlay: 2000,
modal: 3000,
menu: 4000,
toasts: 5000,
popover: 9000,
titleBarDivider: 10000,
loadingIndicatorBar: 20000,
commandBar: 30000,
};
export default depths;

3
shared/styles/index.ts Normal file
View File

@@ -0,0 +1,3 @@
export { default as depths } from "./depths";
export { default as breakpoints } from "./breakpoints";

View File

@@ -97,30 +97,6 @@ export const base = {
noticeTipText: colors.almostBlack, noticeTipText: colors.almostBlack,
noticeWarningBackground: "#ffadbf", noticeWarningBackground: "#ffadbf",
noticeWarningText: colors.almostBlack, noticeWarningText: colors.almostBlack,
breakpoints: {
mobile: 0,
// targeting all devices
tablet: 737,
// targeting devices that are larger than the iPhone 6 Plus (which is 736px in landscape mode)
desktop: 1025,
// targeting devices that are larger than the iPad (which is 1024px in landscape mode)
desktopLarge: 1600,
},
depths: {
header: 800,
sidebar: 900,
// Note: editor toolbars are 900
hoverPreview: 998,
// Note: editor lightbox is z-index 999
modalOverlay: 2000,
modal: 3000,
menu: 4000,
toasts: 5000,
popover: 9000,
titleBarDivider: 10000,
loadingIndicatorBar: 20000,
commandBar: 30000,
},
}; };
export const light = { export const light = {

View File

@@ -1,6 +1,6 @@
import md5 from "crypto-js/md5"; import md5 from "crypto-js/md5";
import { darken } from "polished"; import { darken } from "polished";
import theme from "../theme"; import theme from "../styles/theme";
export const palette = [ export const palette = [
theme.brand.red, theme.brand.red,