https://github.com/lukeramsden/react-native-draftjs-display
React Native component to render Draft.js ContentState.
https://github.com/lukeramsden/react-native-draftjs-display
draft-js react-native
Last synced: 9 months ago
JSON representation
React Native component to render Draft.js ContentState.
- Host: GitHub
- URL: https://github.com/lukeramsden/react-native-draftjs-display
- Owner: lukeramsden
- License: isc
- Created: 2020-05-28T09:44:26.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-06T07:16:37.000Z (over 3 years ago)
- Last Synced: 2023-03-05T22:59:01.832Z (about 3 years ago)
- Topics: draft-js, react-native
- Language: TypeScript
- Homepage:
- Size: 973 KB
- Stars: 4
- Watchers: 2
- Forks: 1
- Open Issues: 14
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# react-native-draftjs-display
 [](https://www.codefactor.io/repository/github/lukeramsden/react-native-draftjs-display)
Barebones React Native component to display Draft.js content.
Partly forked from [jdponomarev/react-native-draftjs-render](https://github.com/jdponomarev/react-native-draftjs-render), with the original code coming from [globocom/react-native-draftjs-render](https://github.com/globocom/react-native-draftjs-render). Re-written to use TypeScript, and to better fit in with my use-case.
This library is intentionally very minimal to allow you to use your own components (or a component kit like material design) and styling easily, and as such has very few defaults in that regard.
## Usage
```tsx
// Use DraftText but with our own text component, or one from a UI kit.
const TextBlockHandler = useCallback(
(category: string) => ({block}: {block: DraftContentBlock}) => (
}
/>
),
[],
);
// ...
<>
{data.getPost?.content && (
,
'header-one': TextBlockHandler('h1'),
'header-two': TextBlockHandler('h2'),
'header-three': TextBlockHandler('h3'),
'header-four': TextBlockHandler('h4'),
'header-five': TextBlockHandler('h5'),
'header-six': TextBlockHandler('h6'),
paragraph: TextBlockHandler('p1'),
unstyled: TextBlockHandler('p1'),
// see below, "List Handlers"
'ordered-list-item': OrderedListBlockHandler(),
'unordered-list-item': UnorderedListBlockHandler(),
}}
/>
)}
>;
```
### List Handlers
This library, as of writing, has no list handling functionality or helpers. That may change, but for now, here's my provisional implementation of rendering nested lists:
In these examples, `tw('...')` is from [tailwind-rn](github.com/vadimdemedes/tailwind-rn), and ``, ``, and `` are from [react-native-ui-kitten](github.com/akveo/react-native-ui-kitten). Use this as an example for your own apps.
##### Unordered list
These are easy, as you just render an indent and a prefix icon based on the `block.depth` property.
```tsx
const UnorderedListBlockHandler = useCallback(
() => ({block}: {block: DraftContentBlock}) => (
(
)}
title={() => (
}
/>
)}
/>
),
[],
);
```
##### Ordered list
Now these are a little more involved, as you need to have your own counter, which counts each depth separately, and then resets between separate lists. Here's my implementation:
```tsx
const OrderedListBlockHandler = useCallback(() => {
// an array of numbers, with the index being the depth, and the number being the counter
let listCountersAtDepth: number[] = [];
return ({
block,
prevBlock,
}: {
block: DraftContentBlock;
prevBlock?: DraftContentBlock; // introduced in v1.3.0
}) => {
// reset list counter completely if previous block is not a list item
if (prevBlock && prevBlock.type !== 'ordered-list-item') {
listCountersAtDepth = [];
}
// initialise counter at this block's depth
if (!listCountersAtDepth[block.depth]) {
listCountersAtDepth[block.depth] = 0;
}
// increase counter
listCountersAtDepth[block.depth]++;
return (
{/*
you could just do `listCountersAtDepth[block.depth]` and call it a day,
but this renders each indentation a different way, to differentiate them
numberToBase26 does exactly as it sounds, takes a number and turns it in to the alphabet
with 1 being a, 26 being z, and 27 being aa etc.
arabicToRoman also does exactly what you'd expect
the implementation of these is left to the reader (hint: StackOverflow!)
The `block.depth % 3` is so that it loops, as technically you could have any maximum block.depth,
but we only have 3 options to display the counter
*/}
{block.depth % 3 === 0
? listCountersAtDepth[block.depth]
: block.depth % 3 === 1
? numberToBase26(listCountersAtDepth[block.depth]).toLowerCase()
: block.depth % 3 === 2
? arabicToRoman(listCountersAtDepth[block.depth]).toLowerCase()
: listCountersAtDepth[block.depth]}.
}
/>
);
};
}, []);
```
## Development
Clone this repository and install its dependencies:
```bash
git clone https://github.com/lukeramsden/react-native-draftjs-display
cd react-native-draftjs-display
yarn # or npm install, if you're so inclined
```
`yarn run build` builds the library to `dist`.
`yarn test` builds the library, then tests it.
## License
[ISC](LICENSE).