Skip to content

Commit

Permalink
docs: reorganize
Browse files Browse the repository at this point in the history
  • Loading branch information
linonetwo committed Jan 14, 2024
1 parent 0667934 commit 1de42ec
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 147 deletions.
2 changes: 1 addition & 1 deletion demo/tiddlers/$__DefaultTiddlers.tid
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ modifier: 林一二
title: $:/DefaultTiddlers
type: text/vnd.tiddlywiki

Index
Index $:/plugins/linonetwo/tw-react/readme
22 changes: 1 addition & 21 deletions demo/tiddlers/Index.tid
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,4 @@ type: text/vnd.tiddlywiki

{{$:/snippets/minilanguageswitcher}}

```tid
<$likeButtonExampleWidget stateTiddler="$:/state/tw-react/readme/like-button" />
```

Button1:

<$likeButtonExampleWidget stateTiddler="$:/state/tw-react/readme/like-button" />

Button2:

<$likeButtonExampleWidget stateTiddler="$:/state/tw-react/readme/like-button" />

State:

{{$:/state/tw-react/readme/like-button}}

Two buttons have shared state [[$:/state/tw-react/readme/like-button]], but not updated when state changed (although you can implement this in the `refresh` method by yourself in your own component), so when you click one, and close this tiddler then reopen it, you will see two buttons have same ''clicked'' state.

`likeButtonExampleWidget` is a class component, it calls a functional component `ExampleFunction` that will use react hook to update self +1 every second.

[[Readme|$:/plugins/linonetwo/tw-react/readme]]
{{$:/plugins/linonetwo/tw-react/docs/example}}
22 changes: 22 additions & 0 deletions src/docs/FAQ.tid
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
title: $:/plugins/linonetwo/tw-react/docs/FAQ
creator: LinOnetwo

!! FAQ

!!! _jsxRuntime

`slate-write/node_modules/react-dnd/dist/cjs/core/DndProvider.js` has `var _jsxRuntime = require("react/jsx-runtime");`

But `slate-write/node_modules/react-dnd/dist/esm/core/DndProvider.mjs` has `import { jsx as _jsx } from "react/jsx-runtime.js";`

Note the difference between `react/jsx-runtime` and `react/jsx-runtime.js`!

Currently tw-react ship with `react/jsx-runtime.js`, so if your plugin uses cjs version of react-dnd, you will have error:

```
Error executing boot module $:/plugins/linonetwo/slate-write/components/index.js: "Cannot find module named 'react/jsx-runtime' required by module '$:/plugins/linonetwo/slate-write/components/index.js', resolved to react/jsx-runtime"

undefined
```

The solution is to ask me provide a version of tw-react that has `react/jsx-runtime`, or you can use esm version of `react-dnd`.
29 changes: 29 additions & 0 deletions src/docs/example.tid
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
title: $:/plugins/linonetwo/tw-react/docs/example
creator: LinOnetwo
type: text/vnd.tiddlywiki

!! Example

```tid
<$likeButtonExampleWidget stateTiddler="$:/state/tw-react/readme/like-button" />
```

Button1:

<$likeButtonExampleWidget stateTiddler="$:/state/tw-react/readme/like-button" />

Button2:

<$likeButtonExampleWidget stateTiddler="$:/state/tw-react/readme/like-button" />

State:

{{$:/state/tw-react/readme/like-button}}

It keeps its state via a state tiddler, and title of state tiddler is pass-in using `getProps = () => ({ stateTiddler: this.getAttribute('stateTiddler') });`, so `stateTiddler` attribute is passed from widget parameter to the React props.

Two buttons have shared state [[$:/state/tw-react/readme/like-button]], but not updated when state changed (although you can implement this in the `refresh` method by yourself in your own component), so when you click one, and close this tiddler then reopen it, you will see two buttons have same ''clicked'' state.

`likeButtonExampleWidget` is a class component, it calls a functional component `ExampleFunction` that will use react hook to update self +1 every second.

