react-children-hooks 0.3.0 → 0.5.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.
package/dist/index.d.ts CHANGED
@@ -14,16 +14,47 @@ type ChildrenCountBounds = {
14
14
  */
15
15
  maximum: number;
16
16
  };
17
+ /**
18
+ * Optional traversal bounds used by the element-based query and validation hooks.
19
+ */
20
+ type TraversalOptions = {
21
+ /**
22
+ * The minimum inclusive child depth to include in results, where `0` represents direct children.
23
+ */
24
+ depth?: number;
25
+ /**
26
+ * The maximum inclusive child depth to include in results, where `0` represents direct children.
27
+ */
28
+ maximumDepth?: number;
29
+ };
30
+ /**
31
+ * Optional traversal metadata used by the element-based query hooks.
32
+ */
33
+ type QueryOptions = TraversalOptions;
17
34
  /**
18
35
  * Represents a React element whose props and element type are narrowed to the provided React element type.
19
36
  *
20
37
  * @typeParam T The React element type used to narrow the element's props and type.
21
38
  */
22
39
  type ElementOfType<T extends React.ElementType> = React.ReactElement<React.ComponentProps<T>, T>;
40
+ /**
41
+ * A callback child, also known as a render-prop child.
42
+ *
43
+ * @typeParam TArguments The positional argument tuple accepted by the callback.
44
+ * @typeParam TResult The value returned by the callback.
45
+ */
46
+ type CallbackChild<TArguments extends unknown[] = [], TResult = React.ReactNode> = (...args: TArguments) => TResult;
47
+ /**
48
+ * A direct-children value that may include callback children alongside regular React children.
49
+ *
50
+ * @typeParam TArguments The positional argument tuple accepted by callback children.
51
+ * @typeParam TResult The value returned by callback children.
52
+ */
53
+ type CallbackChildren<TArguments extends unknown[] = [], TResult = React.ReactNode> = React.ReactNode | CallbackChild<TArguments, TResult> | readonly CallbackChildren<TArguments, TResult>[];
23
54
  /**
24
55
  * Optional reporting metadata used by the validation hooks to derive thrown validation messages.
25
56
  */
