index.mjs.map 11.9 KB
{
  "version": 3,
  "sources": ["../src/checkbox.tsx"],
  "sourcesContent": ["import * as React from 'react';\nimport { useComposedRefs } from '@radix-ui/react-compose-refs';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { composeEventHandlers } from '@radix-ui/primitive';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport { usePrevious } from '@radix-ui/react-use-previous';\nimport { useSize } from '@radix-ui/react-use-size';\nimport { Presence } from '@radix-ui/react-presence';\nimport { Primitive } from '@radix-ui/react-primitive';\n\nimport type { Scope } from '@radix-ui/react-context';\n\n/* -------------------------------------------------------------------------------------------------\n * Checkbox\n * -----------------------------------------------------------------------------------------------*/\n\nconst CHECKBOX_NAME = 'Checkbox';\n\ntype ScopedProps<P> = P & { __scopeCheckbox?: Scope };\nconst [createCheckboxContext, createCheckboxScope] = createContextScope(CHECKBOX_NAME);\n\ntype CheckedState = boolean | 'indeterminate';\n\ntype CheckboxContextValue = {\n  state: CheckedState;\n  disabled?: boolean;\n};\n\nconst [CheckboxProvider, useCheckboxContext] =\n  createCheckboxContext<CheckboxContextValue>(CHECKBOX_NAME);\n\ntype CheckboxElement = React.ElementRef<typeof Primitive.button>;\ntype PrimitiveButtonProps = React.ComponentPropsWithoutRef<typeof Primitive.button>;\ninterface CheckboxProps extends Omit<PrimitiveButtonProps, 'checked' | 'defaultChecked'> {\n  checked?: CheckedState;\n  defaultChecked?: CheckedState;\n  required?: boolean;\n  onCheckedChange?(checked: CheckedState): void;\n}\n\nconst Checkbox = React.forwardRef<CheckboxElement, CheckboxProps>(\n  (props: ScopedProps<CheckboxProps>, forwardedRef) => {\n    const {\n      __scopeCheckbox,\n      name,\n      checked: checkedProp,\n      defaultChecked,\n      required,\n      disabled,\n      value = 'on',\n      onCheckedChange,\n      form,\n      ...checkboxProps\n    } = props;\n    const [button, setButton] = React.useState<HTMLButtonElement | null>(null);\n    const composedRefs = useComposedRefs(forwardedRef, (node) => setButton(node));\n    const hasConsumerStoppedPropagationRef = React.useRef(false);\n    // We set this to true by default so that events bubble to forms without JS (SSR)\n    const isFormControl = button ? form || !!button.closest('form') : true;\n    const [checked = false, setChecked] = useControllableState({\n      prop: checkedProp,\n      defaultProp: defaultChecked,\n      onChange: onCheckedChange,\n    });\n    const initialCheckedStateRef = React.useRef(checked);\n    React.useEffect(() => {\n      const form = button?.form;\n      if (form) {\n        const reset = () => setChecked(initialCheckedStateRef.current);\n        form.addEventListener('reset', reset);\n        return () => form.removeEventListener('reset', reset);\n      }\n    }, [button, setChecked]);\n\n    return (\n      <CheckboxProvider scope={__scopeCheckbox} state={checked} disabled={disabled}>\n        <Primitive.button\n          type=\"button\"\n          role=\"checkbox\"\n          aria-checked={isIndeterminate(checked) ? 'mixed' : checked}\n          aria-required={required}\n          data-state={getState(checked)}\n          data-disabled={disabled ? '' : undefined}\n          disabled={disabled}\n          value={value}\n          {...checkboxProps}\n          ref={composedRefs}\n          onKeyDown={composeEventHandlers(props.onKeyDown, (event) => {\n            // According to WAI ARIA, Checkboxes don't activate on enter keypress\n            if (event.key === 'Enter') event.preventDefault();\n          })}\n          onClick={composeEventHandlers(props.onClick, (event) => {\n            setChecked((prevChecked) => (isIndeterminate(prevChecked) ? true : !prevChecked));\n            if (isFormControl) {\n              hasConsumerStoppedPropagationRef.current = event.isPropagationStopped();\n              // if checkbox is in a form, stop propagation from the button so that we only propagate\n              // one click event (from the input). We propagate changes from an input so that native\n              // form validation works and form events reflect checkbox updates.\n              if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation();\n            }\n          })}\n        />\n        {isFormControl && (\n          <BubbleInput\n            control={button}\n            bubbles={!hasConsumerStoppedPropagationRef.current}\n            name={name}\n            value={value}\n            checked={checked}\n            required={required}\n            disabled={disabled}\n            form={form}\n            // We transform because the input is absolutely positioned but we have\n            // rendered it **after** the button. This pulls it back to sit on top\n            // of the button.\n            style={{ transform: 'translateX(-100%)' }}\n            defaultChecked={isIndeterminate(defaultChecked) ? false : defaultChecked}\n          />\n        )}\n      </CheckboxProvider>\n    );\n  }\n);\n\nCheckbox.displayName = CHECKBOX_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * CheckboxIndicator\n * -----------------------------------------------------------------------------------------------*/\n\nconst INDICATOR_NAME = 'CheckboxIndicator';\n\ntype CheckboxIndicatorElement = React.ElementRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface CheckboxIndicatorProps extends PrimitiveSpanProps {\n  /**\n   * Used to force mounting when more control is needed. Useful when\n   * controlling animation with React animation libraries.\n   */\n  forceMount?: true;\n}\n\nconst CheckboxIndicator = React.forwardRef<CheckboxIndicatorElement, CheckboxIndicatorProps>(\n  (props: ScopedProps<CheckboxIndicatorProps>, forwardedRef) => {\n    const { __scopeCheckbox, forceMount, ...indicatorProps } = props;\n    const context = useCheckboxContext(INDICATOR_NAME, __scopeCheckbox);\n    return (\n      <Presence present={forceMount || isIndeterminate(context.state) || context.state === true}>\n        <Primitive.span\n          data-state={getState(context.state)}\n          data-disabled={context.disabled ? '' : undefined}\n          {...indicatorProps}\n          ref={forwardedRef}\n          style={{ pointerEvents: 'none', ...props.style }}\n        />\n      </Presence>\n    );\n  }\n);\n\nCheckboxIndicator.displayName = INDICATOR_NAME;\n\n/* ---------------------------------------------------------------------------------------------- */\n\ntype InputProps = React.ComponentPropsWithoutRef<'input'>;\ninterface BubbleInputProps extends Omit<InputProps, 'checked'> {\n  checked: CheckedState;\n  control: HTMLElement | null;\n  bubbles: boolean;\n}\n\nconst BubbleInput = (props: BubbleInputProps) => {\n  const { control, checked, bubbles = true, defaultChecked, ...inputProps } = props;\n  const ref = React.useRef<HTMLInputElement>(null);\n  const prevChecked = usePrevious(checked);\n  const controlSize = useSize(control);\n\n  // Bubble checked change to parents (e.g form change event)\n  React.useEffect(() => {\n    const input = ref.current!;\n    const inputProto = window.HTMLInputElement.prototype;\n    const descriptor = Object.getOwnPropertyDescriptor(inputProto, 'checked') as PropertyDescriptor;\n    const setChecked = descriptor.set;\n\n    if (prevChecked !== checked && setChecked) {\n      const event = new Event('click', { bubbles });\n      input.indeterminate = isIndeterminate(checked);\n      setChecked.call(input, isIndeterminate(checked) ? false : checked);\n      input.dispatchEvent(event);\n    }\n  }, [prevChecked, checked, bubbles]);\n\n  const defaultCheckedRef = React.useRef(isIndeterminate(checked) ? false : checked);\n  return (\n    <input\n      type=\"checkbox\"\n      aria-hidden\n      defaultChecked={defaultChecked ?? defaultCheckedRef.current}\n      {...inputProps}\n      tabIndex={-1}\n      ref={ref}\n      style={{\n        ...props.style,\n        ...controlSize,\n        position: 'absolute',\n        pointerEvents: 'none',\n        opacity: 0,\n        margin: 0,\n      }}\n    />\n  );\n};\n\nfunction isIndeterminate(checked?: CheckedState): checked is 'indeterminate' {\n  return checked === 'indeterminate';\n}\n\nfunction getState(checked: CheckedState) {\n  return isIndeterminate(checked) ? 'indeterminate' : checked ? 'checked' : 'unchecked';\n}\n\nconst Root = Checkbox;\nconst Indicator = CheckboxIndicator;\n\nexport {\n  createCheckboxScope,\n  //\n  Checkbox,\n  CheckboxIndicator,\n  //\n  Root,\n  Indicator,\n};\nexport type { CheckboxProps, CheckboxIndicatorProps, CheckedState };\n"],
  "mappings": "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",
  "names": ["form"]
}