See [[$:/plugins/linonetwo/tw-react/example.ts]] for example.
98 changes: 98 additions & 0 deletions src/docs/install.tid
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
title: $:/plugins/linonetwo/tw-react/docs/install
creator: LinOnetwo

!! Install

As a user, just install from [[CPL|https://tw-cpl.netlify.app/#linonetwo%2Ftw-react:Index%20linonetwo%2Ftw-react]].

As a developer, you can continue reading.

!!! Require and externalize 'react', 'react-dom'

Please make sure to externalize them, for example in the [[RollUp|https://rollupjs.org/]]:

```json
{
external: ['react', 'react-dom']
}
```

Otherwise you will get [[You might have more than one copy of React in the same app|https://reactjs.org/docs/error-decoder.html/?invariant=321]] error.

And use the subclass of Widget provided by this plugin:

```
const Widget = require('$:/plugins/linonetwo/tw-react/widget.js').widget
```

!!! Using Typescript

# use [[TW5-Typed|https://github.com/tiddly-gittly/TW5-Typed]] for basic tw types, see its readme for install instruction
# install `tw-react` package via `npm i tw-react`, and import the type by `import type { ReactWidget } from 'tw-react';`

Use the type:

```js
import { useRenderTiddler } from '$:/plugins/linonetwo/tw-react/index.js';
import type { ReactWidget } from 'tw-react';

const Widget = require('$:/plugins/linonetwo/tw-react/widget.js').widget as typeof ReactWidget;

class YourWidget extends Widget {
reactComponent = SomeReactComponent;
getProps = () => {
return {
stateTiddler: this.getAttribute('stateTiddler'),
// ... other props for your react component
};
};
}
```

!!! Props

Anything returned from `getProps` method will pass to react component, passing `stateTiddler` is a good idea, but is not mandatory.

For example, this is what I returned in my `linonetwo/smart-form` plugin:

```js
getProps = () => {
const currentTiddler = this.getAttribute('tiddler', this.getVariable('currentTiddler'));
// with lots of filter running and data transforms...
return {
schema,
formData,
children: null,
onChange,
};
};
```

!!! React Hooks

We provided some hooks for reactive data management with tw data source. You can import them from the `$:/plugins/linonetwo/tw-react/index.js` (Instead of from `tw-react` package, because they already included in the plugin).

```ts
import { useFilter } from '$:/plugins/linonetwo/tw-react/index.js'
```

You can't import them from plugin's file, because they are optional, so only included in the npm package, not in the plugin json bundle.

!!!! useFilter

Get list of titles from a filter.

```ts
const titles = useFilter('[all[]tag[Index]]');
```

The second parameter is an optional dependencies list, you can use it to trigger re-calculate. Otherwise it only rerun filter when filter text changes.

```ts
const [toggle, setToggle] = useState(false);
const titles = useFilter('[all[]tag[Index]]', [toggle]);

...

<Button onClick={() => setToggle(!toggle)}>Trigger refresh</Button>
```
6 changes: 6 additions & 0 deletions src/docs/reactAPIs.tid
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
title: $:/plugins/linonetwo/tw-react/docs/reactAPIs
creator: LinOnetwo

!! React APIs

TBD, read the source now.
2 changes: 1 addition & 1 deletion src/plugin.info
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"core-version": ">=5.3.0",
"plugin-type": "plugin",
"version": "0.5.3",
"list": "readme"
"list": "readme tree"
}
126 changes: 2 additions & 124 deletions src/readme.tid
Original file line number Diff line number Diff line change
Expand Up @@ -8,130 +8,8 @@ This is a dependency of slate-write WYSIWYG editor and flowtiwi-sidebar and many

!! Example

```tid
<$likeButtonExampleWidget stateTiddler="$:/state/tw-react/readme/like-button" />
```

<$likeButtonExampleWidget stateTiddler="$:/state/tw-react/readme/like-button" />

It keeps its state via a state tiddler, and title of state tiddler is pass-in using `getProps = () => ({ stateTiddler: this.getAttribute('stateTiddler') });`, so `stateTiddler` attribute is passed from widget parameter to the React props.

See [[$:/plugins/linonetwo/tw-react/example.ts]] for example.
{{$:/plugins/linonetwo/tw-react/docs/example}}

!! Usage

!!! React APIs

<$list filter="[tag[ReactAPI]]" />

!! Install

!!! Require and externalize 'react', 'react-dom'

Please make sure to externalize them, for example in the [[RollUp|https://rollupjs.org/]]:

```json
{
external: ['react', 'react-dom']
}
```

Otherwise you will get [[You might have more than one copy of React in the same app|https://reactjs.org/docs/error-decoder.html/?invariant=321]] error.

And use the subclass of Widget provided by this plugin:

```
const Widget = require('$:/plugins/linonetwo/tw-react/widget.js').widget
```

!!! Using Typescript

# use [[TW5-Typed|https://github.com/tiddly-gittly/TW5-Typed]] for basic tw types, see its readme for install instruction
# install `tw-react` package via `npm i tw-react`, and import the type by `import type { ReactWidget } from 'tw-react';`

Use the type:

```js
import { useRenderTiddler } from '$:/plugins/linonetwo/tw-react/index.js';
import type { ReactWidget } from 'tw-react';

const Widget = require('$:/plugins/linonetwo/tw-react/widget.js').widget as typeof ReactWidget;

class YourWidget extends Widget {
reactComponent = SomeReactComponent;
getProps = () => {
return {
stateTiddler: this.getAttribute('stateTiddler'),
// ... other props for your react component
};
};
}
```

!!! Props

Anything returned from `getProps` method will pass to react component, passing `stateTiddler` is a good idea, but is not mandatory.

For example, this is what I returned in my `linonetwo/smart-form` plugin:

```js
getProps = () => {
const currentTiddler = this.getAttribute('tiddler', this.getVariable('currentTiddler'));
// with lots of filter running and data transforms...
return {
schema,
formData,
children: null,
onChange,
};
};
```

!!! React Hooks

We provided some hooks for reactive data management with tw data source. You can import them from the `$:/plugins/linonetwo/tw-react/index.js` (Instead of from `tw-react` package, because they already included in the plugin).

```ts
import { useFilter } from '$:/plugins/linonetwo/tw-react/index.js'
```

You can't import them from plugin's file, because they are optional, so only included in the npm package, not in the plugin json bundle.

!!!! useFilter

Get list of titles from a filter.

```ts
const titles = useFilter('[all[]tag[Index]]');
```

The second parameter is an optional dependencies list, you can use it to trigger re-calculate. Otherwise it only rerun filter when filter text changes.

```ts
const [toggle, setToggle] = useState(false);
const titles = useFilter('[all[]tag[Index]]', [toggle]);

...

<Button onClick={() => setToggle(!toggle)}>Trigger refresh</Button>
```

!! FAQ

!!!

`slate-write/node_modules/react-dnd/dist/cjs/core/DndProvider.js` has `var _jsxRuntime = require("react/jsx-runtime");`

But `slate-write/node_modules/react-dnd/dist/esm/core/DndProvider.mjs` has `import { jsx as _jsx } from "react/jsx-runtime.js";`

Note the difference between `react/jsx-runtime` and `react/jsx-runtime.js`!

Currently tw-react ship with `react/jsx-runtime.js`, so if your plugin uses cjs version of react-dnd, you will have error:

```
Error executing boot module $:/plugins/linonetwo/slate-write/components/index.js: "Cannot find module named 'react/jsx-runtime' required by module '$:/plugins/linonetwo/slate-write/components/index.js', resolved to react/jsx-runtime"

undefined
```

The solution is to ask me provide a version of tw-react that has `react/jsx-runtime`, or you can use esm version of `react-dnd`.
<<tree prefix:"$:/plugins/linonetwo/tw-react/docs/">>

0 comments on commit 1de42ec

Please sign in to comment.