1import React, { ReactElement } from 'react';
2
3/** Returns the ID value of the first, and only, child element  */
4export function getChildId(children: ReactElement): string | undefined {
5  let inputId: unknown;
6
7  // Get the first, and only, child to retrieve form input's id
8  const child = React.Children.only(children);
9
10  // Retrieve input's id to apply on the label for correct click interaction
11  // For some components (like Select), we want to get the ID from a different prop
12  if ('id' in child?.props) {
13    inputId = child.props.id;
14  } else if ('inputId' in child.props) {
15    inputId = child?.props.inputId;
16  }
17
18  return typeof inputId === 'string' ? inputId : undefined;
19}
20
21/**
22 * Given react node or function returns element accordingly
23 *
24 * @param itemToRender
25 * @param props props to be passed to the function if item provided as such
26 */
27export function renderOrCallToRender<TProps = any>(
28  itemToRender: ((props?: TProps) => React.ReactNode) | React.ReactNode,
29  props?: TProps
30): React.ReactNode {
31  if (React.isValidElement(itemToRender) || typeof itemToRender === 'string' || typeof itemToRender === 'number') {
32    return itemToRender;
33  }
34
35  if (typeof itemToRender === 'function') {
36    return itemToRender(props);
37  }
38
39  throw new Error(`${itemToRender} is not a React element nor a function that returns React element`);
40}
41