React-markdown: change or disable checkbox - [ ]

Created on 16 Apr 2019  路  1Comment  路  Source: remarkjs/react-markdown

By default - [ ] renders <input type="checkbox" /> and it's changeable so that doesn't make any sense.
How can I replace checkbox with a custom element?

馃檵 typquestion

Most helpful comment

@untitledlt this is possible by passing in a custom renderer for listItem and then handle the checked property.

import {listItem as defaultListItem} from 'react-markdown/lib/renderers';

const renderListItem = props => {
  if (props.checked !== null && props.checked !== undefined) {
    return (
      // your checkbox component
    );
  }
  // otherwise default to list item
  return defaultListItem(props);
}


<ReactMarkdown
  source={value}
  renderers={{listItem: renderListItem}} />

Handling the click gets a little trickier. I solved it by specifying rawSourcePos={true} prop and then adding an onCheck function to the checkbox component that takes the line and value. When the checkbox is toggled simple update the line in your markdown string with the opposite checkbox text.

const generateCheckbox = checked => checked ? '- [x]' : '- [ ]';

const onToggle = (lineIndex, checked) {
  const lines = markdown.split('\n');

  lines[lineIndex] = lines[lineIndex].replace(
    generateCheckbox(!checked),
    generateCheckbox(checked)
  );

  updateMarkdownText(lines.join('\n'));
}

const Checkbox = (props) => {
  const lineIndex = props.sourcePosition.start.line - 1;
  const onToggle = props.onToggle(lineIndex, !props.checked);

  return (
    // your component
  );
}

(Note -- code is untested but based from a working example).

>All comments

@untitledlt this is possible by passing in a custom renderer for listItem and then handle the checked property.

import {listItem as defaultListItem} from 'react-markdown/lib/renderers';

const renderListItem = props => {
  if (props.checked !== null && props.checked !== undefined) {
    return (
      // your checkbox component
    );
  }
  // otherwise default to list item
  return defaultListItem(props);
}


<ReactMarkdown
  source={value}
  renderers={{listItem: renderListItem}} />

Handling the click gets a little trickier. I solved it by specifying rawSourcePos={true} prop and then adding an onCheck function to the checkbox component that takes the line and value. When the checkbox is toggled simple update the line in your markdown string with the opposite checkbox text.

const generateCheckbox = checked => checked ? '- [x]' : '- [ ]';

const onToggle = (lineIndex, checked) {
  const lines = markdown.split('\n');

  lines[lineIndex] = lines[lineIndex].replace(
    generateCheckbox(!checked),
    generateCheckbox(checked)
  );

  updateMarkdownText(lines.join('\n'));
}

const Checkbox = (props) => {
  const lineIndex = props.sourcePosition.start.line - 1;
  const onToggle = props.onToggle(lineIndex, !props.checked);

  return (
    // your component
  );
}

(Note -- code is untested but based from a working example).

Was this page helpful?
0 / 5 - 0 ratings