Commit d96250bb authored by Tamlyn Rhodes's avatar Tamlyn Rhodes

feat(xpub-edit): convert to styled-components

parent b53bed79
Pipeline #4698 failed with stages
in 4 minutes and 4 seconds
......@@ -5,8 +5,8 @@ import { EditorView } from 'prosemirror-view'
import baseClasses from 'prosemirror-view/style/prosemirror.css'
import MenuBar from './MenuBar'
import classes from './Editor.local.css'
import decorations from '../decorations'
import { withEditorStyle } from './withStyles'
class Editor extends React.Component {
constructor(props) {
......@@ -18,9 +18,8 @@ class Editor extends React.Component {
}
createEditorView = node => {
const { className } = this.props
const { state } = this.state
const { autoFocus, readonly, onBlur } = this.props
const { autoFocus, className, readonly, onBlur } = this.props
this.view = new EditorView(node, {
state,
......@@ -28,15 +27,9 @@ class Editor extends React.Component {
dispatchTransaction: this.dispatchTransaction,
decorations: decorations({
props: this.props,
classes,
}),
attributes: {
class: classnames(
baseClasses.ProseMirror,
classes.ProseMirror,
className,
!readonly && classes.ProseMirrorEditable,
),
class: classnames(className, baseClasses.ProseMirror),
},
handleDOMEvents: {
blur: onBlur
......@@ -81,4 +74,4 @@ class Editor extends React.Component {
}
}
export default Editor
export default withEditorStyle(Editor)
.ProseMirror {
background: linear-gradient(to right, transparent 0%, transparent 2px, white 2px, white 4px), linear-gradient(white 0%, white 90%, var(--color-back) 92%, white 100%);
background-repeat: repeat-X, repeat-Y;
background-size: 4px 100%, 100% 1.8em;
font-family: var(--font-reviewer);
font-size: 0.8em;
line-height: 1.8;
min-height: 1em;
}
.ProseMirrorEditable:hover {
--color-back: var(--color-primary);
}
.ProseMirror:focus {
outline: none;
}
.ProseMirror:active,
.ProseMirror:focus {
--color-back: #eee;
background: linear-gradient(to right, transparent 0%, transparent 2px, white 2px, white 4px), linear-gradient(white 0%, white 90%, var(--color-back) 92%, white 100%);
background-repeat: repeat-X, repeat-Y;
background-size: 4px 100%, 100% 1.8em;
caret-color: var(--color-primary);
}
.ProseMirror hr {
border: none;
margin: 1em 0;
padding: 2px 10px;
}
.ProseMirror hr::after {
background-color: silver;
content: "";
display: block;
height: 1px;
line-height: 2px;
}
.ProseMirror ul,
.ProseMirror ol {
padding-left: 30px;
}
.ProseMirror blockquote {
border-left: 3px solid #eee;
margin-left: 0;
margin-right: 0;
padding-left: 1em;
}
.ProseMirror img {
cursor: default;
}
.ProseMirror th,
.ProseMirror td {
border: 1px solid #eee;
padding: 2px 5px;
}
.ProseMirror .placeholder {
color: #aaa;
font-family: var(--font-interface);
font-style: italic;
height: 0;
pointer-events: none;
}
.ProseMirror:focus .placeholder {
display: none;
}
.ProseMirror p {
margin-bottom: 0;
margin-top: 0;
}
import React from 'react'
import styled from 'styled-components'
import map from 'lodash/map'
import classnames from 'classnames'
import classes from './MenuBar.local.css'
import MenuButton from './MenuButton'
const MenuBar = ({ title, menu, state, dispatch }) => {
const handle = cmd => e => {
e.preventDefault()
cmd(state, dispatch)
}
const Wrapper = styled.div`
align-items: baseline;
display: flex;
margin-bottom: 0.8em;
margin-top: 0;
`
const Button = (item, key) => (
<button
className={classnames({
[classes.button]: true,
[classes.active]: item.active && item.active(state),
})}
disabled={item.enable && !item.enable(state)}
key={key}
onMouseDown={handle(item.run)}
title={item.title}
type="button"
>
{item.content}
</button>
)
const Legend = styled.div`
font-size: var(--font-size-base);
margin-right: 10px;
`
return (
<div className={classes.toolbar}>
{title && <div className={classes.title}>{title}</div>}
const MenuBar = ({ title, menu, state, dispatch }) => (
<Wrapper>
{title && <Legend>{title}</Legend>}
{menu.marks && map(menu.marks, Button)}
{menu.blocks && map(menu.blocks, Button)}
{menu.insert && map(menu.insert, Button)}
{menu.history && map(menu.history, Button)}
{menu.table && map(menu.table, Button)}
</div>
)
}
{['marks', 'blocks', 'insert', 'history', 'table'].map(name =>
map(menu[name], (item, key) => (
<MenuButton
handle={e => {
e.preventDefault()
item.run(state, dispatch)
}}
item={item}
key={key}
state={state}
title={title}
/>
)),
)}
</Wrapper>
)
export default MenuBar
.toolbar {
align-items: baseline;
display: flex;
margin-bottom: 0.8em;
margin-top: 0;
}
.button {
background: white;
border: none;
border-bottom: 2px solid transparent;
color: #777;
cursor: pointer;
height: 20px;
margin: 0 0.4em;
min-width: 20px;
padding: 0;
}
.button:hover {
border-bottom: 2px solid var(--color-primary);
color: var(--color-primary);
}
.button.active {
border-bottom: 2px solid black;
}
.title {
font-size: 1.1em;
font-weight: 600;
margin-right: 10px;
margin-top: 0;
}
import React from 'react'
import styled from 'styled-components'
const Button = styled.button`
background: var(--color-background);
border: none;
border-bottom: 2px solid transparent;
color: #777;
cursor: pointer;
height: 20px;
margin: 0 0.4em;
min-width: 20px;
padding: 0;
&:hover {
border-bottom-color: var(--color-primary);
color: var(--color-primary);
}
border-bottom-color: ${({ active }) => active && 'black'};
`
const MenuButton = ({ item, state, handle }) => (
<Button
active={item.active && item.active(state)}
disabled={item.enable && !item.enable(state)}
onMouseDown={handle}
title={item.title}
>
{item.content}
</Button>
)
export default MenuButton
import styled from 'styled-components'
import Editor from './Editor'
const StyledEditor = styled(Editor).attrs({
basePlaceholderClassName: 'placeholder',
})`
font-family: var(--font-writing);
font-size: var(--font-size-base);
line-height: 1.8;
min-height: 1em;
margin-bottom: var(--grid-unit);
border: var(--border-width) var(--border-style) var(--color-border);
border-radius: var(--border-radius);
padding: calc(var(--grid-unit) / 2);
&:focus {
outline: none;
}
hr {
border: none;
margin: 1em 0;
padding: 2px 10px;
}
hr::after {
background-color: silver;
content: '';
display: block;
height: 1px;
line-height: 2px;
}
ul,
ol {
padding-left: 30px;
}
blockquote {
border-left: 3px solid #eee;
margin-left: 0;
margin-right: 0;
padding-left: 1em;
}
img {
cursor: default;
}
th,
td {
border: 1px solid #eee;
padding: 2px 5px;
}
.placeholder {
color: var(--color-text-placeholder);
font-family: var(--font-interface);
height: 0;
pointer-events: none;
}
&:focus .placeholder {
display: none;
}
p {
margin-bottom: 0;
margin-top: 0;
}
`
export default StyledEditor
......@@ -3,7 +3,7 @@ import classnames from 'classnames'
import { EditorState } from 'prosemirror-state'
import { EditorView } from 'prosemirror-view'
import baseClasses from 'prosemirror-view/style/prosemirror.css'
import classes from './Editor.local.css'
import { withViewerStyle } from './withStyles'
class Viewer extends React.Component {
constructor(props) {
......@@ -22,11 +22,7 @@ class Viewer extends React.Component {
state,
dispatchTransaction: () => false,
attributes: {
class: classnames(
baseClasses.ProseMirror,
classes.ProseMirror,
className,
),
class: classnames(baseClasses.ProseMirror, className),
},
})
}
......@@ -36,4 +32,4 @@ class Viewer extends React.Component {
}
}
export default Viewer
export default withViewerStyle(Viewer)
.root {
font-family: var(--font-reviewer);
font-size: 0.8em;
line-height: 1.7;
}
.root {
font-family: var(--font-author);
font-size: 1em;
line-height: 1.5;
}
.placeholder {
color: #aaa;
font-family: var(--font-interface);
font-style: italic;
}
......@@ -7,6 +7,7 @@ const value = faker.lorem.sentence(200);
value={value}
title="Abstract"
placeholder="Enter a short description of the work…"
onBlur={value => console.log(value)}
onChange={value => console.log(value)}/>
```
......@@ -17,5 +18,6 @@ When no content has been entered, a placeholder is displayed.
value=""
title="Abstract"
placeholder="Enter a short description of the work…"
onBlur={value => console.log(value)}
onChange={value => console.log(value)}/>
```
.root {
font-family: var(--font-author);
font-size: 1em;
hyphens: auto;
line-height: 1.5;
max-width: 50ch;
min-height: 5em;
text-align: justify;
}
.placeholder {
font-family: var(--font-interface);
font-style: italic;
}
......@@ -7,6 +7,7 @@ const value = faker.lorem.sentence(50);
value={value}
title="Note"
placeholder="Enter a message…"
onBlur={value => console.log(value)}
onChange={value => console.log(value)}/>
```
......@@ -17,5 +18,6 @@ When no content has been entered, a placeholder is displayed.
value=""
title="Note"
placeholder="Enter a message…"
onBlur={value => console.log(value)}
onChange={value => console.log(value)}/>
```
......@@ -4,5 +4,6 @@ An editor for plain text, with no options for adding blocks or applying text for
<TextEditor
value=""
placeholder="Enter some text…"
onBlur={value => console.log(value)}
onChange={value => console.log(value)}/>
```
......@@ -7,7 +7,8 @@ const value = faker.lorem.sentence(15);
value={value}
title="Title"
placeholder="Enter the title…"
onChange={value => console.log(value)}/>
onChange={value => console.log(value)}
onBlur={value => console.log(value)}/>
```
When no content is provided, a placeholder is displayed.
......@@ -17,5 +18,6 @@ When no content is provided, a placeholder is displayed.
value=""
title="Title"
placeholder="Enter the title…"
onChange={value => console.log(value)}/>
onChange={value => console.log(value)}
onBlur={value => console.log(value)}/>
```
.root {
display: inline-block;
font-family: var(--font-author) !important;
margin-bottom: 0;
margin-top: 0;
}
import styled, { css } from 'styled-components'
const contentStyles = css`
hr {
border: none;
margin: 1em 0;
padding: 2px 10px;
}
hr::after {
background-color: silver;
content: '';
display: block;
height: 1px;
line-height: 2px;
}
ul,
ol {
padding-left: 30px;
}
blockquote {
border-left: 3px solid #eee;
margin-left: 0;
margin-right: 0;
padding-left: 1em;
}
img {
cursor: default;
}
th,
td {
border: 1px solid #eee;
padding: 2px 5px;
}
p {
margin-bottom: 0;
margin-top: 0;
}
`
export const withEditorStyle = Component => styled(Component).attrs({
basePlaceholderClassName: 'placeholder',
})`
font-family: var(--font-writing);
font-size: var(--font-size-base);
line-height: 1.8;
min-height: 1em;
margin-bottom: var(--grid-unit);
border: var(--border-width) var(--border-style) var(--color-border);
border-radius: var(--border-radius);
padding: calc(var(--grid-unit) / 2);
&:focus {
outline: none;
}
.placeholder {
color: var(--color-text-placeholder);
font-family: var(--font-interface);
height: 0;
pointer-events: none;
}
&:focus .placeholder {
display: none;
}
${contentStyles};
`
export const withViewerStyle = Component => styled(Component)`
font-family: var(--font-reading);
font-size: var(--font-size-base);
line-height: 1.8;
margin-bottom: var(--grid-unit);
${contentStyles};
`
import { DecorationSet, Decoration } from 'prosemirror-view'
export default ({ props, classes }) => state => {
export default ({ props }) => state => {
const { doc } = state
const decorations = []
......@@ -12,7 +12,7 @@ export default ({ props, classes }) => state => {
) {
const placeHolder = document.createElement('div')
placeHolder.textContent = props.placeholder
placeHolder.classList.add(classes.placeholder)
placeHolder.classList.add(props.basePlaceholderClassName)
if (props.placeholderClassName) {
placeHolder.classList.add(props.placeholderClassName)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment