@khanacademy/wonder-blocks-timing 2.1.1 → 2.1.2

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 (69) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/components/action-scheduler-provider.d.ts +26 -0
  3. package/dist/components/action-scheduler-provider.js.flow +35 -0
  4. package/dist/components/with-action-scheduler.d.ts +14 -0
  5. package/dist/components/with-action-scheduler.js.flow +26 -0
  6. package/dist/es/index.js +157 -119
  7. package/dist/hooks/internal/use-updating-ref.d.ts +13 -0
  8. package/dist/hooks/internal/use-updating-ref.js.flow +22 -0
  9. package/dist/hooks/use-interval.d.ts +8 -0
  10. package/dist/hooks/use-interval.js.flow +18 -0
  11. package/dist/hooks/use-scheduled-interval.d.ts +2 -0
  12. package/dist/hooks/use-scheduled-interval.js.flow +13 -0
  13. package/dist/hooks/use-scheduled-timeout.d.ts +2 -0
  14. package/dist/hooks/use-scheduled-timeout.js.flow +13 -0
  15. package/dist/hooks/use-timeout.d.ts +8 -0
  16. package/dist/hooks/use-timeout.js.flow +18 -0
  17. package/dist/index.d.ts +8 -0
  18. package/dist/index.js +158 -123
  19. package/dist/index.js.flow +31 -2
  20. package/dist/util/action-scheduler.d.ts +21 -0
  21. package/dist/util/action-scheduler.js.flow +39 -0
  22. package/dist/util/animation-frame.d.ts +62 -0
  23. package/dist/util/animation-frame.js.flow +71 -0
  24. package/dist/util/interval.d.ts +60 -0
  25. package/dist/util/interval.js.flow +70 -0
  26. package/dist/util/policies.d.ts +8 -0
  27. package/dist/util/policies.js.flow +17 -0
  28. package/dist/util/timeout.d.ts +62 -0
  29. package/dist/util/timeout.js.flow +72 -0
  30. package/dist/util/types.d.ts +228 -0
  31. package/dist/util/types.js.flow +235 -0
  32. package/dist/util/types.typestest.d.ts +1 -0
  33. package/dist/util/types.typestest.js.flow +6 -0
  34. package/package.json +3 -3
  35. package/src/components/__tests__/{action-scheduler-provider.test.js → action-scheduler-provider.test.tsx} +0 -2
  36. package/src/components/__tests__/{with-action-scheduler.test.js → with-action-scheduler.test.tsx} +6 -6
  37. package/src/components/{action-scheduler-provider.js → action-scheduler-provider.ts} +4 -5
  38. package/src/components/{with-action-scheduler.js → with-action-scheduler.tsx} +10 -18
  39. package/src/hooks/__tests__/{use-interval.test.js → use-interval.test.ts} +5 -6
  40. package/src/hooks/__tests__/{use-scheduled-interval.test.js → use-scheduled-interval.test.ts} +5 -6
  41. package/src/hooks/__tests__/{use-scheduled-timeout.test.js → use-scheduled-timeout.test.ts} +9 -10
  42. package/src/hooks/__tests__/{use-timeout.test.js → use-timeout.test.ts} +5 -6
  43. package/src/hooks/internal/{use-updating-ref.js → use-updating-ref.ts} +5 -2
  44. package/src/hooks/{use-interval.js → use-interval.ts} +1 -2
  45. package/src/hooks/{use-scheduled-interval.js → use-scheduled-interval.ts} +2 -2
  46. package/src/hooks/{use-scheduled-timeout.js → use-scheduled-timeout.ts} +2 -2
  47. package/src/hooks/{use-timeout.js → use-timeout.ts} +1 -2
  48. package/src/{index.js → index.ts} +0 -1
  49. package/src/util/__tests__/{action-scheduler.test.js → action-scheduler.test.ts} +6 -16
  50. package/src/util/__tests__/{animation-frame.test.js → animation-frame.test.ts} +8 -7
  51. package/src/util/__tests__/{interval.test.js → interval.test.ts} +1 -2
  52. package/src/util/__tests__/{timeout.test.js → timeout.test.ts} +1 -2
  53. package/src/util/{action-scheduler.js → action-scheduler.ts} +13 -6
  54. package/src/util/{animation-frame.js → animation-frame.ts} +4 -4
  55. package/src/util/{interval.js → interval.ts} +5 -4
  56. package/src/util/{policies.js → policies.ts} +2 -3
  57. package/src/util/{timeout.js → timeout.ts} +5 -4
  58. package/src/util/{types.js → types.ts} +21 -28
  59. package/src/util/{types.flowtest.js → types.typestest.tsx} +20 -18
  60. package/tsconfig.json +11 -0
  61. package/tsconfig.tsbuildinfo +1 -0
  62. package/src/components/__docs__/migration.stories.mdx +0 -112
  63. package/src/components/__docs__/types.ischedule-actions.stories.mdx +0 -157
  64. package/src/components/__docs__/with-action-scheduler-examples.js +0 -80
  65. package/src/components/__docs__/with-action-scheduler.stories.mdx +0 -218
  66. package/src/hooks/__docs__/use-interval.stories.mdx +0 -80
  67. package/src/hooks/__docs__/use-scheduled-interval.stories.mdx +0 -147
  68. package/src/hooks/__docs__/use-scheduled-timeout.stories.mdx +0 -148
  69. package/src/hooks/__docs__/use-timeout.stories.mdx +0 -80
