import {
  createSize
} from "../chunk/KVL5CS3M.jsx";
import {
  COLOR_INTL_TRANSLATIONS,
  parseColor
} from "../chunk/KNLKPWUU.jsx";
import {
  useLocale
} from "../chunk/LR7LBJN3.jsx";
import {
  FORM_CONTROL_FIELD_PROP_NAMES,
  createFormControlField
} from "../chunk/NGHEENNE.jsx";
import {
  FormControlLabel
} from "../chunk/FOXVCQFV.jsx";
import {
  createFormResetListener
} from "../chunk/QJIB6BDF.jsx";
import {
  FormControlErrorMessage
} from "../chunk/ZZYKR3VO.jsx";
import {
  FORM_CONTROL_PROP_NAMES,
  FormControlContext,
  FormControlDescription,
  createFormControl,
  useFormControlContext
} from "../chunk/XUUROM4M.jsx";
import "../chunk/JNCCF6MP.jsx";
import {
  createControllableSignal
} from "../chunk/FN6EICGO.jsx";
import "../chunk/OYES4GOP.jsx";
import {
  Polymorphic
} from "../chunk/FLVHQV4A.jsx";
import "../chunk/5WXHJDCZ.jsx";

// src/color-wheel/color-wheel-input.tsx
import {
  callHandler,
  mergeDefaultProps,
  visuallyHiddenStyles
} from "@kobalte/utils";
import { splitProps } from "solid-js";
import { combineStyle } from "@solid-primitives/props";

// src/color-wheel/color-wheel-context.tsx
import { createContext, useContext } from "solid-js";
var ColorWheelContext = createContext();
function useColorWheelContext() {
  const context = useContext(ColorWheelContext);
  if (context === void 0) {
    throw new Error(
      "[kobalte]: `useColorWheelContext` must be used within a `ColorWheel` component"
    );
  }
  return context;
}

// src/color-wheel/color-wheel-input.tsx
function ColorWheelInput(props) {
  const formControlContext = useFormControlContext();
  const context = useColorWheelContext();
  const mergedProps = mergeDefaultProps(
    {
      id: context.generateId("input")
    },
    props
  );
  const [local, formControlFieldProps, others] = splitProps(
    mergedProps,
    ["style", "onChange"],
    FORM_CONTROL_FIELD_PROP_NAMES
  );
  const { fieldProps } = createFormControlField(formControlFieldProps);
  const onChange = (e) => {
    callHandler(e, local.onChange);
    const target = e.target;
    context.state.setHue(Number.parseFloat(target.value));
    target.value = String(context.state.hue()) ?? "";
  };
  return <input
    type="range"
    id={fieldProps.id()}
    name={formControlContext.name()}
    tabIndex={context.state.isDisabled() ? void 0 : -1}
    min={context.state.minValue()}
    max={context.state.maxValue()}
    step={context.state.step()}
    value={context.state.hue()}
    required={formControlContext.isRequired()}
    disabled={formControlContext.isDisabled()}
    readonly={formControlContext.isReadOnly()}
    style={combineStyle({ ...visuallyHiddenStyles }, local.style)}
    aria-valuetext={context.getThumbValueLabel()}
    aria-label={fieldProps.ariaLabel()}
    aria-labelledby={fieldProps.ariaLabelledBy()}
    aria-describedby={fieldProps.ariaDescribedBy()}
    aria-invalid={formControlContext.validationState() === "invalid" || void 0}
    aria-required={formControlContext.isRequired() || void 0}
    aria-disabled={formControlContext.isDisabled() || void 0}
    aria-readonly={formControlContext.isReadOnly() || void 0}
    onChange={onChange}
    {...formControlContext.dataset()}
    {...others}
  />;
}

// src/color-wheel/color-wheel-root.tsx
import {
  access,
  createGenerateId,
  mergeDefaultProps as mergeDefaultProps3,
  mergeRefs
} from "@kobalte/utils";
import {
  createMemo as createMemo2,
  createSignal as createSignal2,
  createUniqueId,
  splitProps as splitProps2
} from "solid-js";

// src/color-wheel/create-color-wheel-state.ts
import { mergeDefaultProps as mergeDefaultProps2 } from "@kobalte/utils";
import { createMemo, createSignal } from "solid-js";

