react-children-hooks 0.2.0 → 0.4.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/README.md CHANGED
@@ -2,32 +2,52 @@
2
2
 
3
3
  `react-children-hooks` is a TypeScript-first React library for inspecting, traversing, querying, and validating `props.children`.
4
4
 
5
+ Element-based query and validation hooks inspect direct children by default, and can optionally traverse deeper descendant levels through `QueryOptions`, `TraversalOptions`, and `ValidationOptions`.
6
+
5
7
  ## API Reference
6
8
 
7
9
  ### Query Hooks
8
10
 
9
- - [`useChildByType`](./docs/api/useChildByType.md)
10
- - [`useChildWhere`](./docs/api/useChildWhere.md)
11
- - [`useChildrenByType`](./docs/api/useChildrenByType.md)
12
- - [`useChildrenWhere`](./docs/api/useChildrenWhere.md)
13
-
14
- ### Validation + Query Hooks
15
-
16
- - [`useExactChildrenWhere`](./docs/api/useExactChildrenWhere.md)
17
- - [`useMaximumChildrenWhere`](./docs/api/useMaximumChildrenWhere.md)
18
- - [`useMinimumChildrenWhere`](./docs/api/useMinimumChildrenWhere.md)
19
- - [`useRequiredChildWhere`](./docs/api/useRequiredChildWhere.md)
11
+ - [`useCallbackChild`](./docs/useCallbackChild.md)
12
+ - [`useChildByType`](./docs/useChildByType.md)
13
+ - [`useChildMatching`](./docs/useChildMatching.md)
14
+ - [`useChildrenByType`](./docs/useChildrenByType.md)
15
+ - [`useChildrenMatching`](./docs/useChildrenMatching.md)
16
+
17
+ ### Query + Validation Hooks
18
+
19
+ - [`useBoundedChildrenByType`](./docs/useBoundedChildrenByType.md)
20
+ - [`useBoundedChildrenMatching`](./docs/useBoundedChildrenMatching.md)
21
+ - [`useExactChildrenByType`](./docs/useExactChildrenByType.md)
22
+ - [`useExactChildrenMatching`](./docs/useExactChildrenMatching.md)
23
+ - [`useMaximumChildrenByType`](./docs/useMaximumChildrenByType.md)
24
+ - [`useMaximumChildrenMatching`](./docs/useMaximumChildrenMatching.md)
25
+ - [`useMinimumChildrenByType`](./docs/useMinimumChildrenByType.md)
26
+ - [`useMinimumChildrenMatching`](./docs/useMinimumChildrenMatching.md)
27
+ - [`useOptionalChildByType`](./docs/useOptionalChildByType.md)
28
+ - [`useOptionalChildMatching`](./docs/useOptionalChildMatching.md)
29
+ - [`useRequiredCallbackChild`](./docs/useRequiredCallbackChild.md)
30
+ - [`useRequiredChildByType`](./docs/useRequiredChildByType.md)
31
+ - [`useRequiredChildMatching`](./docs/useRequiredChildMatching.md)
32
+ - [`useUniqueChildByType`](./docs/useUniqueChildByType.md)
33
+ - [`useUniqueChildMatching`](./docs/useUniqueChildMatching.md)
20
34
 
21
35
  ### Validation Hooks
22
36
 
23
- - [`useHasChildWhere`](./docs/api/useHasChildWhere.md)
37
+ - [`useHasChildMatching`](./docs/useHasChildMatching.md)
24
38
 
25
39
  ### Utilities
26
40
 
27
- - [`childrenToElements`](./docs/api/childrenToElements.md)
28
- - [`isElementOfType`](./docs/api/isElementOfType.md)
29
- - [`isReactElement`](./docs/api/isReactElement.md)
41
+ - [`childrenToElements`](./docs/childrenToElements.md)
42
+ - [`isElementOfType`](./docs/isElementOfType.md)
43
+ - [`isReactElement`](./docs/isReactElement.md)
30
44
 
31
45
  ### Types
32
46
 
