{"version":3,"file":"ColorPicker.mjs","names":["colorPickerMessages","useControlledState","Input","InputNumber"],"sources":["../../../src/base-ui/ColorPicker/ColorPicker.tsx"],"sourcesContent":["'use client';\n\nimport { cx, useThemeMode } from 'antd-style';\nimport { Pipette } from 'lucide-react';\nimport { type CSSProperties, memo, useEffect, useRef, useState } from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport { Input, InputNumber } from '@/base-ui/Input';\nimport { rootVariants } from '@/base-ui/Input/style';\nimport { panelStyles } from '@/base-ui/panelStyles';\nimport {\n  PopoverPopup,\n  PopoverPortal,\n  PopoverPositioner,\n  PopoverRoot,\n  PopoverTriggerElement,\n} from '@/base-ui/Popover';\nimport { Slider } from '@/base-ui/Slider';\nimport colorPickerMessages from '@/i18n/resources/en/colorPicker';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport Icon from '@/Icon';\n\nimport { formatColor, type Hsva, normalizeHexInput, parseColor } from './color';\nimport SaturationArea from './SaturationArea';\nimport { styles } from './style';\nimport type { ColorPickerProps } from './type';\n\nconst DEFAULT_COLOR = '#000000';\n\nconst hasEyeDropper = () => typeof window !== 'undefined' && 'EyeDropper' in window;\n\nconst ColorPicker = memo<ColorPickerProps>(\n  ({\n    alpha = false,\n    children,\n    className,\n    defaultValue = DEFAULT_COLOR,\n    disabled,\n    onChange,\n    onChangeComplete,\n    presets,\n    showText,\n    size = 'middle',\n    style,\n    value,\n  }) => {\n    const { t } = useTranslation(colorPickerMessages);\n    const { isDarkMode } = useThemeMode();\n    const [hex, setHex] = useControlledState<string>(defaultValue, {\n      defaultValue,\n      onChange,\n      value,\n    });\n    const [hsva, setHsva] = useState<Hsva>(() => parseColor(hex));\n    const [draft, setDraft] = useState(hex.slice(1).toUpperCase());\n    const popupRef = useRef<HTMLDivElement>(null);\n\n    useEffect(() => {\n      setHsva((current) =>\n        formatColor(current, alpha) === hex.toLowerCase() ? current : parseColor(hex, current.h),\n      );\n      setDraft(hex.slice(1).toUpperCase());\n    }, [hex, alpha]);\n\n    const update = (next: Hsva) => {\n      setHsva(next);\n      setHex(formatColor(next, alpha));\n    };\n    const commit = (next: Hsva) => onChangeComplete?.(formatColor(next, alpha));\n    const apply = (next: Hsva) => {\n      update(next);\n      commit(next);\n    };\n\n    const commitDraft = () => {\n      const normalized = normalizeHexInput(draft);\n      if (!normalized) return setDraft(hex.slice(1).toUpperCase());\n      apply(parseColor(normalized, hsva.h));\n    };\n\n    const swatch = (dimension: number) => (\n      <span className={styles.swatch} style={{ height: dimension, width: dimension }}>\n        <span style={{ background: hex }} />\n      </span>\n    );\n\n    const trigger =\n      children ??\n      (showText ? (\n        <button\n          aria-label={t('colorPicker.trigger')}\n          disabled={disabled}\n          style={style}\n          type=\"button\"\n          className={cx(\n            rootVariants({ size, variant: isDarkMode ? 'filled' : 'outlined' }),\n            styles.textTrigger,\n            className,\n          )}\n        >\n          {swatch(18)}\n          <span style={{ fontFamily: 'var(--lobe-font-family-code, monospace)' }}>\n            {hex.toUpperCase()}\n          </span>\n        </button>\n      ) : (\n        <button\n          aria-label={t('colorPicker.trigger')}\n          className={cx(styles.swatchButton, className)}\n          disabled={disabled}\n          style={style}\n          type=\"button\"\n        >\n          {swatch(24)}\n        </button>\n      ));\n\n    return (\n      <PopoverRoot>\n        <PopoverTriggerElement>{trigger}</PopoverTriggerElement>\n        <PopoverPortal>\n          <PopoverPositioner placement=\"bottomLeft\">\n            <PopoverPopup\n              className={panelStyles.popup}\n              ref={popupRef}\n              initialFocus={() =>\n                popupRef.current?.querySelector<HTMLElement>('[role=\"slider\"]') ?? true\n              }\n            >\n              <div className={styles.panel}>\n                <div className={styles.summary}>\n                  {swatch(40)}\n                  <div>\n                    <div className={styles.value}>{hex.toUpperCase()}</div>\n                    <div className={panelStyles.label}>\n                      {alpha ? `HEX · ${Math.round(hsva.a * 100)}%` : 'HEX'}\n                    </div>\n                  </div>\n                  {hasEyeDropper() && (\n                    <button\n                      aria-label={t('colorPicker.eyeDropper')}\n                      className={panelStyles.nav}\n                      style={{ marginInlineStart: 'auto' }}\n                      type=\"button\"\n                      onClick={async () => {\n                        const dropper = new (\n                          window as unknown as {\n                            EyeDropper: new () => { open: () => Promise<{ sRGBHex: string }> };\n                          }\n                        ).EyeDropper();\n                        const result = await dropper.open().catch(() => null);\n                        if (result) apply({ ...parseColor(result.sRGBHex, hsva.h), a: hsva.a });\n                      }}\n                    >\n                      <Icon icon={Pipette} size={14} />\n                    </button>\n                  )}\n                </div>\n                <SaturationArea\n                  hue={hsva.h}\n                  label={t('colorPicker.saturation')}\n                  saturation={hsva.s}\n                  value={hsva.v}\n                  onChange={(s, v) => update({ ...hsva, s, v })}\n                  onChangeComplete={(s, v) => commit({ ...hsva, s, v })}\n                />\n                <Slider\n                  aria-label={t('colorPicker.hue')}\n                  max={360}\n                  min={0}\n                  value={hsva.h}\n                  classNames={{\n                    indicator: styles.hidden,\n                    thumb: styles.sliderThumb,\n                    track: styles.hueTrack,\n                  }}\n                  onChange={(h) => update({ ...hsva, h })}\n                  onChangeComplete={(h) => commit({ ...hsva, h })}\n                />\n                {alpha && (\n                  <Slider\n                    aria-label={t('colorPicker.alpha')}\n                    max={100}\n                    min={0}\n                    value={Math.round(hsva.a * 100)}\n                    classNames={{\n                      indicator: styles.hidden,\n                      thumb: styles.sliderThumb,\n                      track: styles.alphaTrack,\n                    }}\n                    styles={{\n                      track: {\n                        '--lobe-color-picker-alpha': formatColor(hsva, false),\n                      } as CSSProperties,\n                    }}\n                    onChange={(a) => update({ ...hsva, a: a / 100 })}\n                    onChangeComplete={(a) => commit({ ...hsva, a: a / 100 })}\n                  />\n                )}\n                <div className={styles.hexRow}>\n                  <Input\n                    aria-label=\"HEX\"\n                    prefix={<span className={panelStyles.label}>HEX</span>}\n                    value={draft}\n                    variant=\"filled\"\n                    onBlur={commitDraft}\n                    onChange={(event) => setDraft(event.target.value)}\n                    onPressEnter={commitDraft}\n                  />\n                  {alpha && (\n                    <InputNumber\n                      aria-label={t('colorPicker.alpha')}\n                      className={styles.alphaField}\n                      controls={false}\n                      max={100}\n                      min={0}\n                      suffix=\"%\"\n                      value={Math.round(hsva.a * 100)}\n                      variant=\"filled\"\n                      onChange={(a) => a !== null && apply({ ...hsva, a: a / 100 })}\n                    />\n                  )}\n                </div>\n                {presets && presets.length > 0 && (\n                  <div\n                    aria-label={t('colorPicker.presets')}\n                    className={styles.presets}\n                    role=\"group\"\n                  >\n                    {presets.map((color) => (\n                      <button\n                        aria-label={color}\n                        aria-pressed={color.toLowerCase() === hex.slice(0, 7).toLowerCase()}\n                        className={styles.preset}\n                        key={color}\n                        style={{ background: color }}\n                        type=\"button\"\n                        onClick={() =>\n                          apply({ ...parseColor(color, hsva.h), a: parseColor(color).a })\n                        }\n                      />\n                    ))}\n                  </div>\n                )}\n              </div>\n            </PopoverPopup>\n          </PopoverPositioner>\n        </PopoverPortal>\n      </PopoverRoot>\n    );\n  },\n);\n\nColorPicker.displayName = 'ColorPicker';\n\nexport default ColorPicker;\n"],"mappings":"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"}