diff options
| author | jackyzha0 <[email protected]> | 2021-03-05 22:17:18 -0800 |
|---|---|---|
| committer | jackyzha0 <[email protected]> | 2021-03-05 22:17:18 -0800 |
| commit | 3e8500d466b641ef34c24f8b0de8163a44ba7a9e (patch) | |
| tree | ebb3411d636912b12f9fee14ecd494601cd796fc | |
| parent | remove extra langs (diff) | |
| download | ctrl-v-3e8500d466b641ef34c24f8b0de8163a44ba7a9e.tar.xz ctrl-v-3e8500d466b641ef34c24f8b0de8163a44ba7a9e.zip | |
refactoring css
27 files changed, 372 insertions, 348 deletions
diff --git a/frontend/public/index.html b/frontend/public/index.html index b328944..8ca24a5 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -9,7 +9,6 @@ content="a modern, open-source pastebin with latex and markdown rendering support" /> <link rel="icon" href="icon.png"> - <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jackyzha0/[email protected]/src/lite.css"> <link rel="preconnect" href="https://fonts.gstatic.com"> <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;700&display=swap" rel="stylesheet"> <title>ctrl-v | a modern, open-source pastebin </title> diff --git a/frontend/src/App.js b/frontend/src/App.js new file mode 100644 index 0000000..99e71ae --- /dev/null +++ b/frontend/src/App.js @@ -0,0 +1,60 @@ +import React from 'react'; +import NewPaste from './components/NewPaste' +import ViewPaste from './components/ViewPaste' +import Footer from './components/Footer' +import styled from 'styled-components' +import { + BrowserRouter as Router, + Switch, + Route, + useParams +} from "react-router-dom"; +import Raw from './components/renderers/Raw' +import ThemeProvider from './theme/ThemeProvider' +import GlobalStyle from './theme/GlobalStyle' +import {Watermark} from "./components/Watermark"; + +const Main = styled.div` + margin-top: 10vh; + padding: 0 20vw 30px 20vw; +` + +const GetPasteWithParam = () => { + let { hash } = useParams(); + return <ViewPaste hash = {hash} />; +} + +const GetRawWithParam = () => { + let { hash } = useParams(); + return <Raw hash={hash} />; +} + +const App = () => { + return ( + <ThemeProvider> + <GlobalStyle /> + <Router> + <Switch> + <Route path="/raw/:hash"><GetRawWithParam /></Route> + <Route> + <Watermark/> + <Main id="appElement"> + <Switch> + <Route path="/:hash"> + <GetPasteWithParam /> + </Route> + <Route path="/"> + <NewPaste /> + </Route> + </Switch> + <Footer /> + </Main> + </Route> + </Switch> + </Router> + </ThemeProvider> + ); +} + + +export default App; diff --git a/frontend/src/components/App.js b/frontend/src/components/App.js deleted file mode 100644 index f28a220..0000000 --- a/frontend/src/components/App.js +++ /dev/null @@ -1,76 +0,0 @@ -import React from 'react'; -import NewPaste from './NewPaste' -import ViewPaste from './ViewPaste' -import Footer from './Footer' -import styled from 'styled-components' -import { - BrowserRouter as Router, - Switch, - Route, - useParams -} from "react-router-dom"; -import Raw from './renderers/Raw' - -const Logo = styled.div` - position: absolute; - bottom: 1.5em; - left: 2em; - opacity: 0.3; - - & h1 { - font-size: 3rem; - } -` - -const Main = styled.main` - margin-top: 10vh; -` - -const GetPasteWithParam = () => { - let { hash } = useParams(); - return <ViewPaste hash = {hash} />; -} - -const GetRawWithParam = () => { - let { hash } = useParams(); - return <Raw hash={hash} />; -} - -const App = () => { - return ( - <Router> - <Switch> - <Route path="/raw/:hash" - children={<GetRawWithParam />} - /> - <Route> - <div className="lt-content-column"> - <Logo> - <nav> - <h1 className="mainLogo"> - <a href="https://github.com/jackyzha0/ctrl-v">ctrl-v</a> - </h1> - </nav> - </Logo> - - <Main id="appElement"> - <Switch> - <Route path="/:hash" - children={<GetPasteWithParam />} - /> - <Route path="/"> - <NewPaste /> - </Route> - </Switch> - </Main> - - <Footer /> - </div> - </Route> - </Switch> - </Router> - ); -} - - -export default App; diff --git a/frontend/src/components/Footer.js b/frontend/src/components/Footer.js index 3186a42..1074fcb 100644 --- a/frontend/src/components/Footer.js +++ b/frontend/src/components/Footer.js @@ -3,6 +3,9 @@ import styled from 'styled-components' const SpacedFooter = styled.div` margin: 2em 0; + & a { + color: ${p => p.theme.colors.text}; + } ` const Link = (props) => { @@ -14,7 +17,7 @@ const Link = (props) => { const Footer = () => { return ( <SpacedFooter> - (c) 2020 — <Link link="https://jzhao.xyz/" name="jacky" />, <Link link="https://ryanmehri.tech/" name="ryan" /> + <p>(c) 2020 — <Link link="https://jzhao.xyz/" name="jacky" />, <Link link="https://ryanmehri.tech/" name="ryan" /></p> </SpacedFooter> ); } diff --git a/frontend/src/components/Form/Button.js b/frontend/src/components/Form/Button.js new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/frontend/src/components/Form/Button.js diff --git a/frontend/src/components/Form/Input.js b/frontend/src/components/Form/Input.js new file mode 100644 index 0000000..86af7d1 --- /dev/null +++ b/frontend/src/components/Form/Input.js @@ -0,0 +1,3 @@ +import {RelPositioning} from "../Inputs/shared"; +import React from "react"; + diff --git a/frontend/src/components/Form/index.js b/frontend/src/components/Form/index.js new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/frontend/src/components/Form/index.js diff --git a/frontend/src/components/Form/mixins.js b/frontend/src/components/Form/mixins.js new file mode 100644 index 0000000..dd26f7e --- /dev/null +++ b/frontend/src/components/Form/mixins.js @@ -0,0 +1,33 @@ +import {css} from 'styled-components'; + +export const Dropshadow = css` + box-shadow: 0 14px 28px rgba(27, 33, 48,0.06), 0 10px 10px rgba(27, 33, 48,0.02); +` + +export const InputLike = css` + width: 100%; + font-family: 'JetBrains Mono', monospace; + font-size: 0.8em; + padding: calc(0.8em - 1px); + border-radius: 3px; + border: 1px solid ${p => p.theme.colors.border}; + outline: none; + margin: 1.7em 0; +` + +export const ButtonLike = css` + font-family: 'JetBrains Mono', serif; + font-weight: 700; + padding: 0.8em 2em; + margin: 2em 0; + outline: 0; + + ${p => p.primary ? ` + color: #faf9f5; + background-color: #111111; + ` : ` + color: #faf9f5; + background-color: #111111; + `} + +`
\ No newline at end of file diff --git a/frontend/src/components/Inputs.js b/frontend/src/components/Inputs.js deleted file mode 100644 index e18133d..0000000 --- a/frontend/src/components/Inputs.js +++ /dev/null @@ -1,200 +0,0 @@ -import React, {useEffect, useRef} from 'react'; -import CharLimit from './decorators/CharLimit' -import styled from 'styled-components' -import FloatingLabel from './decorators/FloatingLabel' -import Dropdown from 'react-dropdown'; -import { LANGS, THEMES } from './renderers/Code'; -import * as indentation from 'indent-textarea'; - -const RelPositioning = styled.div` - position: relative; - height: calc(100% - 4em); -` - -const FlexChild = styled.div` - display: block; - margin-left: 2em; -` - -const TitleInput = (props) => { - return ( - <RelPositioning> - <FloatingLabel - label="title" - id={props.id} - value={props.value} /> - <input - name="title" - readOnly={props.readOnly} - className="lt-shadow" - placeholder="Title" - id={props.id} - type="text" - autoFocus - autoComplete="off" - onChange={props.onChange} - value={props.value} /> - <CharLimit - content={props.value} - maxLength={props.maxLength} /> - </RelPositioning> - ); -} - -const PasteInput = ({content, ...props}) => { - const textInput = useRef(null); - - useEffect(() => { - indentation.watch(textInput.current); - }, [textInput]) - - return ( - <RelPositioning> - <FloatingLabel - label="content" - id={props.id} - value={content} /> - <textarea - name="content" - readOnly={props.readOnly} - placeholder="Paste your text here" - value={content} - id={props.id} - ref={textInput} - required - onChange={props.onChange} - className="lt-shadow" /> - <CharLimit - content={content} - maxLength={props.maxLength} /> - </RelPositioning> - ); -} - -const PassInput = (props) => { - return ( - <FlexChild> - <RelPositioning> - <FloatingLabel - label="password" - id={props.id} - value={props.value} /> - <input - name="pass" - className="lt-shadow" - placeholder="password" - type="password" - autoComplete="off" - onChange={props.onChange} - value={props.value} - id={props.id} /> - </RelPositioning> - </FlexChild> - ); -} - -const GenericDropdown = (props) => { - function _onSelect(option) { - props.onChange({ - target: { - name: props.label, - value: option.label - } - }); - } - - return ( - <FlexChild> - <Dropdown - options={props.options} - onChange={_onSelect} - value={props.value} - placeholder={props.placeholder} - id={props.id} /> - <FloatingLabel - label={props.label} - id={props.id} - value={props.value} /> - </FlexChild> - ); -} - -const ExpiryInput = (props) => { - const options = [ - '5 years', - '1 year', - '1 month', - '1 week', - '1 day', - '1 hour', - '10 min', - ]; - - return ( - <GenericDropdown - {...props} - options={options} - placeholder='1 week' - label='expiry' - /> - ); -} - -const LangInput = (props) => { - const options = Object.entries(LANGS).map((key, _) => { - return { - 'value': key[1], - 'label': key[0] - } - }) - - return ( - <GenericDropdown - {...props} - options={options} - placeholder={LANGS.auto} - label='language' - /> - ); -} - -const ThemeInput = (props) => { - const options = Object.entries(THEMES).map((key, _) => { - return { - 'value': key[1], - 'label': key[0] - } - }) - - return ( - <GenericDropdown - {...props} - options={options} - placeholder={'atom'} - label='theme' - /> - ); -} - -const PasteURLInput = ({id, fullURL}) => { - return ( - <FlexChild> - <RelPositioning> - <FloatingLabel - label="url" - id={id} - value={id} /> - <input - name="paste_url" - className="lt-shadow" - type="text" - readOnly - autoFocus - id={id} - value={fullURL} /> - </RelPositioning> - </FlexChild> - ); -} - -export { TitleInput, PasteInput, PassInput, ExpiryInput, PasteURLInput, LangInput, ThemeInput }
\ No newline at end of file diff --git a/frontend/src/components/Inputs/Code.js b/frontend/src/components/Inputs/Code.js new file mode 100644 index 0000000..1353d95 --- /dev/null +++ b/frontend/src/components/Inputs/Code.js @@ -0,0 +1,35 @@ +import React, {useEffect, useRef} from "react"; +import * as indentation from "indent-textarea"; +import FloatingLabel from "../decorators/FloatingLabel"; +import CharLimit from "../decorators/CharLimit"; +import {RelPositioning} from "./shared"; + +export const Code = ({content, ...props}) => { + const textInput = useRef(null); + + useEffect(() => { + indentation.watch(textInput.current); + }, [textInput]) + + return ( + <RelPositioning> + <FloatingLabel + label="content" + id={props.id} + value={content} /> + <textarea + name="content" + readOnly={props.readOnly} + placeholder="Paste your text here" + value={content} + id={props.id} + ref={textInput} + required + onChange={props.onChange} + className="lt-shadow" /> + <CharLimit + content={content} + maxLength={props.maxLength} /> + </RelPositioning> + ); +}
\ No newline at end of file diff --git a/frontend/src/components/Inputs/Dropdown.js b/frontend/src/components/Inputs/Dropdown.js new file mode 100644 index 0000000..c467408 --- /dev/null +++ b/frontend/src/components/Inputs/Dropdown.js @@ -0,0 +1,84 @@ +import Dropdown from "react-dropdown"; +import FloatingLabel from "../decorators/FloatingLabel"; +import React from "react"; +import {LANGS, THEMES} from "../renderers/Code"; +import {FlexChild} from "./shared"; + +const GenericDropdown = (props) => { + function _onSelect(option) { + props.onChange({ + target: { + name: props.label, + value: option.label + } + }); + } + + return ( + <FlexChild> + <Dropdown + options={props.options} + onChange={_onSelect} + value={props.value} + placeholder={props.placeholder} + id={props.id} /> + <FloatingLabel + label={props.label} + id={props.id} + value={props.value} /> + </FlexChild> + ); +} + +export const Expiry = (props) => { + const options = [ + '5 years', + '1 year', + '1 month', + '1 week', + '1 day', + '1 hour', + '10 min', + ]; + + return ( + <GenericDropdown + {...props} + options={options} + placeholder='1 week' + label='expiry' + /> + ); +} + +export const Language = (props) => { + const options = Object.entries(LANGS).map((key, _) => ({ + 'value': key[1], + 'label': key[0] + })) + + return ( + <GenericDropdown + {...props} + options={options} + placeholder={LANGS.auto} + label='language' + /> + ); +} + +export const Theme = (props) => { + const options = Object.entries(THEMES).map((key) => ({ + 'value': key[1], + 'label': key[0] + })) + + return ( + <GenericDropdown + {...props} + options={options} + placeholder={'atom'} + label='theme' + /> + ); +}
\ No newline at end of file diff --git a/frontend/src/components/Inputs/Password.js b/frontend/src/components/Inputs/Password.js new file mode 100644 index 0000000..7311832 --- /dev/null +++ b/frontend/src/components/Inputs/Password.js @@ -0,0 +1,14 @@ +import React from "react"; +import {Labelled} from "./shared"; + +export const Password = (props) => <Labelled label="password"> + <input + name="pass" + className="lt-shadow" + placeholder="password" + type="password" + autoComplete="off" + onChange={props.onChange} + value={props.value} + id={props.id} /> +</Labelled>
\ No newline at end of file diff --git a/frontend/src/components/Inputs/Text.js b/frontend/src/components/Inputs/Text.js new file mode 100644 index 0000000..866da91 --- /dev/null +++ b/frontend/src/components/Inputs/Text.js @@ -0,0 +1,25 @@ +import CharLimit from "../decorators/CharLimit"; +import React from "react"; +import {Labelled} from "./shared"; + +export const Text = React.forwardRef(({label, id, readOnly, onChange, value, maxLength, autoFocus}, ref) => { + return ( + <Labelled label={label} value={value}> + <input + ref={ref} + name={label} + readOnly={readOnly} + className="lt-shadow" + placeholder="Title" + id={id} + type="text" + autoFocus={autoFocus} + autoComplete="off" + onChange={onChange} + value={value} /> + <CharLimit + content={value} + maxLength={maxLength} /> + </Labelled> + ); +})
\ No newline at end of file diff --git a/frontend/src/components/Inputs/index.js b/frontend/src/components/Inputs/index.js new file mode 100644 index 0000000..b16deb3 --- /dev/null +++ b/frontend/src/components/Inputs/index.js @@ -0,0 +1,6 @@ +import {Code} from './Code'; +import {Expiry, Language, Theme} from "./Dropdown"; +import {Password} from "./Password"; +import {Text} from "./Text"; + +export {Code, Expiry, Language, Theme, Password, Text};
\ No newline at end of file diff --git a/frontend/src/components/Inputs/shared.js b/frontend/src/components/Inputs/shared.js new file mode 100644 index 0000000..18ba164 --- /dev/null +++ b/frontend/src/components/Inputs/shared.js @@ -0,0 +1,25 @@ +import styled from "styled-components"; +import React from "react"; +import FloatingLabel from "../decorators/FloatingLabel"; + +export const RelPositioning = styled.div` + position: relative; + height: calc(100% - 4em); +` + +export const FlexChild = styled.div` + display: block; + margin-left: 2em; +` + +export const Labelled = ({label, value, children}) => { + console.log(children) + return (<FlexChild> + <RelPositioning> + <FloatingLabel label={label} value={value} > + <span>{label}</span> + {children} + </FloatingLabel> + </RelPositioning> + </FlexChild>) +}
\ No newline at end of file diff --git a/frontend/src/components/NewPaste.js b/frontend/src/components/NewPaste.js index a8405b8..9447611 100644 --- a/frontend/src/components/NewPaste.js +++ b/frontend/src/components/NewPaste.js @@ -1,5 +1,5 @@ import React, { useEffect, useState, useRef } from 'react'; -import { TitleInput, PasteInput } from './Inputs' +import { Text, Code } from './Inputs' import OptionsContainer from './Options' import Error from './Err' import { PostNewPaste } from '../helpers/httpHelper' @@ -78,7 +78,7 @@ const NewPaste = () => { } function renderPreview() { - const pasteInput = <PasteInput + const pasteInput = <Code onChange={(e) => { setContent(e.target.value) }} content={content} maxLength="100000" @@ -129,7 +129,8 @@ const NewPaste = () => { return ( <form onSubmit={handleSubmit}> <PasteModal hash={hash} /> - <TitleInput + <Text + label="title" onChange={(e) => {setTitle(e.target.value)}} value={title} maxLength="100" diff --git a/frontend/src/components/Options.js b/frontend/src/components/Options.js index 09f92f3..fb7e88c 100644 --- a/frontend/src/components/Options.js +++ b/frontend/src/components/Options.js @@ -1,6 +1,6 @@ import React from 'react'; import styled from 'styled-components' -import { PassInput, ExpiryInput, LangInput } from './Inputs' +import { Password, Expiry, Language } from './Inputs' const Flex = styled.div` float: right; @@ -17,15 +17,15 @@ const Flex = styled.div` const OptionsContainer = ({pass, lang, expiry, onPassChange, onLangChange, onExpiryChange}) => { return ( <Flex> - <PassInput + <Password value={pass} onChange={onPassChange} id="passwordInput" /> - <LangInput + <Language value={lang} onChange={onLangChange} id="langInput" /> - <ExpiryInput + <Expiry value={expiry} onChange={onExpiryChange} id="expiryInput" /> diff --git a/frontend/src/components/PasteInfo.js b/frontend/src/components/PasteInfo.js index bab7e23..114d0e1 100644 --- a/frontend/src/components/PasteInfo.js +++ b/frontend/src/components/PasteInfo.js @@ -1,7 +1,7 @@ import React from 'react'; import styled from 'styled-components' import { useHistory } from 'react-router-dom'; -import { ThemeInput } from './Inputs' +import { Theme } from './Inputs' import { exportComponentAsPNG } from "react-component-export-image"; const Bold = styled.span` @@ -68,7 +68,7 @@ const PasteInfo = (props) => { save png </Button> {renderable()} - <ThemeInput + <Theme value={props.theme} onChange={props.onChange} id="themeInput" /> diff --git a/frontend/src/components/ViewPaste.js b/frontend/src/components/ViewPaste.js index a4f1844..165fa6e 100644 --- a/frontend/src/components/ViewPaste.js +++ b/frontend/src/components/ViewPaste.js @@ -1,6 +1,6 @@ import React, { useEffect, useState, useRef } from 'react'; import Error from './Err'; -import { TitleInput } from './Inputs'; +import { Text } from './Inputs'; import CodeRenderer from './renderers/Code' import PasteInfo from './PasteInfo'; import PasswordModal from './modals/PasswordModal' @@ -130,7 +130,8 @@ const ViewPaste = (props) => { value={enteredPass} onChange={(e) => setEnteredPass(e.target.value)} validateCallback={validatePass} /> - <TitleInput + <Text + label="title" value={title} id="titleInput" readOnly /> diff --git a/frontend/src/components/Watermark.js b/frontend/src/components/Watermark.js new file mode 100644 index 0000000..027aeb6 --- /dev/null +++ b/frontend/src/components/Watermark.js @@ -0,0 +1,26 @@ +import styled from "styled-components"; +import React from "react"; + +const Logo = styled.h1` + position: absolute; + bottom: 0.75em; + left: 1em; + opacity: 0.3; + font-size: 50px; + margin: 0 0; + transition: opacity 0.5s cubic-bezier(.25,.8,.25,1); + + & > a { + text-decoration: none; + position: relative; + color: ${p => p.theme.colors.text}; + + } + + &:hover { + opacity: 1; + } +` +export const Watermark = () => <Logo> + <a href="https://github.com/jackyzha0/ctrl-v">ctrl-v</a> +</Logo>
\ No newline at end of file diff --git a/frontend/src/components/decorators/FloatingLabel.js b/frontend/src/components/decorators/FloatingLabel.js index ef56b44..1e5a427 100644 --- a/frontend/src/components/decorators/FloatingLabel.js +++ b/frontend/src/components/decorators/FloatingLabel.js @@ -2,19 +2,20 @@ import React from 'react'; import styled, { css } from 'styled-components' const StyledLabel = styled.label` - position: absolute; - top: 0.5em; - font-weight: 700; - font-size: 1em; - opacity: 0; - transition: all 0.5s cubic-bezier(.25,.8,.25,1); - - ${props => - (props.value.length > 0) && - css` - top: -0.1em; - opacity: 1 - `}; + & > span { + position: absolute; + top: 0.5em; + font-weight: 700; + font-size: 1em; + opacity: 0.5; + transition: all 0.5s cubic-bezier(.25,.8,.25,1); + + ${props => + (props.value?.length > 0) && + css` + opacity: 1 + `}; + } ` const FloatingLabel = (props) => { @@ -22,9 +23,8 @@ const FloatingLabel = (props) => { <StyledLabel label={props.label} value={props.value} - className={props.id} - htmlFor={props.id}> - {props.label} + > + {props.children} </StyledLabel> ); } diff --git a/frontend/src/components/modals/PasswordModal.js b/frontend/src/components/modals/PasswordModal.js index bf373cc..bf25eeb 100644 --- a/frontend/src/components/modals/PasswordModal.js +++ b/frontend/src/components/modals/PasswordModal.js @@ -1,6 +1,6 @@ import React, { useRef } from 'react'; import Modal from 'react-modal'; -import { PassInput } from '../Inputs' +import { Password } from '../Inputs' import { RightPad, LeftPad, ModalHeader, Padding } from './shared' import Error from '../Err'; @@ -36,7 +36,7 @@ const PasswordModal = (props) => { <ModalHeader><span role="img" aria-label="warning">🚧 </span>err: password protected</ModalHeader> </LeftPad> <RightPad> - <PassInput + <Password value={props.value} onChange={props.onChange} /> </RightPad> diff --git a/frontend/src/components/modals/PasteModal.js b/frontend/src/components/modals/PasteModal.js index 7b28abb..6c74e19 100644 --- a/frontend/src/components/modals/PasteModal.js +++ b/frontend/src/components/modals/PasteModal.js @@ -2,7 +2,7 @@ import React from 'react'; import Modal from 'react-modal'; import { LeftPad, ModalHeader, RightPad } from './shared' import { useHistory } from 'react-router-dom'; -import { PasteURLInput } from '../Inputs' +import { Text } from '../Inputs' import { useClipboard } from 'use-clipboard-copy'; const modalStyles = { @@ -39,11 +39,7 @@ const PasteModal = (props) => { <ModalHeader><span role="img" aria-label="success">📎 </span>paste created</ModalHeader> </LeftPad> <RightPad> - <PasteURLInput - id="paste_modal" - fullURL={fullURL} /> - <input - hidden + <Text type="text" value={fullURL} readOnly diff --git a/frontend/src/css/index.css b/frontend/src/css/index.css index 39da6d1..0340813 100644 --- a/frontend/src/css/index.css +++ b/frontend/src/css/index.css @@ -4,13 +4,6 @@ } } -body { - margin: 0; - padding: 0; - background-color: #faf9f5; - font-family: 'JetBrains Mono', serif; -} - form { width: 100%; } @@ -127,32 +120,6 @@ button[type=button] { margin: 2em 2em; } -.mainLogo { - font-size: 50px; - margin: 0 0; - display: inline-block; -} - -.mainLogo a { - text-decoration: none; - position: relative; - margin: 3px; -} - -.mainLogo a::after { - content: ""; - position: absolute; - left: 0; - bottom: 0; - height: 4px; - background-color: #111111; - width: 0; - transition: width 0.25s ease; -} - -.mainLogo:hover a::after { - width: 100%; -} /* fixing markdown renderer */ .md h3 { diff --git a/frontend/src/index.js b/frontend/src/index.js index 437fe03..7173ce5 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -1,7 +1,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import './css/index.css'; -import App from './components/App'; +import App from './App'; ReactDOM.render( <React.StrictMode> diff --git a/frontend/src/theme/GlobalStyle.js b/frontend/src/theme/GlobalStyle.js new file mode 100644 index 0000000..9fe80a5 --- /dev/null +++ b/frontend/src/theme/GlobalStyle.js @@ -0,0 +1,11 @@ +import { createGlobalStyle } from 'styled-components' + +export default createGlobalStyle` + body { + margin: 0; + padding: 0; + background: ${(p) => p.theme.colors.background}; + font-family: 'JetBrains Mono', monospace; + color: ${(p) => p.theme.colors.text}; + } +`
\ No newline at end of file diff --git a/frontend/src/theme/ThemeProvider.js b/frontend/src/theme/ThemeProvider.js new file mode 100644 index 0000000..a104a5a --- /dev/null +++ b/frontend/src/theme/ThemeProvider.js @@ -0,0 +1,12 @@ +import React from 'react' +import { ThemeProvider } from 'styled-components' + +const theme = { + colors: { + background: '#faf9f5', + border: '#565656', + text: '#111111', + }, +} + +export default ({ children }) => <ThemeProvider theme={theme}>{children}</ThemeProvider>
\ No newline at end of file |