UNPKG

element-plus

Version:

A Component Library for Vue 3

1 lines 10.8 kB
{"version":3,"file":"color-picker2.mjs","names":[],"sources":["../../../../../../packages/components/color-picker/src/color-picker.vue"],"sourcesContent":["<template>\n <el-tooltip\n ref=\"popper\"\n :visible=\"showPicker\"\n :show-arrow=\"false\"\n :fallback-placements=\"['bottom', 'top', 'right', 'left']\"\n :offset=\"0\"\n :gpu-acceleration=\"false\"\n :popper-class=\"[ns.be('picker', 'panel'), popperClass!]\"\n :popper-style=\"popperStyle\"\n :stop-popper-mouse-event=\"false\"\n pure\n loop\n role=\"dialog\"\n effect=\"light\"\n trigger=\"click\"\n :teleported=\"teleported\"\n :transition=\"`${ns.namespace.value}-zoom-in-top`\"\n :persistent=\"persistent\"\n :append-to=\"appendTo\"\n @show=\"handleShowTooltip\"\n @hide=\"setShowPicker(false)\"\n >\n <template #content>\n <el-color-picker-panel\n ref=\"pickerPanelRef\"\n v-bind=\"panelProps\"\n v-click-outside:[triggerRef]=\"handleClickOutside\"\n :border=\"false\"\n :validate-event=\"false\"\n @keydown.esc=\"handleEsc\"\n >\n <template #footer>\n <div>\n <el-button\n v-if=\"clearable\"\n :class=\"ns.be('footer', 'link-btn')\"\n text\n size=\"small\"\n @click=\"clear\"\n >\n {{ t('el.colorpicker.clear') }}\n </el-button>\n <el-button\n plain\n size=\"small\"\n :class=\"ns.be('footer', 'btn')\"\n @click=\"confirmValue\"\n >\n {{ t('el.colorpicker.confirm') }}\n </el-button>\n </div>\n </template>\n </el-color-picker-panel>\n </template>\n <template #default>\n <div\n :id=\"buttonId\"\n ref=\"triggerRef\"\n v-bind=\"$attrs\"\n :class=\"btnKls\"\n role=\"button\"\n :aria-label=\"buttonAriaLabel\"\n :aria-labelledby=\"buttonAriaLabelledby\"\n :aria-description=\"\n t('el.colorpicker.description', { color: modelValue || '' })\n \"\n :aria-disabled=\"colorDisabled\"\n :tabindex=\"colorDisabled ? undefined : tabindex\"\n @keydown=\"handleKeyDown\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n >\n <div :class=\"ns.be('picker', 'trigger')\" @click=\"handleTrigger\">\n <span :class=\"[ns.be('picker', 'color'), ns.is('alpha', showAlpha)]\">\n <span\n :class=\"ns.be('picker', 'color-inner')\"\n :style=\"{\n backgroundColor: displayedColor,\n }\"\n >\n <el-icon\n v-show=\"modelValue || showPanelColor\"\n :class=\"[ns.be('picker', 'icon'), ns.is('icon-arrow-down')]\"\n >\n <arrow-down />\n </el-icon>\n <el-icon\n v-show=\"!modelValue && !showPanelColor\"\n :class=\"[ns.be('picker', 'empty'), ns.is('icon-close')]\"\n >\n <close />\n </el-icon>\n </span>\n </span>\n </div>\n </div>\n </template>\n </el-tooltip>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, nextTick, provide, ref, watch } from 'vue'\nimport { debounce, pick } from 'lodash-unified'\nimport { ElIcon } from '@element-plus/components/icon'\nimport { reactiveComputed } from '@vueuse/core'\nimport { ClickOutside as vClickOutside } from '@element-plus/directives'\nimport { ElTooltip } from '@element-plus/components/tooltip'\nimport { ElButton } from '@element-plus/components/button'\nimport {\n useFormDisabled,\n useFormItem,\n useFormItemInputId,\n useFormSize,\n} from '@element-plus/components/form'\nimport {\n useEmptyValues,\n useFocusController,\n useLocale,\n useNamespace,\n} from '@element-plus/hooks'\nimport {\n CHANGE_EVENT,\n EVENT_CODE,\n UPDATE_MODEL_EVENT,\n} from '@element-plus/constants'\nimport { debugWarn, getEventCode } from '@element-plus/utils'\nimport { ArrowDown, Close } from '@element-plus/icons-vue'\nimport { colorPickerEmits, colorPickerPropsDefaults } from './color-picker'\nimport {\n ElColorPickerPanel,\n ROOT_COMMON_COLOR_INJECTION_KEY,\n colorPickerPanelProps,\n} from '@element-plus/components/color-picker-panel'\nimport Color from '@element-plus/components/color-picker-panel/src/utils/color'\nimport { useCommonColor } from '@element-plus/components/color-picker-panel/src/composables/use-common-color'\n\nimport type { ColorPickerPanelInstance } from '@element-plus/components/color-picker-panel'\nimport type { TooltipInstance } from '@element-plus/components/tooltip'\nimport type { ColorPickerProps } from './color-picker'\n\ndefineOptions({\n name: 'ElColorPicker',\n})\nconst props = withDefaults(\n defineProps<ColorPickerProps>(),\n colorPickerPropsDefaults\n)\n\nconst emit = defineEmits(colorPickerEmits)\n\nconst { t } = useLocale()\nconst ns = useNamespace('color')\nconst { formItem } = useFormItem()\nconst colorSize = useFormSize()\nconst colorDisabled = useFormDisabled()\nconst { valueOnClear, isEmptyValue } = useEmptyValues(props, null)\nconst commonColor = useCommonColor(props, emit)\nconst { inputId: buttonId, isLabeledByFormItem } = useFormItemInputId(props, {\n formItemContext: formItem,\n})\n\nconst popper = ref<TooltipInstance>()\nconst triggerRef = ref()\nconst pickerPanelRef = ref<ColorPickerPanelInstance>()\nconst showPicker = ref(false)\nconst showPanelColor = ref(false)\n\n// active-change is used to prevent modelValue changes from triggering.\nlet shouldActiveChange = true\n\nconst { isFocused, handleFocus, handleBlur } = useFocusController(triggerRef, {\n disabled: colorDisabled,\n beforeBlur(event) {\n return popper.value?.isFocusInsideContent(event)\n },\n afterBlur() {\n setShowPicker(false)\n resetColor()\n if (props.validateEvent) {\n formItem?.validate?.('blur').catch((err) => debugWarn(err))\n }\n },\n})\n\nconst color = reactiveComputed(\n () => pickerPanelRef.value?.color ?? commonColor.color\n) as Color\n\nconst panelProps = computed(() =>\n pick(props, Object.keys(colorPickerPanelProps))\n)\n\nconst displayedColor = computed(() => {\n if (!props.modelValue && !showPanelColor.value) {\n return 'transparent'\n }\n return displayedRgb(color, props.showAlpha)\n})\n\nconst currentColor = computed(() => {\n return !props.modelValue && !showPanelColor.value ? '' : color.value\n})\n\nconst buttonAriaLabel = computed<string | undefined>(() => {\n return !isLabeledByFormItem.value\n ? props.ariaLabel || t('el.colorpicker.defaultLabel')\n : undefined\n})\n\nconst buttonAriaLabelledby = computed<string | undefined>(() => {\n return isLabeledByFormItem.value ? formItem?.labelId : undefined\n})\n\nconst btnKls = computed(() => {\n return [\n ns.b('picker'),\n ns.is('disabled', colorDisabled.value),\n ns.bm('picker', colorSize.value),\n ns.is('focused', isFocused.value),\n ]\n})\n\nfunction displayedRgb(color: Color, showAlpha: boolean) {\n const { r, g, b, a } = color.toRgb()\n return showAlpha ? `rgba(${r}, ${g}, ${b}, ${a})` : `rgb(${r}, ${g}, ${b})`\n}\n\nfunction setShowPicker(value: boolean) {\n showPicker.value = value\n}\n\nconst debounceSetShowPicker = debounce(setShowPicker, 100, { leading: true })\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 if (showPicker.value) {\n resetColor()\n }\n debounceSetShowPicker(!showPicker.value)\n}\n\nfunction confirmValue() {\n const value = isEmptyValue(color.value) ? valueOnClear.value : color.value\n emit(UPDATE_MODEL_EVENT, value)\n emit(CHANGE_EVENT, 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, valueOnClear.value)\n emit(CHANGE_EVENT, valueOnClear.value)\n if (props.modelValue !== valueOnClear.value && props.validateEvent) {\n formItem?.validate('change').catch((err) => debugWarn(err))\n }\n resetColor()\n emit('clear')\n}\n\nfunction handleShowTooltip() {\n pickerPanelRef?.value?.inputRef?.focus()\n}\n\nfunction handleClickOutside() {\n if (!showPicker.value) return\n hide()\n isFocused.value && focus()\n}\n\nfunction handleEsc(event: KeyboardEvent) {\n event.preventDefault()\n event.stopPropagation()\n setShowPicker(false)\n resetColor()\n}\n\nfunction handleKeyDown(event: KeyboardEvent) {\n const code = getEventCode(event)\n\n switch (code) {\n case EVENT_CODE.enter:\n case EVENT_CODE.numpadEnter:\n case EVENT_CODE.space:\n event.preventDefault()\n event.stopPropagation()\n show()\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\nwatch(\n () => currentColor.value,\n (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 () => 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)\n\nwatch(\n () => showPicker.value,\n () => {\n pickerPanelRef.value && nextTick(pickerPanelRef.value.update)\n }\n)\n\nprovide(ROOT_COMMON_COLOR_INJECTION_KEY, commonColor)\n\ndefineExpose({\n /**\n * @description current color object\n */\n color,\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</script>\n"],"mappings":""}