import { dynamic } from "@solidjs/web";
import { createMemo, omit } from "solid-js";
import { useBaseUiId } from "../internals/base-ui-id.jsx";
import { createChangeEventDetails, REASONS } from "../internals/change-event-details.jsx";
import { composeRefs, userRef } from "../internals/compose-refs.jsx";
import { createControlledState } from "../internals/create-controlled-state.jsx";
import { useFieldRootContext } from "../internals/field-context.jsx";
import { fieldStateAttrs } from "../internals/field-state-attrs.jsx";
import { readOption } from "../internals/maybe-accessor.jsx";
import { mergeRootProps } from "../internals/merge-root-props.jsx";
import { resolveClassStyle } from "../internals/resolve-class-style.jsx";
import { areArraysEqual } from "../internals/slider-utils/are-arrays-equal.jsx";
import { useFieldControlValidation } from "../internals/use-field-control-validation/use-field-control-validation.jsx";
import { useValueChanged } from "../internals/use-value-changed.jsx";
import { createCheckboxGroup } from "./create-checkbox-group.jsx";

/**
 * State projected to `data-*` attributes. Extends the field-root state —
 * forms/fields drive the `data-*` validity surface.
 */

const EMPTY = Object.freeze([]);

/**
 * Provides a shared value array to a series of `<Checkbox.Root>` elements.
 * Renders a `<div role="group">` (or `as` override).
 *
 * §1 wave 2: replaces `renderElement` with `dynamic(() => props.as ?? "div")`.
 * Field-validity attrs (`data-valid`/`data-invalid`/`data-touched`/`data-dirty`/
 * `data-filled`/`data-focused`) flow via `fieldStateAttrs(state)`; the
 * `data-disabled` presence attr is emitted via an inline getter; aria-invalid
 * + aria-describedby come from `validation.getValidationProps()`.
 */
export function CheckboxGroup(props) {
  const field = useFieldRootContext();
  const id = useBaseUiId(typeof props.id === "string" ? props.id : undefined);

  // Controlled / uncontrolled value array (Base UI `value` / `defaultValue`
  // contract, mirroring React's `useControlled` in `CheckboxGroup`): the
  // `value` prop wins while its resolved value is defined (an empty array
  // IS controlled); otherwise an internal signal (seeded once from
  // `defaultValue`, else `[]`) backs the state.
  const [resolvedValue, setUncontrolledValue] = createControlledState({
    controlled: () => readOption(props.value),
    default: () => readOption(props.defaultValue),
    fallback: EMPTY,
    name: "<CheckboxGroup>",
    state: "value"
  });

  // Base UI exposes `defaultValue` on the group context only while
  // uncontrolled (`externalValue === undefined ? defaultValueProp ?? [] :
  // undefined`) — child checkboxes derive their own seed from it.
  const contextDefaultValue = () => readOption(props.value) === undefined ? readOption(props.defaultValue) ?? EMPTY : undefined;
  const c = createCheckboxGroup({
    value: resolvedValue,
    defaultValue: contextDefaultValue,
    allValues: () => readOption(props.allValues),
    disabled: () => field.disabled() || readOption(props.disabled) === true,
    onValueChange: (next, event) => {
      const details = createChangeEventDetails(REASONS.none, event);
      // 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?.(next, details);
      if (details.isCanceled) {
        event.preventDefault();
        return;
      }
      setUncontrolledValue(next);
    }
  });
  const value = c.value;
  const controlRef = {
    current: null
  };
  const validation = useFieldControlValidation({
    value: () => value() ?? EMPTY,
    id: () => id,
    controlRef,
    getValue: () => value() ?? EMPTY,
    enabled: () => !!field.name()
  });
  useValueChanged(() => value() ?? EMPTY, () => {
    const current = value() ?? EMPTY;
    const initial = field.validityData().initialValue;
    const initialArr = Array.isArray(initial) ? initial : EMPTY;
    field.setFilled(current.length > 0);
    field.setDirty(!areArraysEqual(current, initialArr));
    if (field.shouldValidateOnChange()) {
      void validation.commit(current);
    } else {
      void validation.commit(current, true);
    }
  });
  const state = createMemo(() => ({
    ...field.state(),
    disabled: c.disabled()
  }));
  const userStyling = resolveClassStyle(props, () => state());
  const userProps = omit(props, "class", "style", "attrs", "as", "allValues", "children", "defaultValue", "disabled", "id", "onValueChange", "value");

  // Internal slot bag: id, role, data-disabled, plus aria-invalid /
  // aria-describedby from field-validation. Field-state validity attrs
  // flow through `fieldStateAttrs(state)`.
  const internalSlot = {
    id,
    role: "group",
    get "data-disabled"() {
      return c.disabled() ? "" : undefined;
    }
  };
  const validationBag = validation.getValidationProps() ?? {};
  const styledUserProps = mergeRootProps(userStyling, userProps);
  let merged = mergeRootProps(internalSlot, validationBag);
  merged = mergeRootProps(merged, fieldStateAttrs(state));
  merged = mergeRootProps(merged, styledUserProps);
  const Tag = dynamic(() => props.as ?? "div");
  return <Tag {...merged} ref={composeRefs(el => {
    controlRef.current = el;
  }, userRef(props))}>
			<c.Provider>{props.children}</c.Provider>
		</Tag>;
}
//# sourceMappingURL=checkbox-group.jsx.map
