diff --git a/app/components/Actions.ts b/app/components/Actions.ts index 54b1212de..6f750eb8d 100644 --- a/app/components/Actions.ts +++ b/app/components/Actions.ts @@ -1,5 +1,6 @@ import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s } from "@shared/styles"; import Flex from "~/components/Flex"; export const Action = styled(Flex)` @@ -20,7 +21,7 @@ export const Separator = styled.div` margin-left: 12px; width: 1px; height: 28px; - background: ${(props) => props.theme.divider}; + background: ${s("divider")}; `; const Actions = styled(Flex)` @@ -29,8 +30,8 @@ const Actions = styled(Flex)` right: 0; left: 0; border-radius: 3px; - background: ${(props) => props.theme.background}; - transition: ${(props) => props.theme.backgroundTransition}; + background: ${s("background")}; + transition: ${s("backgroundTransition")}; padding: 12px; backdrop-filter: blur(20px); diff --git a/app/components/Avatar/Avatar.tsx b/app/components/Avatar/Avatar.tsx index e7bc55c21..c5459a914 100644 --- a/app/components/Avatar/Avatar.tsx +++ b/app/components/Avatar/Avatar.tsx @@ -1,5 +1,6 @@ import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; import useBoolean from "~/hooks/useBoolean"; import Initials from "./Initials"; @@ -63,8 +64,8 @@ const IconWrapper = styled.div` position: absolute; bottom: -2px; right: -2px; - background: ${(props) => props.theme.accent}; - border: 2px solid ${(props) => props.theme.background}; + background: ${s("accent")}; + border: 2px solid ${s("background")}; border-radius: 100%; width: 20px; height: 20px; diff --git a/app/components/Avatar/AvatarWithPresence.tsx b/app/components/Avatar/AvatarWithPresence.tsx index 7cbe5c5bd..abd02f543 100644 --- a/app/components/Avatar/AvatarWithPresence.tsx +++ b/app/components/Avatar/AvatarWithPresence.tsx @@ -2,6 +2,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import { useTranslation } from "react-i18next"; import styled, { css } from "styled-components"; +import { s } from "@shared/styles"; import User from "~/models/User"; import Avatar from "~/components/Avatar"; import Tooltip from "~/components/Tooltip"; @@ -106,7 +107,7 @@ const AvatarWrapper = styled.div` &:hover:after { border: 2px solid ${(props) => props.$color}; - box-shadow: inset 0 0 0 2px ${(props) => props.theme.background}; + box-shadow: inset 0 0 0 2px ${s("background")}; } `} `; diff --git a/app/components/Branding.tsx b/app/components/Branding.tsx index bea13a7b2..a5dff9352 100644 --- a/app/components/Branding.tsx +++ b/app/components/Branding.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import env from "~/env"; import OutlineIcon from "./Icons/OutlineIcon"; @@ -26,16 +26,16 @@ const Link = styled.a` font-size: 14px; text-decoration: none; border-top-right-radius: 2px; - color: ${(props) => props.theme.text}; + color: ${s("text")}; display: flex; align-items: center; svg { - fill: ${(props) => props.theme.text}; + fill: ${s("text")}; } &:hover { - background: ${(props) => props.theme.sidebarBackground}; + background: ${s("sidebarBackground")}; } ${breakpoint("tablet")` diff --git a/app/components/Breadcrumb.tsx b/app/components/Breadcrumb.tsx index 197b08efa..eacacade7 100644 --- a/app/components/Breadcrumb.tsx +++ b/app/components/Breadcrumb.tsx @@ -2,9 +2,9 @@ import { GoToIcon } from "outline-icons"; import * as React from "react"; import { Link } from "react-router-dom"; import styled from "styled-components"; +import { s, ellipsis } from "@shared/styles"; import Flex from "~/components/Flex"; import BreadcrumbMenu from "~/menus/BreadcrumbMenu"; -import { ellipsis } from "~/styles"; import { MenuInternalLink } from "~/types"; type Props = { @@ -61,7 +61,7 @@ function Breadcrumb({ const Slash = styled(GoToIcon)` flex-shrink: 0; - fill: ${(props) => props.theme.divider}; + fill: ${s("divider")}; `; const Item = styled(Link)<{ $highlight: boolean; $withIcon: boolean }>` @@ -70,7 +70,7 @@ const Item = styled(Link)<{ $highlight: boolean; $withIcon: boolean }>` flex-shrink: 1; min-width: 0; cursor: var(--pointer); - color: ${(props) => props.theme.text}; + color: ${s("text")}; font-size: 15px; height: 24px; font-weight: ${(props) => (props.$highlight ? "500" : "inherit")}; diff --git a/app/components/Button.tsx b/app/components/Button.tsx index a176124ee..e374ea564 100644 --- a/app/components/Button.tsx +++ b/app/components/Button.tsx @@ -3,6 +3,7 @@ import { ExpandedIcon } from "outline-icons"; import { darken, lighten, transparentize } from "polished"; import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; import ActionButton, { Props as ActionButtonProps, } from "~/components/ActionButton"; @@ -22,8 +23,8 @@ const RealButton = styled(ActionButton)` margin: 0; padding: 0; border: 0; - background: ${(props) => props.theme.accent}; - color: ${(props) => props.theme.accentText}; + background: ${s("accent")}; + color: ${s("accentText")}; box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px; border-radius: 4px; font-size: 14px; diff --git a/app/components/CollectionDescription.tsx b/app/components/CollectionDescription.tsx index 968e8a72c..31132bc8b 100644 --- a/app/components/CollectionDescription.tsx +++ b/app/components/CollectionDescription.tsx @@ -4,6 +4,7 @@ import { transparentize } from "polished"; import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; +import { s } from "@shared/styles"; import Collection from "~/models/Collection"; import Arrow from "~/components/Arrow"; import ButtonLink from "~/components/ButtonLink"; @@ -141,7 +142,7 @@ function CollectionDescription({ collection }: Props) { const Disclosure = styled(NudeButton)` opacity: 0; - color: ${(props) => props.theme.divider}; + color: ${s("divider")}; position: absolute; top: calc(25vh - 50px); left: 50%; @@ -155,12 +156,12 @@ const Disclosure = styled(NudeButton)` } &:active { - color: ${(props) => props.theme.sidebarText}; + color: ${s("sidebarText")}; } `; const Placeholder = styled(ButtonLink)` - color: ${(props) => props.theme.placeholder}; + color: ${s("placeholder")}; cursor: text; min-height: 27px; `; @@ -193,7 +194,7 @@ const Input = styled.div` margin: -8px; padding: 8px; border-radius: 8px; - transition: ${(props) => props.theme.backgroundTransition}; + transition: ${s("backgroundTransition")}; &:after { content: ""; @@ -206,7 +207,7 @@ const Input = styled.div` background: linear-gradient( 180deg, ${(props) => transparentize(1, props.theme.background)} 0%, - ${(props) => props.theme.background} 100% + ${s("background")} 100% ); } @@ -218,7 +219,7 @@ const Input = styled.div` } &[data-editing="true"] { - background: ${(props) => props.theme.secondaryBackground}; + background: ${s("secondaryBackground")}; } .block-menu-trigger, diff --git a/app/components/CommandBar.tsx b/app/components/CommandBar.tsx index 37cf4bbbf..f89fbc0a0 100644 --- a/app/components/CommandBar.tsx +++ b/app/components/CommandBar.tsx @@ -5,7 +5,7 @@ import { useTranslation } from "react-i18next"; import { Portal } from "react-portal"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import CommandBarResults from "~/components/CommandBarResults"; import SearchActions from "~/components/SearchActions"; import rootActions from "~/actions/root"; @@ -73,12 +73,12 @@ const SearchInput = styled(KBarSearch)` width: 100%; outline: none; border: none; - background: ${(props) => props.theme.menuBackground}; - color: ${(props) => props.theme.text}; + background: ${s("menuBackground")}; + color: ${s("text")}; &:disabled, &::placeholder { - color: ${(props) => props.theme.placeholder}; + color: ${s("placeholder")}; } `; @@ -86,8 +86,8 @@ const Animator = styled(KBarAnimator)` max-width: 600px; max-height: 75vh; width: 90vw; - background: ${(props) => props.theme.menuBackground}; - color: ${(props) => props.theme.text}; + background: ${s("menuBackground")}; + color: ${s("text")}; border-radius: 8px; overflow: hidden; box-shadow: rgb(0 0 0 / 40%) 0px 16px 60px; diff --git a/app/components/CommandBarItem.tsx b/app/components/CommandBarItem.tsx index c011f8a5e..7d578e784 100644 --- a/app/components/CommandBarItem.tsx +++ b/app/components/CommandBarItem.tsx @@ -2,9 +2,9 @@ import { ActionImpl } from "kbar"; import { ArrowIcon, BackIcon } from "outline-icons"; import * as React from "react"; import styled, { css, useTheme } from "styled-components"; +import { s, ellipsis } from "@shared/styles"; import Flex from "~/components/Flex"; import Key from "~/components/Key"; -import { ellipsis } from "~/styles"; type Props = { action: ActionImpl; @@ -77,12 +77,12 @@ const Icon = styled(Flex)` justify-content: center; width: 24px; height: 24px; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; flex-shrink: 0; `; const Ancestor = styled.span` - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; `; const Content = styled(Flex)` diff --git a/app/components/CommandBarResults.tsx b/app/components/CommandBarResults.tsx index 7c2b59ee1..1664b62f6 100644 --- a/app/components/CommandBarResults.tsx +++ b/app/components/CommandBarResults.tsx @@ -1,6 +1,7 @@ import { useMatches, KBarResults } from "kbar"; import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; import CommandBarItem from "~/components/CommandBarItem"; export default function CommandBarResults() { @@ -30,6 +31,6 @@ const Header = styled.h3` letter-spacing: 0.04em; margin: 0; padding: 16px 0 4px 20px; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; height: 36px; `; diff --git a/app/components/ContentEditable.tsx b/app/components/ContentEditable.tsx index 0f03546f2..7bf75bcba 100644 --- a/app/components/ContentEditable.tsx +++ b/app/components/ContentEditable.tsx @@ -1,6 +1,7 @@ import isPrintableKeyEvent from "is-printable-key-event"; import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; import useOnScreen from "~/hooks/useOnScreen"; type Props = Omit, "ref" | "onChange"> & { @@ -166,10 +167,10 @@ function placeCaret(element: HTMLElement, atStart: boolean) { } const Content = styled.span` - background: ${(props) => props.theme.background}; - transition: ${(props) => props.theme.backgroundTransition}; - color: ${(props) => props.theme.text}; - -webkit-text-fill-color: ${(props) => props.theme.text}; + background: ${s("background")}; + transition: ${s("backgroundTransition")}; + color: ${s("text")}; + -webkit-text-fill-color: ${s("text")}; outline: none; resize: none; cursor: text; @@ -180,8 +181,8 @@ const Content = styled.span` &:empty::before { display: inline-block; - color: ${(props) => props.theme.placeholder}; - -webkit-text-fill-color: ${(props) => props.theme.placeholder}; + color: ${s("placeholder")}; + -webkit-text-fill-color: ${s("placeholder")}; content: attr(data-placeholder); pointer-events: none; height: 0; diff --git a/app/components/ContextMenu/Header.ts b/app/components/ContextMenu/Header.ts index d824c85c6..afbc65cbf 100644 --- a/app/components/ContextMenu/Header.ts +++ b/app/components/ContextMenu/Header.ts @@ -1,10 +1,11 @@ import styled from "styled-components"; +import { s } from "@shared/styles"; const Header = styled.h3` font-size: 11px; font-weight: 600; text-transform: uppercase; - color: ${(props) => props.theme.sidebarText}; + color: ${s("sidebarText")}; letter-spacing: 0.04em; margin: 1em 12px 0.5em; `; diff --git a/app/components/ContextMenu/index.tsx b/app/components/ContextMenu/index.tsx index 60f83c969..d0154b1a3 100644 --- a/app/components/ContextMenu/index.tsx +++ b/app/components/ContextMenu/index.tsx @@ -4,7 +4,7 @@ import { useTranslation } from "react-i18next"; import { Menu, MenuStateReturn } from "reakit/Menu"; import styled, { DefaultTheme } from "styled-components"; import breakpoint from "styled-components-breakpoint"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import Scrollable from "~/components/Scrollable"; import useMenuContext from "~/hooks/useMenuContext"; import useMenuHeight from "~/hooks/useMenuHeight"; @@ -171,7 +171,7 @@ export const Backdrop = styled.div` left: 0; right: 0; bottom: 0; - background: ${(props) => props.theme.backdrop}; + background: ${s("backdrop")}; z-index: ${depths.menu - 1}; `; @@ -203,7 +203,7 @@ export const Background = styled(Scrollable)` animation: ${mobileContextMenu} 200ms ease; transform-origin: 50% 100%; max-width: 100%; - background: ${(props) => props.theme.menuBackground}; + background: ${s("menuBackground")}; border-radius: 6px; padding: 6px; min-width: 180px; diff --git a/app/components/Divider.ts b/app/components/Divider.ts index a9d3b469f..949813d71 100644 --- a/app/components/Divider.ts +++ b/app/components/Divider.ts @@ -1,8 +1,9 @@ import styled from "styled-components"; +import { s } from "@shared/styles"; const Divider = styled.hr` border: 0; - border-bottom: 1px solid ${(props) => props.theme.divider}; + border-bottom: 1px solid ${s("divider")}; margin: 0; padding: 0; `; diff --git a/app/components/DocumentCard.tsx b/app/components/DocumentCard.tsx index f11d33bcc..14a2df413 100644 --- a/app/components/DocumentCard.tsx +++ b/app/components/DocumentCard.tsx @@ -7,13 +7,13 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import styled, { useTheme } from "styled-components"; +import { s, ellipsis } from "@shared/styles"; import Document from "~/models/Document"; import Pin from "~/models/Pin"; import Flex from "~/components/Flex"; import NudeButton from "~/components/NudeButton"; import Time from "~/components/Time"; import useStores from "~/hooks/useStores"; -import { ellipsis } from "~/styles"; import CollectionIcon from "./Icons/CollectionIcon"; import EmojiIcon from "./Icons/EmojiIcon"; import Squircle from "./Squircle"; @@ -165,9 +165,9 @@ const AnimatePresence = styled(m.div)` `; const Fold = styled.svg` - fill: ${(props) => props.theme.background}; - stroke: ${(props) => props.theme.inputBorder}; - background: ${(props) => props.theme.background}; + fill: ${s("background")}; + stroke: ${s("inputBorder")}; + background: ${s("background")}; position: absolute; top: -1px; @@ -175,11 +175,11 @@ const Fold = styled.svg` `; const PinButton = styled(NudeButton)` - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; &:hover, &:active { - color: ${(props) => props.theme.text}; + color: ${s("text")}; } `; @@ -189,7 +189,7 @@ const Actions = styled(Flex)` right: ${(props) => (props.dir === "rtl" ? "auto" : "4px")}; left: ${(props) => (props.dir === "rtl" ? "4px" : "auto")}; opacity: 0; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; // move actions above content z-index: 2; @@ -222,7 +222,7 @@ const DocumentMeta = styled(Text)` display: flex; align-items: center; gap: 2px; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; margin: 0 0 0 -2px; `; @@ -236,9 +236,9 @@ const DocumentLink = styled(Link)<{ height: 100%; border-radius: 8px; cursor: var(--pointer); - background: ${(props) => props.theme.background}; + background: ${s("background")}; transition: transform 50ms ease-in-out; - border: 1px solid ${(props) => props.theme.inputBorder}; + border: 1px solid ${s("inputBorder")}; border-bottom-width: 2px; border-right-width: 2px; @@ -275,7 +275,7 @@ const Heading = styled.h3` max-height: 66px; // 3*line-height overflow: hidden; - color: ${(props) => props.theme.text}; + color: ${s("text")}; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; `; diff --git a/app/components/DocumentExplorerNode.tsx b/app/components/DocumentExplorerNode.tsx index fddcc57dc..ca5bfdba4 100644 --- a/app/components/DocumentExplorerNode.tsx +++ b/app/components/DocumentExplorerNode.tsx @@ -3,10 +3,10 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s, ellipsis } from "@shared/styles"; import Flex from "~/components/Flex"; import Disclosure from "~/components/Sidebar/components/Disclosure"; import Text from "~/components/Text"; -import { ellipsis } from "~/styles"; type Props = { selected: boolean; @@ -98,7 +98,7 @@ export const Node = styled.span<{ overflow: hidden; font-size: 16px; width: ${(props) => props.style.width}; - color: ${(props) => props.theme.text}; + color: ${s("text")}; cursor: var(--pointer); padding: 12px; border-radius: 6px; diff --git a/app/components/DocumentExplorerSearchResult.tsx b/app/components/DocumentExplorerSearchResult.tsx index 989c65d75..d1c624c1a 100644 --- a/app/components/DocumentExplorerSearchResult.tsx +++ b/app/components/DocumentExplorerSearchResult.tsx @@ -3,10 +3,10 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import scrollIntoView from "smooth-scroll-into-view-if-needed"; import styled from "styled-components"; +import { ellipsis } from "@shared/styles"; import { Node as SearchResult } from "~/components/DocumentExplorerNode"; import Flex from "~/components/Flex"; import Text from "~/components/Text"; -import { ellipsis } from "~/styles"; type Props = { selected: boolean; diff --git a/app/components/DocumentListItem.tsx b/app/components/DocumentListItem.tsx index 03cf23569..081d29363 100644 --- a/app/components/DocumentListItem.tsx +++ b/app/components/DocumentListItem.tsx @@ -6,6 +6,7 @@ import { Link } from "react-router-dom"; import { CompositeStateReturn, CompositeItem } from "reakit/Composite"; import styled, { css } from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s } from "@shared/styles"; import Document from "~/models/Document"; import Badge from "~/components/Badge"; import Button from "~/components/Button"; @@ -181,7 +182,7 @@ const Actions = styled(EventBoundary)` ${NudeButton} { &:hover, &[aria-expanded="true"] { - background: ${(props) => props.theme.sidebarControlHoverBackground}; + background: ${s("sidebarControlHoverBackground")}; } } @@ -223,7 +224,7 @@ const DocumentLink = styled(Link)<{ &:active, &:focus, &:focus-within { - background: ${(props) => props.theme.listItemHoverBackground}; + background: ${s("listItemHoverBackground")}; ${Actions} { opacity: 1; @@ -241,7 +242,7 @@ const DocumentLink = styled(Link)<{ ${(props) => props.$menuOpen && css` - background: ${(props) => props.theme.listItemHoverBackground}; + background: ${s("listItemHoverBackground")}; ${Actions} { opacity: 1; @@ -262,7 +263,7 @@ const Heading = styled.h3<{ rtl?: boolean }>` margin-bottom: 0.25em; overflow: hidden; white-space: nowrap; - color: ${(props) => props.theme.text}; + color: ${s("text")}; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; `; @@ -280,7 +281,7 @@ const Title = styled(Highlight)` const ResultContext = styled(Highlight)` display: block; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; font-size: 14px; margin-top: -0.25em; margin-bottom: 0.25em; diff --git a/app/components/DocumentMeta.tsx b/app/components/DocumentMeta.tsx index 8c6c339bb..92e8c28e1 100644 --- a/app/components/DocumentMeta.tsx +++ b/app/components/DocumentMeta.tsx @@ -4,6 +4,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import styled from "styled-components"; +import { s, ellipsis } from "@shared/styles"; import Document from "~/models/Document"; import DocumentBreadcrumb from "~/components/DocumentBreadcrumb"; import DocumentTasks from "~/components/DocumentTasks"; @@ -11,7 +12,6 @@ import Flex from "~/components/Flex"; import Time from "~/components/Time"; import useCurrentUser from "~/hooks/useCurrentUser"; import useStores from "~/hooks/useStores"; -import { ellipsis } from "~/styles"; type Props = { showCollection?: boolean; @@ -185,7 +185,7 @@ const DocumentMeta: React.FC = ({ const Container = styled(Flex)<{ rtl?: boolean }>` justify-content: ${(props) => (props.rtl ? "flex-end" : "flex-start")}; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; font-size: 13px; white-space: nowrap; overflow: hidden; diff --git a/app/components/Empty.ts b/app/components/Empty.ts index db9550f30..f12aafba5 100644 --- a/app/components/Empty.ts +++ b/app/components/Empty.ts @@ -1,7 +1,8 @@ import styled from "styled-components"; +import { s } from "@shared/styles"; const Empty = styled.p` - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; user-select: none; `; diff --git a/app/components/ErrorBoundary.tsx b/app/components/ErrorBoundary.tsx index efc99b76b..3091ea929 100644 --- a/app/components/ErrorBoundary.tsx +++ b/app/components/ErrorBoundary.tsx @@ -3,6 +3,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import { withTranslation, Trans, WithTranslation } from "react-i18next"; import styled from "styled-components"; +import { s } from "@shared/styles"; import { githubIssuesUrl, feedbackUrl } from "@shared/utils/urlHelpers"; import Button from "~/components/Button"; import CenteredContent from "~/components/CenteredContent"; @@ -137,7 +138,7 @@ class ErrorBoundary extends React.Component { } const Pre = styled.pre` - background: ${(props) => props.theme.secondaryBackground}; + background: ${s("secondaryBackground")}; padding: 16px; border-radius: 4px; font-size: 12px; diff --git a/app/components/EventListItem.tsx b/app/components/EventListItem.tsx index a9fdaac83..7354bd7fe 100644 --- a/app/components/EventListItem.tsx +++ b/app/components/EventListItem.tsx @@ -14,6 +14,7 @@ import { useTranslation } from "react-i18next"; import { useLocation } from "react-router-dom"; import { CompositeStateReturn } from "reakit/Composite"; import styled, { css } from "styled-components"; +import { s } from "@shared/styles"; import Document from "~/models/Document"; import Event from "~/models/Event"; import Avatar from "~/components/Avatar"; @@ -197,7 +198,7 @@ const ItemStyle = css` left: 23px; width: 2px; height: calc(100% + 8px); - background: ${(props) => props.theme.textSecondary}; + background: ${s("textSecondary")}; opacity: 0.25; } diff --git a/app/components/Facepile.tsx b/app/components/Facepile.tsx index 9bd058d21..a9de5116e 100644 --- a/app/components/Facepile.tsx +++ b/app/components/Facepile.tsx @@ -1,6 +1,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; import User from "~/models/User"; import Avatar from "~/components/Avatar"; import Flex from "~/components/Flex"; @@ -59,8 +60,8 @@ const More = styled.div<{ size: number }>` height: ${(props) => props.size}px; border-radius: 100%; background: ${(props) => props.theme.slate}; - color: ${(props) => props.theme.text}; - border: 2px solid ${(props) => props.theme.background}; + color: ${s("text")}; + border: 2px solid ${s("background")}; text-align: center; font-size: 11px; font-weight: 600; diff --git a/app/components/FilterOptions.tsx b/app/components/FilterOptions.tsx index f40e35211..db89d7b1f 100644 --- a/app/components/FilterOptions.tsx +++ b/app/components/FilterOptions.tsx @@ -1,6 +1,7 @@ import * as React from "react"; import { useMenuState, MenuButton } from "reakit/Menu"; import styled from "styled-components"; +import { s } from "@shared/styles"; import Button, { Inner } from "~/components/Button"; import ContextMenu from "~/components/ContextMenu"; import MenuItem from "~/components/ContextMenu/MenuItem"; @@ -80,7 +81,7 @@ const Note = styled(Text)` line-height: 1.2em; font-size: 14px; font-weight: 400; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; `; const LabelWithNote = styled.div` diff --git a/app/components/GroupListItem.tsx b/app/components/GroupListItem.tsx index f19a37360..0d867aad6 100644 --- a/app/components/GroupListItem.tsx +++ b/app/components/GroupListItem.tsx @@ -4,6 +4,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; import { MAX_AVATAR_DISPLAY } from "@shared/constants"; +import { s } from "@shared/styles"; import CollectionGroupMembership from "~/models/CollectionGroupMembership"; import Group from "~/models/Group"; import GroupMembers from "~/scenes/GroupMembers"; @@ -81,7 +82,7 @@ const Image = styled(Flex)` justify-content: center; width: 32px; height: 32px; - background: ${(props) => props.theme.secondaryBackground}; + background: ${s("secondaryBackground")}; border-radius: 32px; `; diff --git a/app/components/Guide.tsx b/app/components/Guide.tsx index 4f90ddd68..305f4d9ef 100644 --- a/app/components/Guide.tsx +++ b/app/components/Guide.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { Dialog, DialogBackdrop, useDialogState } from "reakit/Dialog"; import styled from "styled-components"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import Scrollable from "~/components/Scrollable"; import usePrevious from "~/hooks/usePrevious"; @@ -71,7 +71,7 @@ const Backdrop = styled.div` left: 0; right: 0; bottom: 0; - background-color: ${(props) => props.theme.backdrop} !important; + background-color: ${s("backdrop")} !important; z-index: ${depths.modalOverlay}; transition: opacity 200ms ease-in-out; opacity: 0; @@ -92,8 +92,8 @@ const Scene = styled.div` justify-content: center; align-items: flex-start; width: 350px; - background: ${(props) => props.theme.background}; - transition: ${(props) => props.theme.backgroundTransition}; + background: ${s("background")}; + transition: ${s("backgroundTransition")}; border-radius: 8px; outline: none; opacity: 0; diff --git a/app/components/Header.tsx b/app/components/Header.tsx index af940ec3b..85c7e283e 100644 --- a/app/components/Header.tsx +++ b/app/components/Header.tsx @@ -5,7 +5,7 @@ import { transparentize } from "polished"; import * as React from "react"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import Button from "~/components/Button"; import Fade from "~/components/Fade"; import Flex from "~/components/Flex"; @@ -113,7 +113,7 @@ const Wrapper = styled(Flex)` top: 0; z-index: ${depths.header}; position: sticky; - background: ${(props) => props.theme.background}; + background: ${s("background")}; ${(props) => props.$passThrough diff --git a/app/components/Highlight.tsx b/app/components/Highlight.tsx index efb243714..f65ff125a 100644 --- a/app/components/Highlight.tsx +++ b/app/components/Highlight.tsx @@ -2,6 +2,7 @@ import { escapeRegExp } from "lodash"; import * as React from "react"; import replace from "string-replace-to-array"; import styled from "styled-components"; +import { s } from "@shared/styles"; type Props = React.HTMLAttributes & { highlight: (string | null | undefined) | RegExp; @@ -43,7 +44,7 @@ function Highlight({ } export const Mark = styled.mark` - background: ${(props) => props.theme.searchHighlight}; + background: ${s("searchHighlight")}; border-radius: 2px; padding: 0 2px; `; diff --git a/app/components/HoverPreview.tsx b/app/components/HoverPreview.tsx index 20eb25d80..bd15ed46a 100644 --- a/app/components/HoverPreview.tsx +++ b/app/components/HoverPreview.tsx @@ -2,7 +2,7 @@ import { transparentize } from "polished"; import * as React from "react"; import { Portal } from "react-portal"; import styled from "styled-components"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import parseDocumentSlug from "@shared/utils/parseDocumentSlug"; import { isExternalUrl } from "@shared/utils/urls"; import HoverPreviewDocument from "~/components/HoverPreviewDocument"; @@ -163,7 +163,7 @@ const CardContent = styled.div` // &:after — gradient mask for overflow text const Card = styled.div` backdrop-filter: blur(10px); - background: ${(props) => props.theme.background}; + background: ${s("background")}; border-radius: 4px; box-shadow: 0 30px 90px -20px rgba(0, 0, 0, 0.3), 0 0 1px 1px rgba(0, 0, 0, 0.05); @@ -186,13 +186,13 @@ const Card = styled.div` 90deg, ${(props) => transparentize(1, props.theme.background)} 0%, ${(props) => transparentize(1, props.theme.background)} 75%, - ${(props) => props.theme.background} 90% + ${s("background")} 90% ); bottom: 0; left: 0; right: 0; height: 1.7em; - border-bottom: 16px solid ${(props) => props.theme.background}; + border-bottom: 16px solid ${s("background")}; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } @@ -236,7 +236,7 @@ const Pointer = styled.div<{ offset: number }>` &:after { border: 7px solid transparent; - border-bottom-color: ${(props) => props.theme.background}; + border-bottom-color: ${s("background")}; } `; diff --git a/app/components/HoverPreviewDocument.tsx b/app/components/HoverPreviewDocument.tsx index 41475937c..a4c6238c7 100644 --- a/app/components/HoverPreviewDocument.tsx +++ b/app/components/HoverPreviewDocument.tsx @@ -2,6 +2,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import { Link } from "react-router-dom"; import styled from "styled-components"; +import { s } from "@shared/styles"; import parseDocumentSlug from "@shared/utils/parseDocumentSlug"; import DocumentMeta from "~/components/DocumentMeta"; import Editor from "~/components/Editor"; @@ -52,7 +53,7 @@ const Content = styled(Link)` const Heading = styled.h2` margin: 0 0 0.75em; - color: ${(props) => props.theme.text}; + color: ${s("text")}; `; export default observer(HoverPreviewDocument); diff --git a/app/components/IconPicker.tsx b/app/components/IconPicker.tsx index 04399b0d8..1625deb35 100644 --- a/app/components/IconPicker.tsx +++ b/app/components/IconPicker.tsx @@ -40,6 +40,7 @@ import { useTranslation } from "react-i18next"; import { useMenuState, MenuButton, MenuItem } from "reakit/Menu"; import styled, { useTheme } from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s } from "@shared/styles"; import { colorPalette } from "@shared/utils/collections"; import ContextMenu from "~/components/ContextMenu"; import Flex from "~/components/Flex"; @@ -323,7 +324,7 @@ const Icons = styled.div` `; const Button = styled(NudeButton)` - border: 1px solid ${(props) => props.theme.inputBorder}; + border: 1px solid ${s("inputBorder")}; width: 32px; height: 32px; `; diff --git a/app/components/Input.tsx b/app/components/Input.tsx index 78dc84d9a..bb8893d4b 100644 --- a/app/components/Input.tsx +++ b/app/components/Input.tsx @@ -2,9 +2,10 @@ import * as React from "react"; import { VisuallyHidden } from "reakit/VisuallyHidden"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s, ellipsis } from "@shared/styles"; import Flex from "~/components/Flex"; import Text from "~/components/Text"; -import { ellipsis, undraggableOnDesktop } from "~/styles"; +import { undraggableOnDesktop } from "~/styles"; const RealTextarea = styled.textarea<{ hasIcon?: boolean }>` border: 0; @@ -12,11 +13,11 @@ const RealTextarea = styled.textarea<{ hasIcon?: boolean }>` padding: 8px 12px 8px ${(props) => (props.hasIcon ? "8px" : "12px")}; outline: none; background: none; - color: ${(props) => props.theme.text}; + color: ${s("text")}; &:disabled, &::placeholder { - color: ${(props) => props.theme.placeholder}; + color: ${s("placeholder")}; } `; @@ -26,7 +27,7 @@ const RealInput = styled.input<{ hasIcon?: boolean }>` padding: 8px 12px 8px ${(props) => (props.hasIcon ? "8px" : "12px")}; outline: none; background: none; - color: ${(props) => props.theme.text}; + color: ${s("text")}; height: 30px; min-width: 0; ${ellipsis()} @@ -34,14 +35,13 @@ const RealInput = styled.input<{ hasIcon?: boolean }>` &:disabled, &::placeholder { - color: ${(props) => props.theme.placeholder}; + color: ${s("placeholder")}; } &:-webkit-autofill, &:-webkit-autofill:hover, &:-webkit-autofill:focus { - -webkit-box-shadow: 0 0 0px 1000px ${(props) => props.theme.background} - inset; + -webkit-box-shadow: 0 0 0px 1000px ${s("background")} inset; } &::-webkit-search-cancel-button { @@ -96,7 +96,7 @@ export const Outline = styled(Flex)<{ font-weight: normal; align-items: center; overflow: hidden; - background: ${(props) => props.theme.background}; + background: ${s("background")}; /* Prevents an issue where input placeholder appears in a selected style when double clicking title bar */ user-select: none; diff --git a/app/components/InputColor.tsx b/app/components/InputColor.tsx index 282812eb3..12fa3db93 100644 --- a/app/components/InputColor.tsx +++ b/app/components/InputColor.tsx @@ -2,6 +2,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import { MenuButton, useMenuState } from "reakit/Menu"; import styled from "styled-components"; +import { s } from "@shared/styles"; import ContextMenu from "./ContextMenu"; import DelayedMount from "./DelayedMount"; import Input, { Props as InputProps } from "./Input"; @@ -60,7 +61,7 @@ const InputColor: React.FC = ({ value, onChange, ...rest }) => { const SwatchButton = styled(NudeButton)<{ $background: string | undefined }>` background: ${(props) => props.$background}; - border: 1px solid ${(props) => props.theme.inputBorder}; + border: 1px solid ${s("inputBorder")}; border-radius: 50%; position: absolute; bottom: 20px; @@ -80,7 +81,7 @@ const StyledColorPicker = styled(ColorPicker)` input { user-select: text; - color: ${(props) => props.theme.text} !important; + color: ${s("text")} !important; } `; diff --git a/app/components/InputSelect.tsx b/app/components/InputSelect.tsx index b9ce01766..9a07432ac 100644 --- a/app/components/InputSelect.tsx +++ b/app/components/InputSelect.tsx @@ -9,6 +9,7 @@ import { CheckmarkIcon } from "outline-icons"; import * as React from "react"; import { VisuallyHidden } from "reakit/VisuallyHidden"; import styled, { css } from "styled-components"; +import { s } from "@shared/styles"; import Button, { Inner } from "~/components/Button"; import Text from "~/components/Text"; import useMenuHeight from "~/hooks/useMenuHeight"; @@ -218,7 +219,7 @@ const Background = styled(ContextMenuBackground)` `; const Placeholder = styled.span` - color: ${(props) => props.theme.placeholder}; + color: ${s("placeholder")}; `; const Spacer = styled.div` @@ -236,7 +237,7 @@ const StyledButton = styled(Button)<{ nude?: boolean }>` cursor: default; &:hover:not(:disabled) { - background: ${(props) => props.theme.buttonNeutralBackground}; + background: ${s("buttonNeutralBackground")}; } ${(props) => @@ -276,7 +277,7 @@ const Positioner = styled(Position)` ${StyledSelectOption} { &[aria-selected="true"] { color: ${(props) => props.theme.white}; - background: ${(props) => props.theme.accent}; + background: ${s("accent")}; box-shadow: none; cursor: var(--pointer); diff --git a/app/components/Labeled.tsx b/app/components/Labeled.tsx index 145957630..98631b79f 100644 --- a/app/components/Labeled.tsx +++ b/app/components/Labeled.tsx @@ -1,6 +1,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; import Flex from "~/components/Flex"; type Props = { @@ -18,7 +19,7 @@ export const Label = styled(Flex)` font-weight: 500; padding-bottom: 4px; display: inline-block; - color: ${(props) => props.theme.text}; + color: ${s("text")}; `; export default observer(Labeled); diff --git a/app/components/LanguagePrompt.tsx b/app/components/LanguagePrompt.tsx index 8c057abc7..c236a1633 100644 --- a/app/components/LanguagePrompt.tsx +++ b/app/components/LanguagePrompt.tsx @@ -5,7 +5,6 @@ import styled from "styled-components"; import { languages, languageOptions } from "@shared/i18n"; import ButtonLink from "~/components/ButtonLink"; import Flex from "~/components/Flex"; -import NoticeTip from "~/components/NoticeTip"; import env from "~/env"; import useCurrentUser from "~/hooks/useCurrentUser"; import useStores from "~/hooks/useStores"; @@ -61,7 +60,7 @@ export default function LanguagePrompt() { const appName = env.APP_NAME; return ( - + @@ -87,10 +86,28 @@ export default function LanguagePrompt() { {t("Dismiss")} - + ); } +const Wrapper = styled.p` + background: ${(props) => props.theme.brand.marine}; + color: ${(props) => props.theme.almostBlack}; + padding: 10px 12px; + margin-top: 24px; + border-radius: 4px; + position: relative; + + a { + color: ${(props) => props.theme.almostBlack}; + font-weight: 500; + } + + a:hover { + text-decoration: underline; + } +`; + const Link = styled(ButtonLink)` color: ${(props) => props.theme.almostBlack}; font-weight: 500; diff --git a/app/components/Layout.tsx b/app/components/Layout.tsx index 41f5d1195..b70be6cd9 100644 --- a/app/components/Layout.tsx +++ b/app/components/Layout.tsx @@ -3,6 +3,7 @@ import * as React from "react"; import { Helmet } from "react-helmet"; import styled, { DefaultTheme } from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s } from "@shared/styles"; import Flex from "~/components/Flex"; import { LoadingIndicatorBar } from "~/components/LoadingIndicator"; import SkipNavContent from "~/components/SkipNavContent"; @@ -76,8 +77,8 @@ const Layout: React.FC = ({ }; const Container = styled(Flex)` - background: ${(props) => props.theme.background}; - transition: ${(props) => props.theme.backgroundTransition}; + background: ${s("background")}; + transition: ${s("backgroundTransition")}; position: relative; width: 100%; min-height: 100%; diff --git a/app/components/List/Error.tsx b/app/components/List/Error.tsx index b4bc6d720..0998c2d24 100644 --- a/app/components/List/Error.tsx +++ b/app/components/List/Error.tsx @@ -2,6 +2,7 @@ import { DisconnectedIcon, WarningIcon } from "outline-icons"; import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; +import { s } from "@shared/styles"; import Empty from "~/components/Empty"; import useEventListener from "~/hooks/useEventListener"; import { OfflineError } from "~/utils/errors"; @@ -43,10 +44,10 @@ const Content = styled(Empty)` white-space: nowrap; ${ButtonLink} { - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; &:hover { - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; text-decoration: underline; } } diff --git a/app/components/List/Item.tsx b/app/components/List/Item.tsx index 6a41ae6ea..63676b234 100644 --- a/app/components/List/Item.tsx +++ b/app/components/List/Item.tsx @@ -1,9 +1,9 @@ import { LocationDescriptor } from "history"; import * as React from "react"; import styled, { useTheme } from "styled-components"; +import { s, ellipsis } from "@shared/styles"; import Flex from "~/components/Flex"; import NavLink from "~/components/NavLink"; -import { ellipsis } from "~/styles"; export type Props = Omit, "title"> & { image?: React.ReactNode; @@ -98,7 +98,7 @@ const Image = styled(Flex)` user-select: none; flex-shrink: 0; align-self: center; - color: ${(props) => props.theme.text}; + color: ${s("text")}; `; const Heading = styled.p<{ $small?: boolean }>` diff --git a/app/components/LoadingIndicator/LoadingIndicatorBar.tsx b/app/components/LoadingIndicator/LoadingIndicatorBar.tsx index 26957c78f..ab1bedce3 100644 --- a/app/components/LoadingIndicator/LoadingIndicatorBar.tsx +++ b/app/components/LoadingIndicator/LoadingIndicatorBar.tsx @@ -1,6 +1,6 @@ import * as React from "react"; import styled, { keyframes } from "styled-components"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; const LoadingIndicatorBar = () => { return ( @@ -28,7 +28,7 @@ const Container = styled.div` const Loader = styled.div` width: 100%; height: 2px; - background-color: ${(props) => props.theme.accent}; + background-color: ${s("accent")}; `; export default LoadingIndicatorBar; diff --git a/app/components/Modal.tsx b/app/components/Modal.tsx index 43c0f7a8a..ed282b9a2 100644 --- a/app/components/Modal.tsx +++ b/app/components/Modal.tsx @@ -6,7 +6,7 @@ import { useTranslation } from "react-i18next"; import { Dialog, DialogBackdrop, useDialogState } from "reakit/Dialog"; import styled, { DefaultTheme } from "styled-components"; import breakpoint from "styled-components-breakpoint"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import Flex from "~/components/Flex"; import NudeButton from "~/components/NudeButton"; import Scrollable from "~/components/Scrollable"; @@ -171,8 +171,8 @@ const Fullscreen = styled.div` display: flex; justify-content: center; align-items: flex-start; - background: ${(props) => props.theme.background}; - transition: ${(props) => props.theme.backgroundTransition}; + background: ${s("background")}; + transition: ${s("backgroundTransition")}; outline: none; ${breakpoint("tablet")` @@ -209,7 +209,7 @@ const Close = styled(NudeButton)` right: 0; margin: 12px; opacity: 0.75; - color: ${(props) => props.theme.text}; + color: ${s("text")}; width: auto; height: auto; @@ -229,7 +229,7 @@ const Back = styled(NudeButton)` top: ${Desktop.hasInsetTitlebar() ? "3rem" : "2rem"}; left: 2rem; opacity: 0.75; - color: ${(props) => props.theme.text}; + color: ${s("text")}; font-weight: 500; width: auto; height: auto; @@ -244,7 +244,7 @@ const Back = styled(NudeButton)` `; const Header = styled(Flex)` - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; align-items: center; justify-content: space-between; font-weight: 600; @@ -262,16 +262,16 @@ const Small = styled.div` display: flex; justify-content: center; align-items: flex-start; - background: ${(props) => props.theme.modalBackground}; - transition: ${(props) => props.theme.backgroundTransition}; - box-shadow: ${(props) => props.theme.modalShadow}; + background: ${s("modalBackground")}; + transition: ${s("backgroundTransition")}; + box-shadow: ${s("modalShadow")}; border-radius: 8px; outline: none; ${NudeButton} { &:hover, &[aria-expanded="true"] { - background: ${(props) => props.theme.sidebarControlHoverBackground}; + background: ${s("sidebarControlHoverBackground")}; } vertical-align: middle; } diff --git a/app/components/Notice.tsx b/app/components/Notice.tsx index fe6fd10c3..901bb88dd 100644 --- a/app/components/Notice.tsx +++ b/app/components/Notice.tsx @@ -1,5 +1,6 @@ import React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; import Flex from "./Flex"; import Text from "./Text"; @@ -33,8 +34,8 @@ const Title = styled.span` `; const Container = styled(Text)` - background: ${(props) => props.theme.sidebarBackground}; - color: ${(props) => props.theme.sidebarText}; + background: ${s("sidebarBackground")}; + color: ${s("sidebarText")}; padding: 10px 12px; border-radius: 4px; position: relative; diff --git a/app/components/NoticeAlert.tsx b/app/components/NoticeAlert.tsx index c2d55d574..35d2b1033 100644 --- a/app/components/NoticeAlert.tsx +++ b/app/components/NoticeAlert.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import Notice from "~/components/Notice"; -const AlertNotice: React.FC = ({ children }) => { +const NoticeAlert: React.FC = ({ children }) => { return ( { ); }; -export default AlertNotice; +export default NoticeAlert; diff --git a/app/components/NoticeTip.ts b/app/components/NoticeTip.ts deleted file mode 100644 index fa687a52e..000000000 --- a/app/components/NoticeTip.ts +++ /dev/null @@ -1,21 +0,0 @@ -import styled from "styled-components"; - -const Notice = styled.p` - background: ${(props) => props.theme.brand.marine}; - color: ${(props) => props.theme.almostBlack}; - padding: 10px 12px; - margin-top: 24px; - border-radius: 4px; - position: relative; - - a { - color: ${(props) => props.theme.almostBlack}; - font-weight: 500; - } - - a:hover { - text-decoration: underline; - } -`; - -export default Notice; diff --git a/app/components/PlaceholderText.tsx b/app/components/PlaceholderText.tsx index bd4c74749..4785fbb69 100644 --- a/app/components/PlaceholderText.tsx +++ b/app/components/PlaceholderText.tsx @@ -1,6 +1,7 @@ import * as React from "react"; import styled from "styled-components"; import { randomInteger } from "@shared/random"; +import { s } from "@shared/styles"; import Flex from "~/components/Flex"; import { pulsate } from "~/styles/animations"; @@ -30,7 +31,7 @@ const Mask = styled(Flex)<{ props.height ? props.height : props.header ? 24 : 18}px; margin-bottom: 6px; border-radius: 6px; - background-color: ${(props) => props.theme.divider}; + background-color: ${s("divider")}; animation: ${pulsate} 2s infinite; animation-delay: ${(props) => props.delay || 0}s; diff --git a/app/components/Popover.tsx b/app/components/Popover.tsx index 275582850..27734c3f5 100644 --- a/app/components/Popover.tsx +++ b/app/components/Popover.tsx @@ -3,7 +3,7 @@ import { Dialog } from "reakit/Dialog"; import { Popover as ReakitPopover, PopoverProps } from "reakit/Popover"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import useMobile from "~/hooks/useMobile"; import { fadeAndScaleIn } from "~/styles/animations"; @@ -42,13 +42,13 @@ const Popover: React.FC = ({ const Contents = styled.div<{ $shrink?: boolean; $width?: number }>` animation: ${fadeAndScaleIn} 200ms ease; transform-origin: 75% 0; - background: ${(props) => props.theme.menuBackground}; + background: ${s("menuBackground")}; border-radius: 6px; padding: ${(props) => (props.$shrink ? "6px 0" : "12px 24px")}; max-height: 75vh; overflow-x: hidden; overflow-y: auto; - box-shadow: ${(props) => props.theme.menuShadow}; + box-shadow: ${s("menuShadow")}; width: ${(props) => props.$width}px; ${breakpoint("mobile", "tablet")` diff --git a/app/components/Scrollable.tsx b/app/components/Scrollable.tsx index b8b94f588..d8a845360 100644 --- a/app/components/Scrollable.tsx +++ b/app/components/Scrollable.tsx @@ -1,8 +1,8 @@ import { observer } from "mobx-react"; import * as React from "react"; import styled from "styled-components"; +import { hideScrollbars } from "@shared/styles"; import useWindowSize from "~/hooks/useWindowSize"; -import { hideScrollbars } from "~/styles"; type Props = React.HTMLAttributes & { shadow?: boolean; diff --git a/app/components/SearchListItem.tsx b/app/components/SearchListItem.tsx index 5b63a16ec..23483ffde 100644 --- a/app/components/SearchListItem.tsx +++ b/app/components/SearchListItem.tsx @@ -4,9 +4,10 @@ import { Link } from "react-router-dom"; import { CompositeItem } from "reakit/Composite"; import styled, { css } from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s, ellipsis } from "@shared/styles"; import Document from "~/models/Document"; import Highlight, { Mark } from "~/components/Highlight"; -import { ellipsis, hover } from "~/styles"; +import { hover } from "~/styles"; import { sharedDocumentPath } from "~/utils/routeHelpers"; type Props = { @@ -101,13 +102,13 @@ const DocumentLink = styled(Link)<{ &:active, &:focus, &:focus-within { - background: ${(props) => props.theme.listItemHoverBackground}; + background: ${s("listItemHoverBackground")}; } ${(props) => props.$menuOpen && css` - background: ${(props) => props.theme.listItemHoverBackground}; + background: ${s("listItemHoverBackground")}; `} `; @@ -120,7 +121,7 @@ const Heading = styled.h4<{ rtl?: boolean }>` margin-bottom: 0.25em; overflow: hidden; white-space: nowrap; - color: ${(props) => props.theme.text}; + color: ${s("text")}; `; const Title = styled(Highlight)` @@ -134,7 +135,7 @@ const Title = styled(Highlight)` const ResultContext = styled(Highlight)` display: block; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; font-size: 14px; margin-top: -0.25em; margin-bottom: 0.25em; diff --git a/app/components/Sidebar/Right.tsx b/app/components/Sidebar/Right.tsx index df5225349..1ad0ef799 100644 --- a/app/components/Sidebar/Right.tsx +++ b/app/components/Sidebar/Right.tsx @@ -3,7 +3,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import styled, { useTheme } from "styled-components"; import breakpoint from "styled-components-breakpoint"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import ErrorBoundary from "~/components/ErrorBoundary"; import Flex from "~/components/Flex"; import ResizeBorder from "~/components/Sidebar/components/ResizeBorder"; @@ -119,10 +119,9 @@ const Sidebar = styled(m.div)<{ }>` display: flex; flex-shrink: 0; - background: ${(props) => props.theme.background}; - width: ${(props) => props.theme.sidebarRightWidth}px; + background: ${s("background")}; max-width: 70%; - border-left: 1px solid ${(props) => props.theme.divider}; + border-left: 1px solid ${s("divider")}; transition: border-left 100ms ease-in-out; z-index: 1; diff --git a/app/components/Sidebar/Sidebar.tsx b/app/components/Sidebar/Sidebar.tsx index 8dc3ff339..b3ae5ce53 100644 --- a/app/components/Sidebar/Sidebar.tsx +++ b/app/components/Sidebar/Sidebar.tsx @@ -5,7 +5,7 @@ import { Portal } from "react-portal"; import { useLocation } from "react-router-dom"; import styled, { useTheme } from "styled-components"; import breakpoint from "styled-components-breakpoint"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import Flex from "~/components/Flex"; import useMenuContext from "~/hooks/useMenuContext"; import usePrevious from "~/hooks/usePrevious"; @@ -224,7 +224,7 @@ const Backdrop = styled.a` right: 0; cursor: default; z-index: ${depths.sidebar - 1}; - background: ${(props) => props.theme.backdrop}; + background: ${s("backdrop")}; `; type ContainerProps = { @@ -239,9 +239,9 @@ const Container = styled(Flex)` top: 0; bottom: 0; width: 100%; - background: ${(props) => props.theme.sidebarBackground}; + background: ${s("sidebarBackground")}; transition: box-shadow 100ms ease-in-out, transform 100ms ease-out, - ${(props) => props.theme.backgroundTransition} + ${s("backgroundTransition")} ${(props: ContainerProps) => props.$isAnimating ? `,width ${ANIMATION_MS}ms ease-out` : ""}; transform: translateX( diff --git a/app/components/Sidebar/components/Disclosure.tsx b/app/components/Sidebar/components/Disclosure.tsx index eb6236f5f..9e538a7f8 100644 --- a/app/components/Sidebar/components/Disclosure.tsx +++ b/app/components/Sidebar/components/Disclosure.tsx @@ -2,6 +2,7 @@ import { CollapsedIcon } from "outline-icons"; import * as React from "react"; import { useTranslation } from "react-i18next"; import styled, { css } from "styled-components"; +import { s } from "@shared/styles"; import NudeButton from "~/components/NudeButton"; type Props = React.ComponentProps & { @@ -30,11 +31,11 @@ const Button = styled(NudeButton)<{ $root?: boolean }>` position: absolute; left: -24px; flex-shrink: 0; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; &:hover { - color: ${(props) => props.theme.text}; - background: ${(props) => props.theme.sidebarControlHoverBackground}; + color: ${s("text")}; + background: ${s("sidebarControlHoverBackground")}; } ${(props) => diff --git a/app/components/Sidebar/components/EditableTitle.tsx b/app/components/Sidebar/components/EditableTitle.tsx index e9cce0b5b..579aeb40a 100644 --- a/app/components/Sidebar/components/EditableTitle.tsx +++ b/app/components/Sidebar/components/EditableTitle.tsx @@ -1,5 +1,6 @@ import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; import useToasts from "~/hooks/useToasts"; type Props = { @@ -113,8 +114,8 @@ function EditableTitle({ } const Input = styled.input` - color: ${(props) => props.theme.text}; - background: ${(props) => props.theme.background}; + color: ${s("text")}; + background: ${s("background")}; width: calc(100% + 12px); border-radius: 3px; border: 0; @@ -123,7 +124,7 @@ const Input = styled.input` height: 32px; &:focus { - outline-color: ${(props) => props.theme.accent}; + outline-color: ${s("accent")}; } `; diff --git a/app/components/Sidebar/components/Header.tsx b/app/components/Sidebar/components/Header.tsx index 610d8b47b..fa8d2de7b 100644 --- a/app/components/Sidebar/components/Header.tsx +++ b/app/components/Sidebar/components/Header.tsx @@ -1,6 +1,7 @@ import { CollapsedIcon } from "outline-icons"; import * as React from "react"; import styled, { keyframes } from "styled-components"; +import { s } from "@shared/styles"; import usePersistedState from "~/hooks/usePersistedState"; import { undraggableOnDesktop } from "~/styles"; @@ -67,7 +68,7 @@ const Button = styled.button` font-size: 13px; font-weight: 600; user-select: none; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; letter-spacing: 0.03em; margin: 0; padding: 4px 2px 4px 12px; @@ -81,7 +82,7 @@ const Button = styled.button` &:not(:disabled):hover, &:not(:disabled):active { - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; cursor: var(--pointer); } `; diff --git a/app/components/Sidebar/components/HeaderButton.tsx b/app/components/Sidebar/components/HeaderButton.tsx index dbbb63ae1..fc6758241 100644 --- a/app/components/Sidebar/components/HeaderButton.tsx +++ b/app/components/Sidebar/components/HeaderButton.tsx @@ -1,6 +1,7 @@ import { ExpandedIcon, MoreIcon } from "outline-icons"; import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; import Flex from "~/components/Flex"; import { undraggableOnDesktop } from "~/styles"; @@ -46,7 +47,7 @@ const HeaderButton = React.forwardRef( ); const Title = styled(Flex)` - color: ${(props) => props.theme.text}; + color: ${s("text")}; flex-shrink: 1; text-overflow: ellipsis; white-space: nowrap; @@ -59,7 +60,7 @@ const Wrapper = styled(Flex)<{ minHeight: number }>` font-weight: 500; border-radius: 4px; margin: 8px; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; border: 0; background: none; flex-shrink: 0; @@ -76,9 +77,9 @@ const Wrapper = styled(Flex)<{ minHeight: number }>` &:active, &:hover, &[aria-expanded="true"] { - color: ${(props) => props.theme.sidebarText}; + color: ${s("sidebarText")}; transition: background 100ms ease-in-out; - background: ${(props) => props.theme.sidebarActiveBackground}; + background: ${s("sidebarActiveBackground")}; } `; diff --git a/app/components/Sidebar/components/HistoryNavigation.tsx b/app/components/Sidebar/components/HistoryNavigation.tsx index 6129eeb4e..3b43ef775 100644 --- a/app/components/Sidebar/components/HistoryNavigation.tsx +++ b/app/components/Sidebar/components/HistoryNavigation.tsx @@ -2,6 +2,7 @@ import { ArrowIcon } from "outline-icons"; import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; +import { s } from "@shared/styles"; import Flex from "~/components/Flex"; import NudeButton from "~/components/NudeButton"; import Tooltip from "~/components/Tooltip"; @@ -63,7 +64,7 @@ const Navigation = styled(Flex)` `; const Forward = styled(ArrowIcon)<{ $active: boolean }>` - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; opacity: ${(props) => (props.$active ? 1 : 0.5)}; transition: color 100ms ease-in-out; diff --git a/app/components/Sidebar/components/ResizeBorder.ts b/app/components/Sidebar/components/ResizeBorder.ts index 050ed2ce3..653ddf046 100644 --- a/app/components/Sidebar/components/ResizeBorder.ts +++ b/app/components/Sidebar/components/ResizeBorder.ts @@ -1,4 +1,5 @@ import styled from "styled-components"; +import { s } from "@shared/styles"; import { undraggableOnDesktop } from "~/styles"; const ResizeBorder = styled.div<{ dir?: "left" | "right" }>` @@ -14,7 +15,7 @@ const ResizeBorder = styled.div<{ dir?: "left" | "right" }>` &:hover { transition-delay: 500ms; transition: background 250ms ease-in-out; - background: ${(props) => props.theme.sidebarActiveBackground}; + background: ${s("sidebarActiveBackground")}; } &:after { diff --git a/app/components/Sidebar/components/SidebarLink.tsx b/app/components/Sidebar/components/SidebarLink.tsx index 1ab6cd9b4..172278204 100644 --- a/app/components/Sidebar/components/SidebarLink.tsx +++ b/app/components/Sidebar/components/SidebarLink.tsx @@ -2,6 +2,7 @@ import { LocationDescriptor } from "history"; import * as React from "react"; import styled, { useTheme, css } from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s } from "@shared/styles"; import { NavigationNode } from "@shared/types"; import EventBoundary from "~/components/EventBoundary"; import NudeButton from "~/components/NudeButton"; @@ -144,12 +145,12 @@ const Actions = styled(EventBoundary)<{ showActions?: boolean }>` top: 4px; right: 4px; gap: 4px; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; transition: opacity 50ms; height: 24px; svg { - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; fill: currentColor; opacity: 0.5; } @@ -217,20 +218,20 @@ const Link = styled(NavLink)<{ } & + ${Actions} { - background: ${(props) => props.theme.sidebarBackground}; + background: ${s("sidebarBackground")}; ${NudeButton} { background: transparent; &:hover, &[aria-expanded="true"] { - background: ${(props) => props.theme.sidebarControlHoverBackground}; + background: ${s("sidebarControlHoverBackground")}; } } } &[aria-current="page"] + ${Actions} { - background: ${(props) => props.theme.sidebarActiveBackground}; + background: ${s("sidebarActiveBackground")}; } ${breakpoint("tablet")` diff --git a/app/components/Sidebar/components/Toggle.tsx b/app/components/Sidebar/components/Toggle.tsx index a57abd538..24a4c40e0 100644 --- a/app/components/Sidebar/components/Toggle.tsx +++ b/app/components/Sidebar/components/Toggle.tsx @@ -2,6 +2,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s } from "@shared/styles"; import Arrow from "~/components/Arrow"; type Props = { @@ -39,10 +40,10 @@ export const ToggleButton = styled.button<{ $direction?: "left" | "right" }>` padding: 8px; border: 0; pointer-events: none; - color: ${(props) => props.theme.divider}; + color: ${s("divider")}; &:active { - color: ${(props) => props.theme.sidebarText}; + color: ${s("sidebarText")}; } ${breakpoint("tablet")` diff --git a/app/components/SkipNavLink.tsx b/app/components/SkipNavLink.tsx index 544583b58..4099a4ae8 100644 --- a/app/components/SkipNavLink.tsx +++ b/app/components/SkipNavLink.tsx @@ -1,6 +1,6 @@ import * as React from "react"; import styled from "styled-components"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import { id } from "~/components/SkipNavContent"; export default function SkipNavLink() { @@ -23,9 +23,9 @@ const Anchor = styled.a` position: fixed; top: 12px; left: 12px; - background: ${(props) => props.theme.background}; - color: ${(props) => props.theme.text}; - outline-color: ${(props) => props.theme.accent}; + background: ${s("background")}; + color: ${s("text")}; + outline-color: ${s("accent")}; z-index: ${depths.popover}; width: auto; height: auto; diff --git a/app/components/Subheading.tsx b/app/components/Subheading.tsx index d165fc6f8..4a402a2c8 100644 --- a/app/components/Subheading.tsx +++ b/app/components/Subheading.tsx @@ -1,12 +1,13 @@ import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; type Props = { sticky?: boolean; }; const H3 = styled.h3` - border-bottom: 1px solid ${(props) => props.theme.divider}; + border-bottom: 1px solid ${s("divider")}; margin: 12px 0; line-height: 1; `; @@ -16,7 +17,7 @@ const Underline = styled.div` font-weight: 500; font-size: 14px; line-height: 1.5; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; padding-top: 6px; padding-bottom: 6px; `; @@ -28,8 +29,8 @@ const Background = styled.div<{ sticky?: boolean }>` ${(props) => (props.sticky ? "top: 54px;" : "")} margin: 0 -8px; padding: 0 8px; - background: ${(props) => props.theme.background}; - transition: ${(props) => props.theme.backgroundTransition}; + background: ${s("background")}; + transition: ${s("backgroundTransition")}; z-index: 1; `; diff --git a/app/components/Switch.tsx b/app/components/Switch.tsx index df371fea6..c8f2c6d64 100644 --- a/app/components/Switch.tsx +++ b/app/components/Switch.tsx @@ -1,5 +1,6 @@ import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; import { LabelText } from "~/components/Input"; import Text from "~/components/Text"; import { undraggableOnDesktop } from "~/styles"; @@ -124,11 +125,11 @@ const HiddenInput = styled.input<{ width: number; height: number }>` } &:checked + ${Slider} { - background-color: ${(props) => props.theme.accent}; + background-color: ${s("accent")}; } &:focus + ${Slider} { - box-shadow: 0 0 1px ${(props) => props.theme.accent}; + box-shadow: 0 0 1px ${s("accent")}; } &:checked + ${Slider}:before { diff --git a/app/components/Tab.tsx b/app/components/Tab.tsx index d200c7327..b020f1e5c 100644 --- a/app/components/Tab.tsx +++ b/app/components/Tab.tsx @@ -1,6 +1,7 @@ import { m } from "framer-motion"; import * as React from "react"; import styled, { useTheme } from "styled-components"; +import { s } from "@shared/styles"; import NavLink from "~/components/NavLink"; type Props = Omit, "children"> & { @@ -15,12 +16,12 @@ const TabLink = styled(NavLink)` font-weight: 500; font-size: 14px; cursor: var(--pointer); - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; margin-right: 24px; padding: 6px 0; &:hover { - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; } `; @@ -32,7 +33,7 @@ const Active = styled(m.div)` height: 3px; width: 100%; border-radius: 3px; - background: ${(props) => props.theme.textSecondary}; + background: ${s("textSecondary")}; `; const transition = { diff --git a/app/components/Table.tsx b/app/components/Table.tsx index b3842a6f0..a8e9f36af 100644 --- a/app/components/Table.tsx +++ b/app/components/Table.tsx @@ -5,6 +5,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import { useTable, useSortBy, usePagination } from "react-table"; import styled from "styled-components"; +import { s } from "@shared/styles"; import Button from "~/components/Button"; import DelayedMount from "~/components/DelayedMount"; import Empty from "~/components/Empty"; @@ -225,7 +226,7 @@ const DescSortIcon = styled(CollapsedIcon)` margin-left: -2px; &:hover { - fill: ${(props) => props.theme.text}; + fill: ${s("text")}; } `; @@ -256,7 +257,7 @@ const SortWrapper = styled(Flex)<{ $sortable: boolean }>` const Cell = styled.td` padding: 10px 6px; - border-bottom: 1px solid ${(props) => props.theme.divider}; + border-bottom: 1px solid ${s("divider")}; font-size: 14px; &:first-child { @@ -273,7 +274,7 @@ const Cell = styled.td` ${NudeButton} { &:hover, &[aria-expanded="true"] { - background: ${(props) => props.theme.sidebarControlHoverBackground}; + background: ${s("sidebarControlHoverBackground")}; } } `; @@ -299,11 +300,11 @@ const Head = styled.th` position: sticky; top: 54px; padding: 6px 6px 0; - border-bottom: 1px solid ${(props) => props.theme.divider}; - background: ${(props) => props.theme.background}; - transition: ${(props) => props.theme.backgroundTransition}; + border-bottom: 1px solid ${s("divider")}; + background: ${s("background")}; + transition: ${s("backgroundTransition")}; font-size: 14px; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; font-weight: 500; z-index: 1; diff --git a/app/components/Tabs.tsx b/app/components/Tabs.tsx index e4939e58e..699237aba 100644 --- a/app/components/Tabs.tsx +++ b/app/components/Tabs.tsx @@ -2,10 +2,11 @@ import { AnimateSharedLayout } from "framer-motion"; import { transparentize } from "polished"; import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; import useWindowSize from "~/hooks/useWindowSize"; const Nav = styled.nav<{ $shadowVisible?: boolean }>` - border-bottom: 1px solid ${(props) => props.theme.divider}; + border-bottom: 1px solid ${s("divider")}; margin: 12px 0; overflow-y: auto; white-space: nowrap; @@ -43,13 +44,13 @@ const Sticky = styled.div` top: 54px; margin: 0 -8px; padding: 0 8px; - background: ${(props) => props.theme.background}; - transition: ${(props) => props.theme.backgroundTransition}; + background: ${s("background")}; + transition: ${s("backgroundTransition")}; z-index: 1; `; export const Separator = styled.span` - border-left: 1px solid ${(props) => props.theme.divider}; + border-left: 1px solid ${s("divider")}; position: relative; top: 2px; margin-right: 24px; diff --git a/app/components/TeamLogo.ts b/app/components/TeamLogo.ts index ec8501e62..e799353a8 100644 --- a/app/components/TeamLogo.ts +++ b/app/components/TeamLogo.ts @@ -1,9 +1,10 @@ import styled from "styled-components"; +import { s } from "@shared/styles"; import Avatar from "./Avatar"; const TeamLogo = styled(Avatar)` border-radius: 4px; - border: 1px solid ${(props) => props.theme.divider}; + border: 1px solid ${s("divider")}; `; export default TeamLogo; diff --git a/app/components/Toast.tsx b/app/components/Toast.tsx index 779978c43..a2f9bb339 100644 --- a/app/components/Toast.tsx +++ b/app/components/Toast.tsx @@ -2,6 +2,7 @@ import { CheckboxIcon, InfoIcon, WarningIcon } from "outline-icons"; import { darken } from "polished"; import * as React from "react"; import styled, { css } from "styled-components"; +import { s } from "@shared/styles"; import { fadeAndScaleIn, pulse } from "~/styles/animations"; import { Toast as TToast } from "~/types"; import Spinner from "./Spinner"; @@ -72,7 +73,7 @@ function Toast({ closeAfterMs = 3000, onRequestClose, toast }: Props) { const Action = styled.span` display: inline-block; padding: 4px 8px; - color: ${(props) => props.theme.toastText}; + color: ${s("toastText")}; background: ${(props) => darken(0.05, props.theme.toastBackground)}; border-radius: 4px; margin-left: 8px; @@ -99,8 +100,8 @@ const Container = styled.div` animation: ${fadeAndScaleIn} 100ms ease; margin: 8px 0; padding: 0 12px; - color: ${(props) => props.theme.toastText}; - background: ${(props) => props.theme.toastBackground}; + color: ${s("toastText")}; + background: ${s("toastBackground")}; font-size: 15px; border-radius: 5px; cursor: default; diff --git a/app/components/Toasts.tsx b/app/components/Toasts.tsx index b052a62de..8f4f8eb67 100644 --- a/app/components/Toasts.tsx +++ b/app/components/Toasts.tsx @@ -23,8 +23,8 @@ function Toasts() { const List = styled.ol` position: fixed; - left: ${(props) => props.theme.hpadding}; - bottom: ${(props) => props.theme.vpadding}; + left: 16px; + bottom: 16px; list-style: none; margin: 0; padding: 0; diff --git a/app/components/Tooltip.tsx b/app/components/Tooltip.tsx index c44b5008a..67489fd28 100644 --- a/app/components/Tooltip.tsx +++ b/app/components/Tooltip.tsx @@ -2,6 +2,7 @@ import Tippy, { TippyProps } from "@tippyjs/react"; import * as React from "react"; import styled, { createGlobalStyle } from "styled-components"; import { roundArrow } from "tippy.js"; +import { s } from "@shared/styles"; export type Props = Omit & { tooltip?: React.ReactChild | React.ReactChild[]; @@ -45,9 +46,9 @@ const Shortcut = styled.kbd` font: 10px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; line-height: 10px; - color: ${(props) => props.theme.tooltipBackground}; + color: ${s("tooltipBackground")}; vertical-align: middle; - background-color: ${(props) => props.theme.tooltipText}; + background-color: ${s("tooltipText")}; border-radius: 3px; `; @@ -60,8 +61,8 @@ export const TooltipStyles = createGlobalStyle` } .tippy-box{ position:relative; - background-color: ${(props) => props.theme.tooltipBackground}; - color: ${(props) => props.theme.tooltipText}; + background-color: ${s("tooltipBackground")}; + color: ${s("tooltipText")}; border-radius:4px; font-size:13px; line-height:1.4; @@ -113,7 +114,7 @@ export const TooltipStyles = createGlobalStyle` .tippy-arrow{ width:16px; height:16px; - color: ${(props) => props.theme.tooltipBackground}; + color: ${s("tooltipBackground")}; } .tippy-arrow:before{ content:""; @@ -160,7 +161,7 @@ export const TooltipStyles = createGlobalStyle` .tippy-svg-arrow{ width:16px; height:16px; - fill: ${(props) => props.theme.tooltipBackground}; + fill: ${s("tooltipBackground")}; text-align:initial } .tippy-svg-arrow,.tippy-svg-arrow>svg{ diff --git a/app/components/Typing.tsx b/app/components/Typing.tsx index e8b5fcb6c..a32888eaa 100644 --- a/app/components/Typing.tsx +++ b/app/components/Typing.tsx @@ -1,5 +1,6 @@ import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; type Props = { /** The size to render the indicator, defaults to 24px */ @@ -20,7 +21,7 @@ export default function Typing({ size = 24 }: Props) { } const Wrapper = styled.svg` - fill: ${(props) => props.theme.textTertiary}; + fill: ${s("textTertiary")}; @keyframes blink { 50% { diff --git a/app/editor/components/FloatingToolbar.tsx b/app/editor/components/FloatingToolbar.tsx index c99f08cf0..6b4752cc3 100644 --- a/app/editor/components/FloatingToolbar.tsx +++ b/app/editor/components/FloatingToolbar.tsx @@ -2,7 +2,7 @@ import { NodeSelection } from "prosemirror-state"; import { CellSelection } from "prosemirror-tables"; import * as React from "react"; import styled from "styled-components"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import { Portal } from "~/components/Portal"; import useComponentSize from "~/hooks/useComponentSize"; import useEventListener from "~/hooks/useEventListener"; @@ -217,7 +217,7 @@ const Wrapper = styled.div<{ position: absolute; z-index: ${depths.editorToolbar}; opacity: 0; - background-color: ${(props) => props.theme.toolbarBackground}; + background-color: ${s("toolbarBackground")}; border-radius: 4px; transform: scale(0.95); transition: opacity 150ms cubic-bezier(0.175, 0.885, 0.32, 1.275), @@ -235,7 +235,7 @@ const Wrapper = styled.div<{ width: 24px; height: 24px; transform: translateX(-50%) rotate(45deg); - background: ${(props) => props.theme.toolbarBackground}; + background: ${s("toolbarBackground")}; border-radius: 3px; z-index: -1; position: absolute; diff --git a/app/editor/components/Input.tsx b/app/editor/components/Input.tsx index 15e7137be..0b90a8044 100644 --- a/app/editor/components/Input.tsx +++ b/app/editor/components/Input.tsx @@ -1,9 +1,10 @@ import styled from "styled-components"; +import { s } from "@shared/styles"; const Input = styled.input` font-size: 15px; - background: ${(props) => props.theme.toolbarInput}; - color: ${(props) => props.theme.toolbarItem}; + background: ${s("toolbarInput")}; + color: ${s("toolbarItem")}; border-radius: 2px; padding: 3px 8px; border: 0; diff --git a/app/editor/components/LinkEditor.tsx b/app/editor/components/LinkEditor.tsx index bf92ef828..0aa87c48e 100644 --- a/app/editor/components/LinkEditor.tsx +++ b/app/editor/components/LinkEditor.tsx @@ -10,6 +10,7 @@ import { setTextSelection } from "prosemirror-utils"; import { EditorView } from "prosemirror-view"; import * as React from "react"; import styled from "styled-components"; +import { s } from "@shared/styles"; import { isInternalUrl, sanitizeUrl } from "@shared/utils/urls"; import Flex from "~/components/Flex"; import { ResizingHeightContainer } from "~/components/ResizingHeightContainer"; @@ -403,7 +404,7 @@ const Wrapper = styled(Flex)` `; const SearchResults = styled(Scrollable)<{ $hasResults: boolean }>` - background: ${(props) => props.theme.toolbarBackground}; + background: ${s("toolbarBackground")}; position: absolute; top: 100%; width: 100%; diff --git a/app/editor/components/LinkSearchResult.tsx b/app/editor/components/LinkSearchResult.tsx index 4aecf2c64..f155d7998 100644 --- a/app/editor/components/LinkSearchResult.tsx +++ b/app/editor/components/LinkSearchResult.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import scrollIntoView from "smooth-scroll-into-view-if-needed"; import styled from "styled-components"; -import { ellipsis } from "~/styles"; +import { s, ellipsis } from "@shared/styles"; type Props = React.HTMLAttributes & { icon: React.ReactNode; @@ -78,7 +78,7 @@ const ListItem = styled.div<{ props.selected ? props.theme.accentText : props.theme.toolbarItem}; background: ${(props) => props.selected ? props.theme.accent : "transparent"}; - font-family: ${(props) => props.theme.fontFamily}; + font-family: ${s("fontFamily")}; text-decoration: none; overflow: hidden; white-space: nowrap; diff --git a/app/editor/components/SuggestionsMenu.tsx b/app/editor/components/SuggestionsMenu.tsx index 6bdc446aa..ff126b4b5 100644 --- a/app/editor/components/SuggestionsMenu.tsx +++ b/app/editor/components/SuggestionsMenu.tsx @@ -9,7 +9,7 @@ import insertFiles from "@shared/editor/commands/insertFiles"; import { EmbedDescriptor } from "@shared/editor/embeds"; import filterExcessSeparators from "@shared/editor/lib/filterExcessSeparators"; import { MenuItem } from "@shared/editor/types"; -import { depths } from "@shared/styles"; +import { depths, s } from "@shared/styles"; import { getEventFiles } from "@shared/utils/files"; import { AttachmentValidation } from "@shared/validations"; import { Portal } from "~/components/Portal"; @@ -583,7 +583,7 @@ const LinkInputWrapper = styled.div` const LinkInput = styled(Input)` height: 32px; width: 100%; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; `; const List = styled.ol` @@ -602,7 +602,7 @@ const ListItem = styled.li` const Empty = styled.div` display: flex; align-items: center; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; font-weight: 500; font-size: 14px; height: 32px; @@ -616,14 +616,14 @@ export const Wrapper = styled(Scrollable)<{ left?: number; isAbove: boolean; }>` - color: ${(props) => props.theme.textSecondary}; - font-family: ${(props) => props.theme.fontFamily}; + color: ${s("textSecondary")}; + font-family: ${s("fontFamily")}; position: absolute; z-index: ${depths.editorToolbar}; ${(props) => props.top !== undefined && `top: ${props.top}px`}; ${(props) => props.bottom !== undefined && `bottom: ${props.bottom}px`}; left: ${(props) => props.left}px; - background: ${(props) => props.theme.menuBackground}; + background: ${s("menuBackground")}; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.08) 0px 4px 8px, rgba(0, 0, 0, 0.08) 0px 2px 4px; @@ -647,7 +647,7 @@ export const Wrapper = styled(Scrollable)<{ hr { border: 0; height: 0; - border-top: 1px solid ${(props) => props.theme.divider}; + border-top: 1px solid ${s("divider")}; } ${({ active, isAbove }) => diff --git a/app/editor/components/ToolbarButton.tsx b/app/editor/components/ToolbarButton.tsx index 049bbeabc..4888375d7 100644 --- a/app/editor/components/ToolbarButton.tsx +++ b/app/editor/components/ToolbarButton.tsx @@ -1,4 +1,5 @@ import styled from "styled-components"; +import { s } from "@shared/styles"; type Props = { active?: boolean; disabled?: boolean }; @@ -18,7 +19,7 @@ export default styled.button.attrs((props) => ({ outline: none; pointer-events: all; position: relative; - color: ${(props) => props.theme.toolbarItem}; + color: ${s("toolbarItem")}; &:hover { opacity: 1; diff --git a/app/editor/components/ToolbarMenu.tsx b/app/editor/components/ToolbarMenu.tsx index 300549939..7d50edf9b 100644 --- a/app/editor/components/ToolbarMenu.tsx +++ b/app/editor/components/ToolbarMenu.tsx @@ -1,6 +1,7 @@ import * as React from "react"; import styled from "styled-components"; import { MenuItem } from "@shared/editor/types"; +import { s } from "@shared/styles"; import { useEditor } from "./EditorContext"; import ToolbarButton from "./ToolbarButton"; import ToolbarSeparator from "./ToolbarSeparator"; @@ -11,7 +12,7 @@ type Props = { }; const FlexibleWrapper = styled.div` - color: ${(props) => props.theme.toolbarItem}; + color: ${s("toolbarItem")}; display: flex; gap: 8px; `; diff --git a/app/editor/components/ToolbarSeparator.tsx b/app/editor/components/ToolbarSeparator.tsx index fbd1272aa..0a27a7c4c 100644 --- a/app/editor/components/ToolbarSeparator.tsx +++ b/app/editor/components/ToolbarSeparator.tsx @@ -1,9 +1,10 @@ import styled from "styled-components"; +import { s } from "@shared/styles"; const Separator = styled.div` height: 24px; width: 2px; - background: ${(props) => props.theme.toolbarItem}; + background: ${s("toolbarItem")}; opacity: 0.3; display: inline-block; margin-left: 8px; diff --git a/app/menus/DocumentMenu.tsx b/app/menus/DocumentMenu.tsx index ad1c0c9b5..0ad7f37cb 100644 --- a/app/menus/DocumentMenu.tsx +++ b/app/menus/DocumentMenu.tsx @@ -7,6 +7,7 @@ import { useMenuState, MenuButton, MenuButtonHTMLProps } from "reakit/Menu"; import { VisuallyHidden } from "reakit/VisuallyHidden"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s, ellipsis } from "@shared/styles"; import { getEventFiles } from "@shared/utils/files"; import Document from "~/models/Document"; import ContextMenu from "~/components/ContextMenu"; @@ -45,7 +46,6 @@ import usePolicy from "~/hooks/usePolicy"; import useRequest from "~/hooks/useRequest"; import useStores from "~/hooks/useStores"; import useToasts from "~/hooks/useToasts"; -import { ellipsis } from "~/styles"; import { MenuItem } from "~/types"; import { editDocumentUrl, newDocumentPath } from "~/utils/routeHelpers"; @@ -338,7 +338,7 @@ function DocumentMenu({ const ToggleMenuItem = styled(Switch)` * { font-weight: normal; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; } `; diff --git a/app/menus/NewTemplateMenu.tsx b/app/menus/NewTemplateMenu.tsx index e990d4f28..188d44216 100644 --- a/app/menus/NewTemplateMenu.tsx +++ b/app/menus/NewTemplateMenu.tsx @@ -4,6 +4,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import { MenuButton, useMenuState } from "reakit/Menu"; import styled from "styled-components"; +import { ellipsis } from "@shared/styles"; import Button from "~/components/Button"; import ContextMenu from "~/components/ContextMenu"; import Header from "~/components/ContextMenu/Header"; @@ -12,7 +13,6 @@ import CollectionIcon from "~/components/Icons/CollectionIcon"; import useCurrentTeam from "~/hooks/useCurrentTeam"; import usePolicy from "~/hooks/usePolicy"; import useStores from "~/hooks/useStores"; -import { ellipsis } from "~/styles"; import { MenuItem } from "~/types"; import { newDocumentPath } from "~/utils/routeHelpers"; diff --git a/app/menus/TemplatesMenu.tsx b/app/menus/TemplatesMenu.tsx index f516cbecc..af59d91fb 100644 --- a/app/menus/TemplatesMenu.tsx +++ b/app/menus/TemplatesMenu.tsx @@ -4,6 +4,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import { MenuButton, useMenuState } from "reakit/Menu"; import styled from "styled-components"; +import { ellipsis } from "@shared/styles"; import Document from "~/models/Document"; import Button from "~/components/Button"; import ContextMenu from "~/components/ContextMenu"; @@ -11,7 +12,6 @@ import MenuItem from "~/components/ContextMenu/MenuItem"; import Separator from "~/components/ContextMenu/Separator"; import useCurrentUser from "~/hooks/useCurrentUser"; import useStores from "~/hooks/useStores"; -import { ellipsis } from "~/styles"; import { replaceTitleVariables } from "~/utils/date"; type Props = { diff --git a/app/scenes/CollectionPermissions/components/CollectionGroupMemberListItem.tsx b/app/scenes/CollectionPermissions/components/CollectionGroupMemberListItem.tsx index 8bc8eae78..078051819 100644 --- a/app/scenes/CollectionPermissions/components/CollectionGroupMemberListItem.tsx +++ b/app/scenes/CollectionPermissions/components/CollectionGroupMemberListItem.tsx @@ -1,6 +1,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; +import { s } from "@shared/styles"; import { CollectionPermission } from "@shared/types"; import CollectionGroupMembership from "~/models/CollectionGroupMembership"; import Group from "~/models/Group"; @@ -66,7 +67,7 @@ const Select = styled(InputSelect)` font-size: 14px; border-color: transparent; box-shadow: none; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; select { margin: 0; diff --git a/app/scenes/CollectionPermissions/components/MemberListItem.tsx b/app/scenes/CollectionPermissions/components/MemberListItem.tsx index 3176a21b5..28dc15a7c 100644 --- a/app/scenes/CollectionPermissions/components/MemberListItem.tsx +++ b/app/scenes/CollectionPermissions/components/MemberListItem.tsx @@ -2,6 +2,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import { Trans, useTranslation } from "react-i18next"; import styled from "styled-components"; +import { s } from "@shared/styles"; import { CollectionPermission } from "@shared/types"; import Membership from "~/models/Membership"; import User from "~/models/User"; @@ -94,7 +95,7 @@ const Select = styled(InputSelect)` font-size: 14px; border-color: transparent; box-shadow: none; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; select { margin: 0; diff --git a/app/scenes/DesktopRedirect.tsx b/app/scenes/DesktopRedirect.tsx index 6db11f0e5..399d92e47 100644 --- a/app/scenes/DesktopRedirect.tsx +++ b/app/scenes/DesktopRedirect.tsx @@ -1,6 +1,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; +import { s } from "@shared/styles"; import Flex from "~/components/Flex"; import Heading from "~/components/Heading"; import PageTitle from "~/components/PageTitle"; @@ -40,7 +41,7 @@ const DesktopRedirect = () => { }; const Note = styled(Text)` - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; text-align: center; font-size: 14px; margin-top: 8px; diff --git a/app/scenes/Document/Shared.tsx b/app/scenes/Document/Shared.tsx index c90c005bc..25b978c3f 100644 --- a/app/scenes/Document/Shared.tsx +++ b/app/scenes/Document/Shared.tsx @@ -6,6 +6,7 @@ import { useTranslation } from "react-i18next"; import { RouteComponentProps, useLocation, Redirect } from "react-router-dom"; import styled, { ThemeProvider } from "styled-components"; import { setCookie } from "tiny-cookie"; +import { s } from "@shared/styles"; import { CustomTheme, NavigationNode } from "@shared/types"; import DocumentModel from "~/models/Document"; import Error404 from "~/scenes/Error404"; @@ -197,7 +198,7 @@ function SharedDocumentScene(props: Props) { } const Content = styled(Text)` - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; text-align: center; margin-top: -8px; `; diff --git a/app/scenes/Document/components/CommentThread.tsx b/app/scenes/Document/components/CommentThread.tsx index f6a88b865..c8707e8c3 100644 --- a/app/scenes/Document/components/CommentThread.tsx +++ b/app/scenes/Document/components/CommentThread.tsx @@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next"; import { useHistory } from "react-router-dom"; import scrollIntoView from "smooth-scroll-into-view-if-needed"; import styled, { css } from "styled-components"; +import { s } from "@shared/styles"; import Comment from "~/models/Comment"; import Document from "~/models/Document"; import Avatar from "~/components/Avatar"; @@ -199,7 +200,7 @@ const Reply = styled.button` padding: 8px; margin: 0; background: none; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; font-size: 14px; -webkit-appearance: none; cursor: var(--pointer); diff --git a/app/scenes/Document/components/CommentThreadItem.tsx b/app/scenes/Document/components/CommentThreadItem.tsx index c0698a423..92d286c8b 100644 --- a/app/scenes/Document/components/CommentThreadItem.tsx +++ b/app/scenes/Document/components/CommentThreadItem.tsx @@ -4,6 +4,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import { useTranslation } from "react-i18next"; import styled, { css } from "styled-components"; +import { s } from "@shared/styles"; import { Minute } from "@shared/utils/time"; import Comment from "~/models/Comment"; import Avatar from "~/components/Avatar"; @@ -223,7 +224,7 @@ const Menu = styled(CommentMenu)<{ dir?: "rtl" | "ltr" }>` &:hover, &[aria-expanded="true"] { opacity: 1; - background: ${(props) => props.theme.sidebarActiveBackground}; + background: ${s("sidebarActiveBackground")}; } `; @@ -246,13 +247,12 @@ export const Bubble = styled(Flex)<{ position: relative; flex-grow: 1; font-size: 15px; - color: ${(props) => props.theme.text}; - background: ${(props) => props.theme.commentBackground}; + color: ${s("text")}; + background: ${s("commentBackground")}; min-width: 2em; margin-bottom: 1px; padding: 8px 12px; - transition: color 100ms ease-out, - ${(props) => props.theme.backgroundTransition}; + transition: color 100ms ease-out, ${s("backgroundTransition")}; ${({ $lastOfThread }) => $lastOfThread && diff --git a/app/scenes/Document/components/Contents.tsx b/app/scenes/Document/components/Contents.tsx index 06002988f..a7d31e5f9 100644 --- a/app/scenes/Document/components/Contents.tsx +++ b/app/scenes/Document/components/Contents.tsx @@ -3,6 +3,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s } from "@shared/styles"; import Text from "~/components/Text"; import useWindowScrollPosition from "~/hooks/useWindowScrollPosition"; @@ -101,8 +102,8 @@ const Sticky = styled.div` top: 80px; max-height: calc(100vh - 80px); - background: ${(props) => props.theme.background}; - transition: ${(props) => props.theme.backgroundTransition}; + background: ${s("background")}; + transition: ${s("backgroundTransition")}; margin-top: 72px; margin-right: 52px; @@ -122,7 +123,7 @@ const Sticky = styled.div` const Heading = styled.h3` font-size: 13px; font-weight: 600; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; letter-spacing: 0.03em; `; @@ -145,11 +146,11 @@ const ListItem = styled.li<{ level: number; active?: boolean }>` `; const Link = styled.a` - color: ${(props) => props.theme.text}; + color: ${s("text")}; font-size: 14px; &:hover { - color: ${(props) => props.theme.accent}; + color: ${s("accent")}; } `; diff --git a/app/scenes/Document/components/Document.tsx b/app/scenes/Document/components/Document.tsx index 7f8b011bf..7e657f058 100644 --- a/app/scenes/Document/components/Document.tsx +++ b/app/scenes/Document/components/Document.tsx @@ -13,6 +13,7 @@ import { } from "react-router"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s } from "@shared/styles"; import { NavigationNode } from "@shared/types"; import { Heading } from "@shared/utils/ProsemirrorHelper"; import { parseDomain } from "@shared/utils/domains"; @@ -36,6 +37,7 @@ import { client } from "~/utils/ApiClient"; import { replaceTitleVariables } from "~/utils/date"; import { emojiToUrl } from "~/utils/emoji"; import { isModKey } from "~/utils/keyboard"; + import { documentHistoryUrl, editDocumentUrl, @@ -574,8 +576,8 @@ const Footer = styled.div` const Background = styled(Container)` position: relative; - background: ${(props) => props.theme.background}; - transition: ${(props) => props.theme.backgroundTransition}; + background: ${s("background")}; + transition: ${s("backgroundTransition")}; `; const ReferencesWrapper = styled.div<{ isOnlyTitle?: boolean }>` diff --git a/app/scenes/Document/components/EditableTitle.tsx b/app/scenes/Document/components/EditableTitle.tsx index 4c4de2390..994e24cd5 100644 --- a/app/scenes/Document/components/EditableTitle.tsx +++ b/app/scenes/Document/components/EditableTitle.tsx @@ -7,6 +7,7 @@ import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; import isMarkdown from "@shared/editor/lib/isMarkdown"; import normalizePastedMarkdown from "@shared/editor/lib/markdown/normalize"; +import { s } from "@shared/styles"; import { light } from "@shared/styles/theme"; import { getCurrentDateAsString, @@ -238,8 +239,8 @@ const Title = styled(ContentEditable)` } &::placeholder { - color: ${(props) => props.theme.placeholder}; - -webkit-text-fill-color: ${(props) => props.theme.placeholder}; + color: ${s("placeholder")}; + -webkit-text-fill-color: ${s("placeholder")}; } ${breakpoint("tablet")` diff --git a/app/scenes/Document/components/Insights.tsx b/app/scenes/Document/components/Insights.tsx index 6cd57aa70..197a32b6a 100644 --- a/app/scenes/Document/components/Insights.tsx +++ b/app/scenes/Document/components/Insights.tsx @@ -4,6 +4,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import { useHistory, useRouteMatch } from "react-router-dom"; import styled from "styled-components"; +import { s } from "@shared/styles"; import User from "~/models/User"; import Avatar from "~/components/Avatar"; import { useDocumentContext } from "~/components/DocumentContext"; @@ -179,7 +180,7 @@ const List = styled("ul")` content: "·"; display: inline-block; font-weight: 600; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; width: 10px; } `; diff --git a/app/scenes/Document/components/ReferenceListItem.tsx b/app/scenes/Document/components/ReferenceListItem.tsx index 85fb055d9..e183c9c02 100644 --- a/app/scenes/Document/components/ReferenceListItem.tsx +++ b/app/scenes/Document/components/ReferenceListItem.tsx @@ -3,12 +3,13 @@ import { DocumentIcon } from "outline-icons"; import * as React from "react"; import { Link } from "react-router-dom"; import styled from "styled-components"; +import { s, ellipsis } from "@shared/styles"; import { NavigationNode } from "@shared/types"; import parseTitle from "@shared/utils/parseTitle"; import Document from "~/models/Document"; import Flex from "~/components/Flex"; import EmojiIcon from "~/components/Icons/EmojiIcon"; -import { ellipsis, hover } from "~/styles"; +import { hover } from "~/styles"; import { sharedDocumentPath } from "~/utils/routeHelpers"; type Props = { @@ -32,12 +33,12 @@ const DocumentLink = styled(Link)` &:${hover}, &:active, &:focus { - background: ${(props) => props.theme.listItemHoverBackground}; + background: ${s("listItemHoverBackground")}; } `; const Content = styled(Flex)` - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; margin-left: -4px; `; @@ -47,7 +48,7 @@ const Title = styled.div` font-weight: 500; line-height: 1.25; padding-top: 3px; - color: ${(props) => props.theme.text}; + color: ${s("text")}; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; `; diff --git a/app/scenes/Document/components/SharePopover.tsx b/app/scenes/Document/components/SharePopover.tsx index 6857a5876..2b3c0972d 100644 --- a/app/scenes/Document/components/SharePopover.tsx +++ b/app/scenes/Document/components/SharePopover.tsx @@ -7,6 +7,7 @@ import * as React from "react"; import { useTranslation, Trans } from "react-i18next"; import { Link } from "react-router-dom"; import styled from "styled-components"; +import { s } from "@shared/styles"; import { SHARE_URL_SLUG_REGEX } from "@shared/utils/urlHelpers"; import Document from "~/models/Document"; import Share from "~/models/Share"; @@ -349,7 +350,7 @@ function SharePopover({ } const StyledLink = styled(Link)` - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; text-decoration: underline; `; @@ -374,14 +375,14 @@ const NoticeWrapper = styled.div` const MoreOptionsButton = styled(Button)` background: none; font-size: 14px; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; margin-left: -8px; `; const Separator = styled.div` height: 1px; width: 100%; - background-color: ${(props) => props.theme.divider}; + background-color: ${s("divider")}; `; const SwitchLabel = styled(Flex)` diff --git a/app/scenes/Document/components/SidebarLayout.tsx b/app/scenes/Document/components/SidebarLayout.tsx index 335900e03..19d610516 100644 --- a/app/scenes/Document/components/SidebarLayout.tsx +++ b/app/scenes/Document/components/SidebarLayout.tsx @@ -4,13 +4,12 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import { Portal } from "react-portal"; import styled from "styled-components"; -import { depths } from "@shared/styles"; +import { depths, s, ellipsis } from "@shared/styles"; import Button from "~/components/Button"; import Flex from "~/components/Flex"; import Scrollable from "~/components/Scrollable"; import Tooltip from "~/components/Tooltip"; import useMobile from "~/hooks/useMobile"; -import { ellipsis } from "~/styles"; import { fadeIn } from "~/styles/animations"; type Props = React.HTMLAttributes & { @@ -67,7 +66,7 @@ const Backdrop = styled.a` right: 0; cursor: default; z-index: ${depths.sidebar - 1}; - background: ${(props) => props.theme.backdrop}; + background: ${s("backdrop")}; `; const ForwardIcon = styled(BackIcon)` @@ -91,7 +90,7 @@ const Header = styled(Flex)` align-items: center; position: relative; padding: 16px 12px 16px 16px; - color: ${(props) => props.theme.text}; + color: ${s("text")}; flex-shrink: 0; `; diff --git a/app/scenes/DocumentMove.tsx b/app/scenes/DocumentMove.tsx index 2e489b04a..bac17fff5 100644 --- a/app/scenes/DocumentMove.tsx +++ b/app/scenes/DocumentMove.tsx @@ -3,6 +3,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import { useTranslation, Trans } from "react-i18next"; import styled from "styled-components"; +import { ellipsis } from "@shared/styles"; import { NavigationNode } from "@shared/types"; import Document from "~/models/Document"; import Button from "~/components/Button"; @@ -12,7 +13,6 @@ import Text from "~/components/Text"; import useCollectionTrees from "~/hooks/useCollectionTrees"; import useStores from "~/hooks/useStores"; import useToasts from "~/hooks/useToasts"; -import { ellipsis } from "~/styles"; import { flattenTree } from "~/utils/tree"; type Props = { diff --git a/app/scenes/DocumentPublish.tsx b/app/scenes/DocumentPublish.tsx index 2cd38f8c5..3c807ddf6 100644 --- a/app/scenes/DocumentPublish.tsx +++ b/app/scenes/DocumentPublish.tsx @@ -3,6 +3,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import { useTranslation, Trans } from "react-i18next"; import styled from "styled-components"; +import { ellipsis } from "@shared/styles"; import { NavigationNode } from "@shared/types"; import Document from "~/models/Document"; import Button from "~/components/Button"; @@ -12,7 +13,6 @@ import Text from "~/components/Text"; import useCollectionTrees from "~/hooks/useCollectionTrees"; import useStores from "~/hooks/useStores"; import useToasts from "~/hooks/useToasts"; -import { ellipsis } from "~/styles"; import { flattenTree } from "~/utils/tree"; type Props = { diff --git a/app/scenes/Invite.tsx b/app/scenes/Invite.tsx index 51ba4749e..317f79675 100644 --- a/app/scenes/Invite.tsx +++ b/app/scenes/Invite.tsx @@ -4,6 +4,7 @@ import * as React from "react"; import { useTranslation, Trans } from "react-i18next"; import { Link } from "react-router-dom"; import styled from "styled-components"; +import { s } from "@shared/styles"; import { Role } from "@shared/types"; import { UserValidation } from "@shared/validations"; import Button from "~/components/Button"; @@ -272,7 +273,7 @@ function Invite({ onSubmit }: Props) { const CopyBlock = styled("div")` margin: 2em 0; font-size: 14px; - background: ${(props) => props.theme.secondaryBackground}; + background: ${s("secondaryBackground")}; border-radius: 8px; padding: 16px 16px 8px; `; diff --git a/app/scenes/KeyboardShortcuts.tsx b/app/scenes/KeyboardShortcuts.tsx index 3cf3f8efa..385c0ff32 100644 --- a/app/scenes/KeyboardShortcuts.tsx +++ b/app/scenes/KeyboardShortcuts.tsx @@ -1,6 +1,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; +import { s } from "@shared/styles"; import Flex from "~/components/Flex"; import InputSearch from "~/components/InputSearch"; import Key from "~/components/Key"; @@ -450,7 +451,7 @@ const Keys = styled.dt` clear: left; text-align: right; font-size: 12px; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; display: flex; align-items: center; justify-content: flex-end; @@ -462,7 +463,7 @@ const Label = styled.dd` margin: 0 0 10px; display: flex; align-items: center; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; `; export default React.memo(KeyboardShortcuts); diff --git a/app/scenes/Login/Notices.tsx b/app/scenes/Login/Notices.tsx index d38e32bc2..d25166e0a 100644 --- a/app/scenes/Login/Notices.tsx +++ b/app/scenes/Login/Notices.tsx @@ -1,4 +1,5 @@ import * as React from "react"; +import { Trans } from "react-i18next"; import NoticeAlert from "~/components/NoticeAlert"; import useQuery from "~/hooks/useQuery"; @@ -7,97 +8,101 @@ export default function Notices() { const notice = query.get("notice"); const description = query.get("description"); + if (!notice) { + return null; + } + return ( - <> + {notice === "domain-required" && ( - + Unable to sign-in. Please navigate to your team's custom URL, then try to sign-in again.
If you were invited to a team, you will find a link to it in the invite email. - + )} {notice === "gmail-account-creation" && ( - + Sorry, a new account cannot be created with a personal Gmail address.
Please use a Google Workspaces account instead. -
+ )} {notice === "maximum-teams" && ( - + The team you authenticated with is not authorized on this installation. Try another? - + )} {notice === "malformed-user-info" && ( - + We could not read the user info supplied by your identity provider. - + )} {notice === "email-auth-required" && ( - + Your account uses email sign-in, please sign-in with email to continue. - + )} {notice === "email-auth-ratelimit" && ( - + An email sign-in link was recently sent, please check your inbox or try again in a few minutes. - + )} {(notice === "auth-error" || notice === "state-mismatch") && (description ? ( - {description} + <>{description} ) : ( - + Authentication failed – we were unable to sign you in at this time. Please try again. - + ))} {notice === "invalid-authentication" && (description ? ( - {description} + <>{description} ) : ( - + Authentication failed – you do not have permission to access this team. - + ))} {notice === "expired-token" && ( - + Sorry, it looks like that sign-in link is no longer valid, please try requesting another. - + )} {notice === "suspended" && ( - + Your account has been suspended. To re-activate your account, please contact a team admin. - + )} {notice === "authentication-provider-disabled" && ( - + Authentication failed – this login method was disabled by a team admin. - + )} {notice === "invite-required" && ( - + The team you are trying to join requires an invite before you can create an account.
Please request an invite from your team admin and try again. -
+ )} {notice === "domain-not-allowed" && ( - + Sorry, your domain is not allowed. Please try again with an allowed team domain. - + )} - + ); } diff --git a/app/scenes/Login/index.tsx b/app/scenes/Login/index.tsx index 168165b08..d187c2876 100644 --- a/app/scenes/Login/index.tsx +++ b/app/scenes/Login/index.tsx @@ -6,6 +6,7 @@ import { Trans, useTranslation } from "react-i18next"; import { useLocation, Link, Redirect } from "react-router-dom"; import styled from "styled-components"; import { getCookie, setCookie } from "tiny-cookie"; +import { s } from "@shared/styles"; import { parseDomain } from "@shared/utils/domains"; import { Config } from "~/stores/AuthStore"; import ButtonLarge from "~/components/ButtonLarge"; @@ -278,7 +279,7 @@ const CheckEmailIcon = styled(EmailIcon)` const Background = styled(Fade)` width: 100vw; height: 100%; - background: ${(props) => props.theme.background}; + background: ${s("background")}; display: flex; ${draggableOnDesktop()} `; @@ -288,13 +289,13 @@ const Logo = styled.div` `; const Content = styled(Text)` - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; text-align: center; margin-top: -8px; `; const Note = styled(Text)` - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; text-align: center; font-size: 14px; margin-top: 8px; @@ -337,8 +338,8 @@ const Or = styled.hr` transform: translate3d(-50%, -50%, 0); text-transform: uppercase; font-size: 11px; - color: ${(props) => props.theme.textSecondary}; - background: ${(props) => props.theme.background}; + color: ${s("textSecondary")}; + background: ${s("background")}; border-radius: 2px; padding: 0 4px; } diff --git a/app/scenes/Search/components/RecentSearches.tsx b/app/scenes/Search/components/RecentSearches.tsx index ccf175ccc..f841d1da7 100644 --- a/app/scenes/Search/components/RecentSearches.tsx +++ b/app/scenes/Search/components/RecentSearches.tsx @@ -4,6 +4,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import styled from "styled-components"; +import { s } from "@shared/styles"; import Fade from "~/components/Fade"; import NudeButton from "~/components/NudeButton"; import Tooltip from "~/components/Tooltip"; @@ -53,7 +54,7 @@ const Heading = styled.h2` font-weight: 500; font-size: 14px; line-height: 1.5; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; margin-bottom: 0; `; @@ -70,7 +71,7 @@ const ListItem = styled.li` &:before { content: "·"; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; position: absolute; left: -8px; } @@ -78,24 +79,24 @@ const ListItem = styled.li` const RemoveButton = styled(NudeButton)` opacity: 0; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; &:hover { - color: ${(props) => props.theme.text}; + color: ${s("text")}; } `; const RecentSearch = styled(Link)` display: flex; justify-content: space-between; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; cursor: var(--pointer); padding: 1px 4px; border-radius: 4px; &: ${hover} { - color: ${(props) => props.theme.text}; - background: ${(props) => props.theme.secondaryBackground}; + color: ${s("text")}; + background: ${s("secondaryBackground")}; ${RemoveButton} { opacity: 1; diff --git a/app/scenes/Search/components/SearchInput.tsx b/app/scenes/Search/components/SearchInput.tsx index 3efea4e29..d645b9c1c 100644 --- a/app/scenes/Search/components/SearchInput.tsx +++ b/app/scenes/Search/components/SearchInput.tsx @@ -1,6 +1,7 @@ import { SearchIcon } from "outline-icons"; import * as React from "react"; import styled, { useTheme } from "styled-components"; +import { s } from "@shared/styles"; import Flex from "~/components/Flex"; type Props = React.HTMLAttributes & { @@ -57,26 +58,26 @@ const StyledInput = styled.input` font-weight: 400; outline: none; border: 0; - background: ${(props) => props.theme.sidebarBackground}; - transition: ${(props) => props.theme.backgroundTransition}; + background: ${s("sidebarBackground")}; + transition: ${s("backgroundTransition")}; border-radius: 4px; - color: ${(props) => props.theme.text}; + color: ${s("text")}; ::-webkit-search-cancel-button { -webkit-appearance: none; } ::-webkit-input-placeholder { - color: ${(props) => props.theme.placeholder}; + color: ${s("placeholder")}; } :-moz-placeholder { - color: ${(props) => props.theme.placeholder}; + color: ${s("placeholder")}; } ::-moz-placeholder { - color: ${(props) => props.theme.placeholder}; + color: ${s("placeholder")}; } :-ms-input-placeholder { - color: ${(props) => props.theme.placeholder}; + color: ${s("placeholder")}; } `; diff --git a/app/scenes/Settings/components/DropToImport.tsx b/app/scenes/Settings/components/DropToImport.tsx index 7cd167853..8123c383b 100644 --- a/app/scenes/Settings/components/DropToImport.tsx +++ b/app/scenes/Settings/components/DropToImport.tsx @@ -4,6 +4,7 @@ import * as React from "react"; import Dropzone from "react-dropzone"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; +import { s } from "@shared/styles"; import { AttachmentPreset } from "@shared/types"; import Flex from "~/components/Flex"; import LoadingIndicator from "~/components/LoadingIndicator"; @@ -114,7 +115,7 @@ const DropzoneContainer = styled.div<{ ? props.theme.secondaryBackground : props.theme.background}; border-radius: 8px; - border: 1px dashed ${(props) => props.theme.divider}; + border: 1px dashed ${s("divider")}; padding: 52px; text-align: center; font-size: 15px; @@ -122,7 +123,7 @@ const DropzoneContainer = styled.div<{ opacity: ${(props) => (props.$disabled ? 0.5 : 1)}; &:hover { - background: ${(props) => props.theme.secondaryBackground}; + background: ${s("secondaryBackground")}; } `; diff --git a/app/scenes/Settings/components/ImageInput.tsx b/app/scenes/Settings/components/ImageInput.tsx index 2811973e7..f378418b2 100644 --- a/app/scenes/Settings/components/ImageInput.tsx +++ b/app/scenes/Settings/components/ImageInput.tsx @@ -1,6 +1,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; +import { s } from "@shared/styles"; import Avatar, { IAvatar } from "~/components/Avatar/Avatar"; import Flex from "~/components/Flex"; import ImageUpload, { Props as ImageUploadProps } from "./ImageUpload"; @@ -38,8 +39,8 @@ const ImageBox = styled(Flex)` position: relative; font-size: 14px; border-radius: 8px; - box-shadow: 0 0 0 1px ${(props) => props.theme.secondaryBackground}; - background: ${(props) => props.theme.background}; + box-shadow: 0 0 0 1px ${s("secondaryBackground")}; + background: ${s("background")}; overflow: hidden; .upload { diff --git a/app/scenes/Settings/components/ImageUpload.tsx b/app/scenes/Settings/components/ImageUpload.tsx index bea1b6386..53ea73ebe 100644 --- a/app/scenes/Settings/components/ImageUpload.tsx +++ b/app/scenes/Settings/components/ImageUpload.tsx @@ -5,6 +5,7 @@ import * as React from "react"; import AvatarEditor from "react-avatar-editor"; import Dropzone from "react-dropzone"; import styled from "styled-components"; +import { s } from "@shared/styles"; import { AttachmentPreset } from "@shared/types"; import { AttachmentValidation } from "@shared/validations"; import RootStore from "~/stores/RootStore"; @@ -170,7 +171,7 @@ const RangeInput = styled.input` height: 16px; width: 16px; border-radius: 50%; - background: ${(props) => props.theme.text}; + background: ${s("text")}; cursor: var(--pointer); } diff --git a/app/styles/index.ts b/app/styles/index.ts index cc1513465..5a8245cb8 100644 --- a/app/styles/index.ts +++ b/app/styles/index.ts @@ -38,28 +38,3 @@ export const fadeOnDesktopBackgrounded = () => { body.backgrounded & { opacity: 0.75; } `; }; - -/** - * Mixin to hide scrollbars. - * - * @returns string of CSS - */ -export const hideScrollbars = () => ` - -ms-overflow-style: none; - overflow: -moz-scrollbars-none; - scrollbar-width: none; - &::-webkit-scrollbar { - display: none; - } -`; - -/** - * Mixin to make text ellipse when it overflows. - * - * @returns string of CSS - */ -export const ellipsis = () => ` - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; -`; diff --git a/app/typings/styled-components.d.ts b/app/typings/styled-components.d.ts index fa4c78aa1..45a8b7500 100644 --- a/app/typings/styled-components.d.ts +++ b/app/typings/styled-components.d.ts @@ -107,9 +107,6 @@ declare module "styled-components" { } interface Spacing { - padding: string; - vpadding: string; - hpadding: string; sidebarWidth: number; sidebarRightWidth: number; sidebarCollapsedWidth: number; diff --git a/plugins/slack/client/components/SlackListItem.tsx b/plugins/slack/client/components/SlackListItem.tsx index fd8da5e8d..dd93c4e54 100644 --- a/plugins/slack/client/components/SlackListItem.tsx +++ b/plugins/slack/client/components/SlackListItem.tsx @@ -4,6 +4,7 @@ import * as React from "react"; import { Trans, useTranslation } from "react-i18next"; import { usePopoverState, PopoverDisclosure } from "reakit/Popover"; import styled from "styled-components"; +import { s } from "@shared/styles"; import { IntegrationType } from "@shared/types"; import Collection from "~/models/Collection"; import Integration from "~/models/Integration"; @@ -111,7 +112,7 @@ function SlackListItem({ integration, collection }: Props) { } const Events = styled.div` - color: ${(props) => props.theme.text}; + color: ${s("text")}; margin-top: -12px; `; diff --git a/shared/editor/components/FileExtension.tsx b/shared/editor/components/FileExtension.tsx index f4f799b71..700e48c59 100644 --- a/shared/editor/components/FileExtension.tsx +++ b/shared/editor/components/FileExtension.tsx @@ -1,6 +1,7 @@ import { AttachmentIcon } from "outline-icons"; import * as React from "react"; import styled from "styled-components"; +import { s } from "../../styles"; import { stringToColor } from "../../utils/color"; type Props = { @@ -27,7 +28,7 @@ export default function FileExtension(props: Props) { } const Icon = styled.span<{ $size: number }>` - font-family: ${(props) => props.theme.fontFamilyMono}; + font-family: ${s("fontFamilyMono")}; display: inline-flex; align-items: center; justify-content: center; diff --git a/shared/editor/components/Frame.tsx b/shared/editor/components/Frame.tsx index 725b14eb1..75f5110a1 100644 --- a/shared/editor/components/Frame.tsx +++ b/shared/editor/components/Frame.tsx @@ -4,6 +4,7 @@ import { OpenIcon } from "outline-icons"; import * as React from "react"; import styled from "styled-components"; import { Optional } from "utility-types"; +import { s } from "../../styles"; type Props = Omit, "children"> & { src?: string; @@ -121,7 +122,7 @@ const Rounded = styled.div<{ `; const Open = styled.a` - color: ${(props) => props.theme.textSecondary} !important; + color: ${s("textSecondary")} !important; font-size: 13px; font-weight: 500; align-items: center; @@ -141,8 +142,8 @@ const Bar = styled.div` display: flex; align-items: center; border-top: 1px solid ${(props) => props.theme.embedBorder}; - background: ${(props) => props.theme.secondaryBackground}; - color: ${(props) => props.theme.textSecondary}; + background: ${s("secondaryBackground")}; + color: ${s("textSecondary")}; padding: 0 8px; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px; diff --git a/shared/editor/components/Image.tsx b/shared/editor/components/Image.tsx index 441144895..0965a1796 100644 --- a/shared/editor/components/Image.tsx +++ b/shared/editor/components/Image.tsx @@ -3,6 +3,7 @@ import type { EditorView } from "prosemirror-view"; import * as React from "react"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { s } from "../../styles"; import { sanitizeUrl } from "../../utils/urls"; import { ComponentProps } from "../types"; import ImageZoom from "./ImageZoom"; @@ -240,7 +241,7 @@ export const Caption = styled.p` display: block; font-style: italic; font-weight: normal; - color: ${(props) => props.theme.textSecondary}; + color: ${s("textSecondary")}; padding: 8px 0 4px; line-height: 16px; text-align: center; @@ -261,7 +262,7 @@ export const Caption = styled.p` } &:empty:before { - color: ${(props) => props.theme.placeholder}; + color: ${s("placeholder")}; content: attr(data-caption); pointer-events: none; } @@ -288,8 +289,8 @@ const ResizeLeft = styled.div<{ $dragging: boolean }>` height: 15%; min-height: 20px; border-radius: 4px; - background: ${(props) => props.theme.toolbarBackground}; - box-shadow: 0 0 0 1px ${(props) => props.theme.toolbarItem}; + background: ${s("toolbarBackground")}; + box-shadow: 0 0 0 1px ${s("toolbarItem")}; opacity: 0.75; } `; @@ -312,8 +313,8 @@ const Button = styled.button` margin: 0; padding: 0; border-radius: 4px; - background: ${(props) => props.theme.background}; - color: ${(props) => props.theme.textSecondary}; + background: ${s("background")}; + color: ${s("textSecondary")}; width: 24px; height: 24px; display: inline-block; @@ -326,7 +327,7 @@ const Button = styled.button` } &:hover { - color: ${(props) => props.theme.text}; + color: ${s("text")}; opacity: 1; } `; diff --git a/shared/editor/components/ImageZoom/Styles.tsx b/shared/editor/components/ImageZoom/Styles.tsx index 6d8169930..0ae854169 100644 --- a/shared/editor/components/ImageZoom/Styles.tsx +++ b/shared/editor/components/ImageZoom/Styles.tsx @@ -1,5 +1,6 @@ import { transparentize } from "polished"; import { createGlobalStyle } from "styled-components"; +import { s } from "../../../styles"; export default createGlobalStyle` [data-rmiz] { @@ -37,7 +38,7 @@ export default createGlobalStyle` background-color: ${(props) => transparentize(1, props.theme.background)}; } [data-rmiz-modal-overlay="visible"] { - background-color: ${(props) => props.theme.background}; + background-color: ${s("background")}; } [data-rmiz-modal-content] { position: relative; diff --git a/shared/editor/components/Widget.tsx b/shared/editor/components/Widget.tsx index c080961e5..f2a971451 100644 --- a/shared/editor/components/Widget.tsx +++ b/shared/editor/components/Widget.tsx @@ -1,5 +1,6 @@ import * as React from "react"; import styled, { css, DefaultTheme, ThemeProps } from "styled-components"; +import { s } from "../../styles"; type Props = { icon: React.ReactNode; @@ -35,14 +36,14 @@ const Children = styled.div` opacity: 0; &:hover { - color: ${(props) => props.theme.text}; + color: ${s("text")}; } `; const Title = styled.strong` font-weight: 500; font-size: 14px; - color: ${(props) => props.theme.text}; + color: ${s("text")}; `; const Preview = styled.div` @@ -51,12 +52,12 @@ const Preview = styled.div` flex-direction: row; flex-grow: 1; align-items: center; - color: ${(props) => props.theme.textTertiary}; + color: ${s("textTertiary")}; `; const Subtitle = styled.span` font-size: 13px; - color: ${(props) => props.theme.textTertiary} !important; + color: ${s("textTertiary")} !important; line-height: 0; `; @@ -64,9 +65,9 @@ const Wrapper = styled.a` display: flex; align-items: center; gap: 6px; - background: ${(props) => props.theme.background}; - color: ${(props) => props.theme.text} !important; - box-shadow: 0 0 0 1px ${(props) => props.theme.divider}; + background: ${s("background")}; + color: ${s("text")} !important; + box-shadow: 0 0 0 1px ${s("divider")}; white-space: nowrap; border-radius: 8px; padding: 6px 8px; @@ -84,7 +85,7 @@ const Wrapper = styled.a` &:active { cursor: pointer !important; text-decoration: none !important; - background: ${(props) => props.theme.secondaryBackground}; + background: ${s("secondaryBackground")}; ${Children} { opacity: 1; diff --git a/shared/i18n/locales/en_US/translation.json b/shared/i18n/locales/en_US/translation.json index f7d037372..6153d59c7 100644 --- a/shared/i18n/locales/en_US/translation.json +++ b/shared/i18n/locales/en_US/translation.json @@ -627,6 +627,19 @@ "You signed in with {{ authProviderName }} last time.": "You signed in with {{ authProviderName }} last time.", "Or": "Or", "Already have an account? Go to <1>login.": "Already have an account? Go to <1>login.", + "Unable to sign-in. Please navigate to your team's custom URL, then try to sign-in again.<1>If you were invited to a team, you will find a link to it in the invite email.": "Unable to sign-in. Please navigate to your team's custom URL, then try to sign-in again.<1>If you were invited to a team, you will find a link to it in the invite email.", + "Sorry, a new account cannot be created with a personal Gmail address.<1>Please use a Google Workspaces account instead.": "Sorry, a new account cannot be created with a personal Gmail address.<1>Please use a Google Workspaces account instead.", + "The team you authenticated with is not authorized on this installation. Try another?": "The team you authenticated with is not authorized on this installation. Try another?", + "We could not read the user info supplied by your identity provider.": "We could not read the user info supplied by your identity provider.", + "Your account uses email sign-in, please sign-in with email to continue.": "Your account uses email sign-in, please sign-in with email to continue.", + "An email sign-in link was recently sent, please check your inbox or try again in a few minutes.": "An email sign-in link was recently sent, please check your inbox or try again in a few minutes.", + "Authentication failed – we were unable to sign you in at this time. Please try again.": "Authentication failed – we were unable to sign you in at this time. Please try again.", + "Authentication failed – you do not have permission to access this team.": "Authentication failed – you do not have permission to access this team.", + "Sorry, it looks like that sign-in link is no longer valid, please try requesting another.": "Sorry, it looks like that sign-in link is no longer valid, please try requesting another.", + "Your account has been suspended. To re-activate your account, please contact a team admin.": "Your account has been suspended. To re-activate your account, please contact a team admin.", + "Authentication failed – this login method was disabled by a team admin.": "Authentication failed – this login method was disabled by a team admin.", + "The team you are trying to join requires an invite before you can create an account.<1>Please request an invite from your team admin and try again.": "The team you are trying to join requires an invite before you can create an account.<1>Please request an invite from your team admin and try again.", + "Sorry, your domain is not allowed. Please try again with an allowed team domain.": "Sorry, your domain is not allowed. Please try again with an allowed team domain.", "Any collection": "Any collection", "Any time": "Any time", "Past day": "Past day", diff --git a/shared/styles/globals.ts b/shared/styles/globals.ts index 9c1436ab8..8260fe497 100644 --- a/shared/styles/globals.ts +++ b/shared/styles/globals.ts @@ -1,6 +1,6 @@ import { createGlobalStyle } from "styled-components"; import styledNormalize from "styled-normalize"; -import { breakpoints, depths } from "."; +import { breakpoints, depths, s } from "."; type Props = { useCursorPointer?: boolean; @@ -37,7 +37,7 @@ export default createGlobalStyle` body { font-size: 16px; line-height: 1.5; - color: ${(props) => props.theme.text}; + color: ${s("text")}; overscroll-behavior-y: none; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; @@ -102,7 +102,7 @@ export default createGlobalStyle` hr { border: 0; height: 0; - border-top: 1px solid ${(props) => props.theme.divider}; + border-top: 1px solid ${s("divider")}; } .js-focus-visible :focus:not(.focus-visible) { @@ -110,7 +110,7 @@ export default createGlobalStyle` } .js-focus-visible .focus-visible { - outline-color: ${(props) => props.theme.accent}; + outline-color: ${s("accent")}; outline-offset: -1px; } `; diff --git a/shared/styles/index.ts b/shared/styles/index.ts index 32d489fb6..d11fa8ad9 100644 --- a/shared/styles/index.ts +++ b/shared/styles/index.ts @@ -1,3 +1,41 @@ +import { DefaultTheme } from "styled-components"; + export { default as depths } from "./depths"; export { default as breakpoints } from "./breakpoints"; + +/** + * Mixin to make text ellipse when it overflows. + * + * @returns string of CSS + */ +export const ellipsis = () => ` + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +`; + +/** + * Mixin to return a theme value. + * + * @returns a theme value + */ +export const s = (key: keyof DefaultTheme) => (props: { + theme: DefaultTheme; +}) => { + return String(props.theme[key]); +}; + +/** + * Mixin to hide scrollbars. + * + * @returns string of CSS + */ +export const hideScrollbars = () => ` + -ms-overflow-style: none; + overflow: -moz-scrollbars-none; + scrollbar-width: none; + &::-webkit-scrollbar { + display: none; + } +`; diff --git a/shared/styles/theme.ts b/shared/styles/theme.ts index 1efdfc6f6..94323c54d 100644 --- a/shared/styles/theme.ts +++ b/shared/styles/theme.ts @@ -44,9 +44,6 @@ const defaultColors: Colors = { }; const spacing = { - padding: "1.5vw 1.875vw", - vpadding: "1.5vw", - hpadding: "1.875vw", sidebarWidth: 260, sidebarRightWidth: 300, sidebarCollapsedWidth: 16,