-
Notifications
You must be signed in to change notification settings - Fork 5
/
use-block.ts
80 lines (74 loc) · 2.08 KB
/
use-block.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import { useContext, useMemo } from 'react';
import { Block, BlockTransition } from './types';
import { createBlock } from './create-sdk-block';
import { FlowContext } from './flow-provider';
/**
* A React hook for accessing a block's state and methods
* corresponding to an intent-based API for manipulating
* said block state.
*
* @example
* ```tsx
* import { useBlock } from "@dopt/react";
* import { Modal } from "@your-company/modal";
*
* export function Application() {
* const [block, transition] = useBlock("HNWvcT78tyTwygnbzU6SW");
* const onClick = useCallback(() => {
* transition('default');
* }, [transition]);
* return (
* <main>
* <Modal isOpen={block.state.active}>
* <h1>👏 Welcome to our app!</h1>
* <p>This is your onboarding experience!</p>
* <button onClick={onClick}>Close me</button>
* </Modal>
* </main>
* );
* }
* ```
*
* @param id - one of {@link Block['sid']} | {@link Block['uid']}
* this param accepts either the user defined identifier (sid) or the system created identifier (the uid)
* @returns [{@link Block}, {@link BlockTransition}] the state of the block and methods to manipulate block state
*
*/
export function useBlock<T>(
id: string
): [block: Block<T>, transition: BlockTransition<T>] {
const {
uninitialized,
blocks,
blockIntention,
log,
blockFields,
blockUidBySid,
} = useContext(FlowContext);
if (uninitialized) {
log.current?.info(
'Accessing block prior to initialization will return default block states.'
);
}
const uid = blockUidBySid.get(id) || id;
const block = useMemo(
() =>
createBlock<T>({
uid,
uninitialized,
blocks,
blockFields,
blockIntention,
}),
[uid, uninitialized, blocks, blockFields, blockIntention]
);
if (!uninitialized && block.version === -1) {
log.current?.warn(
`
Could not find any block matching "${id}" within \`useBlock("${id}")\`.
Returning a default block.
`.trim()
);
}
return [block, block.transition];
}