react-rx 1.0.0-beta.6 → 2.0.0

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.
Files changed (128) hide show
  1. package/.idea/compiler.xml +1 -1
  2. package/.idea/inspectionProfiles/Project_Default.xml +1 -0
  3. package/.idea/markdown.xml +9 -0
  4. package/.idea/misc.xml +0 -6
  5. package/dist/cjs/WithObservable.js +3 -3
  6. package/dist/cjs/displayName.js +1 -1
  7. package/dist/cjs/reactiveComponent.js +6 -6
  8. package/dist/cjs/useAsObservable.js +10 -18
  9. package/dist/cjs/useObservable.js +26 -31
  10. package/dist/cjs/useObservableCallback.js +4 -4
  11. package/dist/cjs/useWithObservable.js +2 -2
  12. package/dist/cjs/utils.js +7 -7
  13. package/dist/cjs/withPropsStream.js +8 -4
  14. package/dist/es2015/useAsObservable.js +10 -18
  15. package/dist/es2015/useObservable.js +24 -31
  16. package/dist/esm/displayName.js +1 -1
  17. package/dist/esm/useAsObservable.js +10 -18
  18. package/dist/esm/useObservable.js +26 -31
  19. package/package.json +5 -3
  20. package/src/useAsObservable.ts +13 -18
  21. package/src/useObservable.ts +39 -34
  22. package/.idea/workspace.xml +0 -228
  23. package/jest.config.js +0 -5
  24. package/website/.babelrc +0 -21
  25. package/website/.prettierrc +0 -7
  26. package/website/README.mdx +0 -1
  27. package/website/package.json +0 -84
  28. package/website/src/@types/babel.d.ts +0 -4
  29. package/website/src/@types/mdx.d.ts +0 -11
  30. package/website/src/@types/react-css-burger.d.ts +0 -4
  31. package/website/src/App.tsx +0 -68
  32. package/website/src/components/Header.tsx +0 -118
  33. package/website/src/components/Link.tsx +0 -18
  34. package/website/src/components/LoadPage.tsx +0 -60
  35. package/website/src/components/Sidebar.tsx +0 -88
  36. package/website/src/components/logos/Github.tsx +0 -10
  37. package/website/src/components/logos/React.tsx +0 -27
  38. package/website/src/components/logos/ReactRxLogo.tsx +0 -39
  39. package/website/src/components/logos/RxJs.tsx +0 -69
  40. package/website/src/components/repl/Checkerboard.tsx +0 -25
  41. package/website/src/components/repl/CodeBlock.tsx +0 -147
  42. package/website/src/components/repl/CodeMirror.tsx +0 -37
  43. package/website/src/components/repl/CodeMirrorMode.tsx +0 -67
  44. package/website/src/components/repl/EvalCode.tsx +0 -55
  45. package/website/src/components/repl/Prelude.tsx +0 -50
  46. package/website/src/components/repl/ShowError.tsx +0 -27
  47. package/website/src/components/repl/codemirror-lib.ts +0 -8
  48. package/website/src/components/repl/codemirror-theme.css +0 -131
  49. package/website/src/components/repl/compile/babel.ts +0 -21
  50. package/website/src/components/repl/eval/evalCallback.ts +0 -27
  51. package/website/src/components/repl/eval/evalCode.ts +0 -7
  52. package/website/src/components/repl/eval/evalExpression.ts +0 -4
  53. package/website/src/components/repl/eval/evalReactDomRender.ts +0 -23
  54. package/website/src/components/repl/index.ts +0 -1
  55. package/website/src/components/repl/runMode.ts +0 -42
  56. package/website/src/datastores/location.ts +0 -14
  57. package/website/src/datastores/page.ts +0 -11
  58. package/website/src/datastores/pageTransition.ts +0 -97
  59. package/website/src/entries/main.css +0 -2
  60. package/website/src/entries/main.tsx +0 -6
  61. package/website/src/examples/FizzBuzz/FizzBuzzExample.tsx +0 -39
  62. package/website/src/examples/FizzBuzz/index.tsx +0 -9
  63. package/website/src/examples/_utils/globalScope.ts +0 -45
  64. package/website/src/examples/animation/AnimationExample.tsx +0 -152
  65. package/website/src/examples/animation/easings.ts +0 -0
  66. package/website/src/examples/animation/index.tsx +0 -15
  67. package/website/src/examples/context/Context.example.jsx +0 -67
  68. package/website/src/examples/context/index.tsx +0 -9
  69. package/website/src/examples/errors/Errors.example.jsx +0 -69
  70. package/website/src/examples/errors/index.tsx +0 -9
  71. package/website/src/examples/event-handlers/EventHandlersExample.tsx +0 -48
  72. package/website/src/examples/event-handlers/index.tsx +0 -9
  73. package/website/src/examples/fetch/FetchExample.jsx +0 -43
  74. package/website/src/examples/fetch/a.txt +0 -1
  75. package/website/src/examples/fetch/b.txt +0 -1
  76. package/website/src/examples/fetch/index.tsx +0 -9
  77. package/website/src/examples/form-data/FormDataExample.jsx +0 -119
  78. package/website/src/examples/form-data/index.tsx +0 -12
  79. package/website/src/examples/form-data/storage.ts +0 -27
  80. package/website/src/examples/forward-ref/ForwardRefExample.tsx +0 -55
  81. package/website/src/examples/forward-ref/index.tsx +0 -9
  82. package/website/src/examples/hello-world/HelloWorld.example.jsx +0 -6
  83. package/website/src/examples/hello-world/index.tsx +0 -9
  84. package/website/src/examples/hooks-interop/HooksInterop.example.tsx +0 -42
  85. package/website/src/examples/hooks-interop/index.tsx +0 -9
  86. package/website/src/examples/passthrough-props/PassThroughPropsExample.jsx +0 -57
  87. package/website/src/examples/passthrough-props/index.tsx +0 -11
  88. package/website/src/examples/reactive-state/ReactiveState.example.jsx +0 -43
  89. package/website/src/examples/reactive-state/index.ts +0 -9
  90. package/website/src/examples/readme-examples/README.mdx +0 -0
  91. package/website/src/examples/readme-examples/index.ts +0 -11
  92. package/website/src/examples/shared-state/SharedState.example.tsx +0 -59
  93. package/website/src/examples/shared-state/index.tsx +0 -9
  94. package/website/src/examples/simple/Counter.example.tsx +0 -14
  95. package/website/src/examples/simple/index.tsx +0 -9
  96. package/website/src/examples/sync/Sync.example.tsx +0 -9
  97. package/website/src/examples/sync/index.tsx +0 -9
  98. package/website/src/examples/tick/TickExample.jsx +0 -51
  99. package/website/src/examples/tick/index.ts +0 -9
  100. package/website/src/examples/todo-app/TodoApp.example.tsx +0 -88
  101. package/website/src/examples/todo-app/index.tsx +0 -12
  102. package/website/src/examples/todo-app/storage.ts +0 -27
  103. package/website/src/examples/use-element/UseElementExample.tsx +0 -70
  104. package/website/src/examples/use-element/index.tsx +0 -9
  105. package/website/src/examples/use-observable/search/SearchExample.tsx +0 -82
  106. package/website/src/examples/use-observable/search/index.tsx +0 -8
  107. package/website/src/examples/use-observable/use-observable/UseObservableExample.tsx +0 -70
  108. package/website/src/examples/use-observable/use-observable/index.tsx +0 -9
  109. package/website/src/index.html +0 -10
  110. package/website/src/mdx-components.tsx +0 -74
  111. package/website/src/pages/Api/Api.mdx +0 -134
  112. package/website/src/pages/Api/ApiPage.tsx +0 -25
  113. package/website/src/pages/Examples/Examples.tsx +0 -105
  114. package/website/src/pages/Examples/ExamplesPage.tsx +0 -13
  115. package/website/src/pages/Guide/Guide.mdx +0 -275
  116. package/website/src/pages/Guide/GuidePage.tsx +0 -25
  117. package/website/src/pages/Index/IndexPage.tsx +0 -50
  118. package/website/src/pages/Index/ReactRxReadme.md +0 -20
  119. package/website/src/pages/NotFound.tsx +0 -3
  120. package/website/src/pages/pages.ts +0 -46
  121. package/website/src/pages/styles.tsx +0 -24
  122. package/website/src/theme.ts +0 -61
  123. package/website/src/utils/parseCodeFenceHeader.ts +0 -32
  124. package/website/tsconfig.json +0 -30
  125. package/website/vercel.json +0 -4
  126. package/website/webpack/config.js +0 -5
  127. package/website/webpack/createConfig.js +0 -95
  128. package/website/webpack/mdx-toc-loader.js +0 -38
