Merge pull request #273 from jorilallo/markdown-checkboxes
Markdown shortcuts for checkbox lists
This commit is contained in:
@@ -22,28 +22,27 @@ export default class TodoItem extends Component {
|
||||
const { children, checked, readOnly } = this.props;
|
||||
|
||||
return (
|
||||
<StyledLi contentEditable={false}>
|
||||
<input
|
||||
<ListItem>
|
||||
<Input
|
||||
type="checkbox"
|
||||
checked={checked}
|
||||
onChange={this.handleChange}
|
||||
disabled={readOnly}
|
||||
contentEditable={false}
|
||||
/>
|
||||
{' '}
|
||||
<span contentEditable={!readOnly} suppressContentEditableWarning>
|
||||
{children}
|
||||
</span>
|
||||
</StyledLi>
|
||||
{children}
|
||||
</ListItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const StyledLi = styled.li`
|
||||
input {
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
&:last-child:focus {
|
||||
outline: none;
|
||||
}
|
||||
const ListItem = styled.li`
|
||||
padding-left: 1.4em;
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
const Input = styled.input`
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0.4em;
|
||||
`;
|
||||
|
||||
13
frontend/components/Editor/components/TodoList.js
Normal file
13
frontend/components/Editor/components/TodoList.js
Normal 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;
|
||||
@@ -40,17 +40,24 @@ export default function MarkdownShortcuts() {
|
||||
onSpace(ev: SyntheticEvent, state: Object) {
|
||||
if (state.isExpanded) return;
|
||||
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);
|
||||
|
||||
if (type) {
|
||||
if (type === 'list-item' && startBlock.type === 'list-item') return;
|
||||
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 (chars === '1.') {
|
||||
if (checked !== undefined) {
|
||||
transform.wrapBlock('todo-list');
|
||||
} else if (chars === '1.') {
|
||||
transform.wrapBlock('ordered-list');
|
||||
} else {
|
||||
transform.wrapBlock('bulleted-list');
|
||||
@@ -234,6 +241,8 @@ export default function MarkdownShortcuts() {
|
||||
case '-':
|
||||
case '+':
|
||||
case '1.':
|
||||
case '[ ]':
|
||||
case '[x]':
|
||||
return 'list-item';
|
||||
case '>':
|
||||
return 'block-quote';
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import Code from './components/Code';
|
||||
import InlineCode from './components/InlineCode';
|
||||
import Image from './components/Image';
|
||||
import Link from './components/Link';
|
||||
import ListItem from './components/ListItem';
|
||||
import TodoList from './components/TodoList';
|
||||
import {
|
||||
Heading1,
|
||||
Heading2,
|
||||
@@ -17,15 +17,6 @@ import {
|
||||
import Paragraph from './components/Paragraph';
|
||||
import type { Props, Node, Transform } from './types';
|
||||
|
||||
const TodoList = styled.ul`
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
|
||||
ul {
|
||||
padding-left: 1em;
|
||||
}
|
||||
`;
|
||||
|
||||
const createSchema = () => {
|
||||
return {
|
||||
marks: {
|
||||
@@ -63,7 +54,7 @@ const createSchema = () => {
|
||||
},
|
||||
|
||||
rules: [
|
||||
// ensure first node is a heading
|
||||
// ensure first node is always a heading
|
||||
{
|
||||
match: (node: Node) => {
|
||||
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) => {
|
||||
return node.kind === 'heading1';
|
||||
|
||||
Reference in New Issue
Block a user