UNPKG

react-cmp-selector

Version:

A powerful and extensible utility for filtering and selecting React components based on specified attributes and values.

107 lines (106 loc) 4.06 kB
import React, { ReactElement, ReactNode } from 'react'; /** * Configuration options for finding and modifying React components * @template P - Props type of the target component */ export interface ComponentFinderProps<P = unknown> { /** React children to search through */ children: ReactNode; /** HTML attribute name to search for (default: 'data-slot') */ attribute?: string; /** Attribute value to match */ value?: string; /** Props to merge into the found component */ props?: Partial<P>; /** Enable debug logging */ debug?: boolean; /** Find all matching components */ findAll?: boolean; /** Callback triggered when component is found */ onFound?: (component: ReactElement) => void; /** Merge strategy for function props */ functionPropMerge?: 'combine' | 'override'; } /** * Custom React hook for finding components by attribute with enhanced capabilities * * @remarks * This hook provides advanced component searching with prop merging, debug capabilities, * and support for complex React trees. It's ideal for component injection patterns. * * @template P - Props type of the target component * @param options - Configuration options for the finder * @returns Found component(s) or null * * @example * // Find and modify a header component * const header = getCmpByAttr({ * value: 'header', * props: { className: 'sticky-header' } * }); * * @example * // Find all matching buttons with combined click handlers * const buttons = getCmpByAttr({ * attribute: 'data-role', * value: 'action-button', * findAll: true, * functionPropMerge: 'combine' * }); */ export declare function getCmpByAttr<P = unknown>({ children, attribute, value, props, debug, findAll, onFound, functionPropMerge }: ComponentFinderProps<P>): ReactNode | ReactNode[] | null; /** * Props for the Slot component * @template P - Props type of the slotted component */ export interface SlotProps<P = unknown> extends Omit<ComponentFinderProps<P>, 'value' | 'findAll' | 'onFound'> { /** Slot identifier to search for */ name: string; /** Fallback content when no slot is found */ fallback?: ReactNode; } /** * Declarative component version of getCmpByAttr * * @remarks * Provides a React component interface for the slot finding functionality * with additional validation and fallback capabilities. * * @example * <Slot name="header" fallback={<DefaultHeader />}> * {children} * </Slot> */ export declare function Slot<P = unknown>({ children, name, attribute, props, debug, fallback, functionPropMerge }: SlotProps<P>): string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null; /** * Utility functions for working with slots */ export declare const SlotUtils: { /** * Creates a slot marker component for type-safe slot declaration * * @param name - Slot identifier * @param attribute - Attribute name to use (default: 'data-slot') * @returns Slot marker component * * @example * const HeaderSlot = SlotUtils.createMarker('header'); * <HeaderSlot>...</HeaderSlot> */ createMarker: (name: string, attribute?: string) => ({ children, ...props }: { children?: ReactNode; } & Record<string, unknown>) => React.DetailedReactHTMLElement<{ [x: string]: unknown; style: { display: "contents"; }; }, HTMLElement>; /** * Validates required slots in development environment * * @param children - Component children to validate * @param requiredSlots - Array of required slot names * @param attribute - Attribute name to check (default: 'data-slot') */ validate: (children: ReactNode, requiredSlots: string[], attribute?: string) => void; };