{"version":3,"file":"color-picker.mjs","sources":["../../../../../../packages/components/color-picker/src/color-picker.vue"],"sourcesContent":["<template>\n  <hl-tooltip\n    ref=\"popper\"\n    :visible=\"showPicker\"\n    :show-arrow=\"false\"\n    :fallback-placements=\"['bottom', 'top', 'right', 'left']\"\n    :offset=\"popperOffset\"\n    :gpu-acceleration=\"false\"\n    :popper-class=\"[namespace + '-picker-popper', popperClass]\"\n    :stop-popper-mouse-event=\"false\"\n    :teleported=\"teleported\"\n    trigger=\"click\"\n    transition=\"dropdown\"\n    persistent\n    @hide=\"setShowPicker(false)\"\n  >\n    <template #content>\n      <hl-group\n        v-click-outside=\"handleClickOutside\"\n        :class=\"namespace + '-panel'\"\n        dir=\"vertical\"\n        full=\"full-x\"\n        gap=\"var(--xs)\"\n        @keydown.esc=\"handleEsc\"\n      >\n        <sv-panel ref=\"svPanel\" :color=\"color\" />\n        <hl-group gap=\"var(--xs)\">\n          <hl-group dir=\"vertical\" full=\"full-x\" gap=\"var(--xxs)\">\n            <hue-slider ref=\"hue\" :color=\"color\" />\n            <alpha-slider v-if=\"showAlpha\" ref=\"alpha\" :color=\"color\" />\n          </hl-group>\n          <div v-if=\"showAlpha\" class=\"current-color\" :style=\"`background-color: ${customInput}`\"></div>\n        </hl-group>\n        <predefine\n          v-if=\"predefine\"\n          ref=\"predefine\"\n          :enable-alpha=\"showAlpha\"\n          :color=\"color\"\n          :colors=\"predefine\"\n          class=\"m-t-xs\"\n        />\n        <hl-group align=\"items-between\" gap=\"var(--xs)\" class=\"m-t-xs\">\n          <hl-input\n            ref=\"inputRef\"\n            v-model=\"customInput\"\n            :validate-event=\"false\"\n            size=\"sm\"\n            fill\n            block\n            spellcheck=\"false\"\n            @keyup.enter=\"handleConfirm\"\n            @blur=\"handleConfirm\"\n          />\n          <hl-group class=\"static\">\n            <hl-button size=\"sm\" type=\"link\" @click=\"clear\">{{ t('hl.colorpicker.clear') }}</hl-button>\n            <hl-button\n              type=\"primary\"\n              size=\"sm\"\n              @click=\"confirmValue\"\n            >\n              {{ t('hl.colorpicker.confirm') }}\n            </hl-button>\n          </hl-group>\n        </hl-group>\n      </hl-group>\n    </template>\n    <template #default>\n      <div\n        :id=\"buttonId\"\n        ref=\"triggerRef\"\n        v-bind=\"$attrs\"\n        :class=\"[\n          namespace + '-picker',\n          colorDisabled ? 'is-disabled' : '',\n          isFocused ? 'is-focused' : '',\n          colorSize,\n        ]\"\n        role=\"button\"\n        :aria-label=\"buttonAriaLabel\"\n        :aria-labelledby=\"buttonAriaLabelledby\"\n        :aria-description=\"\n          t('hl.colorpicker.description', { color: modelValue || '' })\n        \"\n        :aria-disabled=\"colorDisabled\"\n        :tabindex=\"colorDisabled ? -1 : tabindex\"\n        @keydown=\"handleKeyDown\"\n        @focus=\"handleFocus\"\n        @blur=\"handleBlur\"\n      >\n        <div v-if=\"colorDisabled\" class=\"picker-mask\"></div>\n        <div class=\"picker-trigger\" @click=\"handleTrigger\">\n          <span\n            class=\"picker-color\"\n            :style=\"{\n              backgroundColor: displayedColor,\n            }\"\n          >\n            <hl-icon\n              v-show=\"modelValue || showPanelColor\"\n              :class=\"['picker-icon']\"\n            >\n              <system-arrow-down />\n            </hl-icon>\n            <hl-icon v-show=\"!modelValue && !showPanelColor\" :class=\"['picker-empty', 'icon-close']\">\n              <system-close />\n            </hl-icon>\n          </span>\n        </div>\n      </div>\n    </template>\n  </hl-tooltip>\n</template>\n\n<script lang=\"ts\" setup>\nimport {\n  computed,\n  nextTick,\n  onMounted,\n  provide,\n  reactive,\n  ref,\n  watch,\n} from 'vue'\nimport { debounce } from 'lodash-unified'\nimport HlButton from '@hongluan-ui/components/button'\nimport HlIcon from '@hongluan-ui/components/icon'\nimport HlGroup from '@hongluan-ui/components/group'\nimport { ClickOutside as vClickOutside } from '@hongluan-ui/directives'\nimport { useFocusController, useLocale, useNamespace, useConsistentProp, useFormItemInputId, useFormItem } from '@hongluan-ui/hooks'\nimport HlTooltip from '@hongluan-ui/components/tooltip'\nimport HlInput from '@hongluan-ui/components/input'\nimport { EVENT_CODE, UPDATE_MODEL_EVENT } from '@hongluan-ui/constants'\nimport { debugWarn } from '@hongluan-ui/utils'\nimport { SystemArrowDown, SystemClose } from '@hongluan-ui/components/system-icon'\nimport AlphaSlider from './components/alpha-slider.vue'\nimport HueSlider from './components/hue-slider.vue'\nimport Predefine from './components/predefine.vue'\nimport SvPanel from './components/sv-panel.vue'\nimport Color from './utils/color'\nimport {\n  colorPickerContextKey,\n  colorPickerEmits,\n  colorPickerProps,\n} from './color-picker'\nimport type { TooltipInstance } from '@hongluan-ui/components/tooltip'\n\ndefineOptions({\n  name: 'ColorPicker',\n})\nconst props = defineProps(colorPickerProps)\nconst emit = defineEmits(colorPickerEmits)\n\nconst { t } = useLocale()\nconst { namespace } = useNamespace('color')\nconst { form, formItem } = useFormItem()\nconst { inputId: buttonId, isLabeledByFormItem } = useFormItemInputId(\n  props,\n  {\n    formItemContext: formItem,\n  },\n)\nconst hue = ref<InstanceType<typeof HueSlider>>()\nconst svPanel = ref<InstanceType<typeof SvPanel>>()\nconst alpha = ref<InstanceType<typeof AlphaSlider>>()\nconst popper = ref<TooltipInstance>()\nconst triggerRef = ref()\nconst inputRef = ref()\n\nconst {\n  isFocused,\n  handleFocus: _handleFocus,\n  handleBlur,\n} = useFocusController(triggerRef, {\n  beforeBlur(event) {\n    return popper.value?.isFocusInsideContent(event)\n  },\n  afterBlur() {\n    setShowPicker(false)\n    resetColor()\n  },\n})\n\nconst handleFocus = (event: FocusEvent) => {\n  if (colorDisabled.value) return blur()\n  _handleFocus(event)\n}\n\n// active-change is used to prevent modelValue changes from triggering.\nlet shouldActiveChange = true\n\n// data\nconst color = reactive(\n  new Color({\n    enableAlpha: props.showAlpha,\n    format: props.colorFormat || '',\n    value: props.modelValue,\n  }),\n) as Color\n\nconst showPicker = ref(false)\nconst showPanelColor = ref(false)\nconst customInput = ref('')\n// computed\nconst displayedColor = computed(() => {\n  if (!props.modelValue && !showPanelColor.value) {\n    return 'transparent'\n  }\n  return displayedRgb(color, props.showAlpha)\n})\nconst { size: colorSize } = useConsistentProp()\nconst colorDisabled = computed(() => {\n  return !!(props.disabled || form?.disabled)\n})\n\nconst currentColor = computed(() => {\n  return !props.modelValue && !showPanelColor.value ? '' : color.value\n})\nconst popperPaneRef = computed(() => {\n  return popper.value?.popperRef?.contentRef\n})\nconst buttonAriaLabel = computed<string | undefined>(() => {\n  return !isLabeledByFormItem.value\n    ? props.label || props.ariaLabel || t('hl.colorpicker.defaultLabel')\n    : undefined\n})\nconst buttonAriaLabelledby = computed<string | undefined>(() => {\n  return isLabeledByFormItem.value ? formItem?.labelId : undefined\n})\n\n// methods\nfunction displayedRgb(color: Color, showAlpha: boolean) {\n  if (!(color instanceof Color)) {\n    throw new TypeError('color should be instance of _color Class')\n  }\n\n  const { r, g, b } = color.toRgb()\n  return showAlpha\n    ? `rgba(${r}, ${g}, ${b}, ${color.get('alpha') / 100})`\n    : `rgb(${r}, ${g}, ${b})`\n}\n\nfunction setShowPicker(value: boolean) {\n  showPicker.value = value\n}\n\nconst debounceSetShowPicker = debounce(setShowPicker, 100, { leading: true })\n\nfunction show() {\n  if (colorDisabled.value) return\n  setShowPicker(true)\n}\n\nfunction hide() {\n  debounceSetShowPicker(false)\n  resetColor()\n}\n\nfunction resetColor() {\n  nextTick(() => {\n    if (props.modelValue) {\n      color.fromString(props.modelValue)\n    } else {\n      color.value = ''\n      nextTick(() => {\n        showPanelColor.value = false\n      })\n    }\n  })\n}\n\nfunction handleTrigger() {\n  if (colorDisabled.value) return\n  debounceSetShowPicker(!showPicker.value)\n}\n\nfunction handleConfirm() {\n  color.fromString(customInput.value)\n}\n\nfunction confirmValue() {\n  const value = color.value\n  emit(UPDATE_MODEL_EVENT, value)\n  emit('change', value)\n  if (props.validateEvent) {\n    formItem?.validate?.('change').catch(err => debugWarn(err))\n  }\n  debounceSetShowPicker(false)\n  // check if modelValue change, if not change, then reset color.\n  nextTick(() => {\n    const newColor = new Color({\n      enableAlpha: props.showAlpha,\n      format: props.colorFormat || '',\n      value: props.modelValue,\n    })\n    if (!color.compare(newColor)) {\n      resetColor()\n    }\n  })\n}\n\nfunction clear() {\n  debounceSetShowPicker(false)\n  emit(UPDATE_MODEL_EVENT, null)\n  emit('change', null)\n  if (props.modelValue !== null && props.validateEvent) {\n    formItem?.validate?.('change').catch(err => debugWarn(err))\n  }\n  resetColor()\n}\n\nfunction handleClickOutside(event: Event) {\n  if (!showPicker.value) return\n  hide()\n\n  if (isFocused.value) {\n    const _event = new FocusEvent('focus', event)\n    handleBlur(_event)\n  }\n}\n\nfunction handleEsc(event: KeyboardEvent) {\n  event.preventDefault()\n  event.stopPropagation()\n  setShowPicker(false)\n  resetColor()\n}\n\nfunction handleKeyDown(event: KeyboardEvent) {\n  switch (event.code) {\n    case EVENT_CODE.enter:\n    case EVENT_CODE.space:\n      event.preventDefault()\n      event.stopPropagation()\n      show()\n      inputRef.value.focus()\n      break\n    case EVENT_CODE.esc:\n      handleEsc(event)\n      break\n  }\n}\n\nfunction focus() {\n  triggerRef.value.focus()\n}\n\nfunction blur() {\n  triggerRef.value.blur()\n}\n\nonMounted(() => {\n  if (props.modelValue) {\n    customInput.value = currentColor.value\n  }\n})\n\n// watch\nwatch(\n  () => props.modelValue,\n  newVal => {\n    if (!newVal) {\n      showPanelColor.value = false\n    } else if (newVal && newVal !== color.value) {\n      shouldActiveChange = false\n      color.fromString(newVal)\n    }\n  },\n)\nwatch(\n  () => currentColor.value,\n  val => {\n    customInput.value = val\n    shouldActiveChange && emit('activeChange', val)\n    shouldActiveChange = true\n  },\n)\n\nwatch(\n  () => color.value,\n  () => {\n    if (!props.modelValue && !showPanelColor.value) {\n      showPanelColor.value = true\n    }\n  },\n)\n\nwatch(\n  () => showPicker.value,\n  () => {\n    nextTick(() => {\n      hue.value?.update()\n      svPanel.value?.update()\n      alpha.value?.update()\n    })\n  },\n)\n\nprovide(colorPickerContextKey, {\n  currentColor,\n})\n\ndefineExpose({\n  /**\n   * @description current color object\n   */\n  color,\n  popperPaneRef,\n  /**\n   * @description manually show ColorPicker\n   */\n  show,\n  /**\n   * @description manually hide ColorPicker\n   */\n  hide,\n  /**\n   * @description focus the input element\n   */\n  focus,\n  /**\n   * @description blur the input element\n   */\n  blur,\n})\n\n</script>\n"],"names":[],"mappings":"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"}