26
- type ValidationOptions = {
57
+ type ValidationMessageOptions = {
27
58
  /**
28
59
  * An optional consumer-defined trace code that is prefixed to the thrown validation message.
29
60
  */
@@ -33,25 +64,39 @@ type ValidationOptions = {
33
64
  */
34
65
  childName?: string;
35
66
  };
67
+ /**
68
+ * Optional reporting and traversal metadata used by the validation hooks.
69
+ */
70
+ type ValidationOptions = ValidationMessageOptions & TraversalOptions;
36
71
 
37
72
  /**
38
73
  * Returns the first direct child element whose React element type exactly matches the provided type.
39
74
  *
40
75
  * @param children The React children value to inspect.
41
76
  * @param type The element or component type to match against each direct child element.
77
+ * @param options Optional query metadata used to configure how child elements are inspected.
42
78
  * @returns The first direct child element whose type matches the provided element type, or `null` when no match is found.
43
79
  */
44
- declare function useChildByType<T extends ElementType>(children: ReactNode, type: T): ElementOfType<T> | null;
80
+ declare function useChildByType<T extends ElementType>(children: ReactNode, type: T, options?: QueryOptions): ElementOfType<T> | null;
81
+
82
+ /**
83
+ * Returns the first direct callback child from the provided children value.
84
+ *
85
+ * @param children The direct children value to inspect.
86
+ * @returns The first direct callback child, or `null` when no callback child is found.
87
+ */
88
+ declare function useCallbackChild<TArguments extends unknown[] = [], TResult = ReactNode>(children: CallbackChildren<TArguments, TResult>): CallbackChild<TArguments, TResult> | null;
45
89
 
46
90
  /**
47
91
  * Returns the first direct child element that satisfies the provided predicate.
48
92
  *
49
93
  * @param children The React children value to inspect.
50
94
  * @param predicate A predicate that is called with each direct child element to determine whether it matches.
95
+ * @param options Optional query metadata used to configure how child elements are inspected.
51
96
  * @returns The first direct child element that satisfies the provided predicate, or `null` when no match is found.
52
97
  */
53
- declare function useChildMatching<T extends ReactElement>(children: ReactNode, predicate: (element: ReactElement) => element is T): T | null;
54
- declare function useChildMatching(children: ReactNode, predicate: (element: ReactElement) => boolean): ReactElement | null;
98
+ declare function useChildMatching<T extends ReactElement>(children: ReactNode, predicate: (element: ReactElement) => element is T, options?: QueryOptions): T | null;
99
+ declare function useChildMatching(children: ReactNode, predicate: (element: ReactElement) => boolean, options?: QueryOptions): ReactElement | null;
55
100
 
56
101
  /**
57
102
  * Returns the direct child elements whose React element type exactly matches the provided type, or throws when the count falls outside the inclusive bounds.
@@ -81,19 +126,21 @@ declare function useBoundedChildrenMatching(children: ReactNode, predicate: (ele
81
126
  *
82
127
  * @param children The React children value to inspect.
83
128
  * @param type The element or component type to match against each direct child element.
129
+ * @param options Optional query metadata used to configure how child elements are inspected.
84
130
  * @returns An array of direct child elements whose type matches the provided element type.
85
131
  */
86
- declare function useChildrenByType<T extends ElementType>(children: ReactNode, type: T): ElementOfType<T>[];
132
+ declare function useChildrenByType<T extends ElementType>(children: ReactNode, type: T, options?: QueryOptions): ElementOfType<T>[];
87
133
 
88
134
  /**
89
135
  * Returns the direct child elements that satisfy the provided predicate.
90
136
  *
91
137
  * @param children The React children value to inspect.
92
138
  * @param predicate A predicate that is called with each direct child element to determine whether it should be included in the result.
139
+ * @param options Optional query metadata used to configure how child elements are inspected.
93
140
  * @returns An array of direct child elements that satisfy the provided predicate.
94
141
  */
95
- declare function useChildrenMatching<T extends ReactElement>(children: ReactNode, predicate: (element: ReactElement) => element is T): T[];
96
- declare function useChildrenMatching(children: ReactNode, predicate: (element: ReactElement) => boolean): ReactElement[];
142
+ declare function useChildrenMatching<T extends ReactElement>(children: ReactNode, predicate: (element: ReactElement) => element is T, options?: QueryOptions): T[];
143
+ declare function useChildrenMatching(children: ReactNode, predicate: (element: ReactElement) => boolean, options?: QueryOptions): ReactElement[];
97
144
 
98
145
  /**
99
146
  * Returns the direct child elements whose React element type exactly matches the provided type, or throws when the exact count is not met.
@@ -123,10 +170,11 @@ declare function useExactChildrenMatching(children: ReactNode, predicate: (eleme
123
170
  *
124
171
  * @param children The React children value to inspect.
125
172
  * @param predicate A predicate that is called with each direct child element to determine whether it matches.
173
+ * @param options Optional query metadata used to configure how child elements are inspected.
126
174
  * @returns `true` when at least one direct child element satisfies the provided predicate; otherwise `false`.
127
175
  */
128
- declare function useHasChildMatching<T extends ReactElement>(children: ReactNode, predicate: (element: ReactElement) => element is T): boolean;
129
- declare function useHasChildMatching(children: ReactNode, predicate: (element: ReactElement) => boolean): boolean;
176
+ declare function useHasChildMatching<T extends ReactElement>(children: ReactNode, predicate: (element: ReactElement) => element is T, options?: QueryOptions): boolean;
177
+ declare function useHasChildMatching(children: ReactNode, predicate: (element: ReactElement) => boolean, options?: QueryOptions): boolean;
130
178
 
131
179
  /**
132
180
  * Returns the direct child elements whose React element type exactly matches the provided type, or throws when more than the maximum count are found.
@@ -174,6 +222,36 @@ declare function useMinimumChildrenByType<T extends ElementType>(children: React
174
222
  declare function useMinimumChildrenMatching<T extends ReactElement>(children: ReactNode, predicate: (element: ReactElement) => element is T, minimumCount: number, options?: ValidationOptions): T[];
175
223
  declare function useMinimumChildrenMatching(children: ReactNode, predicate: (element: ReactElement) => boolean, minimumCount: number, options?: ValidationOptions): ReactElement[];
176
224
 
225
+ /**
226
+ * Returns the optional direct callback child from the provided children value, or throws when more than one is found.
227
+ *
228
+ * @param children The direct children value to inspect.
229
+ * @param options Optional reporting metadata used to derive the thrown validation message.
230
+ * @returns The optional direct callback child from the provided children value, or `null` when none is found.
231
+ */
232
+ declare function useOptionalCallbackChild<TArguments extends unknown[] = [], TResult = ReactNode>(children: CallbackChildren<TArguments, TResult>, options?: ValidationOptions): CallbackChild<TArguments, TResult> | null;
233
+
234
+ /**
235
+ * Returns the optional direct child element whose React element type exactly matches the provided type, or throws when more than one match is found.
236
+ *
237
+ * @param children The React children value to inspect.
238
+ * @param type The element or component type to match against each direct child element.
239
+ * @param options Optional reporting metadata used to derive the thrown validation message.
240
+ * @returns The optional direct child element whose type matches the provided element type, or `null` when no match is found.
241
+ */
242
+ declare function useOptionalChildByType<T extends ElementType>(children: ReactNode, type: T, options?: ValidationOptions): ElementOfType<T> | null;
243
+
244
+ /**
245
+ * Returns the optional direct child element that satisfies the provided predicate, or throws when more than one match is found.
246
+ *
247
+ * @param children The React children value to inspect.
248
+ * @param predicate A predicate that is called with each direct child element to determine whether it matches.
249
+ * @param options Optional reporting metadata used to derive the thrown validation message.
250
+ * @returns The optional direct child element that satisfies the provided predicate, or `null` when no match is found.
251
+ */
252
+ declare function useOptionalChildMatching<T extends ReactElement>(children: ReactNode, predicate: (element: ReactElement) => element is T, options?: ValidationOptions): T | null;
253
+ declare function useOptionalChildMatching(children: ReactNode, predicate: (element: ReactElement) => boolean, options?: ValidationOptions): ReactElement | null;
254
+
177
255
  /**
178
256
  * Returns the first direct child element whose React element type exactly matches the provided type, or throws when no match is found.
179
257
  *
@@ -184,6 +262,15 @@ declare function useMinimumChildrenMatching(children: ReactNode, predicate: (ele
184
262
  */
185
263
  declare function useRequiredChildByType<T extends ElementType>(children: ReactNode, type: T, options?: ValidationOptions): ElementOfType<T>;
186
264
 
265
+ /**
266
+ * Returns the first direct callback child from the provided children value, or throws when none is found.
267
+ *
268
+ * @param children The direct children value to inspect.
269
+ * @param options Optional reporting metadata used to derive the thrown validation message.
270
+ * @returns The first direct callback child from the provided children value.
271
+ */
272
+ declare function useRequiredCallbackChild<TArguments extends unknown[] = [], TResult = ReactNode>(children: CallbackChildren<TArguments, TResult>, options?: ValidationOptions): CallbackChild<TArguments, TResult>;
273
+
187
274
  /**
188
275
  * Returns the first direct child element that satisfies the provided predicate, or throws when no match is found.
189
276
  *
@@ -196,28 +283,33 @@ declare function useRequiredChildMatching<T extends ReactElement>(children: Reac
196
283
  declare function useRequiredChildMatching(children: ReactNode, predicate: (element: ReactElement) => boolean, options?: ValidationOptions): ReactElement;
197
284
 
198
285
  /**
199
- * Normalizes a React children value into an array containing only valid direct child elements.
286
+ * Returns the only direct callback child from the provided children value, or throws when the match is not unique.
200
287
  *
201
- * @param children The React children value to normalize.
202
- * @returns An array of valid React elements from the provided direct children.
288
+ * @param children The direct children value to inspect.
289
+ * @param options Optional reporting metadata used to derive the thrown validation message.
290
+ * @returns The only direct callback child from the provided children value.
203
291
  */
204
- declare function childrenToElements(children: ReactNode): ReactElement[];
292
+ declare function useUniqueCallbackChild<TArguments extends unknown[] = [], TResult = ReactNode>(children: CallbackChildren<TArguments, TResult>, options?: ValidationOptions): CallbackChild<TArguments, TResult>;
205
293
 
206
294
  /**
207
- * Determines whether a React element exactly matches the provided element or component type.
295
+ * Returns the only direct child element whose React element type exactly matches the provided type, or throws when the match is not unique.
208
296
  *
209
- * @param element The React element to compare.
210
- * @param type The element or component type to match.
211
- * @returns `true` when the element's type exactly matches the provided type; otherwise `false`.
297
+ * @param children The React children value to inspect.
298
+ * @param type The element or component type to match against each direct child element.
299
+ * @param options Optional reporting metadata used to derive the thrown validation message.
300
+ * @returns The only direct child element whose type matches the provided element type.
212
301
  */
213
- declare function isElementOfType<T extends ElementType>(element: ReactElement, type: T): element is ElementOfType<T>;
302
+ declare function useUniqueChildByType<T extends ElementType>(children: ReactNode, type: T, options?: ValidationOptions): ElementOfType<T>;
214
303
 
215
304
  /**
216
- * Determines whether a React node is a valid React element.
305
+ * Returns the only direct child element that satisfies the provided predicate, or throws when the match is not unique.
217
306
  *
218
- * @param node The React node to check.
219
- * @returns `true` when the node is a valid React element; otherwise `false`.
307
+ * @param children The React children value to inspect.
308
+ * @param predicate A predicate that is called with each direct child element to determine whether it matches.
309
+ * @param options Optional reporting metadata used to derive the thrown validation message.
310
+ * @returns The only direct child element that satisfies the provided predicate.
220
311
  */
221
- declare function isReactElement(node: ReactNode): node is ReactElement;
312
+ declare function useUniqueChildMatching<T extends ReactElement>(children: ReactNode, predicate: (element: ReactElement) => element is T, options?: ValidationOptions): T;
313
+ declare function useUniqueChildMatching(children: ReactNode, predicate: (element: ReactElement) => boolean, options?: ValidationOptions): ReactElement;
222
314
 
223
- export { type ChildrenCountBounds, type ElementOfType, type ValidationOptions, childrenToElements, isElementOfType, isReactElement, useBoundedChildrenByType, useBoundedChildrenMatching, useChildByType, useChildMatching, useChildrenByType, useChildrenMatching, useExactChildrenByType, useExactChildrenMatching, useHasChildMatching, useMaximumChildrenByType, useMaximumChildrenMatching, useMinimumChildrenByType, useMinimumChildrenMatching, useRequiredChildByType, useRequiredChildMatching };
315
+ export { type CallbackChild, type CallbackChildren, type ChildrenCountBounds, type ElementOfType, type QueryOptions, type TraversalOptions, type ValidationOptions, useBoundedChildrenByType, useBoundedChildrenMatching, useCallbackChild, useChildByType, useChildMatching, useChildrenByType, useChildrenMatching, useExactChildrenByType, useExactChildrenMatching, useHasChildMatching, useMaximumChildrenByType, useMaximumChildrenMatching, useMinimumChildrenByType, useMinimumChildrenMatching, useOptionalCallbackChild, useOptionalChildByType, useOptionalChildMatching, useRequiredCallbackChild, useRequiredChildByType, useRequiredChildMatching, useUniqueCallbackChild, useUniqueChildByType, useUniqueChildMatching };
package/dist/index.js CHANGED
@@ -15,54 +15,128 @@ function isReactElement(node) {
15
15
  return isValidElement(node);
16
16
  }
17
17
 
18
- // src/childrenToElements.ts
19
- function childrenToElements(children) {
20
- return Children.toArray(children).filter(isReactElement);
21
- }
22
-
23
- // src/useChildMatching.ts
24
- function useChildMatching(children, predicate) {
25
- return useMemo(
26
- () => childrenToElements(children).find(predicate) ?? null,
27
- [children, predicate]
28
- );
29
- }
30
-
31
- // src/useChildByType.ts
32
- function useChildByType(children, type) {
33
- return useChildMatching(
34
- children,
35
- (element) => isElementOfType(element, type)
36
- );
37
- }
38
-
39
18
  // src/reporter.ts
40
19
  import { createReporter } from "runtime-reporter";
41
- var messages = {
20
+ var validationMessages = {
21
+ OPTIONAL_CHILD_MATCHING_PREDICATE_FAILED: "{{ traceCodePrefix }}Optional child validation failed{{ childNameSegment }} because {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected at most 1.",
22
+ UNIQUE_CHILD_MATCHING_PREDICATE_FAILED: "{{ traceCodePrefix }}Unique child validation failed{{ childNameSegment }} because {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected exactly 1.",
42
23
  REQUIRED_CHILD_MATCHING_PREDICATE_FAILED: "{{ traceCodePrefix }}Required child validation failed{{ childNameSegment }} because no direct child satisfied the provided predicate.",
24
+ REQUIRED_CALLBACK_CHILD_FAILED: "{{ traceCodePrefix }}Required callback child validation failed{{ childNameSegment }} because no direct callback child was found.",
25
+ OPTIONAL_CALLBACK_CHILD_FAILED: "{{ traceCodePrefix }}Optional callback child validation failed{{ childNameSegment }} because {{ actualCount }} direct callback children were found; expected at most 1.",
26
+ UNIQUE_CALLBACK_CHILD_FAILED: "{{ traceCodePrefix }}Unique callback child validation failed{{ childNameSegment }} because {{ actualCount }} direct callback children were found; expected exactly 1.",
43
27
  MINIMUM_CHILDREN_MATCHING_PREDICATE_FAILED: "{{ traceCodePrefix }}Minimum children validation failed{{ childNameSegment }} because only {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected at least {{ minimumCount }}.",
44
28
  MAXIMUM_CHILDREN_MATCHING_PREDICATE_FAILED: "{{ traceCodePrefix }}Maximum children validation failed{{ childNameSegment }} because {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected at most {{ maximumCount }}.",
45
29
  EXACT_CHILDREN_MATCHING_PREDICATE_FAILED: "{{ traceCodePrefix }}Exact children validation failed{{ childNameSegment }} because {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected exactly {{ exactCount }}.",
46
30
  BOUNDED_CHILDREN_MATCHING_PREDICATE_FAILED: "{{ traceCodePrefix }}Bounded children validation failed{{ childNameSegment }} because {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected between {{ minimumCount }} and {{ maximumCount }} inclusive."
47
31
  };
32
+ var publicMessages = {
33
+ RCH001: '[RCH001] Traversal option "depth" must be a non-negative integer.',
34
+ RCH002: '[RCH002] Traversal option "maximumDepth" must be a non-negative integer.',
35
+ RCH003: '[RCH003] Traversal option "depth" cannot be greater than "maximumDepth".'
36
+ };
37
+ var messages = {
38
+ ...validationMessages,
39
+ ...publicMessages
40
+ };
48
41
  var reporter = createReporter(
49
42
  process.env.NODE_ENV === "production" ? {} : messages,
50
43
  { formatMessage: (message) => message }
51
44
  );
52
45
  var reporter_default = reporter;
53
46
 
54
- // src/useChildrenMatching.ts
47
+ // src/childrenToElements.ts
48
+ function getTraversalBounds(options) {
49
+ const depth = options?.depth ?? 0;
50
+ const maximumDepth = options?.maximumDepth ?? 0;
51
+ if (!Number.isInteger(depth) || depth < 0) {
52
+ return reporter_default.fail("RCH001");
53
+ }
54
+ if (!Number.isInteger(maximumDepth) || maximumDepth < 0) {
55
+ return reporter_default.fail("RCH002");
56
+ }
57
+ if (depth > maximumDepth) {
58
+ return reporter_default.fail("RCH003");
59
+ }
60
+ return { depth, maximumDepth };
61
+ }
62
+ function collectElementsAtDepth(children, currentDepth, depth, maximumDepth) {
63
+ const directElements = Children.toArray(children).filter(isReactElement);
64
+ let elements = [];
65
+ if (currentDepth >= depth && currentDepth <= maximumDepth) {
66
+ elements = [...directElements];
67
+ }
68
+ for (const element of directElements) {
69
+ const elementProps = element.props;
70
+ const elementsAtDepth = collectElementsAtDepth(
71
+ elementProps.children,
72
+ currentDepth + 1,
73
+ depth,
74
+ maximumDepth
75
+ );
76
+ elements.push(...elementsAtDepth);
77
+ }
78
+ return elements;
79
+ }
80
+ function childrenToElements(children, options) {
81
+ const { depth, maximumDepth } = getTraversalBounds(options);
82
+ return collectElementsAtDepth(children, 0, depth, maximumDepth);
83
+ }
84
+
85
+ // src/useChildMatching.ts
86
+ function useChildMatching(children, predicate, options) {
87
+ return useMemo(
88
+ () => childrenToElements(children, options).find(predicate) ?? null,
89
+ [children, options, predicate]
90
+ );
91
+ }
92
+ var useChildMatching_default = useChildMatching;
93
+
94
+ // src/useChildByType.ts
95
+ function useChildByType(children, type, options) {
96
+ return useChildMatching_default(
97
+ children,
98
+ (element) => isElementOfType(element, type),
99
+ options
100
+ );
101
+ }
102
+
103
+ // src/useCallbackChild.ts
55
104
  import { useMemo as useMemo2 } from "react";
56
- function useChildrenMatching(children, predicate) {
105
+
106
+ // src/callbackChildrenToArray.ts
107
+ function callbackChildrenToArray(children) {
108
+ if (typeof children === "function") {
109
+ return [children];
110
+ }
111
+ if (!Array.isArray(children)) {
112
+ return [];
113
+ }
114
+ return children.flatMap(
115
+ (child) => callbackChildrenToArray(child)
116
+ );
117
+ }
118
+
119
+ // src/useCallbackChild.ts
120
+ function useCallbackChild(children) {
57
121
  return useMemo2(
58
- () => childrenToElements(children).filter(predicate),
59
- [children, predicate]
122
+ () => callbackChildrenToArray(children)[0] ?? null,
123
+ [children]
124
+ );
125
+ }
126
+
127
+ // src/useChildrenMatching.ts
128
+ import { useMemo as useMemo3 } from "react";
129
+ function useChildrenMatching(children, predicate, options) {
130
+ return useMemo3(
131
+ () => childrenToElements(children, options).filter(predicate),
132
+ [children, options, predicate]
60
133
  );
61
134
  }
135
+ var useChildrenMatching_default = useChildrenMatching;
62
136
 
63
137
  // src/useBoundedChildrenMatching.ts
64
138
  function useBoundedChildrenMatching(children, predicate, bounds, options) {
65
- const matchingChildren = useChildrenMatching(children, predicate);
139
+ const matchingChildren = useChildrenMatching_default(children, predicate, options);
66
140
  if (matchingChildren.length >= bounds.minimum && matchingChildren.length <= bounds.maximum) {
67
141
  return matchingChildren;
68
142
  }
@@ -75,10 +149,11 @@ function useBoundedChildrenMatching(children, predicate, bounds, options) {
75
149
  maximumCount: bounds.maximum
76
150
  });
77
151
  }
152
+ var useBoundedChildrenMatching_default = useBoundedChildrenMatching;
78
153
 
79
154
  // src/useBoundedChildrenByType.ts
80
155
  function useBoundedChildrenByType(children, type, bounds, options) {
81
- return useBoundedChildrenMatching(
156
+ return useBoundedChildrenMatching_default(
82
157
  children,
83
158
  (element) => isElementOfType(element, type),
84
159
  bounds,
@@ -87,16 +162,17 @@ function useBoundedChildrenByType(children, type, bounds, options) {
87
162
  }
88
163
 
89
164
  // src/useChildrenByType.ts
90
- function useChildrenByType(children, type) {
91
- return useChildrenMatching(
165
+ function useChildrenByType(children, type, options) {
166
+ return useChildrenMatching_default(
92
167
  children,
93
- (element) => isElementOfType(element, type)
168
+ (element) => isElementOfType(element, type),
169
+ options
94
170
  );
95
171
  }
96
172
 
97
173
  // src/useExactChildrenMatching.ts
98
174
  function useExactChildrenMatching(children, predicate, exactCount, options) {
99
- const matchingChildren = useChildrenMatching(children, predicate);
175
+ const matchingChildren = useChildrenMatching_default(children, predicate, options);
100
176
  if (matchingChildren.length === exactCount) {
101
177
  return matchingChildren;
102
178
  }
@@ -108,10 +184,11 @@ function useExactChildrenMatching(children, predicate, exactCount, options) {
108
184
  exactCount
109
185
  });
110
186
  }
187
+ var useExactChildrenMatching_default = useExactChildrenMatching;
111
188
 
112
189
  // src/useExactChildrenByType.ts
113
190
  function useExactChildrenByType(children, type, exactCount, options) {
114
- return useExactChildrenMatching(
191
+ return useExactChildrenMatching_default(
115
192
  children,
116
193
  (element) => isElementOfType(element, type),
117
194
  exactCount,
@@ -120,17 +197,18 @@ function useExactChildrenByType(children, type, exactCount, options) {
120
197
  }
121
198
 
122
199
  // src/useHasChildMatching.ts
123
- import { useMemo as useMemo3 } from "react";
124
- function useHasChildMatching(children, predicate) {
125
- return useMemo3(
126
- () => childrenToElements(children).some(predicate),
127
- [children, predicate]
200
+ import { useMemo as useMemo4 } from "react";
201
+ function useHasChildMatching(children, predicate, options) {
202
+ return useMemo4(
203
+ () => childrenToElements(children, options).some(predicate),
204
+ [children, options, predicate]
128
205
  );
129
206
  }
207
+ var useHasChildMatching_default = useHasChildMatching;
130
208
 
131
209
  // src/useMaximumChildrenMatching.ts
132
210
  function useMaximumChildrenMatching(children, predicate, maximumCount, options) {
133
- const matchingChildren = useChildrenMatching(children, predicate);
211
+ const matchingChildren = useChildrenMatching_default(children, predicate, options);
134
212
  if (matchingChildren.length <= maximumCount) {
135
213
  return matchingChildren;
136
214
  }
@@ -142,10 +220,11 @@ function useMaximumChildrenMatching(children, predicate, maximumCount, options)
142
220
  maximumCount
143
221
  });
144
222
  }
223
+ var useMaximumChildrenMatching_default = useMaximumChildrenMatching;
145
224
 
146
225
  // src/useMaximumChildrenByType.ts
147
226
  function useMaximumChildrenByType(children, type, maximumCount, options) {
148
- return useMaximumChildrenMatching(
227
+ return useMaximumChildrenMatching_default(
149
228
  children,
150
229
  (element) => isElementOfType(element, type),
151
230
  maximumCount,
@@ -155,7 +234,7 @@ function useMaximumChildrenByType(children, type, maximumCount, options) {
155
234
 
156
235
  // src/useMinimumChildrenMatching.ts
157
236
  function useMinimumChildrenMatching(children, predicate, minimumCount, options) {
158
- const matchingChildren = useChildrenMatching(children, predicate);
237
+ const matchingChildren = useChildrenMatching_default(children, predicate, options);
159
238
  if (matchingChildren.length >= minimumCount) {
160
239
  return matchingChildren;
161
240
  }
@@ -167,10 +246,11 @@ function useMinimumChildrenMatching(children, predicate, minimumCount, options)
167
246
  minimumCount
168
247
  });
169
248
  }
249
+ var useMinimumChildrenMatching_default = useMinimumChildrenMatching;
170
250
 
171
251
  // src/useMinimumChildrenByType.ts
172
252
  function useMinimumChildrenByType(children, type, minimumCount, options) {
173
- return useMinimumChildrenMatching(
253
+ return useMinimumChildrenMatching_default(
174
254
  children,
175
255
  (element) => isElementOfType(element, type),
176
256
  minimumCount,
@@ -178,9 +258,50 @@ function useMinimumChildrenByType(children, type, minimumCount, options) {
178
258
  );
179
259
  }
180
260
 
261
+ // src/useOptionalCallbackChild.ts
262
+ import { useMemo as useMemo5 } from "react";
263
+ function useOptionalCallbackChild(children, options) {
264
+ const callbackChildren = useMemo5(
265
+ () => callbackChildrenToArray(children),
266
+ [children]
267
+ );
268
+ if (callbackChildren.length <= 1) {
269
+ return callbackChildren[0] ?? null;
270
+ }
271
+ return reporter_default.fail("OPTIONAL_CALLBACK_CHILD_FAILED", {
272
+ traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
273
+ childNameSegment: options?.childName ? ` for ${options.childName}` : "",
274
+ actualCount: callbackChildren.length
275
+ });
276
+ }
277
+
278
+ // src/useOptionalChildMatching.ts
279
+ function useOptionalChildMatching(children, predicate, options) {
280
+ const matchingChildren = useChildrenMatching_default(children, predicate, options);
281
+ if (matchingChildren.length <= 1) {
282
+ return matchingChildren[0] ?? null;
283
+ }
284
+ return reporter_default.fail("OPTIONAL_CHILD_MATCHING_PREDICATE_FAILED", {
285
+ traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
286
+ childNameSegment: options?.childName ? ` for ${options.childName}` : "",
287
+ actualCount: matchingChildren.length,
288
+ actualCountPluralSuffix: matchingChildren.length === 1 ? "" : "ren"
289
+ });
290
+ }
291
+ var useOptionalChildMatching_default = useOptionalChildMatching;
292
+
293
+ // src/useOptionalChildByType.ts
294
+ function useOptionalChildByType(children, type, options) {
295
+ return useOptionalChildMatching_default(
296
+ children,
297
+ (element) => isElementOfType(element, type),
298
+ options
299
+ );
300
+ }
301
+
181
302
  // src/useRequiredChildMatching.ts
182
303
  function useRequiredChildMatching(children, predicate, options) {
183
- const child = useChildMatching(children, predicate);
304
+ const child = useChildMatching_default(children, predicate, options);
184
305
  if (child !== null) {
185
306
  return child;
186
307
  }
@@ -189,33 +310,93 @@ function useRequiredChildMatching(children, predicate, options) {
189
310
  childNameSegment: options?.childName ? ` for ${options.childName}` : ""
190
311
  });
191
312
  }
313
+ var useRequiredChildMatching_default = useRequiredChildMatching;
192
314
 
193
315
  // src/useRequiredChildByType.ts
194
316
  function useRequiredChildByType(children, type, options) {
195
- return useRequiredChildMatching(
317
+ return useRequiredChildMatching_default(
318
+ children,
319
+ (element) => isElementOfType(element, type),
320
+ options
321
+ );
322
+ }
323
+
324
+ // src/useRequiredCallbackChild.ts
325
+ import "react";
326
+ function useRequiredCallbackChild(children, options) {
327
+ const callbackChild = useCallbackChild(children);
328
+ if (callbackChild !== null) {
329
+ return callbackChild;
330
+ }
331
+ return reporter_default.fail("REQUIRED_CALLBACK_CHILD_FAILED", {
332
+ traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
333
+ childNameSegment: options?.childName ? ` for ${options.childName}` : ""
334
+ });
335
+ }
336
+
337
+ // src/useUniqueCallbackChild.ts
338
+ import { useMemo as useMemo6 } from "react";
339
+ function useUniqueCallbackChild(children, options) {
340
+ const callbackChildren = useMemo6(
341
+ () => callbackChildrenToArray(children),
342
+ [children]
343
+ );
344
+ if (callbackChildren.length === 1) {
345
+ return callbackChildren[0];
346
+ }
347
+ return reporter_default.fail("UNIQUE_CALLBACK_CHILD_FAILED", {
348
+ traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
349
+ childNameSegment: options?.childName ? ` for ${options.childName}` : "",
350
+ actualCount: callbackChildren.length
351
+ });
352
+ }
353
+
354
+ // src/useUniqueChildMatching.ts
355
+ function useUniqueChildMatching(children, predicate, options) {
356
+ const matchingChildren = useChildrenMatching_default(children, predicate, options);
357
+ if (matchingChildren.length === 1) {
358
+ return matchingChildren[0];
359
+ }
360
+ return reporter_default.fail("UNIQUE_CHILD_MATCHING_PREDICATE_FAILED", {
361
+ traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
362
+ childNameSegment: options?.childName ? ` for ${options.childName}` : "",
363
+ actualCount: matchingChildren.length,
364
+ actualCountPluralSuffix: matchingChildren.length === 1 ? "" : "ren"
365
+ });
366
+ }
367
+ var useUniqueChildMatching_default = useUniqueChildMatching;
368
+
369
+ // src/useUniqueChildByType.ts
370
+ function useUniqueChildByType(children, type, options) {
371
+ return useUniqueChildMatching_default(
196
372
  children,
197
373
  (element) => isElementOfType(element, type),
198
374
  options
199
375
  );
200
376
  }
201
377
  export {
202
- childrenToElements,
203
- isElementOfType,
204
- isReactElement,
205
378
  useBoundedChildrenByType,
206
- useBoundedChildrenMatching,
379
+ useBoundedChildrenMatching_default as useBoundedChildrenMatching,
380
+ useCallbackChild,
207
381
  useChildByType,
208
- useChildMatching,
382
+ useChildMatching_default as useChildMatching,
209
383
  useChildrenByType,
210
- useChildrenMatching,
384
+ useChildrenMatching_default as useChildrenMatching,
211
385
  useExactChildrenByType,
212
- useExactChildrenMatching,
213
- useHasChildMatching,
386
+ useExactChildrenMatching_default as useExactChildrenMatching,
387
+ useHasChildMatching_default as useHasChildMatching,
214
388
  useMaximumChildrenByType,
215
- useMaximumChildrenMatching,
389
+ useMaximumChildrenMatching_default as useMaximumChildrenMatching,
216
390
  useMinimumChildrenByType,
217
- useMinimumChildrenMatching,
391
+ useMinimumChildrenMatching_default as useMinimumChildrenMatching,
392
+ useOptionalCallbackChild,
393
+ useOptionalChildByType,
394
+ useOptionalChildMatching_default as useOptionalChildMatching,
395
+ useRequiredCallbackChild,
218
396
  useRequiredChildByType,
219
- useRequiredChildMatching
397
+ useRequiredChildMatching_default as useRequiredChildMatching,
398
+ useUniqueCallbackChild,
399
+ useUniqueChildByType,
400
+ useUniqueChildMatching_default as useUniqueChildMatching
220
401
  };
221
402
  //# sourceMappingURL=index.js.map