import { dynamic } from "@solidjs/web";
import { omit } from "solid-js";
import { composeRefs, userRef } from "../../internals/compose-refs.jsx";
import { mergeRootProps } from "../../internals/merge-root-props.jsx";
import { useButton } from "../../internals/use-button/use-button.jsx";
import { useCollapsible } from "../create-collapsible.jsx";

/**
 * Props for {@link CollapsibleTrigger}.
 *
 * Stage-01c rewire: this wrapper is now a structural adapter over
 * `useCollapsible()` (axes A + G + P). `render={}` is gone — use `as=`
 * to swap the underlying tag/component.
 */

/**
 * A button that opens and closes the collapsible panel. Renders a `<button>`
 * element (or `as` override).
 *
 * Solid 2 notes:
 *
 * - Reads the collapsible API via `useCollapsible()` — works both under
 *   `<Collapsible.Root>` (which provides the new `CollapsibleContext`) and
 *   inside accordion items (which bridge both contexts).
 * - `useButton` provides keyboard activation (Space/Enter) and
 *   disabled-suppression via `event.preventDefault()`. Composed via
 *   `mergeRootProps(buttonProps, c.trigger(userProps))`: `buttonProps` is
 *   the "internal" side (runs first), `c.trigger(userProps)` is the "user"
 *   side. This ordering ensures `useButton`'s disabled check fires before the
 *   toggle onClick. When disabled, `useButton.onClick` calls `preventDefault()`
 *   which gates the `mergeRootProps` chain and stops the toggle from running.
 * - All keys from both sides use plain-object getters (not a Proxy), so every
 *   key is always in `ownKeys` regardless of its current value. This avoids the
 *   Solid 2 undefined-attr tracking footgun: `data-panel-open` is in `ownKeys`
 *   even when closed (returning `undefined`) so the reactive binding is
 *   established on first spread.
 * - `aria-expanded` emits the literal `"true"`/`"false"` string (not a raw
 *   boolean) because RFC 07's enumerated-pseudo-boolean rules collapse raw
 *   `true` to a presence-only attribute, and screen readers expect the string.
 * - `aria-controls` is gated on `open` (matching React's `open ? panelId :
 *   undefined`) — the getter returns `undefined` while closed, so the attribute
 *   is omitted rather than dangling at a panel that isn't in the DOM (notably
 *   under SSR). `mergeRootProps` keeps the key reactive across spreads even when
 *   it starts `undefined`, so the old `""`-seed undefined-attr workaround is no
 *   longer needed (see `create-collapsible.tsx`).
 */
export function CollapsibleTrigger(props) {
  const c = useCollapsible();

  // Context `disabled` wins unless the consumer explicitly overrides it.
  const disabled = () => {
    const own = props.disabled;
    if (own !== undefined) return Boolean(own);
    return c.disabled();
  };
  const nativeButton = () => props.nativeButton ?? true;
  const {
    props: buttonProps,
    ref: buttonRef
  } = useButton({
    disabled,
    focusableWhenDisabled: () => true,
    native: nativeButton
  });

  // Strip our config keys before passing user props into the trigger slot.
  const userProps = omit(props, "as", "disabled", "nativeButton");

  // Compose: buttonProps is "internal" (runs first on onClick), c.trigger()
  // is "user" (runs second, gated by defaultPrevented). This ordering preserves
  // the disabled check from useButton gating the toggle handler.
  //
  // Both sides return plain objects with Object.defineProperty getters, so ALL
  // keys survive in the output's ownKeys regardless of current value — Solid's
  // compiled spread sees them and sets up reactive bindings even for keys whose
  // initial value is undefined (e.g. data-panel-open when closed).
  const merged = mergeRootProps(buttonProps, c.trigger(userProps));
  const Tag = dynamic(() => props.as ?? "button");
  return <Tag {...merged} ref={composeRefs(buttonRef, userRef(props))} />;
}
//# sourceMappingURL=collapsible-trigger.jsx.map