@@ -1,42 +0,0 @@
1
- import {
2
- forwardRef,
3
- map,
4
- React,
5
- ReactDOM,
6
- rxComponent,
7
- useAsObservable
8
- } from '../_utils/globalScope'
9
- import {combineLatest, timer} from 'rxjs'
10
- //@endimport
11
-
12
- const ticks$ = timer(0, 1000)
13
-
14
- function useClickCounter(): [number, () => void] {
15
- const [clickCount, setClickCount] = React.useState(0)
16
- const inc = React.useCallback(() => setClickCount((c) => c + 1), [])
17
-
18
- return [clickCount, inc]
19
- }
20
-
21
- const HooksInteropExample = rxComponent(() => {
22
- const [clickCount, inc] = useClickCounter()
23
-
24
- // This is required in order to turn clickCount into an observable value
25
- const click$ = useAsObservable(clickCount)
26
-
27
- return combineLatest([click$, ticks$]).pipe(
28
- map(([clickCount, tickNumber]) => (
29
- <>
30
- Tick: {tickNumber}
31
- <button onClick={inc}>
32
- This button has been clicked {clickCount} times
33
- </button>
34
- </>
35
- ))
36
- )
37
- })
38
-
39
- ReactDOM.render(
40
- <HooksInteropExample />,
41
- document.getElementById('forward-ref-example')
42
- )
@@ -1,9 +0,0 @@
1
- import {Example} from '../../pages/Examples/Examples'
2
-
3
- const fs = require('fs')
4
-
5
- export const HooksInteropExample: Example = {
6
- id: 'hooks-interop',
7
- title: 'React hooks interop',
8
- source: fs.readFileSync(`${__dirname}/HooksInterop.example.tsx`, 'utf-8')
9
- }
@@ -1,57 +0,0 @@
1
- import {
2
- combineLatest,
3
- map,
4
- React,
5
- ReactDOM,
6
- rxComponent,
7
- take,
8
- timer
9
- } from '../_utils/globalScope'
10
- import {formatDistance} from 'date-fns'
11
- //@endimport
12
-
13
- const {share} = operators
14
-
15
- const UPDATE_INTERVAL = 1000
16
- const currentTime$ = timer(0, UPDATE_INTERVAL).pipe(
17
- take(10),
18
- map(() => new Date()),
19
- share()
20
- )
21
-
22
- const TimeDistance = rxComponent(props$ =>
23
- combineLatest([currentTime$, props$]).pipe(
24
- map(([currentTime, ownerProps]) =>
25
- formatDistance(ownerProps.time, currentTime, {
26
- includeSeconds: ownerProps.includeSeconds
27
- })
28
- )
29
- )
30
- )
31
-
32
- const NOW = new Date()
33
- const PassThroughPropsExample = () => (
34
- <>
35
- <h2>
36
- With <code>includeSeconds</code> true
37
- </h2>
38
- With synchronized updates
39
- <p>
40
- Page loaded <TimeDistance time={NOW} includeSeconds /> ago
41
- </p>
42
- <p>
43
- Page loaded <TimeDistance time={NOW} includeSeconds /> ago
44
- </p>
45
- <h2>
46
- Without <code>includeSeconds</code>
47
- </h2>
48
- <p>
49
- Page loaded <TimeDistance time={NOW} /> ago
50
- </p>
51
- </>
52
- )
53
-
54
- ReactDOM.render(
55
- <PassThroughPropsExample />,
56
- document.getElementById('pass-through-props-example')
57
- )
@@ -1,11 +0,0 @@
1
- import {Example} from '../../pages/Examples/Examples'
2
- import {formatDistance} from 'date-fns'
3
-
4
- const fs = require('fs')
5
-
6
- export const PassThroughPropsExample: Example = {
7
- id: 'pass-through-props',
8
- title: 'Pass through props',
9
- scope: {formatDistance},
10
- source: fs.readFileSync(`${__dirname}/PassThroughPropsExample.jsx`, 'utf-8')
11
- }
@@ -1,43 +0,0 @@
1
- import {
2
- map,
3
- React,
4
- ReactDOM,
5
- rxComponent,
6
- startWith,
7
- switchMap,
8
- timer,
9
- state
10
- } from '../_utils/globalScope'
11
- //@endimport
12
-
13
- const ReactiveStateExample = rxComponent(() => {
14
- const [delay$, setDelay] = state(100)
15
-
16
- return delay$.pipe(
17
- switchMap(delay =>
18
- timer(500, delay).pipe(
19
- map(n => `Count: ${n}`),
20
- startWith('Starting counter…'),
21
- map(label => (
22
- <>
23
- Counter interval (ms):{' '}
24
- <input
25
- type="range"
26
- min={0}
27
- max={1000}
28
- step={100}
29
- onChange={e => setDelay(Number(e.currentTarget.value))}
30
- />
31
- {delay}
32
- <div>{label}</div>
33
- </>
34
- ))
35
- )
36
- )
37
- )
38
- })
39
-
40
- ReactDOM.render(
41
- <ReactiveStateExample />,
42
- document.getElementById('use-state-example')
43
- )
@@ -1,9 +0,0 @@
1
- import {Example} from '../../pages/Examples/Examples'
2
-
3
- const fs = require('fs')
4
-
5
- export const ReactiveStateExample: Example = {
6
- id: 'reactive-state',
7
- title: 'Reactive component state',
8
- source: fs.readFileSync(`${__dirname}/ReactiveState.example.jsx`, 'utf-8')
9
- }
File without changes
@@ -1,11 +0,0 @@
1
- import ReadmeExamples from './README.mdx'
2
-
3
- const fs = require('fs')
4
-
5
- export default {
6
- name: 'readme-examples',
7
- component: ReadmeExamples,
8
- title: 'Readme examples',
9
- type: 'mixed',
10
- source: fs.readFileSync(`${__dirname}/ReadmeExamples.tsx`, 'utf-8')
11
- }
@@ -1,59 +0,0 @@
1
- import {
2
- map,
3
- of,
4
- React,
5
- ReactDOM,
6
- rxComponent,
7
- scan
8
- } from '../_utils/globalScope'
9
-
10
- import {observableCallback} from 'observable-callback'
11
- import {CSSProperties} from 'react'
12
- //@endimport
13
-
14
- const CONTAINER: CSSProperties = {
15
- display: 'flex',
16
- alignItems: 'center',
17
- position: 'relative',
18
- height: 200,
19
- width: 200,
20
- textAlign: 'center'
21
- }
22
-
23
- const BADGE: CSSProperties = {
24
- borderRadius: 26,
25
- backgroundColor: 'red',
26
- padding: 4,
27
- height: 26,
28
- width: 26
29
- }
30
-
31
- const [clicks$, click] = observableCallback()
32
- const clickCount$ = clicks$.pipe(scan((count) => count + 1, 0))
33
-
34
- const ClickCountBadge = rxComponent(
35
- clickCount$.pipe(map((clicks) => <span style={BADGE}>{clicks}</span>))
36
- )
37
-
38
- const Clicker = rxComponent(of(<button onClick={click}>CLICK ME!</button>))
39
-
40
- const Example = (
41
- <div style={CONTAINER}>
42
- <div style={{position: 'absolute', top: 0, left: 0}}>
43
- <ClickCountBadge />
44
- </div>
45
- <div style={{position: 'absolute', top: 0, right: 0}}>
46
- <ClickCountBadge />
47
- </div>
48
- <div style={{width: '100%'}}>
49
- <Clicker />
50
- </div>
51
- <div style={{position: 'absolute', bottom: 0, left: 0}}>
52
- <ClickCountBadge />
53
- </div>
54
- <div style={{position: 'absolute', bottom: 0, right: 0}}>
55
- <ClickCountBadge />
56
- </div>
57
- </div>
58
- )
59
- ReactDOM.render(Example, document.getElementById('shared-state-example'))
@@ -1,9 +0,0 @@
1
- import {Example} from '../../pages/Examples/Examples'
2
-
3
- const fs = require('fs')
4
-
5
- export const SharedStateExample: Example = {
6
- id: 'shared-state',
7
- title: 'Sharing state',
8
- source: fs.readFileSync(`${__dirname}/SharedState.example.tsx`, 'utf-8')
9
- }
@@ -1,14 +0,0 @@
1
- import {
2
- map,
3
- React,
4
- ReactDOM,
5
- rxComponent,
6
- timer
7
- } from '../_utils/globalScope'
8
- //@endimport
9
-
10
- const Counter = rxComponent(
11
- timer(0, 1000).pipe(map(seconds => <>Seconds: {seconds}</>))
12
- )
13
-
14
- ReactDOM.render(<Counter />, document.getElementById('counter-example'))
@@ -1,9 +0,0 @@
1
- import {Example} from '../../pages/Examples/Examples'
2
-
3
- const fs = require('fs')
4
-
5
- export const SimpleExample: Example = {
6
- id: 'stateful-component',
7
- title: 'A stateful component',
8
- source: fs.readFileSync(`${__dirname}/Counter.example.tsx`, 'utf-8')
9
- }
@@ -1,9 +0,0 @@
1
- import * as React from 'react'
2
- import {from, ReactDOM, rxComponent} from '../_utils/globalScope'
3
- //@endimport
4
-
5
- const Sync = rxComponent(
6
- from(['This', 'will', 'only', 'render', 'once!'])
7
- )
8
-
9
- ReactDOM.render(<Sync />, document.getElementById('counter-example'))
@@ -1,9 +0,0 @@
1
- import {Example} from '../../pages/Examples/Examples'
2
-
3
- import {readFileSync} from 'fs'
4
-
5
- export const SyncExample: Example = {
6
- id: 'sync-render',
7
- title: 'Sync rendering',
8
- source: readFileSync(`${__dirname}/Sync.example.tsx`, 'utf-8')
9
- }
@@ -1,51 +0,0 @@
1
- import {
2
- map,
3
- mapTo,
4
- React,
5
- ReactDOM,
6
- rxComponent,
7
- startWith,
8
- switchMap,
9
- timer
10
- } from '../_utils/globalScope'
11
- //@endimport
12
-
13
- const {distinctUntilChanged, sampleTime} = operators
14
-
15
- const Ticker = rxComponent(props$ =>
16
- props$.pipe(
17
- map(props => props.tick),
18
- distinctUntilChanged(),
19
- switchMap(tick => timer(300).pipe(mapTo(tick))),
20
- startWith(0),
21
- map(tick => `Delayed tick: ${tick}`)
22
- )
23
- )
24
-
25
- const TickerWithSubTick = rxComponent(props$ =>
26
- props$.pipe(
27
- map(props => props.tick),
28
- distinctUntilChanged(),
29
- switchMap(tick => timer(0, 10).pipe(map(subtick => ({tick, subtick})))),
30
- sampleTime(20),
31
- map(props => (
32
- <div>
33
- {props.tick}:{props.subtick}
34
- </div>
35
- ))
36
- )
37
- )
38
-
39
- const TickExample = rxComponent(
40
- timer(0, 1000).pipe(
41
- map(tick => (
42
- <>
43
- <div>Tick: {tick}</div>
44
- <Ticker tick={tick} />
45
- <TickerWithSubTick tick={tick} />
46
- </>
47
- ))
48
- )
49
- )
50
-
51
- ReactDOM.render(<TickExample />, document.getElementById('ticker-example'))
@@ -1,9 +0,0 @@
1
- import {Example} from '../../pages/Examples/Examples'
2
-
3
- const fs = require('fs')
4
-
5
- export const TickExample: Example = {
6
- id: 'ticker',
7
- title: 'Ticker',
8
- source: fs.readFileSync(`${__dirname}/TickExample.jsx`, 'utf-8')
9
- }
@@ -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,9 +0,0 @@
1
- import {Example} from '../../pages/Examples/Examples'
2
-
3
- const fs = require('fs')
4
-
5
- export const UseElementExample: Example = {
6
- id: 'use-element',
7
- title: 'Use element',
8
- source: fs.readFileSync(`${__dirname}/UseElementExample.tsx`, 'utf-8')
9
- }
@@ -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,8 +0,0 @@
1
- import {Example} from '../../pages/Examples/Examples'
2
- const fs = require('fs')
3
-
4
- export const SearchExample: Example = {
5
- id: 'search',
6
- title: 'Search',
7
- source: fs.readFileSync(`${__dirname}/SearchExample.tsx`, 'utf-8')
8
- }