// src/color-wheel/utils.ts
function roundToStep(value, step) {
  return Math.round(value / step) * step;
}
function mod(n, m) {
  return (n % m + m) % m;
}
function roundDown(v) {
  const r = Math.floor(v);
  if (r === v) {
    return v - 1;
  }
  return r;
}
function degToRad(deg) {
  return deg * Math.PI / 180;
}
function radToDeg(rad) {
  return rad * 180 / Math.PI;
}
function angleToCartesian(angle, radius) {
  const rad = degToRad(360 - angle + 90);
  const x = Math.sin(rad) * radius;
  const y = Math.cos(rad) * radius;
  return { x, y };
}
function cartesianToAngle(x, y, radius) {
  const deg = radToDeg(Math.atan2(y / radius, x / radius));
  return (deg + 360) % 360;
}

// src/color-wheel/create-color-wheel-state.ts
function createColorWheelState(props) {
  const mergedProps = mergeDefaultProps2(
    {
      isDisabled: () => false
    },
    props
  );
  const defaultValue = createMemo(() => {
    return mergedProps.defaultValue() ?? parseColor("hsl(0, 100%, 50%)");
  });
  const [value, setValue] = createControllableSignal({
    value: mergedProps.value,
    defaultValue,
    onChange: (value2) => mergedProps.onChange?.(value2)
  });
  const color = createMemo(() => {
    const colorSpace = value().getColorSpace();
    return colorSpace === "hsl" || colorSpace === "hsb" ? value() : value().toFormat("hsl");
  });
  const channelRange = () => color().getChannelRange("hue");
  const step = () => channelRange().step;
  const pageSize = () => channelRange().pageSize;
  const maxValue = () => channelRange().maxValue;
  const minValue = () => channelRange().minValue;
  const [isDragging, setIsDragging] = createSignal(false);
  const resetValue = () => {
    setValue(defaultValue());
  };
  const hue = () => color().getChannelValue("hue");
  const setHue = (value2) => {
    let newValue = value2 > 360 ? 0 : value2;
    newValue = roundToStep(mod(newValue, 360), step());
    if (hue() !== newValue) {
      setValue(color().withChannelValue("hue", newValue));
    }
  };
  const increment = (stepSize = 1) => {
    const newStepSize = Math.max(stepSize, step());
    let newValue = hue() + newStepSize;
    if (newValue >= maxValue()) {
      newValue = minValue();
    }
    setHue(roundToStep(mod(newValue, 360), newStepSize));
  };
  const decrement = (stepSize = 1) => {
    const newStepSize = Math.max(stepSize, step());
    if (hue() === 0) {
      setHue(roundDown(360 / newStepSize) * newStepSize);
    } else {
      setHue(roundToStep(mod(hue() - newStepSize, 360), newStepSize));
    }
  };
  const getThumbPosition = () => angleToCartesian(hue(), mergedProps.thumbRadius());
  const setThumbValue = (x, y, radius) => {
    if (mergedProps.isDisabled())
      return;
    setHue(cartesianToAngle(x, y, radius));
  };
  const updateDragging = (dragging) => {
    if (mergedProps.isDisabled())
      return;
    const wasDragging = isDragging();
    setIsDragging(dragging);
    if (wasDragging && !isDragging()) {
      mergedProps.onChangeEnd?.(color());
    }
  };
  return {
    value: color,
    setValue,
    hue,
    setHue,
    step,
    pageSize,
    maxValue,
    minValue,
    increment,
    decrement,
    getThumbPosition,
    setThumbValue,
    isDragging,
    setIsDragging: updateDragging,
    resetValue,
    isDisabled: mergedProps.isDisabled
  };
}

