react-rx 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/jest.config.js +0 -5
- package/website/.babelrc +0 -21
- package/website/.prettierrc +0 -7
- package/website/README.mdx +0 -1
- package/website/package.json +0 -84
- package/website/src/@types/babel.d.ts +0 -4
- package/website/src/@types/mdx.d.ts +0 -11
- package/website/src/@types/react-css-burger.d.ts +0 -4
- package/website/src/App.tsx +0 -68
- package/website/src/components/Header.tsx +0 -118
- package/website/src/components/Link.tsx +0 -18
- package/website/src/components/LoadPage.tsx +0 -60
- package/website/src/components/Sidebar.tsx +0 -88
- package/website/src/components/logos/Github.tsx +0 -10
- package/website/src/components/logos/React.tsx +0 -27
- package/website/src/components/logos/ReactRxLogo.tsx +0 -39
- package/website/src/components/logos/RxJs.tsx +0 -69
- package/website/src/components/repl/Checkerboard.tsx +0 -25
- package/website/src/components/repl/CodeBlock.tsx +0 -147
- package/website/src/components/repl/CodeMirror.tsx +0 -37
- package/website/src/components/repl/CodeMirrorMode.tsx +0 -67
- package/website/src/components/repl/EvalCode.tsx +0 -55
- package/website/src/components/repl/Prelude.tsx +0 -50
- package/website/src/components/repl/ShowError.tsx +0 -27
- package/website/src/components/repl/codemirror-lib.ts +0 -8
- package/website/src/components/repl/codemirror-theme.css +0 -131
- package/website/src/components/repl/compile/babel.ts +0 -21
- package/website/src/components/repl/eval/evalCallback.ts +0 -27
- package/website/src/components/repl/eval/evalCode.ts +0 -7
- package/website/src/components/repl/eval/evalExpression.ts +0 -4
- package/website/src/components/repl/eval/evalReactDomRender.ts +0 -23
- package/website/src/components/repl/index.ts +0 -1
- package/website/src/components/repl/runMode.ts +0 -42
- package/website/src/datastores/location.ts +0 -14
- package/website/src/datastores/page.ts +0 -11
- package/website/src/datastores/pageTransition.ts +0 -97
- package/website/src/entries/main.css +0 -2
- package/website/src/entries/main.tsx +0 -6
- package/website/src/examples/FizzBuzz/FizzBuzzExample.tsx +0 -39
- package/website/src/examples/FizzBuzz/index.tsx +0 -9
- package/website/src/examples/_utils/globalScope.ts +0 -45
- package/website/src/examples/animation/AnimationExample.tsx +0 -152
- package/website/src/examples/animation/easings.ts +0 -0
- package/website/src/examples/animation/index.tsx +0 -15
- package/website/src/examples/context/Context.example.jsx +0 -67
- package/website/src/examples/context/index.tsx +0 -9
- package/website/src/examples/errors/Errors.example.jsx +0 -69
- package/website/src/examples/errors/index.tsx +0 -9
- package/website/src/examples/event-handlers/EventHandlersExample.tsx +0 -48
- package/website/src/examples/event-handlers/index.tsx +0 -9
- package/website/src/examples/fetch/FetchExample.jsx +0 -43
- package/website/src/examples/fetch/a.txt +0 -1
- package/website/src/examples/fetch/b.txt +0 -1
- package/website/src/examples/fetch/index.tsx +0 -9
- package/website/src/examples/form-data/FormDataExample.jsx +0 -119
- package/website/src/examples/form-data/index.tsx +0 -12
- package/website/src/examples/form-data/storage.ts +0 -27
- package/website/src/examples/forward-ref/ForwardRefExample.tsx +0 -55
- package/website/src/examples/forward-ref/index.tsx +0 -9
- package/website/src/examples/hello-world/HelloWorld.example.jsx +0 -6
- package/website/src/examples/hello-world/index.tsx +0 -9
- package/website/src/examples/hooks-interop/HooksInterop.example.tsx +0 -42
- package/website/src/examples/hooks-interop/index.tsx +0 -9
- package/website/src/examples/passthrough-props/PassThroughPropsExample.jsx +0 -57
- package/website/src/examples/passthrough-props/index.tsx +0 -11
- package/website/src/examples/reactive-state/ReactiveState.example.jsx +0 -43
- package/website/src/examples/reactive-state/index.ts +0 -9
- package/website/src/examples/readme-examples/README.mdx +0 -0
- package/website/src/examples/readme-examples/index.ts +0 -11
- package/website/src/examples/shared-state/SharedState.example.tsx +0 -59
- package/website/src/examples/shared-state/index.tsx +0 -9
- package/website/src/examples/simple/Counter.example.tsx +0 -14
- package/website/src/examples/simple/index.tsx +0 -9
- package/website/src/examples/sync/Sync.example.tsx +0 -9
- package/website/src/examples/sync/index.tsx +0 -9
- package/website/src/examples/tick/TickExample.jsx +0 -51
- package/website/src/examples/tick/index.ts +0 -9
- package/website/src/examples/todo-app/TodoApp.example.tsx +0 -88
- package/website/src/examples/todo-app/index.tsx +0 -12
- package/website/src/examples/todo-app/storage.ts +0 -27
- package/website/src/examples/use-element/UseElementExample.tsx +0 -70
- package/website/src/examples/use-element/index.tsx +0 -9
- package/website/src/examples/use-observable/search/SearchExample.tsx +0 -82
- package/website/src/examples/use-observable/search/index.tsx +0 -8
- package/website/src/examples/use-observable/use-observable/UseObservableExample.tsx +0 -70
- package/website/src/examples/use-observable/use-observable/index.tsx +0 -9
- package/website/src/index.html +0 -10
- package/website/src/mdx-components.tsx +0 -74
- package/website/src/pages/Api/Api.mdx +0 -134
- package/website/src/pages/Api/ApiPage.tsx +0 -25
- package/website/src/pages/Examples/Examples.tsx +0 -105
- package/website/src/pages/Examples/ExamplesPage.tsx +0 -13
- package/website/src/pages/Guide/Guide.mdx +0 -275
- package/website/src/pages/Guide/GuidePage.tsx +0 -25
- package/website/src/pages/Index/IndexPage.tsx +0 -50
- package/website/src/pages/Index/ReactRxReadme.md +0 -20
- package/website/src/pages/NotFound.tsx +0 -3
- package/website/src/pages/pages.ts +0 -46
- package/website/src/pages/styles.tsx +0 -24
- package/website/src/theme.ts +0 -61
- package/website/src/utils/parseCodeFenceHeader.ts +0 -32
- package/website/tsconfig.json +0 -30
- package/website/vercel.json +0 -4
- package/website/webpack/config.js +0 -5
- package/website/webpack/createConfig.js +0 -95
- package/website/webpack/mdx-toc-loader.js +0 -38
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import {ChangeEvent, FormEvent} from 'react'
|
|
2
|
-
import {
|
|
3
|
-
combineLatest,
|
|
4
|
-
filter,
|
|
5
|
-
map,
|
|
6
|
-
mapTo,
|
|
7
|
-
merge,
|
|
8
|
-
operators,
|
|
9
|
-
React,
|
|
10
|
-
ReactDOM,
|
|
11
|
-
rxComponent,
|
|
12
|
-
scan,
|
|
13
|
-
startWith,
|
|
14
|
-
tap,
|
|
15
|
-
handler
|
|
16
|
-
} from '../_utils/globalScope'
|
|
17
|
-
import styled from 'styled-components'
|
|
18
|
-
//@endimport
|
|
19
|
-
|
|
20
|
-
const {withLatestFrom} = operators
|
|
21
|
-
|
|
22
|
-
interface TodoItem {
|
|
23
|
-
id: number
|
|
24
|
-
text: string
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const TodoApp = rxComponent(() => {
|
|
28
|
-
const [onInput$, handleInput] = handler<ChangeEvent<HTMLInputElement>>()
|
|
29
|
-
const [onSubmit$, handleSubmit] = handler<FormEvent<HTMLFormElement>>()
|
|
30
|
-
|
|
31
|
-
const text$ = onInput$.pipe(
|
|
32
|
-
map(e => e.currentTarget.value),
|
|
33
|
-
startWith('')
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
const items$ = onSubmit$.pipe(
|
|
37
|
-
tap(e => e.preventDefault()),
|
|
38
|
-
withLatestFrom(text$),
|
|
39
|
-
map(([_, text]) => text),
|
|
40
|
-
filter(text => text.length > 0),
|
|
41
|
-
map(text => ({text, id: Date.now()})),
|
|
42
|
-
scan((items: TodoItem[], item) => items.concat(item), []),
|
|
43
|
-
startWith([])
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
const inputValue$ = merge(text$, onSubmit$.pipe(mapTo('')))
|
|
47
|
-
|
|
48
|
-
return combineLatest([inputValue$, items$]).pipe(
|
|
49
|
-
map(([text, items]) => (
|
|
50
|
-
<Wrapper>
|
|
51
|
-
<h3>TODO</h3>
|
|
52
|
-
<TodoList items={items} />
|
|
53
|
-
<form onSubmit={handleSubmit}>
|
|
54
|
-
<label htmlFor="new-todo">What needs to be done?</label>
|
|
55
|
-
<input id="new-todo" onChange={handleInput} value={text} />
|
|
56
|
-
<button>Add #{items.length + 1}</button>
|
|
57
|
-
</form>
|
|
58
|
-
</Wrapper>
|
|
59
|
-
))
|
|
60
|
-
)
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
interface ListProps {
|
|
64
|
-
items: TodoItem[]
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function TodoList(props: ListProps) {
|
|
68
|
-
return (
|
|
69
|
-
<ul>
|
|
70
|
-
{props.items.map(item => (
|
|
71
|
-
<li key={item.id}>{item.text}</li>
|
|
72
|
-
))}
|
|
73
|
-
</ul>
|
|
74
|
-
)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
ReactDOM.render(<TodoApp />, document.getElementById('todo-app-example'))
|
|
78
|
-
|
|
79
|
-
const Wrapper = styled.div`
|
|
80
|
-
label {
|
|
81
|
-
display: block;
|
|
82
|
-
margin-top: 10px;
|
|
83
|
-
}
|
|
84
|
-
input {
|
|
85
|
-
width: 100%;
|
|
86
|
-
padding: 5px;
|
|
87
|
-
}
|
|
88
|
-
`
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import {Example} from '../../pages/Examples/Examples'
|
|
2
|
-
import storage from './storage'
|
|
3
|
-
import styled from 'styled-components'
|
|
4
|
-
|
|
5
|
-
const fs = require('fs')
|
|
6
|
-
|
|
7
|
-
export const TodoAppExample: Example = {
|
|
8
|
-
id: 'todo-app',
|
|
9
|
-
title: 'An Application',
|
|
10
|
-
scope: {storage, styled},
|
|
11
|
-
source: fs.readFileSync(`${__dirname}/TodoApp.example.tsx`, 'utf-8')
|
|
12
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import {Observable, of} from 'rxjs'
|
|
2
|
-
|
|
3
|
-
const tryParse = <T>(val: any, defaultValue: T): T => {
|
|
4
|
-
try {
|
|
5
|
-
return JSON.parse(val)
|
|
6
|
-
} catch (err) {
|
|
7
|
-
return defaultValue
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const get = <T>(key: string, defValue: T): Observable<T> => {
|
|
12
|
-
const val = localStorage.getItem(key)
|
|
13
|
-
return of(val === null ? defValue : tryParse<T>(val, defValue))
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const set = <T>(key: string, nextValue: T): Observable<T> => {
|
|
17
|
-
// Can't stringify undefined, and nulls are what
|
|
18
|
-
// `getItem` returns when key does not exist
|
|
19
|
-
if (typeof nextValue === 'undefined' || nextValue === null) {
|
|
20
|
-
localStorage.removeItem(key)
|
|
21
|
-
} else {
|
|
22
|
-
localStorage.setItem(key, JSON.stringify(nextValue))
|
|
23
|
-
}
|
|
24
|
-
return of(nextValue)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export default {get, set}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
map,
|
|
3
|
-
elementRef,
|
|
4
|
-
operators,
|
|
5
|
-
React,
|
|
6
|
-
ReactDOM,
|
|
7
|
-
rxComponent,
|
|
8
|
-
timer
|
|
9
|
-
} from '../_utils/globalScope'
|
|
10
|
-
|
|
11
|
-
//@endimport
|
|
12
|
-
|
|
13
|
-
const {withLatestFrom} = operators
|
|
14
|
-
|
|
15
|
-
const STYLE: React.CSSProperties = {
|
|
16
|
-
textAlign: 'center',
|
|
17
|
-
border: '1px dashed'
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const SPEED = 2
|
|
21
|
-
const unpx = (v: string) => Number(v.replace(/px$/, ''))
|
|
22
|
-
|
|
23
|
-
const UseElementExample = rxComponent(() => {
|
|
24
|
-
const [element$, ref] = elementRef<HTMLElement>()
|
|
25
|
-
|
|
26
|
-
const count$ = timer(0, 16).pipe(
|
|
27
|
-
map((n) => n % 400),
|
|
28
|
-
map((n) => (n > 200 ? -1 : 1))
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
return count$.pipe(
|
|
32
|
-
withLatestFrom(element$),
|
|
33
|
-
map(([direction, element]) => {
|
|
34
|
-
const Tag = direction === 1 ? 'section' : 'article'
|
|
35
|
-
return (
|
|
36
|
-
<div style={{height: '20em', display: 'flex', alignItems: 'center'}}>
|
|
37
|
-
<Tag
|
|
38
|
-
// this connects the element$ observable to the actual element
|
|
39
|
-
ref={ref}
|
|
40
|
-
style={{
|
|
41
|
-
...STYLE,
|
|
42
|
-
backgroundColor: Tag == 'article' ? '#335186' : '#90441a',
|
|
43
|
-
borderRadius:
|
|
44
|
-
unpx(element?.style.borderRadius || '20px') +
|
|
45
|
-
direction * SPEED * -0.1,
|
|
46
|
-
height: (element?.clientHeight || 0) + direction * SPEED,
|
|
47
|
-
width: (element?.clientWidth || 0) + direction * SPEED
|
|
48
|
-
}}
|
|
49
|
-
>
|
|
50
|
-
<div
|
|
51
|
-
style={{
|
|
52
|
-
...(element && {fontSize: element.clientHeight / 5}),
|
|
53
|
-
width: '100%',
|
|
54
|
-
height: '100%',
|
|
55
|
-
lineHeight: '500%'
|
|
56
|
-
}}
|
|
57
|
-
>
|
|
58
|
-
{`<${Tag}>`}
|
|
59
|
-
</div>
|
|
60
|
-
</Tag>
|
|
61
|
-
</div>
|
|
62
|
-
)
|
|
63
|
-
})
|
|
64
|
-
)
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
ReactDOM.render(
|
|
68
|
-
<UseElementExample />,
|
|
69
|
-
document.getElementById('use-element-example')
|
|
70
|
-
)
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
map,
|
|
3
|
-
React,
|
|
4
|
-
ReactDOM,
|
|
5
|
-
timer,
|
|
6
|
-
useMemoObservable,
|
|
7
|
-
of,
|
|
8
|
-
operators,
|
|
9
|
-
filter,
|
|
10
|
-
switchMap
|
|
11
|
-
} from '../../_utils/globalScope'
|
|
12
|
-
import {Observable} from 'rxjs'
|
|
13
|
-
//@endimport
|
|
14
|
-
|
|
15
|
-
const {distinctUntilChanged, debounceTime} = operators
|
|
16
|
-
|
|
17
|
-
interface SearchResult {
|
|
18
|
-
keyword: string
|
|
19
|
-
hits: Hit[]
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
interface Hit {
|
|
23
|
-
title: string
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const range = (len: number) => {
|
|
27
|
-
const res = []
|
|
28
|
-
for (let i = 0; i <= len; i++) {
|
|
29
|
-
res.push(null)
|
|
30
|
-
}
|
|
31
|
-
return res
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// A search function that takes longer time to complete for shorter keywords
|
|
35
|
-
// e.g. a keyword of one character takes 9 seconds while a keyword of 9 characters takes 1 second
|
|
36
|
-
const search = (keyword: string): Observable<SearchResult> => {
|
|
37
|
-
const delay = Math.max(1, Math.round(10 - keyword.length))
|
|
38
|
-
return timer(delay * 200).pipe(
|
|
39
|
-
map(() => range(delay).map((_, i) => ({title: `Hit #${i}`}))),
|
|
40
|
-
map((hits) => ({keyword, hits}))
|
|
41
|
-
)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function SearchExample() {
|
|
45
|
-
const [keyword, setKeyword] = React.useState('')
|
|
46
|
-
return (
|
|
47
|
-
<>
|
|
48
|
-
<input
|
|
49
|
-
type="search"
|
|
50
|
-
style={{width: '100%'}}
|
|
51
|
-
value={keyword}
|
|
52
|
-
placeholder="Type a keyword to search"
|
|
53
|
-
onChange={(event) => setKeyword(event.target.value)}
|
|
54
|
-
/>
|
|
55
|
-
<div>
|
|
56
|
-
The more characters you type, the faster the results will appear
|
|
57
|
-
</div>
|
|
58
|
-
{useMemoObservable(() =>
|
|
59
|
-
of(keyword).pipe(
|
|
60
|
-
debounceTime(200),
|
|
61
|
-
distinctUntilChanged(),
|
|
62
|
-
filter((v) => v !== ''),
|
|
63
|
-
switchMap((kw: string) => search(kw)),
|
|
64
|
-
map((result: SearchResult) => (
|
|
65
|
-
<>
|
|
66
|
-
<h1>Searched for {result.keyword}</h1>
|
|
67
|
-
<div>Got {result.hits.length} hits</div>
|
|
68
|
-
<ul>
|
|
69
|
-
{result.hits.map((hit, i) => (
|
|
70
|
-
<li key={i}>{hit.title}</li>
|
|
71
|
-
))}
|
|
72
|
-
</ul>
|
|
73
|
-
</>
|
|
74
|
-
))
|
|
75
|
-
),
|
|
76
|
-
[keyword]
|
|
77
|
-
)}
|
|
78
|
-
</>
|
|
79
|
-
)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
ReactDOM.render(<SearchExample />, document.getElementById('search-example'))
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import * as React from 'react'
|
|
2
|
-
import {Observable, of, timer} from 'rxjs'
|
|
3
|
-
import {ReactDOM, useMemoObservable} from '../../_utils/globalScope'
|
|
4
|
-
import {observableCallback} from 'observable-callback'
|
|
5
|
-
import {map, startWith, switchMap} from 'rxjs/operators'
|
|
6
|
-
//@endimport
|
|
7
|
-
|
|
8
|
-
const justNumbers$ = timer(0, 500)
|
|
9
|
-
|
|
10
|
-
const numberReactElement$ = justNumbers$.pipe(
|
|
11
|
-
map((num) => <div>The number is {num}!</div>)
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
const [onSpeedChange$, onSpeedChange] = observableCallback<
|
|
15
|
-
React.SyntheticEvent<HTMLInputElement>
|
|
16
|
-
>()
|
|
17
|
-
|
|
18
|
-
const speed$: Observable<number> = onSpeedChange$.pipe(
|
|
19
|
-
map((event) => Number(event.currentTarget.value)),
|
|
20
|
-
startWith(1000)
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
const UseObservableExample = () => (
|
|
24
|
-
<>
|
|
25
|
-
<h2>An observable of react elements</h2>
|
|
26
|
-
{useMemoObservable(of(<div>HELLO SYNC</div>), [])}
|
|
27
|
-
{useMemoObservable(numberReactElement$.pipe(startWith(2)), [])}
|
|
28
|
-
<h2>An observable with child as render func</h2>
|
|
29
|
-
{useMemoObservable(
|
|
30
|
-
timer(0, 100).pipe(
|
|
31
|
-
startWith(2),
|
|
32
|
-
map((num) => <>The number is {num}</>)
|
|
33
|
-
),
|
|
34
|
-
[]
|
|
35
|
-
)}
|
|
36
|
-
|
|
37
|
-
<h2>Nested</h2>
|
|
38
|
-
<p>You can adjust the update speed by changing update interval below</p>
|
|
39
|
-
{useMemoObservable(
|
|
40
|
-
() =>
|
|
41
|
-
speed$.pipe(
|
|
42
|
-
switchMap(
|
|
43
|
-
(speed: number): Observable<[number, number]> =>
|
|
44
|
-
timer(0, speed).pipe(
|
|
45
|
-
map((update): [number, number] => [speed, update])
|
|
46
|
-
)
|
|
47
|
-
),
|
|
48
|
-
map(([speed, update]: [number, number]) => (
|
|
49
|
-
<>
|
|
50
|
-
Update interval:
|
|
51
|
-
<input
|
|
52
|
-
type="number"
|
|
53
|
-
value={speed}
|
|
54
|
-
onChange={onSpeedChange}
|
|
55
|
-
step={200}
|
|
56
|
-
min={0}
|
|
57
|
-
/>
|
|
58
|
-
<div>Update {update}</div>
|
|
59
|
-
</>
|
|
60
|
-
))
|
|
61
|
-
),
|
|
62
|
-
[]
|
|
63
|
-
)}
|
|
64
|
-
</>
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
ReactDOM.render(
|
|
68
|
-
<UseObservableExample />,
|
|
69
|
-
document.getElementById('use-observable-example')
|
|
70
|
-
)
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import {Example} from '../../../pages/Examples/Examples'
|
|
2
|
-
|
|
3
|
-
const fs = require('fs')
|
|
4
|
-
|
|
5
|
-
export const UseObservableExample: Example = {
|
|
6
|
-
id: 'use-observable',
|
|
7
|
-
title: 'Use observable',
|
|
8
|
-
source: fs.readFileSync(`${__dirname}/UseObservableExample.tsx`, 'utf-8')
|
|
9
|
-
}
|
package/website/src/index.html
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import {CodeMirrorMode} from './components/repl/CodeMirrorMode'
|
|
2
|
-
|
|
3
|
-
import * as React from 'react'
|
|
4
|
-
import styled from 'styled-components'
|
|
5
|
-
import {rxComponent} from 'react-rx'
|
|
6
|
-
import {map} from 'rxjs/operators'
|
|
7
|
-
import {combineLatest} from 'rxjs'
|
|
8
|
-
import {location$} from './datastores/location'
|
|
9
|
-
import {parseCodeFenceHeader} from './utils/parseCodeFenceHeader'
|
|
10
|
-
import {ModeSpec} from './components/repl/runMode'
|
|
11
|
-
|
|
12
|
-
const ModeWrapper = styled.div`
|
|
13
|
-
color: #fff;
|
|
14
|
-
`
|
|
15
|
-
|
|
16
|
-
const InlineCode = styled.code`
|
|
17
|
-
font-size: 0.9em;
|
|
18
|
-
background-color: #e4e4e4;
|
|
19
|
-
padding: 1px 4px;
|
|
20
|
-
border-radius: 2px;
|
|
21
|
-
`
|
|
22
|
-
|
|
23
|
-
const CODEMIRROR_TSX_MODE: ModeSpec = {
|
|
24
|
-
name: 'jsx',
|
|
25
|
-
base: {name: 'javascript', typescript: true}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const TSX_MODE_TYPES = ['js', 'jsx', 'tsx', 'ts']
|
|
29
|
-
|
|
30
|
-
interface InlineCodeProps {
|
|
31
|
-
children: string
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
interface CodeProps {
|
|
35
|
-
children: string
|
|
36
|
-
className: 'language-js' | 'language-jsx' | 'language-tsx'
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export const components = {
|
|
40
|
-
inlineCode: InlineCode,
|
|
41
|
-
code: (props: CodeProps) => {
|
|
42
|
-
const [lang, range] = parseCodeFenceHeader(
|
|
43
|
-
props.className.replace(/^language-/, '')
|
|
44
|
-
)
|
|
45
|
-
const mode =
|
|
46
|
-
lang && TSX_MODE_TYPES.includes(lang) ? CODEMIRROR_TSX_MODE : null
|
|
47
|
-
return (
|
|
48
|
-
<ModeWrapper>
|
|
49
|
-
<CodeMirrorMode highlighted={range} mode={mode}>
|
|
50
|
-
{props.children}
|
|
51
|
-
</CodeMirrorMode>
|
|
52
|
-
</ModeWrapper>
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const hash$ = location$.pipe(map(location => location.hash))
|
|
58
|
-
|
|
59
|
-
const BookmarkedLink = rxComponent<{
|
|
60
|
-
href: string
|
|
61
|
-
children: React.ReactNode
|
|
62
|
-
}>(props$ =>
|
|
63
|
-
combineLatest([props$, hash$]).pipe(
|
|
64
|
-
map(([props, hash]) => (
|
|
65
|
-
<a href={props.href} className={hash === props.href ? 'selected' : ''}>
|
|
66
|
-
{props.children}
|
|
67
|
-
</a>
|
|
68
|
-
))
|
|
69
|
-
)
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
export const tocComponents = {
|
|
73
|
-
a: BookmarkedLink
|
|
74
|
-
}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
# Reactive Component
|
|
2
|
-
|
|
3
|
-
## component()
|
|
4
|
-
|
|
5
|
-
**Signature**
|
|
6
|
-
|
|
7
|
-
```ts
|
|
8
|
-
function component<Props>(
|
|
9
|
-
observable: Observable<Props>
|
|
10
|
-
): React.FunctionComponent<{}>
|
|
11
|
-
function component<Props>(
|
|
12
|
-
component: Component<Props>
|
|
13
|
-
): React.FunctionComponent<Props>
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
**Usage**
|
|
17
|
-
|
|
18
|
-
```ts
|
|
19
|
-
import * as ReactRx from 'react-rx'
|
|
20
|
-
|
|
21
|
-
export const MyComponent = ReactRx.component(props$ =>
|
|
22
|
-
props$.pipe(map(props => <div>...</div>))
|
|
23
|
-
)
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## forwardRef()
|
|
27
|
-
|
|
28
|
-
The `React.forwardRef()` equivalent for a Reactive component.
|
|
29
|
-
|
|
30
|
-
** Signature **
|
|
31
|
-
|
|
32
|
-
```ts
|
|
33
|
-
function forwardRef<Props, Ref>(
|
|
34
|
-
component: (
|
|
35
|
-
input$: Observable<Props>,
|
|
36
|
-
ref: React.RefObject<Ref>
|
|
37
|
-
) => React.FunctionComponent<Props>
|
|
38
|
-
)
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
**Usage**
|
|
42
|
-
|
|
43
|
-
```js
|
|
44
|
-
import * as ReactRx from 'react-rx'
|
|
45
|
-
|
|
46
|
-
const MyInputWrapper = ReactRx.forwardRef((props$, ref) =>
|
|
47
|
-
props$.pipe(
|
|
48
|
-
map(props => (
|
|
49
|
-
<input
|
|
50
|
-
ref={ref}
|
|
51
|
-
type="text"
|
|
52
|
-
value={props.value}
|
|
53
|
-
onChange={props.onChange}
|
|
54
|
-
/>
|
|
55
|
-
))
|
|
56
|
-
)
|
|
57
|
-
)
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## useState()
|
|
61
|
-
|
|
62
|
-
Equivalent to `React.useState()` with the only difference that instead of the stateful value, it returns an observable representing the state changes (e.g. instead of `[T, update(value: T)]`, it returns `[Observable<T>, update(value: T)]`.
|
|
63
|
-
|
|
64
|
-
**Signature**
|
|
65
|
-
|
|
66
|
-
```ts
|
|
67
|
-
function useState<T = undefined>(): [
|
|
68
|
-
Observable<T | undefined>,
|
|
69
|
-
React.Dispatch<React.SetStateAction<T | undefined>>
|
|
70
|
-
]
|
|
71
|
-
function useState<T>(
|
|
72
|
-
initial: T | (() => T)
|
|
73
|
-
): [Observable<T>, React.Dispatch<React.SetStateAction<T>>]
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## useContext()
|
|
77
|
-
|
|
78
|
-
Equivalent to `React.useContext()` with the only difference that instead of a stateful context value, it returns an observable representing the context value changes.
|
|
79
|
-
|
|
80
|
-
** Signature **
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
function useContext<T>(context: React.Context<T>): Observable<T>
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## useEvent()
|
|
87
|
-
|
|
88
|
-
This has no React API equivalent, but creates a `[Observable<Event>, (Event) => void]` tuple, where the first value is an observable of the arguments the second function is called with.
|
|
89
|
-
|
|
90
|
-
**Signature**
|
|
91
|
-
|
|
92
|
-
```ts
|
|
93
|
-
function useObservableEvent<Event>(): [
|
|
94
|
-
Observable<Event>,
|
|
95
|
-
(event: Event) => void
|
|
96
|
-
]
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## toObservable()
|
|
100
|
-
|
|
101
|
-
Converts any value inside a Functional React component to an observable of changes to that value.
|
|
102
|
-
|
|
103
|
-
```ts
|
|
104
|
-
function toObservable<T>(value: T): Observable<T>
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
# React hooks
|
|
108
|
-
|
|
109
|
-
## useObservable()
|
|
110
|
-
|
|
111
|
-
A React hook that returns the current/latest value from an observable
|
|
112
|
-
|
|
113
|
-
**Signature**
|
|
114
|
-
|
|
115
|
-
```ts
|
|
116
|
-
function useObservable<T>(observable$: Observable<T>): T | null
|
|
117
|
-
function useObservable<T>(observable$: Observable<T>, initialValue: T): T
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## useObservableState()
|
|
121
|
-
|
|
122
|
-
Same as `useState()` described in the Reactive Component section above, exported under a different name for clarity when using in regular React components
|
|
123
|
-
|
|
124
|
-
## useObservableContext()
|
|
125
|
-
|
|
126
|
-
Same as `useContext()` described in the Reactive Component section above, exported under a different name for clarity when using in regular React components
|
|
127
|
-
|
|
128
|
-
## useObservableEvent()
|
|
129
|
-
|
|
130
|
-
Same as `useEvent()` described in the Reactive Component section above, exported under a different name for clarity when using in regular React components
|
|
131
|
-
|
|
132
|
-
## toObservable()
|
|
133
|
-
|
|
134
|
-
Same as `toObservable()` described in the Reactive Component section above
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import {Header} from '../../components/Header'
|
|
2
|
-
import {Container, Content} from '../styles'
|
|
3
|
-
import MDXContent, {Toc} from './Api.mdx'
|
|
4
|
-
import * as React from 'react'
|
|
5
|
-
import {MDXProvider} from '@mdx-js/react'
|
|
6
|
-
import {components, tocComponents} from '../../mdx-components'
|
|
7
|
-
import {Sidebar} from '../../components/Sidebar'
|
|
8
|
-
|
|
9
|
-
export const ApiPage = () => (
|
|
10
|
-
<>
|
|
11
|
-
<Header />
|
|
12
|
-
<Container>
|
|
13
|
-
<Sidebar heading="API Reference">
|
|
14
|
-
<MDXProvider components={tocComponents}>
|
|
15
|
-
<Toc />
|
|
16
|
-
</MDXProvider>
|
|
17
|
-
</Sidebar>
|
|
18
|
-
<Content>
|
|
19
|
-
<MDXProvider components={components}>
|
|
20
|
-
<MDXContent />
|
|
21
|
-
</MDXProvider>
|
|
22
|
-
</Content>
|
|
23
|
-
</Container>
|
|
24
|
-
</>
|
|
25
|
-
)
|