"use client"; // src/switch.tsx import * as React from "react"; import { composeEventHandlers } from "@radix-ui/primitive"; import { useComposedRefs } from "@radix-ui/react-compose-refs"; import { createContextScope } from "@radix-ui/react-context"; import { useControllableState } from "@radix-ui/react-use-controllable-state"; import { usePrevious } from "@radix-ui/react-use-previous"; import { useSize } from "@radix-ui/react-use-size"; import { Primitive } from "@radix-ui/react-primitive"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; var SWITCH_NAME = "Switch"; var [createSwitchContext, createSwitchScope] = createContextScope(SWITCH_NAME); var [SwitchProviderImpl, useSwitchContext] = createSwitchContext(SWITCH_NAME); function SwitchProvider(props) { const { __scopeSwitch, checked: checkedProp, children, defaultChecked, disabled, form, name, onCheckedChange, required, value = "on", // @ts-expect-error internal_do_not_use_render } = props; const [checked, setChecked] = useControllableState({ prop: checkedProp, defaultProp: defaultChecked ?? false, onChange: onCheckedChange, caller: SWITCH_NAME }); const [control, setControl] = React.useState(null); const [bubbleInput, setBubbleInput] = React.useState(null); const hasConsumerStoppedPropagationRef = React.useRef(false); const isFormControl = control ? !!form || !!control.closest("form") : ( // We set this to true by default so that events bubble to forms without JS (SSR) true ); const context = { checked, setChecked, disabled, control, setControl, name, form, value, hasConsumerStoppedPropagationRef, required, defaultChecked, isFormControl, bubbleInput, setBubbleInput }; return /* @__PURE__ */ jsx(SwitchProviderImpl, { scope: __scopeSwitch, ...context, children: isFunction(internal_do_not_use_render) ? internal_do_not_use_render(context) : children }); } var TRIGGER_NAME = "SwitchTrigger"; var SwitchTrigger = React.forwardRef( ({ __scopeSwitch, onClick, ...switchProps }, forwardedRef) => { const { value, disabled, checked, required, setControl, setChecked, hasConsumerStoppedPropagationRef, isFormControl, bubbleInput } = useSwitchContext(TRIGGER_NAME, __scopeSwitch); const composedRefs = useComposedRefs(forwardedRef, setControl); return /* @__PURE__ */ jsx( Primitive.button, { type: "button", role: "switch", "aria-checked": checked, "aria-required": required, "data-state": getState(checked), "data-disabled": disabled ? "" : void 0, disabled, value, ...switchProps, ref: composedRefs, onClick: composeEventHandlers(onClick, (event) => { setChecked((prevChecked) => !prevChecked); if (bubbleInput && isFormControl) { hasConsumerStoppedPropagationRef.current = event.isPropagationStopped(); if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation(); } }) } ); } ); SwitchTrigger.displayName = TRIGGER_NAME; var Switch = React.forwardRef( (props, forwardedRef) => { const { __scopeSwitch, name, checked, defaultChecked, required, disabled, value, onCheckedChange, form, ...switchProps } = props; return /* @__PURE__ */ jsx( SwitchProvider, { __scopeSwitch, checked, defaultChecked, disabled, required, onCheckedChange, name, form, value, internal_do_not_use_render: ({ isFormControl }) => /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx( SwitchTrigger, { ...switchProps, ref: forwardedRef, __scopeSwitch } ), isFormControl && /* @__PURE__ */ jsx( SwitchBubbleInput, { __scopeSwitch } ) ] }) } ); } ); Switch.displayName = SWITCH_NAME; var THUMB_NAME = "SwitchThumb"; var SwitchThumb = React.forwardRef( (props, forwardedRef) => { const { __scopeSwitch, ...thumbProps } = props; const context = useSwitchContext(THUMB_NAME, __scopeSwitch); return /* @__PURE__ */ jsx( Primitive.span, { "data-state": getState(context.checked), "data-disabled": context.disabled ? "" : void 0, ...thumbProps, ref: forwardedRef } ); } ); SwitchThumb.displayName = THUMB_NAME; var BUBBLE_INPUT_NAME = "SwitchBubbleInput"; var SwitchBubbleInput = React.forwardRef( ({ __scopeSwitch, ...props }, forwardedRef) => { const { control, hasConsumerStoppedPropagationRef, checked, defaultChecked, required, disabled, name, value, form, bubbleInput, setBubbleInput } = useSwitchContext(BUBBLE_INPUT_NAME, __scopeSwitch); const composedRefs = useComposedRefs(forwardedRef, setBubbleInput); const prevChecked = usePrevious(checked); const controlSize = useSize(control); React.useEffect(() => { const input = bubbleInput; if (!input) return; const inputProto = window.HTMLInputElement.prototype; const descriptor = Object.getOwnPropertyDescriptor( inputProto, "checked" ); const setChecked = descriptor.set; const bubbles = !hasConsumerStoppedPropagationRef.current; if (prevChecked !== checked && setChecked) { const event = new Event("click", { bubbles }); setChecked.call(input, checked); input.dispatchEvent(event); } }, [bubbleInput, prevChecked, checked, hasConsumerStoppedPropagationRef]); const defaultCheckedRef = React.useRef(checked); return /* @__PURE__ */ jsx( Primitive.input, { type: "checkbox", "aria-hidden": true, defaultChecked: defaultChecked ?? defaultCheckedRef.current, required, disabled, name, value, form, ...props, tabIndex: -1, ref: composedRefs, style: { ...props.style, ...controlSize, position: "absolute", pointerEvents: "none", opacity: 0, margin: 0, // We transform because the input is absolutely positioned but we have // rendered it **after** the button. This pulls it back to sit on top // of the button. transform: "translateX(-100%)" } } ); } ); SwitchBubbleInput.displayName = BUBBLE_INPUT_NAME; function isFunction(value) { return typeof value === "function"; } function getState(checked) { return checked ? "checked" : "unchecked"; } export { Switch as Root, Switch, SwitchThumb, SwitchThumb as Thumb, createSwitchScope, SwitchBubbleInput as unstable_BubbleInput, SwitchProvider as unstable_Provider, SwitchBubbleInput as unstable_SwitchBubbleInput, SwitchProvider as unstable_SwitchProvider, SwitchTrigger as unstable_SwitchTrigger, SwitchTrigger as unstable_Trigger }; //# sourceMappingURL=index.mjs.map