import { dynamic } from "@solidjs/web";
import { omit } from "solid-js";
import { useDirection } from "../direction-provider/direction-provider-context.jsx";
import { composeRefs, userRef } from "../internals/compose-refs.jsx";
import { CompositeRootContext } from "../internals/composite/composite-context.jsx";
import { CompositeList } from "../internals/composite/composite-list.jsx";
import { useCompositeRoot } from "../internals/composite/composite-root.jsx";
import { createControlledState } from "../internals/create-controlled-state.jsx";
import { mergeRootProps } from "../internals/merge-root-props.jsx";
import { resolveClassStyle } from "../internals/resolve-class-style.jsx";
import { createStableCallback } from "../internals/stable-callback.jsx";
import { ToggleGroupContext } from "./toggle-group-context.jsx";

/**
 * State projected to `data-*` attributes. `orientation` projects via the
 * default mapping as `data-orientation="horizontal"` / `"vertical"`.
 * `disabled` + `multiple` are emitted as presence-only attrs.
 */

const EMPTY = Object.freeze([]);

/**
 * Groups a series of `<Toggle>` elements, coordinating their pressed state
 * through a single `value` array. Renders a `<div role="group">` (or `as`
 * override).
 *
 * §1 wave 2: replaces `renderElement` with `dynamic(() => props.as ?? "div")`.
 * The state-attr projection (`data-disabled`, `data-multiple`,
 * `data-orientation`) is emitted via inline reactive getters; the composite
 * root's `props` bag (aria-orientation, onKeyDown, onFocus) is composed via
 * `mergeRootProps`.
 */
export function ToggleGroup(props) {
  const disabled = () => props.disabled === true;
  const multiple = () => props.multiple === true;
  const orientation = () => props.orientation ?? "horizontal";
  const loopFocus = () => props.loopFocus ?? true;
  const direction = useDirection();

  // Controlled / uncontrolled group value (Base UI `value` / `defaultValue`
  // contract, mirroring React's `useControlled` in `ToggleGroup`): the
  // `value` prop wins while defined (an empty array IS controlled);
  // otherwise an internal signal (seeded once from `defaultValue`, else
  // `[]`) backs the state.
  const [value, setUncontrolledValue] = createControlledState({
    controlled: () => props.value,
    default: () => props.defaultValue,
    fallback: EMPTY,
    name: "<ToggleGroup>",
    state: "value"
  });
  const isValueInitialized = () => props.value !== undefined || props.defaultValue !== undefined;
  const setGroupValue = createStableCallback(() => (newValue, nextPressed, details) => {
    const current = value();
    let nextGroupValue;
    if (multiple()) {
      nextGroupValue = current.slice();
      if (nextPressed) {
        nextGroupValue.push(newValue);
      } else {
        const idx = nextGroupValue.indexOf(newValue);
        if (idx > -1) nextGroupValue.splice(idx, 1);
      }
    } else {
      nextGroupValue = nextPressed ? [newValue] : [];
    }
    // Base UI change flow: fire onValueChange first, honor
    // `details.cancel()`, then write the uncontrolled state (a no-op for
    // reads while the `value` prop is controlled).
    props.onValueChange?.(nextGroupValue, details);
    if (details.isCanceled) {
      return;
    }
    setUncontrolledValue(nextGroupValue);
  });
  const composite = useCompositeRoot({
    get orientation() {
      return orientation();
    },
    get loopFocus() {
      return loopFocus();
    },
    direction,
    enableHomeAndEndKeys: true
  });
  const rootContext = {
    highlightedIndex: composite.highlightedIndex,
    onHighlightedIndexChange: composite.onHighlightedIndexChange,
    highlightItemOnHover: () => false,
    relayKeyboardEvent: composite.relayKeyboardEvent,
    present: true
  };
  const contextValue = {
    value,
    setGroupValue,
    disabled,
    get orientation() {
      return orientation();
    },
    multiple,
    isValueInitialized,
    present: true
  };

  // Strip wrapper-owned API keys + `as` + `children` (re-injected wrapped
  // in providers below).
  const userStyling = resolveClassStyle(props, () => ({
    disabled: disabled(),
    multiple: multiple(),
    orientation: orientation()
  }));
  const userProps = omit(props, "class", "style", "attrs", "as", "children", "defaultValue", "disabled", "loopFocus", "multiple", "onValueChange", "orientation", "value");

  // Internal slot bag: role + state-attr getters + composite props
  // (aria-orientation, onKeyDown, onFocus). Inline reactive getters keep
  // the data-attrs live across upstream signal flips.
  const internalSlot = {
    role: "group",
    get "data-disabled"() {
      return disabled() ? "" : undefined;
    },
    get "data-multiple"() {
      return multiple() ? "" : undefined;
    },
    get "data-orientation"() {
      return orientation();
    }
  };
  const styledUserProps = mergeRootProps(userStyling, userProps);
  let merged = mergeRootProps(internalSlot, composite.props);
  merged = mergeRootProps(merged, styledUserProps);
  const Tag = dynamic(() => props.as ?? "div");
  return <Tag {...merged} ref={composeRefs(composite.rootRef, userRef(props))}>
			<ToggleGroupContext value={contextValue}>
				<CompositeRootContext value={rootContext}>
					<CompositeList elementsRef={composite.elementsRef} onMapChange={composite.onMapChange}>
						{props.children}
					</CompositeList>
				</CompositeRootContext>
			</ToggleGroupContext>
		</Tag>;
}
//# sourceMappingURL=toggle-group.jsx.map
