function read(value) {
  return typeof value === "function" ? value() : value;
}

/**
 * Minimal event shape we need for our `onKeyDown` swallow. Covers both Solid
 * JSX events and raw DOM `KeyboardEvent`s.
 */

/**
 * Port of Base UI React's `useFocusableWhenDisabled`
 * (`packages/react/src/utils/useFocusableWhenDisabled.ts`). Produces the
 * narrow set of overrides that let a disabled button-like element remain
 * focusable when the consumer opts in.
 *
 * Solid 2 notes:
 *
 * - Every input may be an accessor. Reads happen inside getters / handlers,
 *   so there is no top-level reactive read in the primitive's body.
 * - ARIA boolean attributes surface as the literal `"true"` / `"false"`
 *   strings (RFC 07) rather than native booleans, matching how `useButton`
 *   already serializes them.
 * - The returned props are a plain proxy-shaped object — splice it into a
 *   `params.props` array and `mergePropsN` handles the rest. Handlers
 *   compose right-to-left with any consumer keybindings.
 */
export function useFocusableWhenDisabled(options) {
  const disabled = () => read(options.disabled) === true;
  const focusableWhenDisabled = () => read(options.focusableWhenDisabled);
  const composite = () => read(options.composite) === true;
  const tabIndexOption = () => read(options.tabIndex) ?? 0;
  const isNativeButton = () => read(options.isNativeButton) ?? true;

  // React parity: on native disabled + focusableWhenDisabled, swallow Tab
  // so the consumer can't accidentally cancel its own tab-navigation, but
  // preventDefault on every other key so activation keys don't fire.
  function onKeyDown(event) {
    if (!disabled()) return;
    if (!focusableWhenDisabled()) return;
    if (event.key === "Tab") return;
    event.preventDefault?.();
  }
  const props = Object.defineProperties(Object.create(null), {
    onKeyDown: {
      enumerable: true,
      configurable: true,
      value: onKeyDown
    },
    tabIndex: {
      enumerable: true,
      configurable: true,
      get: () => {
        // Composite items delegate tab-order to their parent — skip.
        if (composite()) return undefined;
        const native = isNativeButton();
        const isDisabled = disabled();
        if (!native && isDisabled) {
          return focusableWhenDisabled() ? tabIndexOption() : -1;
        }
        return tabIndexOption();
      }
    },
    "aria-disabled": {
      enumerable: true,
      configurable: true,
      // Per Solid 2 RFC 07: ARIA pseudo-boolean attrs take a literal
      // string (not raw boolean), so screen readers see the expected
      // "true"/"false" value.
      get: () => {
        const native = isNativeButton();
        const isDisabled = disabled();
        const fwd = focusableWhenDisabled();
        const isFocusableComposite = composite() && fwd !== false;
        if (native && (fwd || isFocusableComposite) || !native && isDisabled) {
          return isDisabled ? "true" : "false";
        }
        return undefined;
      }
    },
    disabled: {
      enumerable: true,
      configurable: true,
      // Native path only: when focusableWhenDisabled kicks in we
      // clear the native `disabled` attr (so the element still
      // participates in the tab order). Non-focusable composite
      // items keep the attr so the browser can render the visual
      // disabled affordance.
      get: () => {
        if (!isNativeButton()) return undefined;
        const fwd = focusableWhenDisabled();
        const isNonFocusableComposite = composite() && fwd === false;
        if (!fwd || isNonFocusableComposite) {
          return disabled();
        }
        return undefined;
      }
    }
  });
  return {
    props
  };
}
//# sourceMappingURL=use-focusable-when-disabled.jsx.map
