From 2c07ab42163fd82977be41f79042beff6066e883 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sun, 1 Oct 2017 10:03:05 -0700 Subject: [PATCH 1/3] Added ability to caption images (stored in alt) --- .../components/Editor/components/Image.js | 92 +++++++++++++++---- 1 file changed, 74 insertions(+), 18 deletions(-) diff --git a/frontend/components/Editor/components/Image.js b/frontend/components/Editor/components/Image.js index c98ee7a47..bf3a6e75b 100644 --- a/frontend/components/Editor/components/Image.js +++ b/frontend/components/Editor/components/Image.js @@ -1,27 +1,83 @@ // @flow -import React from 'react'; +import React, { Component } from 'react'; +import styled from 'styled-components'; import type { Props } from '../types'; import { color } from 'styles/constants'; -import styled from 'styled-components'; + +class Image extends Component { + props: Props; + + handleChange = (ev: SyntheticInputEvent) => { + const alt = ev.target.value; + const { editor, node } = this.props; + const data = node.data.toObject(); + const state = editor + .getState() + .transform() + .setNodeByKey(node.key, { data: { ...data, alt } }) + .apply(); + + editor.onChange(state); + }; + + handleClick = (ev: SyntheticInputEvent) => { + ev.stopPropagation(); + }; + + render() { + const { attributes, state, node, readOnly } = this.props; + const loading = node.data.get('loading'); + const caption = node.data.get('alt'); + const src = node.data.get('src'); + const active = state.isFocused && state.selection.hasEdgeIn(node); + + return ( + + + + + ); + } +} const StyledImg = styled.img` - box-shadow: ${props => (props.active ? `0 0 0 3px ${color.slate}` : '0')}; + box-shadow: ${props => (props.active ? `0 0 0 2px ${color.slate}` : '0')}; + border-radius: ${props => (props.active ? `2px` : '0')}; opacity: ${props => (props.loading ? 0.5 : 1)}; `; -export default function Image({ attributes, state, node }: Props) { - const loading = node.data.get('loading'); - const alt = node.data.get('alt'); - const src = node.data.get('src'); - const active = state.isFocused && state.selection.hasEdgeIn(node); +const CenteredImage = styled.div` + text-align: center; +`; - return ( - - ); -} +const Caption = styled.input` + border: 0; + display: block; + font-size: 13px; + font-style: italic; + color: ${color.slate}; + margin: 2px auto; + text-align: center; + width: 100%; + outline: none; + + &::placeholder { + color: ${color.slate}; + } +`; + +export default Image; From abff5aa33123dc96e21f9b44e3482756fb4a6614 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sun, 1 Oct 2017 10:05:59 -0700 Subject: [PATCH 2/3] Prevent cropping of descenders --- frontend/components/Editor/components/Image.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/components/Editor/components/Image.js b/frontend/components/Editor/components/Image.js index bf3a6e75b..978d887be 100644 --- a/frontend/components/Editor/components/Image.js +++ b/frontend/components/Editor/components/Image.js @@ -70,7 +70,8 @@ const Caption = styled.input` font-size: 13px; font-style: italic; color: ${color.slate}; - margin: 2px auto; + padding: 2px 0; + line-height: 16px; text-align: center; width: 100%; outline: none; From cfc9e6fb6b63a001b36820b1d649a713f722d645 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sun, 1 Oct 2017 10:58:20 -0700 Subject: [PATCH 3/3] Dont show caption placeholder in reading mode. Make it easier to escape image selected state --- .../components/Editor/components/Image.js | 21 +++++++++++-------- .../Editor/plugins/MarkdownShortcuts.js | 14 ++++++++++++- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/frontend/components/Editor/components/Image.js b/frontend/components/Editor/components/Image.js index 978d887be..af1c5de44 100644 --- a/frontend/components/Editor/components/Image.js +++ b/frontend/components/Editor/components/Image.js @@ -30,6 +30,7 @@ class Image extends Component { const caption = node.data.get('alt'); const src = node.data.get('src'); const active = state.isFocused && state.selection.hasEdgeIn(node); + const showCaption = !readOnly || caption; return ( @@ -40,15 +41,17 @@ class Image extends Component { active={active} loading={loading} /> - + {showCaption && + } ); } diff --git a/frontend/components/Editor/plugins/MarkdownShortcuts.js b/frontend/components/Editor/plugins/MarkdownShortcuts.js index b63fec754..0dd924156 100644 --- a/frontend/components/Editor/plugins/MarkdownShortcuts.js +++ b/frontend/components/Editor/plugins/MarkdownShortcuts.js @@ -215,6 +215,19 @@ export default function MarkdownShortcuts() { return this.onBackspace(ev, state); if (endOffset !== startBlock.length) return; + // Hitting enter while an image is selected should jump caret below and + // insert a new paragraph + if (startBlock.type === 'image') { + ev.preventDefault(); + return state + .transform() + .collapseToEnd() + .insertBlock('paragraph') + .apply(); + } + + // Hitting enter in a heading or blockquote will split the node at that + // point and make the new node a paragraph if ( startBlock.type !== 'heading1' && startBlock.type !== 'heading2' && @@ -228,7 +241,6 @@ export default function MarkdownShortcuts() { } ev.preventDefault(); - return state.transform().splitBlock().setBlock('paragraph').apply(); },