Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/unified-doc/unified-doc-react

react wrapper for unified-doc
https://github.com/unified-doc/unified-doc-react

annotate compile content document export file hast highlight html markdown nlp parse react search text unifiedjs unist

Last synced: 21 days ago
JSON representation

react wrapper for unified-doc

Awesome Lists containing this project

README

        

# unified-doc-react
[`react`][react] wrapper for [**unified-doc**][unified-doc].

---

## Install
```sh
npm install unified-doc-react
```

## Use

### `DocComponent`
For quick and simple rendering of a document, use the React component:

```js
import React from 'react';
import { DocComponent } from 'unified-doc-react';

const options = {
content: '> some **strong** content',
filename: 'doc.md',
marks: [
{ id: 'a', start: 0, end: 5 },
{ id: 'a', start: 10, end: 12 },
],
};

function MyDoc() {
return (

);
}
```

### `DocProvider` and `useDoc`
For building advanced and interactive document applications, wrap your component with a `DocProvider`. Components under the `DocProvider` have access to the `doc` instance via the `useDoc` hook.

```js
// App.js
import React from 'react';
import { DocProvider } from 'unified-doc-react';

import MyDoc from './MyDoc';

const options = {
content: '> some **strong** content',
filename: 'doc.md',
};

function MyApp() {
return (



);
}

// MyDoc.js
import React, { useState } from 'react';
import { saveFile } from 'unified-doc-dom';
import { useDoc } from 'unified-doc-react';

function MyDoc() {
const doc = useDoc();
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);

function clearSearch() {
setQuery('');
setResults([]);
}

function handleSearch(e) {
const query = e.target.value;
const results = doc.search(query);
setQuery(query);
setResults(results);
}

return (


{doc.file().name}


Search



{results.map((result, i) => {
const [left, matched, right] = result.snippet;
return (

{left}
{matched}
{right}

);
})}

Clear search

Contents


{doc.compile().result}

saveFile(doc.file())}>
Download original

saveFile(doc.file('.html'))}>
Download HTML

saveFile(doc.file('.txt'))}>
Download text

Text Contents


{doc.textContent()}


);
}
```

### Use with `unified-doc-dom`
`unified-doc-react` can be used seamlessly with methods in `unified-doc-dom` to build interactive document applications.

```js
import React, { useEffect, useRef, useState } from 'react';
import { fromFile, highlight, registerMarks, selectText } from 'unified-doc-dom';
import { DocComponent } from 'unified-doc-react';
import { v4 as uuidv4 } from 'uuid';

// import optional highlight styles
import 'unified-doc-dom/css/highlight.css';

function MyDoc() {
const docRef = useRef();
const [fileData, setFileData] = useState();
const [marks, setMarks] = useState([]);

function addMark(newMark) {
setMarks(oldMarks => [...oldMarks, { ...newMark, id: uuidv4() }]);
}

// enable and capture selected text as marks
useEffect(() => {
// cleanup function conveniently returned
return selectText(docRef.current, { callback: addMark });
}, []);

// register marks with callbacks
useEffect(() => {
const callbacks = {
onClick: (event, mark) => console.log('clicked', event, mark),
onMouseEnter: (event, mark) => console.log('mouseenter', event, mark),
onMouseOut: (event, mark) => console.log('mouseout', event, mark),
}
// cleanup function conveniently returned
return registerMarks(docRef.current, marks, callbacks);
}, [marks]);

// highlight applied marks given its ID
function highlightLastMark() {
highlight(docRef.current, marks[marks.length - 1].id);
}

// read file data from a JS file
async function uploadFile(e) {
const fileData = await fromFile(e.target.files[0]);
setFileData(fileData);
}

let docContent;
if (!fileData) {
docContent = ;
} else {
const options = {
content: fileData.content,
filename: fileData.name,
marks,
};
docContent = ;
}

return (



Highlight last mark


{docContent}


);
}
```

## API
- [`DocComponent(props)`](#DocComponentprops)
- [`DocProvider(props)`](#DocProviderprops)
- [`useDoc()`](#useDoc)
- [`options`](#options)

The term `doc` used below refers to a `unified-doc` instance. Please refer to [**unified-doc**][unified-doc] for detailed documentation of `doc` API methods.

### `DocComponent(props)`
#### Interface
```ts
function DocComponent(props: Props): React.ReactElement;
```
A simple React component that wraps around a `doc` instance.

#### Related interfaces
```ts
interface Props {
/** options for `doc` instance */
options: Options;
/** optional `className` to attach to rendered `docElement` */
className?: string;
/** a reference to the rendered `docElement` */
ref?: React.Ref;
}
```

### `DocProvider(props)`
#### Interface
```ts
function DocProvider(props: ProviderProps): React.ReactElement;
```
Use the `DocProvider` to expose the `doc` instance in a React context. Components under `DocProvider` can access the `doc` instance via the `useDoc` hook.

#### Related interfaces
```ts
interface ProviderProps {
/** any React node */
children: React.ReactNode;
/** options for `doc` instance */
options: Options;
}
```

### `useDoc()`
#### Interface
```ts
export function useDoc(): DocInstance;
```
Access the `doc` instance in any components under the `DocProvider`.

### `options`
Provide `options` to configure `unified-doc`.

Please refer to [**unified-doc**][unified-doc] for detailed documentation of `options`.

## Development
This project is:
- implemented with the `unified-doc` interface.
- linted with `xo` + `prettier` + `tsc`.
- developed and built with `microbundle`.
- tested with `jest`.
- softly-typed with `typescript` with `checkJs` (only public APIs are typed).

```sh
# install dependencies
npm run bootstrap

# build package with microbundle
npm run build

# clean package (rm dist + node_modules)
npm run clean

# watch/rebuild package with microbundle
npm run dev

# lint package with xo + prettier + tsc
npm run lint

# update semantic version with changelog
npm run release

# test package with jest in --watch mode (make sure to run the 'dev' script)
npm run test

# test package in a single run
npm run test:run
```

[react]: https://github.com/facebook/react
[unified-doc]: https://github.com/unified-doc/unified-doc