{"version":3,"sources":["../src/components/ui.tsx"],"names":["React","UI","as","styles","style","classes","className","children","defaultStyles","props","ref","Component","styleObj","ui_default"],"mappings":"AAAA,OAAOA,MAAW,QAwTlB,IAAMC,EAAkBD,EAAM,WAC5B,CACE,CAAE,GAAAE,EAAI,OAAAC,EAAQ,MAAAC,EAAO,QAAAC,EAAS,UAAAC,EAAW,SAAAC,EAAU,cAAAC,EAAe,GAAGC,CAAM,EAC3EC,IACG,CACH,IAAMC,EAAYT,GAAM,MAElBU,EAAgC,CAAE,GAAGJ,EAAe,GAAGL,EAAQ,GAAGC,CAAM,EAM9E,OACEJ,EAAA,cAACW,EAAA,CAAW,GAAGF,EAAO,IAAKC,EAAK,MAAOE,EAAU,UAH5BP,GAAWC,GAI7BC,CACH,CAEJ,CACF,EAEOM,EAAQZ,EACfA,EAAG,YAAc","sourcesContent":["import React from \"react\";\n\n/**\n * Extracts the appropriate ref type for a given element type.\n *\n * This utility type ensures that refs are properly typed based on the element\n * being rendered. For example, a button element receives HTMLButtonElement ref.\n * Excludes legacy string refs (deprecated since React 16.3).\n *\n * @typeParam C - The HTML element type (e.g., 'button', 'div', 'a')\n * @example\n * ```typescript\n * type ButtonRef = PolymorphicRef<'button'>; // React.Ref<HTMLButtonElement>\n * type DivRef = PolymorphicRef<'div'>; // React.Ref<HTMLDivElement>\n * ```\n */\ntype PolymorphicRef<C extends React.ElementType> = React.Ref<\n  React.ElementRef<C>\n>;\n\n/**\n * Defines the 'as' prop that determines which HTML element to render.\n *\n * This is the core prop that enables polymorphic behavior, allowing components\n * to render as any valid React element type while maintaining type safety.\n *\n * @typeParam C - The HTML element type to render\n * @example\n * ```typescript\n * <UI as=\"button\">Click me</UI>\n * <UI as=\"a\" href=\"/home\">Link</UI>\n * ```\n */\ntype AsProp<C extends React.ElementType> = {\n  as?: C;\n};\n\n/**\n * Identifies props that should be omitted to prevent type conflicts.\n *\n * This type ensures that our custom props don't conflict with native element\n * props by calculating which keys need to be omitted from the native props.\n *\n * @typeParam C - The HTML element type\n * @typeParam P - The custom props to merge\n */\ntype PropsToOmit<C extends React.ElementType, P> = keyof (AsProp<C> & P);\n\n/**\n * Merges custom props with native element props while preventing conflicts.\n *\n * This creates a union of our custom props and the native props for the chosen\n * element, omitting any conflicting keys to ensure type safety.\n *\n * @typeParam C - The HTML element type\n * @typeParam Props - The custom props to add\n * @example\n * ```typescript\n * // For a button, this merges custom props with HTMLButtonElement props\n * type ButtonProps = PolymorphicComponentProp<'button', { variant?: string }>;\n * ```\n */\ntype PolymorphicComponentProp<\n  C extends React.ElementType,\n  Props extends object = Record<string, never>,\n> = React.PropsWithChildren<Props & AsProp<C>> &\n  Omit<React.ComponentPropsWithoutRef<C>, PropsToOmit<C, Props>>;\n\n/**\n * Extends PolymorphicComponentProp to include properly-typed ref support.\n *\n * This is the final type in the polymorphic type chain, adding ref forwarding\n * with the correct ref type for the chosen element. The ref is properly typed\n * to match the element being rendered, enabling focus management and direct\n * DOM access for accessibility features like programmatic focus control.\n *\n * Supports both PolymorphicRef and ForwardedRef for compatibility with\n * React.forwardRef components.\n *\n * @typeParam C - The HTML element type\n * @typeParam Props - The custom props to add\n *\n * @example\n * ```typescript\n * // Using ref for focus management (important for accessibility)\n * const buttonRef = useRef<HTMLButtonElement>(null);\n * useEffect(() => {\n *   // Programmatically focus for keyboard navigation\n *   buttonRef.current?.focus();\n * }, []);\n *\n * return <UI as=\"button\" ref={buttonRef}>Accessible Button</UI>;\n * ```\n */\ntype PolymorphicComponentPropWithRef<\n  C extends React.ElementType,\n  Props extends object = Record<string, never>,\n> = PolymorphicComponentProp<C, Props> & {\n  ref?: PolymorphicRef<C> | React.ForwardedRef<React.ElementRef<C>>;\n};\n\n/**\n * Props for the UI component, extending polymorphic props with style and class support.\n *\n * The UI component automatically forwards all ARIA attributes and native HTML props\n * to the rendered element, ensuring full accessibility support. This includes:\n * - `aria-label`, `aria-labelledby` - Accessible names for screen readers\n * - `aria-describedby` - Additional descriptive text references\n * - `aria-expanded`, `aria-controls` - Interactive widget states\n * - `role` - Semantic role override when needed\n * - All other ARIA attributes and HTML props\n *\n * @typeParam C - The HTML element type to render\n * @property {boolean} [renderStyles] - Reserved for future use. Currently has no effect.\n *   Styles are always rendered regardless of this prop value.\n * @property {React.CSSProperties} [styles] - Inline styles to apply (overrides defaultStyles)\n * @property {React.CSSProperties} [defaultStyles] - Base styles that can be overridden by styles prop\n * @property {string} [classes] - CSS class names to apply to the element (custom prop)\n * @property {string} [className] - CSS class names to apply to the element (React standard prop)\n * @property {string} [id] - HTML id attribute\n * @property {React.ReactNode} [children] - Child elements to render\n *\n * @example\n * ```typescript\n * // All ARIA attributes are automatically forwarded\n * <UI as=\"button\" aria-label=\"Close dialog\" aria-expanded={isOpen}>\n *   <CloseIcon />\n * </UI>\n * ```\n */\ntype UIProps<C extends React.ElementType> = PolymorphicComponentPropWithRef<\n  C,\n  {\n    /** @deprecated Reserved for future use. Currently has no effect. Styles are always rendered. */\n    renderStyles?: boolean;\n    styles?: React.CSSProperties;\n    defaultStyles?: React.CSSProperties;\n    classes?: string;\n    className?: string;\n    id?: string;\n    children?: React.ReactNode;\n  }\n>;\n\n/**\n * UI Component function signature.\n *\n * Defines the polymorphic component that can render as any HTML element while\n * maintaining full TypeScript type safety for element-specific props.\n *\n * @typeParam C - The HTML element type to render (defaults to 'div')\n * @param {UIProps<C>} props - Component props including 'as', styles, and native element props\n * @returns {React.ReactElement} A React element of the specified type\n * @example\n * ```typescript\n * <UI as=\"button\" onClick={handler}>Button</UI>\n * <UI as=\"a\" href=\"/link\">Link</UI>\n * <UI>Default div</UI>\n * ```\n */\ntype UIComponent = (<C extends React.ElementType = \"div\">(\n  props: UIProps<C>\n) => React.ReactElement | null) & { displayName?: string };\n\n/**\n * UI - A polymorphic React component that can render as any HTML element.\n *\n * The UI component is a foundational primitive used throughout fpkit to create\n * flexible, type-safe components. It implements the polymorphic component pattern,\n * allowing a single component to render as different HTML elements while maintaining\n * full TypeScript type safety for element-specific props.\n *\n * ## Accessibility Considerations\n *\n * The UI component forwards all ARIA attributes and native HTML props, placing\n * accessibility responsibility on the consumer. When creating interactive elements,\n * you MUST ensure WCAG 2.1 AA compliance:\n *\n * - **Accessible Names**: All interactive elements need an accessible name via\n *   `aria-label`, `aria-labelledby`, or visible text content\n * - **Semantic HTML**: Prefer semantic elements (`button`, `a`, `nav`) over\n *   generic containers (`div`, `span`) with ARIA roles when possible\n * - **Focus Indicators**: Ensure focus indicators meet WCAG 2.4.7 (3:1 contrast)\n * - **Keyboard Support**: Interactive elements must be keyboard accessible\n *\n * @typeParam C - The HTML element type to render (e.g., 'button', 'div', 'a')\n *\n * @param {C} [as='div'] - The HTML element type to render. Defaults to 'div'.\n * @param {React.CSSProperties} [styles] - Inline styles to apply. Overrides defaultStyles.\n * @param {string} [classes] - CSS class names to apply (custom prop). Takes precedence over className.\n * @param {string} [className] - CSS class names to apply (React standard). Used if classes is not provided.\n * @param {React.CSSProperties} [defaultStyles] - Base styles that can be overridden by styles prop.\n * @param {React.ReactNode} [children] - Child elements to render inside the component.\n * @param {PolymorphicRef<C>} [ref] - Forwarded ref with proper typing for the element type.\n * @param {boolean} [renderStyles] - Reserved for future use. Currently has no effect.\n *\n * @returns {React.ReactElement} A React element of the specified type with merged props.\n *\n * @example\n * // Basic usage - renders as div\n * <UI>Hello World</UI>\n *\n * @example\n * // Polymorphic rendering - renders as button with type-safe props\n * <UI as=\"button\" onClick={handleClick} disabled>\n *   Click me\n * </UI>\n *\n * @example\n * // ✅ GOOD: Accessible button with aria-label for icon-only button\n * <UI as=\"button\" aria-label=\"Close dialog\" onClick={handleClose}>\n *   <CloseIcon />\n * </UI>\n *\n * @example\n * // ✅ GOOD: Accessible link with descriptive text\n * <UI as=\"a\" href=\"/products\">\n *   View all products\n * </UI>\n *\n * @example\n * // ✅ GOOD: Interactive element with proper role and keyboard support\n * <UI\n *   as=\"div\"\n *   role=\"button\"\n *   tabIndex={0}\n *   aria-label=\"Toggle menu\"\n *   onClick={handleToggle}\n *   onKeyDown={(e) => e.key === 'Enter' && handleToggle()}\n * >\n *   Menu\n * </UI>\n *\n * @example\n * // ❌ BAD: Button without accessible name (screen readers can't identify it)\n * <UI as=\"button\" onClick={handleClose}>\n *   <CloseIcon />\n * </UI>\n *\n * @example\n * // ❌ BAD: Non-semantic div with click handler (not keyboard accessible)\n * <UI as=\"div\" onClick={handleClick}>\n *   Click me\n * </UI>\n *\n * @example\n * // ✅ GOOD: Custom focus indicator with WCAG 2.4.7 compliant contrast\n * <UI\n *   as=\"button\"\n *   styles={{\n *     outline: '2px solid transparent',\n *     outlineOffset: '2px',\n *   }}\n *   classes=\"focus:outline-blue-500\"\n * >\n *   Accessible Button\n * </UI>\n *\n * @example\n * // Style merging - defaultStyles provide base, styles override\n * <UI\n *   as=\"span\"\n *   defaultStyles={{ padding: '0.5rem', color: 'blue' }}\n *   styles={{ color: 'red' }}\n * >\n *   Red text with padding\n * </UI>\n *\n * @example\n * // Ref forwarding for focus management\n * const buttonRef = useRef<HTMLButtonElement>(null);\n * useEffect(() => {\n *   // Programmatically focus for keyboard navigation\n *   buttonRef.current?.focus();\n * }, []);\n * <UI as=\"button\" ref={buttonRef}>Auto-focused Button</UI>\n *\n * @example\n * // Building accessible higher-level components with TypeScript\n * interface AccessibleButtonProps extends React.ComponentPropsWithoutRef<'button'> {\n *   variant?: 'primary' | 'secondary';\n *   // Require either aria-label or children for accessibility\n *   'aria-label'?: string;\n *   children?: React.ReactNode;\n * }\n *\n * const AccessibleButton = React.forwardRef<HTMLButtonElement, AccessibleButtonProps>(\n *   ({ variant = 'primary', ...props }, ref) => {\n *     // Runtime check: ensure accessible name is provided\n *     if (!props['aria-label'] && !props.children) {\n *       console.warn('AccessibleButton requires either aria-label or children');\n *     }\n *\n *     return (\n *       <UI\n *         as=\"button\"\n *         ref={ref}\n *         defaultStyles={{\n *           padding: '0.5rem 1rem',\n *           borderRadius: '0.25rem',\n *           backgroundColor: variant === 'primary' ? '#007bff' : '#6c757d',\n *         }}\n *         {...props}\n *       />\n *     );\n *   }\n * );\n */\n// `as unknown as UIComponent` is required: React.forwardRef returns ForwardRefExoticComponent which is\n// structurally incompatible with the polymorphic UIComponent call signature at the type level.\n// This double-cast is the standard pattern for polymorphic forwardRef components (used by Radix UI and similar libraries).\n// eslint-disable-next-line react/display-name -- displayName is set explicitly two lines below; ESLint can't see post-definition assignment\nconst UI: UIComponent = React.forwardRef(\n  <C extends React.ElementType>(\n    { as, styles, style, classes, className, children, defaultStyles, ...props }: UIProps<C>,\n    ref?: PolymorphicRef<C>\n  ) => {\n    const Component = as ?? \"div\";\n\n    const styleObj: React.CSSProperties = { ...defaultStyles, ...styles, ...style };\n\n    // Support both 'classes' (custom) and 'className' (React standard)\n    // 'classes' takes precedence if both are provided\n    const classNameValue = classes ?? className;\n\n    return (\n      <Component {...props} ref={ref} style={styleObj} className={classNameValue}>\n        {children}\n      </Component>\n    );\n  }\n) as unknown as UIComponent;\n\nexport default UI;\nUI.displayName = \"UI\";\n"]}