import { Children, Fragment, isValidElement, ReactNode } from 'react'; import { hasAnyStaticProperty } from '../hasStaticProperty'; /** * Filter out child components that have any of the specified static properties * * **Search Depth:** This function only searches 1 level deep: * - Direct children of the provided children * - Direct children inside React.Fragment components (1 level of fragment nesting) * - Does NOT recursively search nested fragments or deeply nested components * * **Styled Component Support:** Checks component.target and component.__emotion_base * for styled() wrapped components. * * @example * ```ts * // ✅ Will filter out: Direct children with matching properties * * * // ✅ Will filter out: Children inside fragments with matching properties * <> * * // ❌ Will NOT filter: Nested fragments * <><> * * // ❌ Will NOT filter: Deeply nested *
* ``` * * @param children Any React children * @param staticPropertiesToExclude Array of static property names to filter out * @returns ReactNode with matching components filtered out */ export const filterChildren = ( children: ReactNode, staticPropertiesToExclude: Array, ): ReactNode => { // Handle empty/null children - Children.map returns null for these cases if (!children) return []; return Children.map(children, child => { if (!isValidElement(child)) return child; // Handle fragments by filtering their children if (child.type === Fragment) { // Children.map automatically flattens the returned array, // maintaining the fragment flattening behavior return Children.map(child.props.children, fragmentChild => { if (!isValidElement(fragmentChild)) return fragmentChild; if ( hasAnyStaticProperty(fragmentChild.type, staticPropertiesToExclude) ) { return null; // Filter out - React ignores null returns } return fragmentChild; }); } // Filter direct children if (hasAnyStaticProperty(child.type, staticPropertiesToExclude)) { return null; // Filter out - React ignores null returns } return child; }); };