33
- - [`ElementOfType`](./docs/api/ElementOfType.md)
47
+ - [`CallbackChild`](./src/types.ts)
48
+ - [`CallbackChildren`](./src/types.ts)
49
+ - [`ChildrenCountBounds`](./src/types.ts)
50
+ - [`ElementOfType`](./src/types.ts)
51
+ - [`QueryOptions`](./src/types.ts)
52
+ - [`TraversalOptions`](./src/types.ts)
53
+ - [`ValidationOptions`](./src/types.ts)
package/dist/index.cjs CHANGED
@@ -23,15 +23,27 @@ __export(index_exports, {
23
23
  childrenToElements: () => childrenToElements,
24
24
  isElementOfType: () => isElementOfType,
25
25
  isReactElement: () => isReactElement,
26
+ useBoundedChildrenByType: () => useBoundedChildrenByType,
27
+ useBoundedChildrenMatching: () => useBoundedChildrenMatching,
28
+ useCallbackChild: () => useCallbackChild,
26
29
  useChildByType: () => useChildByType,
27
- useChildWhere: () => useChildWhere,
30
+ useChildMatching: () => useChildMatching,
28
31
  useChildrenByType: () => useChildrenByType,
29
- useChildrenWhere: () => useChildrenWhere,
30
- useExactChildrenWhere: () => useExactChildrenWhere,
31
- useHasChildWhere: () => useHasChildWhere,
32
- useMaximumChildrenWhere: () => useMaximumChildrenWhere,
33
- useMinimumChildrenWhere: () => useMinimumChildrenWhere,
34
- useRequiredChildWhere: () => useRequiredChildWhere
32
+ useChildrenMatching: () => useChildrenMatching,
33
+ useExactChildrenByType: () => useExactChildrenByType,
34
+ useExactChildrenMatching: () => useExactChildrenMatching,
35
+ useHasChildMatching: () => useHasChildMatching,
36
+ useMaximumChildrenByType: () => useMaximumChildrenByType,
37
+ useMaximumChildrenMatching: () => useMaximumChildrenMatching,
38
+ useMinimumChildrenByType: () => useMinimumChildrenByType,
39
+ useMinimumChildrenMatching: () => useMinimumChildrenMatching,
40
+ useOptionalChildByType: () => useOptionalChildByType,
41
+ useOptionalChildMatching: () => useOptionalChildMatching,
42
+ useRequiredCallbackChild: () => useRequiredCallbackChild,
43
+ useRequiredChildByType: () => useRequiredChildByType,
44
+ useRequiredChildMatching: () => useRequiredChildMatching,
45
+ useUniqueChildByType: () => useUniqueChildByType,
46
+ useUniqueChildMatching: () => useUniqueChildMatching
35
47
  });
36
48
  module.exports = __toCommonJS(index_exports);
37
49
 
@@ -40,7 +52,7 @@ function isElementOfType(element, type) {
40
52
  return element.type === type;
41
53
  }
42
54
 
43
- // src/useChildWhere.ts
55
+ // src/useChildMatching.ts
44
56
  var import_react3 = require("react");
45
57
 
46
58
  // src/childrenToElements.ts
@@ -52,65 +64,162 @@ function isReactElement(node) {
52
64
  return (0, import_react.isValidElement)(node);
53
65
  }
54
66
 
67
+ // src/reporter.ts
68
+ var import_runtime_reporter = require("runtime-reporter");
69
+ var validationMessages = {
70
+ OPTIONAL_CHILD_MATCHING_PREDICATE_FAILED: "{{ traceCodePrefix }}Optional child validation failed{{ childNameSegment }} because {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected at most 1.",
71
+ UNIQUE_CHILD_MATCHING_PREDICATE_FAILED: "{{ traceCodePrefix }}Unique child validation failed{{ childNameSegment }} because {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected exactly 1.",
72
+ REQUIRED_CHILD_MATCHING_PREDICATE_FAILED: "{{ traceCodePrefix }}Required child validation failed{{ childNameSegment }} because no direct child satisfied the provided predicate.",
73
+ REQUIRED_CALLBACK_CHILD_FAILED: "{{ traceCodePrefix }}Required callback child validation failed{{ childNameSegment }} because no direct callback child was found.",
74
+ 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 }}.",
75
+ MAXIMUM_CHILDREN_MATCHING_PREDICATE_FAILED: "{{ traceCodePrefix }}Maximum children validation failed{{ childNameSegment }} because {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected at most {{ maximumCount }}.",
76
+ EXACT_CHILDREN_MATCHING_PREDICATE_FAILED: "{{ traceCodePrefix }}Exact children validation failed{{ childNameSegment }} because {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected exactly {{ exactCount }}.",
77
+ 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."
78
+ };
79
+ var publicMessages = {
80
+ RCH001: '[RCH001] Traversal option "depth" must be a non-negative integer.',
81
+ RCH002: '[RCH002] Traversal option "maximumDepth" must be a non-negative integer.',
82
+ RCH003: '[RCH003] Traversal option "depth" cannot be greater than "maximumDepth".'
83
+ };
84
+ var messages = {
85
+ ...validationMessages,
86
+ ...publicMessages
87
+ };
88
+ var reporter = (0, import_runtime_reporter.createReporter)(
89
+ process.env.NODE_ENV === "production" ? {} : messages,
90
+ { formatMessage: (message) => message }
91
+ );
92
+ var reporter_default = reporter;
93
+
55
94
  // src/childrenToElements.ts
