UNPKG

@synergycodes/overflow-ui

Version:

A React library for creating node-based UIs and diagram-driven applications. Perfect for React Flow users, providing ready-to-use node templates and components that work seamlessly with React Flow's ecosystem.

71 lines (70 loc) 2.79 kB
import { ReactElement } from 'react'; import { NavLabelButtonProps } from './nav-label-button/nav-label-button'; import { NavIconButtonProps } from './nav-icon-button/nav-icon-button'; import { NavIconLabelButtonProps } from './nav-icon-label-button/nav-icon-label-button'; type WithRef<T> = T & { ref?: React.Ref<HTMLButtonElement>; }; /** * NavButtonProps defines **discriminated overloads** for the Button component using * **structural discrimination** rather than a `type` field. * * The component dynamically determines which button variant to render based on the * **structure of the `children` prop**: * * - If `children` is a single `string`, it's treated as a **Label Button**. * - If `children` is a single icon (ReactElement), it's treated as an **Icon Button**. * - If `children` includes both a string and one or two icons (before/after), * it's treated as an **Icon Label Button**. * * Based on the inferred variant, **only props specific to that variant are allowed**. * This ensures that incorrect prop combinations (e.g., passing label-specific props * to an Icon Button) are caught at compile time. * * This is intentionally implemented with **overloads** instead of a union type, * which would incorrectly allow mixing props between types and compromise type safety. */ type NavButtonProps = { (props: WithRef<NavLabelButtonProps>): ReactElement; (props: WithRef<NavIconButtonProps>): ReactElement; (props: WithRef<NavIconLabelButtonProps>): ReactElement; }; /** * Button is a flexible, and type-safe component that automatically selects * the correct type (Label Button, Icon Button, or Icon Label Button) based on the * structure of its `children` prop. * * **Automatic Type Selection (Structural Discrimination)** * The component uses the shape of `children` to infer which button variant to render: * - **Label Button**: If `children` is a single `string` * - **Icon Button**: If `children` is a single React element (e.g., an icon) * - **Icon Label Button**: If `children` is a combination of string + icon(s) * * **Type Safety via Overloads** * Each variant supports its own unique set of props. Thanks to TypeScript overloads, * only the correct props for a given structure are allowed—invalid combinations * are caught at compile time. * * **How to Use** * * ```tsx * <NavButton>Submit</NavButton> // Label Button * * <NavButton> * <Icon/> * </NavButton> // Icon Button * * <NavButton> * <Icon /> * Confirm * <Icon /> * </NavButton> // Icon Label Button * ``` * * This approach ensures: * - Simplified usage with fewer props * - No accidental mixing of incompatible props * - Autocomplete and type-checking experience */ export declare const NavButton: NavButtonProps; export {};