Merge pull request #273 from jorilallo/markdown-checkboxes

Markdown shortcuts for checkbox lists
This commit is contained in:
Tom Moor
2017-09-27 11:29:32 -04:00
committed by GitHub
4 changed files with 42 additions and 30 deletions

View File

@@ -22,28 +22,27 @@ export default class TodoItem extends Component {
const { children, checked, readOnly } = this.props; const { children, checked, readOnly } = this.props;
return ( return (
<StyledLi contentEditable={false}> <ListItem>
<input <Input
type="checkbox" type="checkbox"
checked={checked} checked={checked}
onChange={this.handleChange} onChange={this.handleChange}
disabled={readOnly} disabled={readOnly}
contentEditable={false}
/> />
{' '} {children}
<span contentEditable={!readOnly} suppressContentEditableWarning> </ListItem>
{children}
</span>
</StyledLi>
); );
} }
} }
const StyledLi = styled.li` const ListItem = styled.li`
input { padding-left: 1.4em;
margin-right: 0.25em; position: relative;
} `;
&:last-child:focus { const Input = styled.input`
outline: none; position: absolute;
} left: 0;
top: 0.4em;
`; `;

View File

@@ -0,0 +1,13 @@
// @flow
import styled from 'styled-components';
const TodoList = styled.ul`
list-style: none;
padding: 0 !important;
ul {
padding-left: 1em;
}
`;
export default TodoList;

View File

@@ -40,17 +40,24 @@ export default function MarkdownShortcuts() {
onSpace(ev: SyntheticEvent, state: Object) { onSpace(ev: SyntheticEvent, state: Object) {
if (state.isExpanded) return; if (state.isExpanded) return;
const { startBlock, startOffset } = state; const { startBlock, startOffset } = state;
const chars = startBlock.text.slice(0, startOffset).replace(/\s*/g, ''); const chars = startBlock.text.slice(0, startOffset).trim();
const type = this.getType(chars); const type = this.getType(chars);
if (type) { if (type) {
if (type === 'list-item' && startBlock.type === 'list-item') return; if (type === 'list-item' && startBlock.type === 'list-item') return;
ev.preventDefault(); ev.preventDefault();
const transform = state.transform().setBlock(type); let checked;
if (chars === '[x]') checked = true;
if (chars === '[ ]') checked = false;
const transform = state
.transform()
.setBlock({ type, data: { checked } });
if (type === 'list-item') { if (type === 'list-item') {
if (chars === '1.') { if (checked !== undefined) {
transform.wrapBlock('todo-list');
} else if (chars === '1.') {
transform.wrapBlock('ordered-list'); transform.wrapBlock('ordered-list');
} else { } else {
transform.wrapBlock('bulleted-list'); transform.wrapBlock('bulleted-list');
@@ -234,6 +241,8 @@ export default function MarkdownShortcuts() {
case '-': case '-':
case '+': case '+':
case '1.': case '1.':
case '[ ]':
case '[x]':
return 'list-item'; return 'list-item';
case '>': case '>':
return 'block-quote'; return 'block-quote';

View File

@@ -1,11 +1,11 @@
// @flow // @flow
import React from 'react'; import React from 'react';
import styled from 'styled-components';
import Code from './components/Code'; import Code from './components/Code';
import InlineCode from './components/InlineCode'; import InlineCode from './components/InlineCode';
import Image from './components/Image'; import Image from './components/Image';
import Link from './components/Link'; import Link from './components/Link';
import ListItem from './components/ListItem'; import ListItem from './components/ListItem';
import TodoList from './components/TodoList';
import { import {
Heading1, Heading1,
Heading2, Heading2,
@@ -17,15 +17,6 @@ import {
import Paragraph from './components/Paragraph'; import Paragraph from './components/Paragraph';
import type { Props, Node, Transform } from './types'; import type { Props, Node, Transform } from './types';
const TodoList = styled.ul`
list-style: none;
padding-left: 0;
ul {
padding-left: 1em;
}
`;
const createSchema = () => { const createSchema = () => {
return { return {
marks: { marks: {
@@ -63,7 +54,7 @@ const createSchema = () => {
}, },
rules: [ rules: [
// ensure first node is a heading // ensure first node is always a heading
{ {
match: (node: Node) => { match: (node: Node) => {
return node.kind === 'document'; return node.kind === 'document';
@@ -77,7 +68,7 @@ const createSchema = () => {
}, },
}, },
// remove any marks in first heading // automatically removes any marks in first heading
{ {
match: (node: Node) => { match: (node: Node) => {
return node.kind === 'heading1'; return node.kind === 'heading1';