// src/color-wheel/color-wheel-root.tsx
function ColorWheelRoot(props) {
  const [ref, setRef] = createSignal2();
  const defaultId = `colorwheel-${createUniqueId()}`;
  const mergedProps = mergeDefaultProps3(
    {
      id: defaultId,
      getValueLabel: (param) => param.formatChannelValue("hue"),
      translations: COLOR_INTL_TRANSLATIONS,
      disabled: false,
      thickness: 30
    },
    props
  );
  const [local, formControlProps, others] = splitProps2(
    mergedProps,
    [
      "ref",
      "value",
      "defaultValue",
      "thickness",
      "onChange",
      "onChangeEnd",
      "getValueLabel",
      "translations",
      "disabled"
    ],
    FORM_CONTROL_PROP_NAMES
  );
  const { formControlContext } = createFormControl(formControlProps);
  const { direction } = useLocale();
  const [trackRef, setTrackRef] = createSignal2();
  const [thumbRef, setThumbRef] = createSignal2();
  const size = createSize(trackRef);
  const outerRadius = createMemo2(() => {
    if (size.width() === 0)
      return void 0;
    return size.width() / 2;
  });
  const thumbRadius = () => (139.75 - local.thickness / 100 * 70) * outerRadius() / 140;
  const state = createColorWheelState({
    value: () => local.value,
    defaultValue: () => local.defaultValue,
    thumbRadius,
    onChange: local.onChange,
    onChangeEnd: local.onChangeEnd,
    isDisabled: () => formControlContext.isDisabled() ?? false
  });
  createFormResetListener(ref, () => state.resetValue());
  const isLTR = () => direction() === "ltr";
  let currentPosition = null;
  const onDragStart = (value) => {
    state.setIsDragging(true);
    state.setThumbValue(
      value[0],
      value[1],
      Math.sqrt(value[0] * value[0] + value[1] * value[1])
    );
    currentPosition = null;
  };
  const onDrag = ({ deltaX, deltaY }) => {
    if (currentPosition === null) {
      currentPosition = state.getThumbPosition();
    }
    currentPosition.x += deltaX;
    currentPosition.y += deltaY;
    state.setThumbValue(currentPosition.x, currentPosition.y, thumbRadius());
    local.onChange?.(state.value());
  };
  const onDragEnd = () => {
    state.setIsDragging(false);
    thumbRef()?.focus();
  };
  const getThumbValueLabel = () => `${state.value().formatChannelValue("hue")}, ${context.state.value().getHueName(local.translations)}`;
  const onHomeKeyDown = (event) => {
    if (!formControlContext.isDisabled()) {
      event.preventDefault();
      event.stopPropagation();
      state.setHue(state.minValue());
    }
  };
  const onEndKeyDown = (event) => {
    if (!formControlContext.isDisabled()) {
      event.preventDefault();
      event.stopPropagation();
      state.setHue(state.maxValue());
    }
  };
  const onStepKeyDown = (event) => {
    if (!formControlContext.isDisabled()) {
      switch (event.key) {
        case "Left":
        case "ArrowLeft":
          event.preventDefault();
          event.stopPropagation();
          if (!isLTR()) {
            state.increment(event.shiftKey ? state.pageSize() : state.step());
          } else {
            state.decrement(event.shiftKey ? state.pageSize() : state.step());
          }
          break;
        case "Down":
        case "ArrowDown":
          event.preventDefault();
          event.stopPropagation();
          state.decrement(event.shiftKey ? state.pageSize() : state.step());
          break;
        case "Up":
        case "ArrowUp":
          event.preventDefault();
          event.stopPropagation();
          state.increment(event.shiftKey ? state.pageSize() : state.step());
          break;
        case "Right":
        case "ArrowRight":
          event.preventDefault();
          event.stopPropagation();
          if (!isLTR()) {
            state.decrement(event.shiftKey ? state.pageSize() : state.step());
          } else {
            state.increment(event.shiftKey ? state.pageSize() : state.step());
          }
          break;
        case "Home":
          onHomeKeyDown(event);
          break;
        case "End":
          onEndKeyDown(event);
          break;
        case "PageUp":
          event.preventDefault();
          event.stopPropagation();
          state.increment(state.pageSize());
          break;
        case "PageDown":
          event.preventDefault();
          event.stopPropagation();
          state.decrement(state.pageSize());
          break;
      }
    }
  };
  const context = {
    state,
    outerRadius,
    thickness: () => local.thickness,
    onDragStart,
    onDrag,
    onDragEnd,
    getThumbValueLabel,
    getValueLabel: local.getValueLabel,
    onStepKeyDown,
    trackRef,
    setTrackRef,
    thumbRef,
    setThumbRef,
    generateId: createGenerateId(() => access(formControlProps.id))
  };
  return <FormControlContext.Provider value={formControlContext}><ColorWheelContext.Provider value={context}><Polymorphic
    as="div"
    ref={mergeRefs(setRef, local.ref)}
    role="group"
    id={access(formControlProps.id)}
    {...formControlContext.dataset()}
    {...others}
  /></ColorWheelContext.Provider></FormControlContext.Provider>;
}