@@ -1,218 +0,0 @@
1
- import {Meta, Story, Subtitle, Canvas} from "@storybook/addon-docs";
2
- import {IDProvider, View} from "@khanacademy/wonder-blocks-core";
3
-
4
- import {
5
- Unmounter,
6
- MyGoodComponentWithScheduler,
7
- MyNaughtyComponent,
8
- } from "./with-action-scheduler-examples.js";
9
- import ComponentInfo from "../../../../../.storybook/components/component-info.js";
10
- import {name, version} from "../../../package.json";
11
-
12
- <Meta
13
- title="Timing / withActionScheduler"
14
- parameters={{
15
- previewTabs: {
16
- canvas: {hidden: true},
17
- },
18
- viewMode: "docs",
19
- chromatic: {
20
- disableSnapshot: true,
21
- },
22
- }}
23
- decorators={[
24
- (Story) => (
25
- <View>{Story()}</View>
26
- ),
27
- ]}
28
- />
29
-
30
- # withActionSceduler
31
-
32
- <Subtitle>
33
- <ComponentInfo name={name} version={version} />
34
- </Subtitle>
35
-
36
- This is a higher order component (HOC) that attaches the given component to an
37
- [`IScheduleActions`](#ischeduleactions) instance. Any actions scheduled will automatically be
38
- cleared on unmount. This allows for "set it and forget it" behavior that won't
39
- leave timers dangling when the component's lifecycle ends.
40
-
41
- For more details on using this component and the [`IScheduleActions`](#ischeduleactions) interface,
42
- see the [API overview](#timing-api-overview).
43
-
44
- ## Flow Types
45
- If you are using Flow typing, you can use the `WithActionSchedulerProps` type
46
- to build the props for the component that you will pass to the `withActionScheduler`
47
- function by spreading the type into your component's `Props` type.
48
-
49
- The added `schedule` prop is of type [`IScheduleActions`](#ischeduleactions). This is what the
50
- `withActionScheduler` function injects to your component.
51
-
52
- The returned value from `withActionScheduler` is a React component with props of
53
- type `TProps`.
54
-
55
- Access to the [timing API](/docs/timing-types-ischeduleactions--page) is provided via the `withActionScheduler` higher order
56
- component.
57
-
58
- ## Usage
59
-
60
- ### Incorrect Usage
61
-
62
- The following component, `MyNaughtyComponent`, will keep spamming our pretend
63
- log even after it was unmounted.
64
-
65
- export const IncorrectUsage = () => (
66
- <IDProvider id="incorrect">
67
- {(id) => (
68
- <View>
69
- <Unmounter>
70
- <MyNaughtyComponent targetId={id} />
71
- </Unmounter>
72
- <View id={id} />
73
- </View>
74
- )}
75
- </IDProvider>
76
- );
77
-
78
- <Canvas>
79
- <Story name="IncorrectUsage">
80
- <IncorrectUsage />
81
- </Story>
82
- </Canvas>
83
-
84
- ```jsx
85
- function Unmounter(props: {|children: React.Node|}): React.Node {
86
- const [mountKids, setMountKids] = React.useState(true);
87
-
88
- const maybeRenderKids = () => {
89
- if (!mountKids) {
90
- return "Children unmounted";
91
- }
92
-
93
- return (
94
- <>
95
- <Button
96
- onClick={() => {
97
- setMountKids(false);
98
- }}
99
- >
100
- Unmount
101
- </Button>
102
- {props.children}
103
- </>
104
- );
105
- };
106
-
107
- return <View>{maybeRenderKids()}</View>;
108
- }
109
-
110
- class MyNaughtyComponent extends React.Component<{|targetId: string|}> {
111
- componentDidMount() {
112
- const {targetId} = this.props;
113
- let counter = 0;
114
- const domElement: HTMLElement = (document.getElementById(
115
- targetId,
116
- ): any);
117
-
118
- setInterval(() => {
119
- domElement.innerText = "Naughty interval logged: " + counter++;
120
- }, 200);
121
- }
122
-
123
- render(): React.Node {
124
- return <View>NaughtyComponent here</View>;
125
- }
126
- }
127
-
128
- const IncorrectUsage = () => (
129
- <IDProvider id="incorrect">
130
- {(id) => (
131
- <View>
132
- <Unmounter>
133
- <MyNaughtyComponent targetId={id} />
134
- </Unmounter>
135
- <View id={id} />
136
- </View>
137
- )}
138
- </IDProvider>
139
- );
140
- ```
141
-
142
- ### Correct Usage
143
-
144
- But if we use `withActionScheduler` and the `interval` method, everything is
145
- fine. Unmount the component, and the logging stops.
146
-
147
- export const CorrectUsage = () => (
148
- <IDProvider id="correct">
149
- {(id) => (
150
- <View>
151
- <Unmounter>
152
- <MyGoodComponentWithScheduler targetId={id} />
153
- </Unmounter>
154
- <View id={id} />
155
- </View>
156
- )}
157
- </IDProvider>
158
- );
159
-
160
- <Canvas>
161
- <Story name="CorrectUsage">
162
- <CorrectUsage />
163
- </Story>
164
- </Canvas>
165
-
166
- ```jsx
167
- import {withActionScheduler} from "@khanacademy/wonder-blocks-timing";
168
- import type {
169
- WithActionSchedulerProps,
170
- WithoutActionScheduler,
171
- } from "@khanacademy/wonder-blocks-timing";
172
-
173
- type Props = {|
174
- ...WithActionSchedulerProps,
175
- targetId: string,
176
- |};
177
-
178
- class MyGoodComponent extends React.Component<Props> {
179
- componentDidMount() {
180
- const {targetId, schedule} = this.props;
181
- let counter = 0;
182
- const domElement: HTMLElement = (document.getElementById(
183
- targetId,
184
- ): any);
185
-
186
- schedule.interval(() => {
187
- domElement.innerText = "Naughty interval logged: " + counter++;
188
- }, 200);
189
- }
190
-
191
- render(): React.Node {
192
- return <View>GoodComponent here</View>;
193
- }
194
- }
195
-
196
- const MyGoodComponentWithScheduler: React.AbstractComponent<
197
- WithoutActionScheduler<React.ElementConfig<typeof MyGoodComponent>>,
198
- MyGoodComponent,
199
- > = withActionScheduler(MyGoodComponent);
200
-
201
- // This is the same as the previous example
202
- function Unmounter(props: {|children: React.Node|}): React.Node {
203
- ...
204
- }
205
-
206
- const CorrectUsage = () => (
207
- <IDProvider id="correct">
208
- {(id) => (
209
- <View>
210
- <Unmounter>
211
- <MyGoodComponentWithScheduler targetId={id} />
212
- </Unmounter>
213
- <View id={id} />
214
- </View>
215
- )}
216
- </IDProvider>
217
- );
218
- ```
@@ -1,80 +0,0 @@
1
- import {Meta, Story, Source, Canvas} from "@storybook/addon-docs";
2
-
3
- import {Body, HeadingSmall} from "@khanacademy/wonder-blocks-typography";
4
- import {View} from "@khanacademy/wonder-blocks-core";
5
- import Button from "@khanacademy/wonder-blocks-button";
6
-
7
- import {useInterval} from "@khanacademy/wonder-blocks-timing";
8
-
9
- <Meta
10
- title="Timing/useInterval"
11
- parameters={{
12
- chromatic: {
13
- disableSnapshot: true,
14
- },
15
- }}
16
- />
17
-
18
- # `useInterval`
19
-
20
- `useInterval` is a hook that provides a simple API for using intervals safely.
21
- It is defined as follows:
22
-
23
- ```ts
24
- function useInterval(
25
- action: () => mixed,
26
- intervalMs: number,
27
- active: boolean,
28
- ): void;
29
- ```
30
-
31
- Notes:
32
-
33
- - Setting `active` to `true` will start the interval and setting it to `false`
34
- will stop it
35
- - Changing the value of `timeoutMs` will reset the interval, changing `action`
36
- will not.
37
-
38
- export const BasicUsage = () => {
39
- const [callCount, setCallCount] = React.useState(0);
40
- const [active, setActive] = React.useState(false);
41
- const callback = React.useCallback(() => {
42
- setCallCount((callCount) => callCount + 1);
43
- }, []);
44
- useInterval(callback, 1000, active);
45
- return (
46
- <View>
47
- <View>callCount = {callCount}</View>
48
- <View>active = {active.toString()}</View>
49
- <Button onClick={() => setActive(!active)} style={{width: 200}}>
50
- Toggle active
51
- </Button>
52
- </View>
53
- );
54
- };
55
-
56
- <Canvas>
57
- <Story name="BasicUsage">
58
- <BasicUsage />
59
- </Story>
60
- </Canvas>
61
-
62
- ```jsx
63
- export const BasicUsage = () => {
64
- const [callCount, setCallCount] = React.useState(0);
65
- const [active, setActive] = React.useState(false);
66
- const callback = React.useCallback(() => {
67
- setCallCount((callCount) => callCount + 1);
68
- }, []);
69
- useInterval(callback, 1000, active);
70
- return (
71
- <View>
72
- <View>callCount = {callCount}</View>
73
- <View>active = {active.toString()}</View>
74
- <Button onClick={() => setActive(!active)} style={{width: 200}}>
75
- Toggle active
76
- </Button>
77
- </View>
78
- );
79
- };
80
- ```
@@ -1,147 +0,0 @@
1
- import {Meta, Story, Source, Canvas} from "@storybook/addon-docs";
2
-
3
- import {Body, HeadingSmall} from "@khanacademy/wonder-blocks-typography";
4
- import {View} from "@khanacademy/wonder-blocks-core";
5
- import Button from "@khanacademy/wonder-blocks-button";
6
-
7
- import {ClearPolicy, SchedulePolicy} from "../../util/policies.js";
8
- import {useScheduledInterval} from "@khanacademy/wonder-blocks-timing";
9
-
10
- <Meta
11
- title="Timing/useScheduledInterval"
12
- parameters={{
13
- chromatic: {
14
- disableSnapshot: true,
15
- },
16
- }}
17
- />
18
-
19
- # `useScheduledInterval`
20
-
21
- `useScheduledInterval` is a hook that provides a convenient API for setting and clearing
22
- an interval. It is defined as follows:
23
-
24
- ```ts
25
- function useScheduledInterval(
26
- action: () => mixed,
27
- timeoutMs: number,
28
- options?: {|
29
- schedulePolicy?: "schedule-immediately" | "schedule-on-demand",
30
- clearPolicy?: "resolve-on-clear" | "cancel-on-clear",
31
- |},
32
- ): ITimeout;
33
-
34
- interface ITimeout {
35
- get isSet(): boolean;
36
- set(): void;
37
- clear(policy?: ClearPolicy): void;
38
- }
39
- ```
40
-
41
- By default the interval will be set immediately up creation. The `options` parameter can
42
- be used to control when when the interval is schedule and whether or not `action` should be
43
- called when the interval is cleared.
44
-
45
- Notes:
46
-
47
- - Because `clear` takes a param, it's import that you don't pass it directly to an event handler,
48
- e.g. `<Button onClick={clear} />` will not work as expected.
49
- - Calling `set` after the interval has been cleared will restart the interval.
50
- - Updating the second paramter, `timeoutMs`, will also restart the interval.
51
- - When the component using this hooks is unmounted, the interval will automatically be cleared.
52
- - Calling `set` after the interval is already set does nothing.
53
-
54
- export const Immediately = () => {
55
- const [callCount, setCallCount] = React.useState(0);
56
- const callback = React.useCallback(() => {
57
- setCallCount((callCount) => callCount + 1);
58
- }, []);
59
- const interval = useScheduledInterval(callback, 1000);
60
- return (
61
- <View>
62
- <View>isSet = {interval.isSet.toString()}</View>
63
- <View>callCount = {callCount}</View>
64
- <View style={{flexDirection: "row"}}>
65
- <Button onClick={() => interval.set()}>Set interval</Button>
66
- <Button onClick={() => interval.clear()}>Clear interval</Button>
67
- </View>
68
- </View>
69
- );
70
- };
71
-
72
- <Canvas>
73
- <Story name="Immediately">
74
- <Immediately />
75
- </Story>
76
- </Canvas>
77
-
78
- ```jsx
79
- const Immediately = () => {
80
- const [callCount, setCallCount] = React.useState(0);
81
- const callback = React.useCallback(() => {
82
- setCallCount((callCount) => callCount + 1);
83
- }, []);
84
- const interval = useScheduledInterval(callback, 1000);
85
- return (
86
- <View>
87
- <View>isSet = {interval.isSet.toString()}</View>
88
- <View>callCount = {callCount}</View>
89
- <View style={{flexDirection: "row"}}>
90
- <Button onClick={() => interval.set()}>Set interval</Button>
91
- <Button onClick={() => interval.clear()}>Clear interval</Button>
92
- </View>
93
- </View>
94
- );
95
- };
96
- ```
97
-
98
- export const OnDemandAndResolveOnClear = () => {
99
- const [callCount, setCallCount] = React.useState(0);
100
- const callback = React.useCallback(() => {
101
- console.log("action called");
102
- setCallCount((callCount) => callCount + 1);
103
- }, []);
104
- const interval = useScheduledInterval(callback, 1000, {
105
- clearPolicy: ClearPolicy.Resolve,
106
- schedulePolicy: SchedulePolicy.OnDemand,
107
- });
108
- return (
109
- <View>
110
- <View>isSet = {interval.isSet.toString()}</View>
111
- <View>callCount = {callCount}</View>
112
- <View style={{flexDirection: "row"}}>
113
- <Button onClick={() => interval.set()}>Set interval</Button>
114
- <Button onClick={() => interval.clear()}>Clear interval</Button>
115
- </View>
116
- </View>
117
- );
118
- };
119
-
120
- <Canvas>
121
- <Story name="OnDemandAndResolveOnClear">
122
- <OnDemandAndResolveOnClear />
123
- </Story>
124
- </Canvas>
125
-
126
- ```jsx
127
- const OnDemandAndResolveOnClear = () => {
128
- const [callCount, setCallCount] = React.useState(0);
129
- const callback = React.useCallback(() => {
130
- setCallCount((callCount) => callCount + 1);
131
- }, []);
132
- const interval = useScheduledInterval(callback, 1000, {
133
- clearPolicy: ClearPolicy.Resolve,
134
- schedulePolicy: SchedulePolicy.OnDemand,
135
- });
136
- return (
137
- <View>
138
- <View>isSet = {interval.isSet.toString()}</View>
139
- <View>callCount = {callCount}</View>
140
- <View style={{flexDirection: "row"}}>
141
- <Button onClick={() => interval.set()}>Set interval</Button>
142
- <Button onClick={() => interval.clear()}>Clear interval</Button>
143
- </View>
144
- </View>
145
- );
146
- };
147
- ```
@@ -1,148 +0,0 @@
1
- import {Meta, Story, Source, Canvas} from "@storybook/addon-docs";
2
-
3
- import {Body, HeadingSmall} from "@khanacademy/wonder-blocks-typography";
4
- import {View} from "@khanacademy/wonder-blocks-core";
5
- import Button from "@khanacademy/wonder-blocks-button";
6
-
7
- import {ClearPolicy, SchedulePolicy} from "../../util/policies.js";
8
- import {useScheduledTimeout} from "@khanacademy/wonder-blocks-timing";
9
-
10
- <Meta
11
- title="Timing/useScheduledTimeout"
12
- parameters={{
13
- chromatic: {
14
- disableSnapshot: true,
15
- },
16
- }}
17
- />
18
-
19
- # `useScheduledTimeout`
20
-
21
- `useScheduledTimeout` is a hook that provides a convenient API for setting and clearing
22
- a timeout. It is defined as follows:
23
-
24
- ```ts
25
- function useScheduledTimeout(
26
- action: () => mixed,
27
- timeoutMs: number,
28
- options?: {|
29
- schedulePolicy?: "schedule-immediately" | "schedule-on-demand",
30
- clearPolicy?: "resolve-on-clear" | "cancel-on-clear",
31
- |},
32
- ): ITimeout;
33
-
34
- interface ITimeout {
35
- get isSet(): boolean;
36
- set(): void;
37
- clear(policy?: ClearPolicy): void;
38
- }
39
- ```
40
-
41
- By default the timeout will be set immediately up creation. The `options` parameter can
42
- be used to control when when the timeout is schedule and whether or not `action` should be
43
- called when the timeout is cleared.
44
-
45
- Notes:
46
-
47
- - Because `clear` takes a param, it's import that you don't pass it directly to an event handler,
48
- e.g. `<Button onClick={clear} />` will not work as expected.
49
- - Calling `set` after the timeout has expired will restart the timeout.
50
- - Updating the second paramter, `timeoutMs`, will also restart the timeout.
51
- - When the component using this hooks is unmounted, the timeout will automatically be cleared.
52
- - Calling `set` after the timeout is set but before it expires means that the timeout will be
53
- reset and will call `action`, `timeoutMs` after the most recent call to `set` was made.
54
-
55
- export const Immediately = () => {
56
- const [callCount, setCallCount] = React.useState(0);
57
- const callback = React.useCallback(() => {
58
- setCallCount((callCount) => callCount + 1);
59
- }, []);
60
- const {isSet, set, clear} = useScheduledTimeout(callback, 1000);
61
- return (
62
- <View>
63
- <View>isSet = {isSet.toString()}</View>
64
- <View>callCount = {callCount}</View>
65
- <View style={{flexDirection: "row"}}>
66
- <Button onClick={set}>Set timeout</Button>
67
- <Button onClick={clear}>Clear timeout</Button>
68
- </View>
69
- </View>
70
- );
71
- };
72
-
73
- <Canvas>
74
- <Story name="Immediately">
75
- <Immediately />
76
- </Story>
77
- </Canvas>
78
-
79
- ```jsx
80
- const Immediately = () => {
81
- const [callCount, setCallCount] = React.useState(0);
82
- const callback = React.useCallback(() => {
83
- setCallCount((callCount) => callCount + 1);
84
- }, []);
85
- const {isSet, set, clear} = useScheduledTimeout(callback, 1000);
86
- return (
87
- <View>
88
- <View>isSet = {isSet.toString()}</View>
89
- <View>callCount = {callCount}</View>
90
- <View style={{flexDirection: "row"}}>
91
- <Button onClick={() => set()}>Set timeout</Button>
92
- <Button onClick={() => clear()}>Clear timeout</Button>
93
- </View>
94
- </View>
95
- );
96
- };
97
- ```
98
-
99
- export const OnDemandAndResolveOnClear = () => {
100
- const [callCount, setCallCount] = React.useState(0);
101
- const callback = React.useCallback(() => {
102
- console.log("action called");
103
- setCallCount((callCount) => callCount + 1);
104
- }, []);
105
- const {isSet, set, clear} = useScheduledTimeout(callback, 1000, {
106
- clearPolicy: ClearPolicy.Resolve,
107
- schedulePolicy: SchedulePolicy.OnDemand,
108
- });
109
- return (
110
- <View>
111
- <View>isSet = {isSet.toString()}</View>
112
- <View>callCount = {callCount}</View>
113
- <View style={{flexDirection: "row"}}>
114
- <Button onClick={() => set()}>Set timeout</Button>
115
- <Button onClick={() => clear()}>Clear timeout</Button>
116
- </View>
117
- </View>
118
- );
119
- };
120
-
121
- <Canvas>
122
- <Story name="OnDemandAndResolveOnClear">
123
- <OnDemandAndResolveOnClear />
124
- </Story>
125
- </Canvas>
126
-
127
- ```jsx
128
- const OnDemandAndResolveOnClear = () => {
129
- const [callCount, setCallCount] = React.useState(0);
130
- const callback = React.useCallback(() => {
131
- setCallCount((callCount) => callCount + 1);
132
- }, []);
133
- const {isSet, set, clear} = useScheduledTimeout(callback, 1000, {
134
- clearPolicy: ClearPolicy.Resolve,
135
- schedulePolicy: SchedulePolicy.OnDemand,
136
- });
137
- return (
138
- <View>
139
- <View>isSet = {isSet.toString()}</View>
140
- <View>callCount = {callCount}</View>
141
- <View style={{flexDirection: "row"}}>
142
- <Button onClick={() => set()}>Set timeout</Button>
143
- <Button onClick={() => clear()}>Clear timeout</Button>
144
- </View>
145
- </View>
146
- );
147
- };
148
- ```
@@ -1,80 +0,0 @@
1
- import {Meta, Story, Source, Canvas} from "@storybook/addon-docs";
2
-
3
- import {Body, HeadingSmall} from "@khanacademy/wonder-blocks-typography";
4
- import {View} from "@khanacademy/wonder-blocks-core";
5
- import Button from "@khanacademy/wonder-blocks-button";
6
-
7
- import {useTimeout} from "@khanacademy/wonder-blocks-timing";
8
-
9
- <Meta
10
- title="Timing/useTimeout"
11
- parameters={{
12
- chromatic: {
13
- disableSnapshot: true,
14
- },
15
- }}
16
- />
17
-
18
- # `useTimeout`
19
-
20
- `useTimeout` is a hook that provides a simple API for using timers safely.
21
- It is defined as follows:
22
-
23
- ```ts
24
- function useTimeout(
25
- action: () => mixed,
26
- timeoutMs: number,
27
- active: boolean,
28
- ): void;
29
- ```
30
-
31
- Notes:
32
-
33
- - Setting `active` to `true` will start the timeout and setting it to `false`
34
- will stop it
35
- - Changing the value of `timeoutMs` will reset the timeout, changing `action`
36
- will not.
37
-
38
- export const BasicUsage = () => {
39
- const [callCount, setCallCount] = React.useState(0);
40
- const [active, setActive] = React.useState(false);
41
- const callback = React.useCallback(() => {
42
- setCallCount((callCount) => callCount + 1);
43
- }, []);
44
- useTimeout(callback, 1000, active);
45
- return (
46
- <View>
47
- <View>callCount = {callCount}</View>
48
- <View>active = {active.toString()}</View>
49
- <Button onClick={() => setActive(!active)} style={{width: 200}}>
50
- Toggle active
51
- </Button>
52
- </View>
53
- );
54
- };
55
-
56
- <Canvas>
57
- <Story name="BasicUsage">
58
- <BasicUsage />
59
- </Story>
60
- </Canvas>
61
-
62
- ```jsx
63
- export const BasicUsage = () => {
64
- const [callCount, setCallCount] = React.useState(0);
65
- const [active, setActive] = React.useState(false);
66
- const callback = React.useCallback(() => {
67
- setCallCount((callCount) => callCount + 1);
68
- }, []);
69
- useTimeout(callback, 1000, active);
70
- return (
71
- <View>
72
- <View>callCount = {callCount}</View>
73
- <View>active = {active.toString()}</View>
74
- <Button onClick={() => setActive(!active)} style={{width: 200}}>
75
- Toggle active
76
- </Button>
77
- </View>
78
- );
79
- };
80
- ```