Skip to content

Commit e165bf8

Browse files
committed
[WB-2281] Address feedback
1 parent 4e13f9f commit e165bf8

5 files changed

Lines changed: 33 additions & 34 deletions

File tree

__docs__/wonder-blocks-timing/use-animation-frame.mdx

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,12 @@ Notes:
3434

3535
- Because `clear` takes a param, it's important that you don't pass it directly to an event handler,
3636
e.g. `<Button onClick={clear} />` will not work as expected.
37-
- Unlike `useTimeout` and `useInterval`, each frame fires **once**. To create a continuous animation loop, call `set()` again inside the action.
37+
- Unlike `useInterval`, each frame fires **once**. Calling `set()` again schedules another single frame.
3838
- When the component using this hook is unmounted, the pending request will automatically be cleared.
3939
- Calling `set()` when a request is already pending cancels the existing request and makes a new one.
4040

41-
## Immediately (default)
42-
43-
With the default `SchedulePolicy.Immediately`, the frame fires automatically on
44-
mount — useful for deferring a one-time DOM read/write to just before the first
45-
paint:
46-
4741
<Canvas sourceState="shown" of={UseAnimationFrameStories.Immediately} />
4842

49-
## Animation loop (OnDemand + Resolve on clear)
50-
51-
The most common pattern — a loop that starts on demand and fires one final
52-
callback on stop via `ClearPolicy.Resolve`, useful for settling animation state
53-
cleanly before halting:
54-
5543
<Canvas sourceState="shown" of={UseAnimationFrameStories.OnDemandAndResolveOnClear} />
5644

57-
## One-shot
58-
59-
Use `SchedulePolicy.OnDemand` to defer a single unit of work to just before the next paint:
60-
6145
<Canvas sourceState="shown" of={UseAnimationFrameStories.OneShot} />

__docs__/wonder-blocks-timing/use-animation-frame.stories.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ export const OnDemandAndResolveOnClear = () => {
3232
const [frameSet, setFrameSet] = React.useState(false);
3333
const runningRef = React.useRef(false);
3434

35+
// Clear the running flag before the animation frame cleanup fires so that
36+
// ClearPolicy.Resolve's final callback doesn't re-schedule on unmount.
37+
React.useEffect(() => () => {
38+
runningRef.current = false;
39+
}, []);
40+
3541
const animationFrame = useAnimationFrame(
3642
() => {
3743
setFrameCount((n) => n + 1);

packages/wonder-blocks-timing/src/hooks/use-action-scheduler.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import ActionScheduler from "../util/action-scheduler";
1212
* All pending actions are automatically cleared when the component unmounts.
1313
*
1414
* @returns An `IScheduleActions` API for scheduling timeouts, intervals, and
15-
* animation frames. The returned API is stable across renders. All actions
16-
* scheduled via this API will be cleared when the component unmounts.
15+
* animation frames. The returned API is stable across renders. This API is a
16+
* no-op if called when not mounted — any calls prior to mounting or after
17+
* unmounting will not have any effect. All actions scheduled via this API
18+
* will be cleared when the component unmounts.
1719
*
1820
* @example
1921
* function MyComponent() {

packages/wonder-blocks-timing/src/hooks/use-animation-frame.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,7 @@ import AnimationFrame from "../util/animation-frame";
1313
* This makes it easier to use with inline lambda functions rather than
1414
* requiring consumers to wrap their action in a `useCallback`. To change
1515
* this behavior, see the `actionPolicy` option.
16-
* @param options Options for the hook.
17-
* @param options.actionPolicy Determines how the action is handled when it
18-
* changes. By default, the action is replaced but the request is not reset,
19-
* and the updated action will be invoked when the frame next fires.
20-
* If you want to reset the request when the action changes, use
21-
* `ActionPolicy.Reset`.
22-
* @param options.clearPolicy Determines how the request is cleared when the
23-
* component is unmounted or the request is recreated. By default, the
24-
* request is cancelled immediately. If you want to let the request run to
25-
* completion, use `ClearPolicy.Resolve`. This policy is also used as the
26-
* default when calling `clear()` manually with no argument. Pass an explicit
27-
* `ClearPolicy` to `clear(policy)` to override it for a specific call.
28-
* @param options.schedulePolicy Determines when the request is scheduled.
29-
* By default, the request is made immediately. If you want to delay
30-
* scheduling the request, use `SchedulePolicy.OnDemand`.
16+
* @param options Options for the hook. See `HookOptions` for details.
3117
* @returns An `IAnimationFrame` API for interacting with the given request.
3218
* This API is a no-op if called when not mounted. This means that any calls
3319
* prior to mounting or after unmounting will not have any effect. This API is

packages/wonder-blocks-timing/src/util/types.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,35 @@ export interface IAnimationFrame {
131131
* Options for the scheduling APIs.
132132
*/
133133
export type Options = {
134+
/**
135+
* Determines when the request is scheduled. By default, the request is
136+
* made immediately on creation. Use `SchedulePolicy.OnDemand` to delay
137+
* scheduling until `set()` is explicitly called.
138+
*/
134139
schedulePolicy?: Policies.SchedulePolicy;
140+
/**
141+
* Determines how the request is cleared when the component is unmounted
142+
* or the request is recreated. By default, the request is cancelled
143+
* immediately. Use `ClearPolicy.Resolve` to invoke the action one final
144+
* time when the request is cleared. This policy is also used as the
145+
* default when calling `clear()` manually with no argument — pass an
146+
* explicit `ClearPolicy` to `clear(policy)` to override it for a
147+
* specific call.
148+
*/
135149
clearPolicy?: Policies.ClearPolicy;
136150
};
137151

138152
/**
139153
* Options for the hook variants of our scheduling APIs.
140154
*/
141155
export type HookOptions = Options & {
156+
/**
157+
* Determines how the action is handled when it changes between renders.
158+
* By default (`ActionPolicy.Passive`), the action is replaced but the
159+
* request is not reset — the updated action will be invoked when the
160+
* request next fires. Use `ActionPolicy.Reset` to cancel the current
161+
* request and start a new one whenever the action changes.
162+
*/
142163
actionPolicy?: Policies.ActionPolicy;
143164
};
144165

0 commit comments

Comments
 (0)