@yamada-ui/react
Version:
React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion
1 lines • 14.5 kB
Source Map (JSON)
{"version":3,"file":"use-color-picker.cjs","names":["useI18n","useFieldProps","useCombobox","useControllableState","useEyeDropper","value","getRootProps: PropGetter","props","getFieldProps: PropGetter","mergeRefs","ref","getInputProps: PropGetter<\"input\">","getEyeDropperProps: PropGetter","runKeyAction"],"sources":["../../../../src/components/color-picker/use-color-picker.ts"],"sourcesContent":["\"use client\"\n\nimport type { ChangeEvent, FocusEvent, MouseEvent } from \"react\"\nimport type { HTMLRefAttributes, PropGetter } from \"../../core\"\nimport type { UseComboboxProps } from \"../../hooks/use-combobox\"\nimport type { ColorFormat } from \"../../utils\"\nimport type { UseColorSelectorProps } from \"../color-selector\"\nimport type { FieldProps } from \"../field\"\nimport { useCallback, useEffect, useRef } from \"react\"\nimport { useCombobox } from \"../../hooks/use-combobox\"\nimport { useControllableState } from \"../../hooks/use-controllable-state\"\nimport { useEyeDropper } from \"../../hooks/use-eye-dropper\"\nimport { useI18n } from \"../../providers/i18n-provider\"\nimport {\n ariaAttr,\n calcFormat,\n contains,\n convertColor,\n focusTransfer,\n handlerAll,\n mergeRefs,\n runIfFn,\n runKeyAction,\n} from \"../../utils\"\nimport { useFieldProps } from \"../field\"\n\nexport interface UseColorPickerProps\n extends Omit<\n UseComboboxProps,\n | \"closeOnSelect\"\n | \"initialFocusValue\"\n | \"onChange\"\n | \"ref\"\n | \"selectFocusRef\"\n | \"selectOnSpace\"\n >,\n HTMLRefAttributes<\"input\">,\n FieldProps {\n /**\n * The `id` attribute of the input element.\n */\n id?: string\n /**\n * The `name` attribute of the input element.\n */\n name?: string\n /**\n * If `true`, allows input.\n *\n * @default true\n */\n allowInput?: boolean\n /**\n * If `true`, the color picker will be closed when the input value changes.\n *\n * @default false\n */\n closeOnChange?: ((ev: ChangeEvent<HTMLInputElement>) => boolean) | boolean\n /**\n * The initial value of the color picker.\n */\n defaultValue?: string\n /**\n * The fallback value of the color picker.\n *\n * @default '#FFFFFF'\n */\n fallbackValue?: string\n /**\n * The format of the color picker.\n * Automatically determines the format of `value` or `defaultValue`.\n *\n * @default 'hex'\n */\n format?: ColorFormat\n /**\n * The function to format the input value.\n */\n formatInput?: (value: string) => string\n /**\n * If `true`, the color picker will be opened when the input value changes.\n *\n * @default true\n */\n openOnChange?: ((ev: ChangeEvent<HTMLInputElement>) => boolean) | boolean\n /**\n * If `true`, the color picker will be opened when the input is focused.\n *\n * @default false\n */\n openOnFocus?: boolean\n /**\n * The pattern used to check the input element.\n */\n pattern?: RegExp\n /**\n * The placeholder for color picker.\n */\n placeholder?: string\n /**\n * The value of the color picker.\n */\n value?: string\n /**\n * The callback invoked when the value changes.\n */\n onChange?: (value: string) => void\n /**\n * The callback invoked when input value state changes.\n */\n onInputChange?: (ev: ChangeEvent<HTMLInputElement>) => void\n}\n\nexport const useColorPicker = (props: UseColorPickerProps) => {\n const { t } = useI18n(\"colorPicker\")\n const {\n props: {\n id,\n ref,\n name,\n allowInput = true,\n closeOnChange = false,\n defaultValue,\n disabled,\n fallbackValue = \"#FFFFFF\",\n format: formatProp,\n formatInput,\n openOnChange = true,\n openOnClick = true,\n openOnFocus = true,\n pattern,\n placeholder,\n readOnly,\n required,\n value: valueProp,\n onChange: onChangeProp,\n onInputChange: onInputChangeProp,\n ...rest\n },\n ariaProps,\n dataProps,\n eventProps,\n } = useFieldProps(props)\n const {\n interactive,\n open,\n getContentProps: getComboboxContentProps,\n getTriggerProps,\n popoverProps,\n onClose,\n onOpen,\n } = useCombobox({\n disabled,\n openOnClick: false,\n openOnEnter: !allowInput,\n openOnSpace: !allowInput,\n placement: \"end-start\",\n readOnly,\n transferFocus: false,\n ...ariaProps,\n ...dataProps,\n ...eventProps,\n ...rest,\n })\n const format =\n formatProp ?? calcFormat(valueProp ?? defaultValue ?? fallbackValue)\n const alpha = format.endsWith(\"a\")\n const fieldRef = useRef<HTMLDivElement>(null)\n const contentRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const focusByClickRef = useRef<boolean>(false)\n const [value, setValue] = useControllableState({\n defaultValue,\n value: valueProp,\n onChange: onChangeProp,\n })\n const { supported: supportedEyeDropper, onOpen: onOpenEyeDropper } =\n useEyeDropper()\n\n const onClick = useCallback(() => {\n if (!interactive) return\n\n focusByClickRef.current = true\n\n if (allowInput) inputRef.current?.focus()\n\n if (openOnClick) onOpen()\n }, [allowInput, interactive, onOpen, openOnClick])\n\n const onMouseDown = useCallback(\n (ev: MouseEvent<HTMLDivElement | HTMLInputElement>) => {\n if (!openOnFocus) return\n\n ev.preventDefault()\n ev.stopPropagation()\n },\n [openOnFocus],\n )\n\n const onFieldFocus = useCallback(() => {\n if (allowInput) return\n\n if (openOnFocus) onOpen()\n\n focusByClickRef.current = false\n }, [allowInput, onOpen, openOnFocus])\n\n const onInputFocus = useCallback(\n (ev: FocusEvent<HTMLInputElement>) => {\n ev.preventDefault()\n ev.stopPropagation()\n\n if (openOnFocus && !focusByClickRef.current) onOpen()\n\n focusByClickRef.current = false\n },\n [onOpen, openOnFocus],\n )\n\n const onBlur = useCallback(\n (ev: FocusEvent<HTMLInputElement>) => {\n if (\n contains(fieldRef.current, ev.relatedTarget) ||\n contains(contentRef.current, ev.relatedTarget)\n ) {\n ev.preventDefault()\n } else {\n setValue((prev) => {\n if (!prev) return prev\n\n let value = convertColor(prev)(format)\n\n if (!value) return prev\n\n if (formatInput) value = formatInput(value)\n\n if (pattern) value = value.replace(pattern, \"\")\n\n return value\n })\n }\n },\n [format, formatInput, pattern, setValue],\n )\n\n const onInputChange = useCallback(\n (ev: ChangeEvent<HTMLInputElement>) => {\n if (!allowInput) return\n\n onInputChangeProp?.(ev)\n\n if (runIfFn(closeOnChange, ev)) {\n onClose()\n } else if (runIfFn(openOnChange, ev)) {\n onOpen()\n }\n\n let inputValue = ev.target.value\n\n if (formatInput) inputValue = formatInput(inputValue)\n\n if (pattern) inputValue = inputValue.replace(pattern, \"\")\n\n setValue(inputValue)\n },\n [\n allowInput,\n closeOnChange,\n formatInput,\n onClose,\n onInputChangeProp,\n onOpen,\n openOnChange,\n pattern,\n setValue,\n ],\n )\n\n const onEyeDropperClick = useCallback(async () => {\n if (!interactive) return\n\n const result = await onOpenEyeDropper()\n\n if (result?.sRGBHex) setValue(result.sRGBHex)\n }, [interactive, onOpenEyeDropper, setValue])\n\n useEffect(() => {\n if (!open) return\n\n return focusTransfer(\n contentRef.current,\n allowInput ? inputRef.current : fieldRef.current,\n )\n }, [allowInput, open])\n\n const getRootProps: PropGetter = useCallback(\n (props) => ({\n ...dataProps,\n ...props,\n }),\n [dataProps],\n )\n\n const getFieldProps: PropGetter = useCallback(\n ({ ref, ...props } = {}) =>\n getTriggerProps({\n ref: mergeRefs(ref, fieldRef),\n \"aria-haspopup\": \"dialog\",\n tabIndex: !allowInput ? 0 : -1,\n ...props,\n onClick: handlerAll(props.onClick, onClick),\n onFocus: handlerAll(props.onFocus, onFieldFocus),\n onMouseDown: handlerAll(props.onMouseDown, onMouseDown),\n }),\n\n [allowInput, getTriggerProps, onClick, onFieldFocus, onMouseDown],\n )\n\n const getInputProps: PropGetter<\"input\"> = useCallback(\n (props = {}) => ({\n id,\n ref: mergeRefs(props.ref, ref, inputRef),\n name,\n style: {\n ...(!allowInput ? { pointerEvents: \"none\" } : {}),\n ...props.style,\n },\n autoComplete: \"off\",\n disabled,\n placeholder,\n readOnly,\n required,\n tabIndex: allowInput ? 0 : -1,\n value,\n ...dataProps,\n ...props,\n onBlur: handlerAll(props.onBlur, onBlur),\n onChange: handlerAll(props.onChange, onInputChange),\n onFocus: handlerAll(props.onFocus, onInputFocus),\n onMouseDown: handlerAll(props.onMouseDown, onMouseDown),\n }),\n [\n allowInput,\n dataProps,\n disabled,\n id,\n name,\n onBlur,\n onInputChange,\n onInputFocus,\n onMouseDown,\n placeholder,\n readOnly,\n ref,\n required,\n value,\n ],\n )\n\n const getEyeDropperProps: PropGetter = useCallback(\n (props = {}) => ({\n ...dataProps,\n \"aria-disabled\": ariaAttr(!interactive),\n \"aria-label\": t(\"Pick a color\"),\n hidden: !supportedEyeDropper,\n role: \"button\",\n tabIndex: interactive ? 0 : -1,\n ...props,\n onClick: handlerAll(props.onClick, onEyeDropperClick),\n onKeyDown: handlerAll(props.onKeyDown, (ev) =>\n runKeyAction(ev, {\n Enter: onEyeDropperClick,\n Space: onEyeDropperClick,\n }),\n ),\n }),\n [dataProps, interactive, onEyeDropperClick, supportedEyeDropper, t],\n )\n\n const getContentProps: PropGetter = useCallback(\n ({ ref, ...props } = {}) =>\n getComboboxContentProps({\n ref: mergeRefs(ref, contentRef),\n role: \"dialog\",\n ...props,\n }),\n [getComboboxContentProps],\n )\n\n const getSelectorProps: PropGetter<UseColorSelectorProps> = useCallback(\n (props = {}) => ({\n disabled,\n fallbackValue,\n format,\n readOnly,\n value,\n ...props,\n onChange: handlerAll(props.onChange, setValue),\n }),\n [disabled, fallbackValue, format, readOnly, value, setValue],\n )\n\n return {\n alpha,\n format,\n interactive,\n open,\n setValue,\n value,\n getContentProps,\n getEyeDropperProps,\n getFieldProps,\n getInputProps,\n getRootProps,\n getSelectorProps,\n popoverProps,\n onClose,\n onOpen,\n }\n}\n\nexport type UseColorPickerReturn = ReturnType<typeof useColorPicker>\n"],"mappings":"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"}