CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-types--shared

Shared TypeScript type definitions for React Spectrum components and hooks, providing common interfaces for DOM interactions, styling, accessibility, internationalization, and component behavior across the React Spectrum ecosystem

Pending
Overview
Eval results
Files

refs.mddocs/

DOM References

DOM reference types and utilities for safe DOM node access and focus management with enhanced forwardRef support for generics.

Capabilities

DOM Reference Values

Reference value interfaces that provide safe access to DOM nodes.

/**
 * DOM ref value with safe DOM node access
 * @template T The type of HTML element (defaults to HTMLElement)
 */
interface DOMRefValue<T extends HTMLElement = HTMLElement> {
  /**
   * Returns the DOM node or null if not available.
   * Marked as UNSAFE to indicate direct DOM access should be used carefully.
   */
  UNSAFE_getDOMNode(): T | null;
}

/**
 * Focusable ref value with focus capabilities and DOM access
 * @template T The type of HTML element for focus operations
 * @template D The type of HTML element for DOM access (defaults to T)
 */
interface FocusableRefValue<T extends HTMLElement = HTMLElement, D extends HTMLElement = T>
  extends DOMRefValue<D> {
  /**
   * Focus the element programmatically
   */
  focus(): void;
}

Reference Types

Type aliases for working with DOM and focusable references.

/**
 * Ref type for DOM elements
 * @template T The type of HTML element (defaults to HTMLElement)
 */
type DOMRef<T extends HTMLElement = HTMLElement> = Ref<DOMRefValue<T>>;

/**
 * Ref type for focusable elements  
 * @template T The type of HTML element (defaults to HTMLElement)
 */
type FocusableRef<T extends HTMLElement = HTMLElement> = Ref<FocusableRefValue<T>>;

/**
 * Enhanced ref object interface
 * @template T The type of the ref value
 */
interface RefObject<T> {
  /** The current ref value */
  current: T;
}

Enhanced forwardRef

Enhanced forwardRef type declaration with proper generic support.

/**
 * Enhanced forwardRef function declaration that preserves generics
 * @template T The ref type
 * @template P The props type
 */
declare function forwardRef<T, P = {}>(
  render: (props: P, ref: Ref<T>) => ReactElement | null
): (props: P & RefAttributes<T>) => ReactElement | null;

/**
 * Type alias for the enhanced forwardRef function
 */
type forwardRefType = typeof forwardRef;

Usage Examples:

import { 
  DOMRef, 
  FocusableRef, 
  DOMRefValue, 
  FocusableRefValue,
  forwardRefType 
} from "@react-types/shared";
import { useRef, forwardRef, useImperativeHandle } from "react";

// Basic DOM ref usage
function ComponentWithDOMRef() {
  const divRef = useRef<DOMRefValue<HTMLDivElement>>(null);

  const handleClick = () => {
    const domNode = divRef.current?.UNSAFE_getDOMNode();
    if (domNode) {
      console.log("DOM node:", domNode);
    }
  };

  return <div ref={divRef} onClick={handleClick}>Click me</div>;
}

// Focusable ref usage
function ComponentWithFocusableRef() {
  const buttonRef = useRef<FocusableRefValue<HTMLButtonElement>>(null);

  const focusButton = () => {
    buttonRef.current?.focus();
  };

  return (
    <>
      <button ref={buttonRef}>Focusable Button</button>
      <button onClick={focusButton}>Focus the button</button>
    </>
  );
}

// Component that accepts DOM ref
interface ComponentProps {
  children: React.ReactNode;
}

const ComponentWithDOMRefProp = forwardRef<DOMRefValue<HTMLDivElement>, ComponentProps>(
  ({ children }, ref) => {
    const divRef = useRef<HTMLDivElement>(null);

    useImperativeHandle(ref, () => ({
      UNSAFE_getDOMNode: () => divRef.current
    }));

    return <div ref={divRef}>{children}</div>;
  }
);

// Component that accepts focusable ref
interface FocusableComponentProps {
  children: React.ReactNode;
  autoFocus?: boolean;
}

const FocusableComponent = forwardRef<FocusableRefValue<HTMLButtonElement>, FocusableComponentProps>(
  ({ children, autoFocus }, ref) => {
    const buttonRef = useRef<HTMLButtonElement>(null);

    useImperativeHandle(ref, () => ({
      UNSAFE_getDOMNode: () => buttonRef.current,
      focus: () => buttonRef.current?.focus()
    }));

    React.useEffect(() => {
      if (autoFocus) {
        buttonRef.current?.focus();
      }
    }, [autoFocus]);

    return <button ref={buttonRef}>{children}</button>;
  }
);

// Using the components
function App() {
  const domRef = useRef<DOMRefValue<HTMLDivElement>>(null);
  const focusableRef = useRef<FocusableRefValue<HTMLButtonElement>>(null);

  const handleDOMAccess = () => {
    const node = domRef.current?.UNSAFE_getDOMNode();
    console.log("DOM node:", node);
  };

  const handleFocus = () => {
    focusableRef.current?.focus();
  };

  return (
    <div>
      <ComponentWithDOMRefProp ref={domRef}>
        <p>Content</p>
      </ComponentWithDOMRefProp>
      
      <FocusableComponent ref={focusableRef}>
        Button Text
      </FocusableComponent>
      
      <button onClick={handleDOMAccess}>Access DOM</button>
      <button onClick={handleFocus}>Focus Button</button>
    </div>
  );
}

// Generic component with enhanced forwardRef
interface GenericComponentProps<T> {
  value: T;
  onChange: (value: T) => void;
}

const GenericComponent = forwardRef<HTMLInputElement, GenericComponentProps<string>>(
  ({ value, onChange }, ref) => {
    return (
      <input
        ref={ref}
        value={value}
        onChange={(e) => onChange(e.target.value)}
      />
    );
  }
);

Install with Tessl CLI

npx tessl i tessl/npm-react-types--shared

docs

collections.md

design-tokens.md

dom-aria.md

drag-drop.md

events.md

index.md

input-handling.md

labelable.md

refs.md

selection.md

styling.md

tile.json