// src/color-wheel/color-wheel-thumb.tsx
import { callHandler as callHandler2, mergeDefaultProps as mergeDefaultProps4, mergeRefs as mergeRefs2 } from "@kobalte/utils";
import { combineStyle as combineStyle2 } from "@solid-primitives/props";
import {
  createSignal as createSignal3,
  splitProps as splitProps3
} from "solid-js";
function ColorWheelThumb(props) {
  const context = useColorWheelContext();
  const formControlContext = useFormControlContext();
  const mergedProps = mergeDefaultProps4(
    {
      id: context.generateId("thumb")
    },
    props
  );
  const [local, formControlFieldProps, others] = splitProps3(
    mergedProps,
    ["style", "onKeyDown", "onPointerDown", "onPointerMove", "onPointerUp"],
    FORM_CONTROL_FIELD_PROP_NAMES
  );
  const { fieldProps } = createFormControlField(formControlFieldProps);
  const onKeyDown = (e) => {
    callHandler2(e, local.onKeyDown);
    context.onStepKeyDown(e);
  };
  const [sRect, setRect] = createSignal3();
  const getValueFromPointer = (pointerPosition) => {
    const rect = sRect() || context.trackRef().getBoundingClientRect();
    setRect(rect);
    return [
      pointerPosition.x - rect.left - rect.width / 2,
      pointerPosition.y - rect.top - rect.height / 2
    ];
  };
  let startPosition = { x: 0, y: 0 };
  const onPointerDown = (e) => {
    callHandler2(e, local.onPointerDown);
    const target = e.currentTarget;
    e.preventDefault();
    e.stopPropagation();
    target.setPointerCapture(e.pointerId);
    target.focus();
    const value = getValueFromPointer({ x: e.clientX, y: e.clientY });
    startPosition = { x: e.clientX, y: e.clientY };
    context.onDragStart?.(value);
  };
  const onPointerMove = (e) => {
    e.stopPropagation();
    callHandler2(e, local.onPointerMove);
    const target = e.currentTarget;
    if (target.hasPointerCapture(e.pointerId)) {
      const delta = {
        deltaX: e.clientX - startPosition.x,
        deltaY: e.clientY - startPosition.y
      };
      context.onDrag?.(delta);
      startPosition = { x: e.clientX, y: e.clientY };
    }
  };
  const onPointerUp = (e) => {
    e.stopPropagation();
    callHandler2(e, local.onPointerUp);
    const target = e.currentTarget;
    if (target.hasPointerCapture(e.pointerId)) {
      target.releasePointerCapture(e.pointerId);
      context.onDragEnd?.();
    }
  };
  return <Polymorphic
    as="span"
    ref={mergeRefs2(context.setThumbRef, props.ref)}
    role="slider"
    id={fieldProps.id()}
    tabIndex={context.state.isDisabled() ? void 0 : 0}
    style={combineStyle2(
      {
        position: "absolute",
        left: `${context.outerRadius() + context.state.getThumbPosition().x}px`,
        top: `${context.outerRadius() + context.state.getThumbPosition().y}px`,
        transform: "translate(-50%, -50%)",
        "forced-color-adjust": "none",
        "touch-action": "none",
        opacity: context.outerRadius() ? 1 : 0,
        transition: "opacity .1s linear",
        "--kb-color-current": context.state.value().toString()
      },
      local.style
    )}
    aria-valuetext={context.getThumbValueLabel()}
    aria-valuemin={context.state.minValue()}
    aria-valuenow={context.state.hue()}
    aria-valuemax={context.state.maxValue()}
    aria-label={fieldProps.ariaLabel()}
    aria-labelledby={fieldProps.ariaLabelledBy()}
    aria-describedby={fieldProps.ariaDescribedBy()}
    onKeyDown={onKeyDown}
    onPointerDown={onPointerDown}
    onPointerMove={onPointerMove}
    onPointerUp={onPointerUp}
    {...formControlContext.dataset()}
    {...others}
  />;
}