56
- function childrenToElements(children) {
57
- return import_react2.Children.toArray(children).filter(isReactElement);
95
+ function getTraversalBounds(options) {
96
+ const depth = options?.depth ?? 0;
97
+ const maximumDepth = options?.maximumDepth ?? 0;
98
+ if (!Number.isInteger(depth) || depth < 0) {
99
+ return reporter_default.fail("RCH001");
100
+ }
101
+ if (!Number.isInteger(maximumDepth) || maximumDepth < 0) {
102
+ return reporter_default.fail("RCH002");
103
+ }
104
+ if (depth > maximumDepth) {
105
+ return reporter_default.fail("RCH003");
106
+ }
107
+ return { depth, maximumDepth };
108
+ }
109
+ function collectElementsAtDepth(children, currentDepth, depth, maximumDepth) {
110
+ const directElements = import_react2.Children.toArray(children).filter(isReactElement);
111
+ let elements = [];
112
+ if (currentDepth >= depth && currentDepth <= maximumDepth) {
113
+ elements = [...directElements];
114
+ }
115
+ for (const element of directElements) {
116
+ const elementProps = element.props;
117
+ const elementsAtDepth = collectElementsAtDepth(
118
+ elementProps.children,
119
+ currentDepth + 1,
120
+ depth,
121
+ maximumDepth
122
+ );
123
+ elements.push(...elementsAtDepth);
124
+ }
125
+ return elements;
126
+ }
127
+ function childrenToElements(children, options) {
128
+ const { depth, maximumDepth } = getTraversalBounds(options);
129
+ return collectElementsAtDepth(children, 0, depth, maximumDepth);
58
130
  }
59
131
 
60
- // src/useChildWhere.ts
61
- function useChildWhere(children, predicate) {
132
+ // src/useChildMatching.ts
133
+ function useChildMatching(children, predicate, options) {
62
134
  return (0, import_react3.useMemo)(
63
- () => childrenToElements(children).find(predicate) ?? null,
64
- [children, predicate]
135
+ () => childrenToElements(children, options).find(predicate) ?? null,
136
+ [children, options, predicate]
65
137
  );
66
138
  }
67
139
 
68
140
  // src/useChildByType.ts
69
- function useChildByType(children, type) {
70
- return useChildWhere(
141
+ function useChildByType(children, type, options) {
142
+ return useChildMatching(
71
143
  children,
72
- (element) => isElementOfType(element, type)
144
+ (element) => isElementOfType(element, type),
145
+ options
73
146
  );
74
147
  }
75
148
 
76
- // src/useChildrenWhere.ts
149
+ // src/useCallbackChild.ts
77
150
  var import_react4 = require("react");
78
- function useChildrenWhere(children, predicate) {
79
- return (0, import_react4.useMemo)(
80
- () => childrenToElements(children).filter(predicate),
81
- [children, predicate]
151
+ function findFirstCallbackChild(children) {
152
+ if (typeof children === "function") {
153
+ return children;
154
+ }
155
+ if (!Array.isArray(children)) {
156
+ return null;
157
+ }
158
+ for (const child of children) {
159
+ const callbackChild = findFirstCallbackChild(
160
+ child
161
+ );
162
+ if (callbackChild) {
163
+ return callbackChild;
164
+ }
165
+ }
166
+ return null;
167
+ }
168
+ function useCallbackChild(children) {
169
+ return (0, import_react4.useMemo)(() => findFirstCallbackChild(children), [children]);
170
+ }
171
+
172
+ // src/useChildrenMatching.ts
173
+ var import_react5 = require("react");
174
+ function useChildrenMatching(children, predicate, options) {
175
+ return (0, import_react5.useMemo)(
176
+ () => childrenToElements(children, options).filter(predicate),
177
+ [children, options, predicate]
82
178
  );
83
179
  }
84
180
 
85
- // src/useChildrenByType.ts
86
- function useChildrenByType(children, type) {
87
- return useChildrenWhere(
181
+ // src/useBoundedChildrenMatching.ts
182
+ function useBoundedChildrenMatching(children, predicate, bounds, options) {
183
+ const matchingChildren = useChildrenMatching(children, predicate, options);
184
+ if (matchingChildren.length >= bounds.minimum && matchingChildren.length <= bounds.maximum) {
185
+ return matchingChildren;
186
+ }
187
+ return reporter_default.fail("BOUNDED_CHILDREN_MATCHING_PREDICATE_FAILED", {
188
+ traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
189
+ childNameSegment: options?.childName ? ` for ${options.childName}` : "",
190
+ actualCount: matchingChildren.length,
191
+ actualCountPluralSuffix: matchingChildren.length === 1 ? "" : "ren",
192
+ minimumCount: bounds.minimum,
193
+ maximumCount: bounds.maximum
194
+ });
195
+ }
196
+
197
+ // src/useBoundedChildrenByType.ts
198
+ function useBoundedChildrenByType(children, type, bounds, options) {
199
+ return useBoundedChildrenMatching(
88
200
  children,
89
- (element) => isElementOfType(element, type)
201
+ (element) => isElementOfType(element, type),
202
+ bounds,
203
+ options
90
204
  );
91
205
  }
92
206
 
93
- // src/reporter.ts
94
- var import_runtime_reporter = require("runtime-reporter");
95
- var messages = {
96
- REQUIRED_CHILD_WHERE_PREDICATE_FAILED: "{{ traceCodePrefix }}Required child validation failed{{ childNameSegment }} because no direct child satisfied the provided predicate.",
97
- MINIMUM_CHILDREN_WHERE_PREDICATE_FAILED: "{{ traceCodePrefix }}Minimum children validation failed{{ childNameSegment }} because only {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected at least {{ minimumCount }}.",
98
- MAXIMUM_CHILDREN_WHERE_PREDICATE_FAILED: "{{ traceCodePrefix }}Maximum children validation failed{{ childNameSegment }} because {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected at most {{ maximumCount }}.",
99
- EXACT_CHILDREN_WHERE_PREDICATE_FAILED: "{{ traceCodePrefix }}Exact children validation failed{{ childNameSegment }} because {{ actualCount }} direct child{{ actualCountPluralSuffix }} satisfied the provided predicate; expected exactly {{ exactCount }}."
100
- };
101
- var reporter = (0, import_runtime_reporter.createReporter)(
102
- process.env.NODE_ENV === "production" ? {} : messages,
103
- { formatMessage: (message) => message }
104
- );
105
- var reporter_default = reporter;
207
+ // src/useChildrenByType.ts
208
+ function useChildrenByType(children, type, options) {
209
+ return useChildrenMatching(
210
+ children,
211
+ (element) => isElementOfType(element, type),
212
+ options
213
+ );
214
+ }
106
215
 
107
- // src/useExactChildrenWhere.ts
108
- function useExactChildrenWhere(children, predicate, exactCount, options) {
109
- const matchingChildren = useChildrenWhere(children, predicate);
216
+ // src/useExactChildrenMatching.ts
217
+ function useExactChildrenMatching(children, predicate, exactCount, options) {
218
+ const matchingChildren = useChildrenMatching(children, predicate, options);
110
219
  if (matchingChildren.length === exactCount) {
111
220
  return matchingChildren;
112
221
  }
113
- return reporter_default.fail("EXACT_CHILDREN_WHERE_PREDICATE_FAILED", {
222
+ return reporter_default.fail("EXACT_CHILDREN_MATCHING_PREDICATE_FAILED", {
114
223
  traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
115
224
  childNameSegment: options?.childName ? ` for ${options.childName}` : "",
116
225
  actualCount: matchingChildren.length,
@@ -119,22 +228,32 @@ function useExactChildrenWhere(children, predicate, exactCount, options) {
119
228
  });
120
229
  }
121
230
 
122
- // src/useHasChildWhere.ts
123
- var import_react5 = require("react");
124
- function useHasChildWhere(children, predicate) {
125
- return (0, import_react5.useMemo)(
126
- () => childrenToElements(children).some(predicate),
127
- [children, predicate]
231
+ // src/useExactChildrenByType.ts
232
+ function useExactChildrenByType(children, type, exactCount, options) {
233
+ return useExactChildrenMatching(
234
+ children,
235
+ (element) => isElementOfType(element, type),
236
+ exactCount,
237
+ options
238
+ );
239
+ }
240
+
241
+ // src/useHasChildMatching.ts
242
+ var import_react6 = require("react");
243
+ function useHasChildMatching(children, predicate, options) {
244
+ return (0, import_react6.useMemo)(
245
+ () => childrenToElements(children, options).some(predicate),
246
+ [children, options, predicate]
128
247
  );
129
248
  }
130
249
 
131
- // src/useMaximumChildrenWhere.ts
132
- function useMaximumChildrenWhere(children, predicate, maximumCount, options) {
133
- const matchingChildren = useChildrenWhere(children, predicate);
250
+ // src/useMaximumChildrenMatching.ts
251
+ function useMaximumChildrenMatching(children, predicate, maximumCount, options) {
252
+ const matchingChildren = useChildrenMatching(children, predicate, options);
134
253
  if (matchingChildren.length <= maximumCount) {
135
254
  return matchingChildren;
136
255
  }
137
- return reporter_default.fail("MAXIMUM_CHILDREN_WHERE_PREDICATE_FAILED", {
256
+ return reporter_default.fail("MAXIMUM_CHILDREN_MATCHING_PREDICATE_FAILED", {
138
257
  traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
139
258
  childNameSegment: options?.childName ? ` for ${options.childName}` : "",
140
259
  actualCount: matchingChildren.length,
@@ -143,13 +262,23 @@ function useMaximumChildrenWhere(children, predicate, maximumCount, options) {
143
262
  });
144
263
  }
145
264
 
146
- // src/useMinimumChildrenWhere.ts
147
- function useMinimumChildrenWhere(children, predicate, minimumCount, options) {
148
- const matchingChildren = useChildrenWhere(children, predicate);
265
+ // src/useMaximumChildrenByType.ts
266
+ function useMaximumChildrenByType(children, type, maximumCount, options) {
267
+ return useMaximumChildrenMatching(
268
+ children,
269
+ (element) => isElementOfType(element, type),
270
+ maximumCount,
271
+ options
272
+ );
273
+ }
274
+
275
+ // src/useMinimumChildrenMatching.ts
276
+ function useMinimumChildrenMatching(children, predicate, minimumCount, options) {
277
+ const matchingChildren = useChildrenMatching(children, predicate, options);
149
278
  if (matchingChildren.length >= minimumCount) {
150
279
  return matchingChildren;
151
280
  }
152
- return reporter_default.fail("MINIMUM_CHILDREN_WHERE_PREDICATE_FAILED", {
281
+ return reporter_default.fail("MINIMUM_CHILDREN_MATCHING_PREDICATE_FAILED", {
153
282
  traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
154
283
  childNameSegment: options?.childName ? ` for ${options.childName}` : "",
155
284
  actualCount: matchingChildren.length,
@@ -158,30 +287,120 @@ function useMinimumChildrenWhere(children, predicate, minimumCount, options) {
158
287
  });
159
288
  }
160
289
 
161
- // src/useRequiredChildWhere.ts
162
- function useRequiredChildWhere(children, predicate, options) {
163
- const child = useChildWhere(children, predicate);
290
+ // src/useMinimumChildrenByType.ts
291
+ function useMinimumChildrenByType(children, type, minimumCount, options) {
292
+ return useMinimumChildrenMatching(
293
+ children,
294
+ (element) => isElementOfType(element, type),
295
+ minimumCount,
296
+ options
297
+ );
298
+ }
299
+
300
+ // src/useOptionalChildMatching.ts
301
+ function useOptionalChildMatching(children, predicate, options) {
302
+ const matchingChildren = useChildrenMatching(children, predicate, options);
303
+ if (matchingChildren.length <= 1) {
304
+ return matchingChildren[0] ?? null;
305
+ }
306
+ return reporter_default.fail("OPTIONAL_CHILD_MATCHING_PREDICATE_FAILED", {
307
+ traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
308
+ childNameSegment: options?.childName ? ` for ${options.childName}` : "",
309
+ actualCount: matchingChildren.length,
310
+ actualCountPluralSuffix: matchingChildren.length === 1 ? "" : "ren"
311
+ });
312
+ }
313
+
314
+ // src/useOptionalChildByType.ts
315
+ function useOptionalChildByType(children, type, options) {
316
+ return useOptionalChildMatching(
317
+ children,
318
+ (element) => isElementOfType(element, type),
319
+ options
320
+ );
321
+ }
322
+
323
+ // src/useRequiredChildMatching.ts
324
+ function useRequiredChildMatching(children, predicate, options) {
325
+ const child = useChildMatching(children, predicate, options);
164
326
  if (child !== null) {
165
327
  return child;
166
328
  }
167
- return reporter_default.fail("REQUIRED_CHILD_WHERE_PREDICATE_FAILED", {
329
+ return reporter_default.fail("REQUIRED_CHILD_MATCHING_PREDICATE_FAILED", {
330
+ traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
331
+ childNameSegment: options?.childName ? ` for ${options.childName}` : ""
332
+ });
333
+ }
334
+
335
+ // src/useRequiredChildByType.ts
336
+ function useRequiredChildByType(children, type, options) {
337
+ return useRequiredChildMatching(
338
+ children,
339
+ (element) => isElementOfType(element, type),
340
+ options
341
+ );
342
+ }
343
+
344
+ // src/useRequiredCallbackChild.ts
345
+ var import_react7 = require("react");
346
+ function useRequiredCallbackChild(children, options) {
347
+ const callbackChild = useCallbackChild(children);
348
+ if (callbackChild !== null) {
349
+ return callbackChild;
350
+ }
351
+ return reporter_default.fail("REQUIRED_CALLBACK_CHILD_FAILED", {
168
352
  traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
169
353
  childNameSegment: options?.childName ? ` for ${options.childName}` : ""
170
354
  });
171
355
  }
356
+
357
+ // src/useUniqueChildMatching.ts
358
+ function useUniqueChildMatching(children, predicate, options) {
359
+ const matchingChildren = useChildrenMatching(children, predicate, options);
360
+ if (matchingChildren.length === 1) {
361
+ return matchingChildren[0];
362
+ }
363
+ return reporter_default.fail("UNIQUE_CHILD_MATCHING_PREDICATE_FAILED", {
364
+ traceCodePrefix: options?.traceCode ? `[${options.traceCode}] ` : "",
365
+ childNameSegment: options?.childName ? ` for ${options.childName}` : "",
366
+ actualCount: matchingChildren.length,
367
+ actualCountPluralSuffix: matchingChildren.length === 1 ? "" : "ren"
368
+ });
369
+ }
370
+
371
+ // src/useUniqueChildByType.ts
372
+ function useUniqueChildByType(children, type, options) {
373
+ return useUniqueChildMatching(
374
+ children,
375
+ (element) => isElementOfType(element, type),
376
+ options
377
+ );
378
+ }
172
379
  // Annotate the CommonJS export names for ESM import in node:
173
380
  0 && (module.exports = {
174
381
  childrenToElements,
175
382
  isElementOfType,
176
383
  isReactElement,
384
+ useBoundedChildrenByType,
385
+ useBoundedChildrenMatching,
386
+ useCallbackChild,
177
387
  useChildByType,
178
- useChildWhere,
388
+ useChildMatching,
179
389
  useChildrenByType,
180
- useChildrenWhere,
181
- useExactChildrenWhere,
182
- useHasChildWhere,
183
- useMaximumChildrenWhere,
184
- useMinimumChildrenWhere,
185
- useRequiredChildWhere
390
+ useChildrenMatching,
391
+ useExactChildrenByType,
392
+ useExactChildrenMatching,
393
+ useHasChildMatching,
394
+ useMaximumChildrenByType,
395
+ useMaximumChildrenMatching,
396
+ useMinimumChildrenByType,
397
+ useMinimumChildrenMatching,
398
+ useOptionalChildByType,
399
+ useOptionalChildMatching,
400
+ useRequiredCallbackChild,
401
+ useRequiredChildByType,
402
+ useRequiredChildMatching,
403
+ useUniqueChildByType,
404
+ useUniqueChildMatching
186
405
  });
187
406
  //# sourceMappingURL=index.cjs.map