@aweebit/react-essentials 0.6.0 → 0.8.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.
@@ -9,7 +9,8 @@ const moValueSymbol = Symbol('noValue');
9
9
  * as an argument to `useContext` or `use` (the hook produced with
10
10
  * {@linkcode createSafeContext} should be used instead)
11
11
  *
12
- * @see {@linkcode createSafeContext}
12
+ * @see
13
+ * {@linkcode createSafeContext}
13
14
  */
14
15
  // The type is conditional so that both React 18 and 19 are correctly supported.
15
16
  // The code duplication is necessary for the type to be displayed correctly by
@@ -20,7 +21,11 @@ export type RestrictedContext<T> =
20
21
  : { Provider: Provider<T>; displayName: string };
21
22
 
22
23
  /**
23
- * @see {@linkcode createSafeContext}
24
+ * The return type of {@linkcode createSafeContext}
25
+ *
26
+ * @see
27
+ * {@linkcode createSafeContext},
28
+ * {@linkcode RestrictedContext}
24
29
  */
25
30
  export type SafeContext<DisplayName extends string, T> = {
26
31
  [K in `${DisplayName}Context`]: RestrictedContext<T>;
@@ -33,25 +38,59 @@ export type SafeContext<DisplayName extends string, T> = {
33
38
  * type and a hook that returns the current context value if one was provided,
34
39
  * or throws an error otherwise
35
40
  *
41
+ * The advantages over vanilla `createContext` are that no default value has to
42
+ * be provided, and that a meaningful context name is displayed in dev tools
43
+ * instead of generic `Context.Provider`.
44
+ *
36
45
  * @example
37
46
  * ```tsx
38
- * const { ItemsContext, useItems } = createSafeContext<string[]>()('Items');
47
+ * enum Direction {
48
+ * Up,
49
+ * Down,
50
+ * Left,
51
+ * Right,
52
+ * }
53
+ *
54
+ * // Before
55
+ * const DirectionContext = createContext<Direction | undefined>(undefined);
56
+ * DirectionContext.displayName = 'DirectionContext';
57
+ *
58
+ * const useDirection = () => {
59
+ * const direction = useContext(DirectionContext);
60
+ * if (direction === undefined) {
61
+ * // Called outside of a <DirectionContext.Provider> boundary!
62
+ * // Or maybe undefined was explicitly provided as the context value
63
+ * // (ideally that shouldn't be allowed, but it is because we had to include
64
+ * // undefined in the context type so as to provide a meaningful default)
65
+ * throw new Error('No DirectionContext value was provided');
66
+ * }
67
+ * // Thanks to the undefined check, the type is now narrowed down to Direction
68
+ * return direction;
69
+ * };
70
+ *
71
+ * // After
72
+ * const { DirectionContext, useDirection } =
73
+ * createSafeContext<Direction>()('Direction'); // That's it :)
39
74
  *
40
75
  * const Parent = () => (
41
- * <ItemsContext value={['compass', 'newspaper', 'banana']}>
76
+ * // Providing undefined as the value is not allowed 👍
77
+ * <Direction.Provider value={Direction.Up}>
42
78
  * <Child />
43
- * </ItemsContext>
79
+ * </Direction.Provider>
44
80
  * );
45
81
  *
46
- * const Child = () => useItems().join(', ');
82
+ * const Child = () => `Current direction: ${Direction[useDirection()]}`;
47
83
  * ```
48
84
  *
49
85
  * @returns
50
86
  * A function that accepts a single string argument `displayName` (e.g.
51
- * `"Items"`) and returns an object with the following properties:
52
- * - ``` `${displayName}Context` ``` (e.g. `ItemsContext`): the context
53
- * - ``` `use${displayName}` ``` (e.g. `useItems`): a hook that returns the
87
+ * `"Direction"`) and returns an object with the following properties:
88
+ * - ``` `${displayName}Context` ``` (e.g. `DirectionContext`): the context
89
+ * - ``` `use${displayName}` ``` (e.g. `useDirection`): a hook that returns the
54
90
  * current context value if one was provided, or throws an error otherwise
91
+ *
92
+ * @see
93
+ * {@linkcode SafeContext}
55
94
  */
56
95
  export function createSafeContext<T = never>() {
57
96
  return <DisplayName extends string>(