// src/color-wheel/color-wheel-track.tsx
import { callHandler as callHandler3, mergeRefs as mergeRefs3 } from "@kobalte/utils";
import { combineStyle as combineStyle3 } from "@solid-primitives/props";
import {
  createSignal as createSignal4,
  splitProps as splitProps4
} from "solid-js";
function ColorWheelTrack(props) {
  const context = useColorWheelContext();
  const formControlContext = useFormControlContext();
  const [local, others] = splitProps4(props, [
    "style",
    "onPointerDown",
    "onPointerMove",
    "onPointerUp"
  ]);
  const [sRect, setRect] = createSignal4();
  const getValueFromPointer = (pointerPosition) => {
    const rect = sRect() || context.trackRef().getBoundingClientRect();
    setRect(rect);
    return [
      pointerPosition.x - rect.left - rect.width / 2,
      pointerPosition.y - rect.top - rect.height / 2
    ];
  };
  let startPosition = { x: 0, y: 0 };
  const onPointerDown = (e) => {
    callHandler3(e, local.onPointerDown);
    const target = e.target;
    target.setPointerCapture(e.pointerId);
    e.preventDefault();
    const value = getValueFromPointer({ x: e.clientX, y: e.clientY });
    startPosition = { x: e.clientX, y: e.clientY };
    context.onDragStart?.(value);
  };
  const onPointerMove = (e) => {
    callHandler3(e, local.onPointerMove);
    const target = e.target;
    if (target.hasPointerCapture(e.pointerId)) {
      context.onDrag?.({
        deltaX: e.clientX - startPosition.x,
        deltaY: e.clientY - startPosition.y
      });
      startPosition = { x: e.clientX, y: e.clientY };
    }
  };
  const onPointerUp = (e) => {
    callHandler3(e, local.onPointerUp);
    const target = e.target;
    if (target.hasPointerCapture(e.pointerId)) {
      target.releasePointerCapture(e.pointerId);
      setRect(void 0);
      context.onDragEnd?.();
    }
  };
  const backgroundStyle = `
      conic-gradient(
        from 90deg,
				${[...Array(13).keys()].map((i) => `hsl(${i * 30} 100% 50%)`).join(",")}
      )
    `;
  return <Polymorphic
    as="div"
    ref={mergeRefs3(context.setTrackRef, props.ref)}
    style={combineStyle3(
      {
        "touch-action": "none",
        "forced-color-adjust": "none",
        background: backgroundStyle,
        "clip-path": "circle(50%)",
        mask: `radial-gradient(#0000 ${70 - context.thickness() / 100 * 70}%, #000 ${70.5 - context.thickness() / 100 * 70}%)`
      },
      local.style
    )}
    onPointerDown={onPointerDown}
    onPointerMove={onPointerMove}
    onPointerUp={onPointerUp}
    {...formControlContext.dataset()}
    {...others}
  />;
}

// src/color-wheel/color-wheel-value-label.tsx
function ColorWheelValueLabel(props) {
  const context = useColorWheelContext();
  const formControlContext = useFormControlContext();
  return <Polymorphic
    as="div"
    {...formControlContext.dataset()}
    {...props}
  >{context.getValueLabel(context.state.value())}</Polymorphic>;
}

// src/color-wheel/index.tsx
var ColorWheel = Object.assign(ColorWheelRoot, {
  Description: FormControlDescription,
  ErrorMessage: FormControlErrorMessage,
  Input: ColorWheelInput,
  Label: FormControlLabel,
  Thumb: ColorWheelThumb,
  Track: ColorWheelTrack,
  ValueLabel: ColorWheelValueLabel
});
export {
  ColorWheel,
  FormControlDescription as Description,
  FormControlErrorMessage as ErrorMessage,
  ColorWheelInput as Input,
  FormControlLabel as Label,
  ColorWheelRoot as Root,
  ColorWheelThumb as Thumb,
  ColorWheelTrack as Track,
  ColorWheelValueLabel as ValueLabel,
  useColorWheelContext
};
