react-marksome
v1.0.1
Published
Lightweight, flexible and readable labels in React using a subset of markdown
Downloads
9,319
Readme
react-marksome
Parses some markdown, builds a tree of segments and renders them in React.
It was designed for adding basic support for styling and links to singleline strings.
See Rationale for more info.
Quick start
Install:
npm i react-marksome
Import and render the Marksome component:
import { Marksome } from 'react-marksome';
function Demo() {
const text =
'The *quick* *brown* **fox** jumps over the *lazy* **dog**. [Wikipedia][1]';
const references: References = {
'1':
'https://en.wikipedia.org/wiki/The_quick_brown_fox_jumps_over_the_lazy_dog',
};
return <Marksome text={text} references={references} />;
}
renders the following line:
The quick brown fox jumps over the lazy dog. Wikipedia
For more examples, see the stories together with related fixtures.
API
Marksome component
React component that parses and renders a subset of markdown.
It expects the markdown text to be provided via a text
prop, which then is combined with reference links ([label][reference]
) defined under the references
prop.
Props
type MarksomeProps = HTMLAttributes<HTMLSpanElement> & {
text: string;
references?: References;
};
type References = Record<string, string | ReferenceRenderFunction>;
type ReferenceRenderFunction = (children: ReactNode) => ReactElement;
Basic usage
See Quick start.
Custom components
One can actually render custom components in the place of reference links by providing a render function instead of link url:
function CustomComponentsDemo() {
const text = 'The following is an actual button: [*Howdie*][greeting-button]';
const references: References = {
'greeting-button': (children) => (
<button
onClick={() => {
alert('Hello!');
}}
>
{children}
</button>
),
};
return <Marksome text={text} references={references} />;
}
Supported Markdown
The current subset of markdown that is supported is:
Emphasis and strong emphasis
Emphasis (*Emphasis*) and strong emphasis (**strong emphasis**) parcing respects the related commonmark spec section.
Link references
Influenced by the related commonmark spec section, link references can be defined in a couple of ways:
- Full reference links:
- input: [react-marksome's Github page][react-marksome github]
- output: react-marksome's Github page
- Shortcut reference links:
- input: [react-marksome github]
- output: react-marksome github
There are certain quirks in marksome that are non-spec:
- it matches reference links regardless if the corresponding reference labels are defined as keys in the
references
prop or not - reference labels are kept as is when looking for the corresponding key in
references
prop (ex: case-sensitive, no space-trimming, etc) - nested squared brackets don't follow the same rules (ex: marksome supports unbalanced brackets)
If reference links are not being matched as you desire, disable unintended matches by escaping the related opening (\[) or closing (\]) brackets.
Rationale
By restricting ourselves to support only some markdown we're able to:
- build a light package (bundlephobia)
- that provides a flexible, readable and condensed format for singleline pieces of text
Additionally, we build out a tree of segments instead of simply using string replacement mostly for extensibility and configuratility, like being able to render segments with custom React components.
All of the above means that users don't need to worry about escaping the text since:
- it relies on regular React components instead of injecting HTML via dangerouslySetInnerHTML
- the only way to inject a link is via a separate references object.
Supported browsers
The following browserslist is supported without the need of any polyfills:
Commands
This project was bootstrapped with TSDX. Check its docs for more info on the commands.
Storybook
npm run storybook
This loads the stories from ./stories
.
Testing
Jest tests are set up to run with npm test
.
Bundle analysis
Calculates the real cost of your library using size-limit with npm run size
and visualize it with npm run analyze
.
Credits
- devuo for providing some ideas and inspiration!