Add/Remove link
This commit is contained in:
parent
72b8e14f07
commit
5fa551dcb2
@ -78,6 +78,6 @@
|
||||
"react-portal": "^2.2.1",
|
||||
"selection-position": "^1.0.0",
|
||||
"slate": "^0.11.0",
|
||||
"slate-markdown-serializer": "^0.1.3"
|
||||
"slate-markdown-serializer": "^0.1.5"
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ class MarkdownControl extends React.Component {
|
||||
this.handleDocumentChange = this.handleDocumentChange.bind(this);
|
||||
this.handleMarkStyleClick = this.handleMarkStyleClick.bind(this);
|
||||
this.handleBlockStyleClick = this.handleBlockStyleClick.bind(this);
|
||||
this.handleInlineClick = this.handleInlineClick.bind(this);
|
||||
this.handleBlockTypeClick = this.handleBlockTypeClick.bind(this);
|
||||
this.handleKeyDown = this.handleKeyDown.bind(this);
|
||||
this.calculateMenuPositions = this.calculateMenuPositions.bind(this);
|
||||
@ -150,6 +151,42 @@ class MarkdownControl extends React.Component {
|
||||
this.setState({ state });
|
||||
}
|
||||
|
||||
/**
|
||||
* When clicking a link, if the selection has a link in it, remove the link.
|
||||
* Otherwise, add a new link with an href and text.
|
||||
*
|
||||
* @param {Event} e
|
||||
*/
|
||||
|
||||
handleInlineClick(type, isActive) {
|
||||
let { state } = this.state;
|
||||
|
||||
if (type === 'link') {
|
||||
if (!state.isExpanded) return;
|
||||
|
||||
if (isActive) {
|
||||
state = state
|
||||
.transform()
|
||||
.unwrapInline('link')
|
||||
.apply();
|
||||
}
|
||||
|
||||
else {
|
||||
const href = window.prompt('Enter the URL of the link:', 'http://www.');
|
||||
state = state
|
||||
.transform()
|
||||
.wrapInline({
|
||||
type: 'link',
|
||||
data: { href }
|
||||
})
|
||||
.collapseToEnd()
|
||||
.apply();
|
||||
}
|
||||
}
|
||||
this.setState({ state });
|
||||
}
|
||||
|
||||
|
||||
handleBlockTypeClick(type) {
|
||||
let { state } = this.state;
|
||||
|
||||
@ -208,7 +245,9 @@ class MarkdownControl extends React.Component {
|
||||
position={this.menuPositions.stylesMenu}
|
||||
marks={this.state.state.marks}
|
||||
blocks={this.state.state.blocks}
|
||||
inlines={this.state.state.inlines}
|
||||
onClickMark={this.handleMarkStyleClick}
|
||||
onClickInline={this.handleInlineClick}
|
||||
onClickBlock={this.handleBlockStyleClick}
|
||||
/>
|
||||
);
|
||||
|
@ -16,8 +16,10 @@ export default class StylesMenu extends Component {
|
||||
this.hasBlock = this.hasBlock.bind(this);
|
||||
this.renderMarkButton = this.renderMarkButton.bind(this);
|
||||
this.renderBlockButton = this.renderBlockButton.bind(this);
|
||||
this.renderLinkButton = this.renderLinkButton.bind(this);
|
||||
this.updateMenuPosition = this.updateMenuPosition.bind(this);
|
||||
this.handleMarkClick = this.handleMarkClick.bind(this);
|
||||
this.handleInlineClick = this.handleInlineClick.bind(this);
|
||||
this.handleBlockClick = this.handleBlockClick.bind(this);
|
||||
this.handleOpen = this.handleOpen.bind(this);
|
||||
}
|
||||
@ -54,6 +56,10 @@ export default class StylesMenu extends Component {
|
||||
const { blocks } = this.props;
|
||||
return blocks.some(node => node.type == type);
|
||||
}
|
||||
hasLinks(type) {
|
||||
const { inlines } = this.props;
|
||||
return inlines.some(inline => inline.type == 'link');
|
||||
}
|
||||
|
||||
handleMarkClick(e, type) {
|
||||
e.preventDefault();
|
||||
@ -70,6 +76,21 @@ export default class StylesMenu extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
handleInlineClick(e, type, isActive) {
|
||||
e.preventDefault();
|
||||
this.props.onClickInline(type, isActive);
|
||||
}
|
||||
|
||||
renderLinkButton() {
|
||||
const isActive = this.hasLinks();
|
||||
const onMouseDown = e => this.handleInlineClick(e, 'link', isActive);
|
||||
return (
|
||||
<span className={styles.button} onMouseDown={onMouseDown} data-active={isActive}>
|
||||
<Icon type="link"/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
handleBlockClick(e, type) {
|
||||
e.preventDefault();
|
||||
const isActive = this.hasBlock(type);
|
||||
@ -103,6 +124,7 @@ export default class StylesMenu extends Component {
|
||||
{this.renderMarkButton('bold', 'bold')}
|
||||
{this.renderMarkButton('italic', 'italic')}
|
||||
{this.renderMarkButton('code', 'code')}
|
||||
{this.renderLinkButton()}
|
||||
{this.renderBlockButton('heading1', 'h1')}
|
||||
{this.renderBlockButton('heading2', 'h2')}
|
||||
{this.renderBlockButton('block-quote', 'quote-left')}
|
||||
@ -122,6 +144,8 @@ StylesMenu.propTypes = {
|
||||
}),
|
||||
marks: PropTypes.object.isRequired,
|
||||
blocks: PropTypes.object.isRequired,
|
||||
inlines: PropTypes.object.isRequired,
|
||||
onClickBlock: PropTypes.func.isRequired,
|
||||
onClickMark: PropTypes.func.isRequired
|
||||
onClickMark: PropTypes.func.isRequired,
|
||||
onClickInline: PropTypes.func.isRequired
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import Block from './Block';
|
||||
import BlockStatic from './BlockStatic';
|
||||
import { Icon } from '../../UI';
|
||||
|
||||
/* eslint react/prop-types: 0, react/no-multi-comp: 0 */
|
||||
|
||||
@ -24,7 +23,7 @@ export const NODES = {
|
||||
'link': (props) => {
|
||||
const { data } = props.node;
|
||||
const href = data.get('href');
|
||||
return <span><a {...props.attributes} href={href}>{props.children}</a><Icon type="link"/></span>;
|
||||
return <a {...props.attributes} href={href}>{props.children}</a>;
|
||||
},
|
||||
'image': (props) => {
|
||||
const { node } = props;
|
||||
|
Loading…
x
Reference in New Issue
Block a user