UNPKG

winbox-ui-next

Version:

We Design Vue 2.0: A Vue.js 3 UI Library

611 lines (610 loc) 19.8 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); import { defineComponent, ref, provide, toRef, computed, watch, watchEffect, createVNode, withDirectives, resolveComponent, nextTick } from "vue"; import { clickoutside } from "vdirs"; import { rgba, rgb2hsv, hsla, hsl2hsv, hsva, hsl2rgb, hsv2rgb, rgb2hsl, hsv2hsl, getPreciseEventTarget, toHexString, toHexaString, toRgbaString, toRgbString, toHslaString, toHslString, toHsvaString, toHsvString } from "seemly"; import { useMergedState, useIsMounted } from "vooks"; import { VBinder, VTarget, VFollower } from "vueuc"; import "../_styles/common/dark.js"; import "../_styles/common/light.js"; import colorPickerLight from "../styles/light.js"; import useFormItem from "../_mixins/use-form-item.js"; import useTheme from "../_mixins/use-theme.js"; import useConfig from "../_mixins/use-config.js"; import "@css-render/vue3-ssr"; import { call } from "../_utils/vue/call.js"; import "../_utils/vue/wrapper.js"; import "../_utils/cssr/index.js"; import { useAdjustedTo } from "../_utils/composable/use-adjusted-to.js"; import "../_utils/composable/use-lock-html-scroll.js"; import "../_utils/composable/use-is-composing.js"; import "../_styles/global/index.cssr.js"; import { useThemeClass } from "../_mixins/use-css-vars-class.js"; import "css-render"; import HueSlider from "./HueSlider.js"; import AlphaSlider from "./AlphaSlider.js"; import Pallete from "./Pallete.js"; import ColorInput from "./ColorInput.js"; import ColorPickerTrigger from "./ColorPickerTrigger.js"; import { deriveDefaultValue, getModeFromValue } from "./utils.js"; import ColorPickerSwatches from "./ColorPickerSwatches.js"; import ColorPreview from "./ColorPreview.js"; import { colorPickerInjectionKey } from "./context.js"; import style from "./styles/index.cssr.js"; import { useI18n } from "../../locale/index.js"; import { createKey } from "../_utils/cssr/create-key.js"; const colorPickerProps = __spreadProps(__spreadValues({}, useTheme.props), { "value": String, "show": { type: Boolean, default: void 0 }, "defaultShow": Boolean, "defaultValue": String, "modes": { type: Array, default: () => ["rgb", "hex", "hsl"] }, "placement": { type: String, default: "bottom-start" }, "to": useAdjustedTo.propTo, "showAlpha": { type: Boolean, default: true }, "showPreview": Boolean, "swatches": Array, "disabled": { type: Boolean, default: void 0 }, "actions": { type: Array, default: null }, "internalActions": Array, "size": String, "renderLabel": Function, "onComplete": Function, "onConfirm": Function, "onUpdate:show": [Function, Array], "onUpdateShow": [Function, Array], "onUpdate:value": [Function, Array], "onUpdateValue": [Function, Array] }); var _ColorPicker = defineComponent({ name: "ColorPicker", props: colorPickerProps, setup(props, { slots }) { const { t } = useI18n(); const selfRef = ref(null); let upcomingValue = null; const formItem = useFormItem(props); const { mergedSizeRef, mergedDisabledRef } = formItem; const { mergedClsPrefixRef, namespaceRef, inlineThemeDisabled } = useConfig(props); const themeRef = useTheme("ColorPicker", "-color-picker", style, colorPickerLight, props, mergedClsPrefixRef); provide(colorPickerInjectionKey, { themeRef, renderLabelRef: toRef(props, "renderLabel"), colorPickerSlots: slots }); const uncontrolledShowRef = ref(props.defaultShow); const mergedShowRef = useMergedState(toRef(props, "show"), uncontrolledShowRef); function doUpdateShow(value) { const { onUpdateShow, "onUpdate:show": _onUpdateShow } = props; if (onUpdateShow) call(onUpdateShow, value); if (_onUpdateShow) call(_onUpdateShow, value); uncontrolledShowRef.value = value; } const { defaultValue } = props; const uncontrolledValueRef = ref(defaultValue === void 0 ? deriveDefaultValue(props.modes, props.showAlpha) : defaultValue); const mergedValueRef = useMergedState(toRef(props, "value"), uncontrolledValueRef); const undoStackRef = ref([mergedValueRef.value]); const valueIndexRef = ref(0); const valueModeRef = computed(() => getModeFromValue(mergedValueRef.value)); const { modes } = props; const displayedModeRef = ref(getModeFromValue(mergedValueRef.value) || modes[0] || "rgb"); function handleUpdateDisplayedMode() { const { modes: modes2 } = props; const { value: displayedMode } = displayedModeRef; const currentModeIndex = modes2.findIndex((mode) => mode === displayedMode); if (~currentModeIndex) { displayedModeRef.value = modes2[(currentModeIndex + 1) % modes2.length]; } else { displayedModeRef.value = "rgb"; } } let _h; let s; let l; let v; let r; let g; let b; let a; const hsvaRef = computed(() => { const { value: mergedValue } = mergedValueRef; if (!mergedValue) return null; switch (valueModeRef.value) { case "hsv": return hsva(mergedValue); case "hsl": [_h, s, l, a] = hsla(mergedValue); return [...hsl2hsv(_h, s, l), a]; case "rgb": case "hex": [r, g, b, a] = rgba(mergedValue); return [...rgb2hsv(r, g, b), a]; } }); const rgbaRef = computed(() => { const { value: mergedValue } = mergedValueRef; if (!mergedValue) return null; switch (valueModeRef.value) { case "rgb": case "hex": return rgba(mergedValue); case "hsv": [_h, s, v, a] = hsva(mergedValue); return [...hsv2rgb(_h, s, v), a]; case "hsl": [_h, s, l, a] = hsla(mergedValue); return [...hsl2rgb(_h, s, l), a]; } }); const hslaRef = computed(() => { const { value: mergedValue } = mergedValueRef; if (!mergedValue) return null; switch (valueModeRef.value) { case "hsl": return hsla(mergedValue); case "hsv": [_h, s, v, a] = hsva(mergedValue); return [...hsv2hsl(_h, s, v), a]; case "rgb": case "hex": [r, g, b, a] = rgba(mergedValue); return [...rgb2hsl(r, g, b), a]; } }); const mergedValueArrRef = computed(() => { switch (displayedModeRef.value) { case "rgb": case "hex": return rgbaRef.value; case "hsv": return hsvaRef.value; case "hsl": return hslaRef.value; } }); const displayedHueRef = ref(0); const displayedAlphaRef = ref(1); const displayedSvRef = ref([0, 0]); function handleUpdateSv(s2, v2) { const { value: hsvaArr } = hsvaRef; const hue = displayedHueRef.value; const alpha = hsvaArr ? hsvaArr[3] : 1; displayedSvRef.value = [s2, v2]; const { showAlpha } = props; switch (displayedModeRef.value) { case "hsv": doUpdateValue((showAlpha ? toHsvaString : toHsvString)([hue, s2, v2, alpha]), "cursor"); break; case "hsl": doUpdateValue((showAlpha ? toHslaString : toHslString)([...hsv2hsl(hue, s2, v2), alpha]), "cursor"); break; case "rgb": doUpdateValue((showAlpha ? toRgbaString : toRgbString)([...hsv2rgb(hue, s2, v2), alpha]), "cursor"); break; case "hex": doUpdateValue((showAlpha ? toHexaString : toHexString)([...hsv2rgb(hue, s2, v2), alpha]), "cursor"); break; } } function handleUpdateHue(hue) { displayedHueRef.value = hue; const { value: hsvaArr } = hsvaRef; if (!hsvaArr) { return; } const [, s2, v2, a2] = hsvaArr; const { showAlpha } = props; switch (displayedModeRef.value) { case "hsv": doUpdateValue((showAlpha ? toHsvaString : toHsvString)([hue, s2, v2, a2]), "cursor"); break; case "rgb": doUpdateValue((showAlpha ? toRgbaString : toRgbString)([...hsv2rgb(hue, s2, v2), a2]), "cursor"); break; case "hex": doUpdateValue((showAlpha ? toHexaString : toHexString)([...hsv2rgb(hue, s2, v2), a2]), "cursor"); break; case "hsl": doUpdateValue((showAlpha ? toHslaString : toHslString)([...hsv2hsl(hue, s2, v2), a2]), "cursor"); break; } } function handleUpdateAlpha(alpha) { switch (displayedModeRef.value) { case "hsv": [_h, s, v] = hsvaRef.value; doUpdateValue(toHsvaString([_h, s, v, alpha]), "cursor"); break; case "rgb": [r, g, b] = rgbaRef.value; doUpdateValue(toRgbaString([r, g, b, alpha]), "cursor"); break; case "hex": [r, g, b] = rgbaRef.value; doUpdateValue(toHexaString([r, g, b, alpha]), "cursor"); break; case "hsl": [_h, s, l] = hslaRef.value; doUpdateValue(toHslaString([_h, s, l, alpha]), "cursor"); break; } displayedAlphaRef.value = alpha; } function doUpdateValue(value, updateSource) { if (updateSource === "cursor") { upcomingValue = value; } else { upcomingValue = null; } const { nTriggerFormChange, nTriggerFormInput } = formItem; const { onUpdateValue, "onUpdate:value": _onUpdateValue } = props; if (onUpdateValue) call(onUpdateValue, value); if (_onUpdateValue) call(_onUpdateValue, value); nTriggerFormChange(); nTriggerFormInput(); uncontrolledValueRef.value = value; } function handleInputUpdateValue(value) { doUpdateValue(value, "input"); void nextTick(handleComplete); } function handleComplete(pushStack = true) { const { value } = mergedValueRef; if (value) { const { nTriggerFormChange, nTriggerFormInput } = formItem; const { onComplete } = props; if (onComplete) { onComplete(value); } const { value: undoStack } = undoStackRef; const { value: valueIndex } = valueIndexRef; if (pushStack) { undoStack.splice(valueIndex + 1, undoStack.length, value); valueIndexRef.value = valueIndex + 1; } nTriggerFormChange(); nTriggerFormInput(); } } function undo() { const { value: valueIndex } = valueIndexRef; if (valueIndex - 1 < 0) return; doUpdateValue(undoStackRef.value[valueIndex - 1], "input"); handleComplete(false); valueIndexRef.value = valueIndex - 1; } function redo() { const { value: valueIndex } = valueIndexRef; if (valueIndex < 0 || valueIndex + 1 >= undoStackRef.value.length) return; doUpdateValue(undoStackRef.value[valueIndex + 1], "input"); handleComplete(false); valueIndexRef.value = valueIndex + 1; } function handleClear() { doUpdateValue(null, "input"); doUpdateShow(false); } function handleConfirm() { const { value } = mergedValueRef; const { onConfirm } = props; if (onConfirm) { onConfirm(value); } doUpdateShow(false); } const undoableRef = computed(() => valueIndexRef.value >= 1); const redoableRef = computed(() => { const { value: undoStack } = undoStackRef; return undoStack.length > 1 && valueIndexRef.value < undoStack.length - 1; }); watch(mergedShowRef, (value) => { if (!value) { undoStackRef.value = [mergedValueRef.value]; valueIndexRef.value = 0; } }); watchEffect(() => { if (upcomingValue && upcomingValue === mergedValueRef.value) ; else { const { value } = hsvaRef; if (value) { displayedHueRef.value = value[0]; displayedAlphaRef.value = value[3]; displayedSvRef.value = [value[1], value[2]]; } } upcomingValue = null; }); const cssVarsRef = computed(() => { const { value: mergedSize } = mergedSizeRef; const { common: { cubicBezierEaseInOut }, self: { [createKey("height", mergedSize)]: height } } = themeRef.value; return { "--n-height": height }; }); const themeClassHandle = inlineThemeDisabled ? useThemeClass("color-picker", computed(() => { return mergedSizeRef.value[0]; }), cssVarsRef, props) : void 0; function renderPanel() { var _a; const { value: rgba2 } = rgbaRef; const { value: displayedHue } = displayedHueRef; const { internalActions, modes: modes2, actions } = props; const { value: mergedClsPrefix } = mergedClsPrefixRef; return createVNode("div", { "class": [`${mergedClsPrefix}-color-picker-panel`, themeClassHandle == null ? void 0 : themeClassHandle.themeClass.value], "onDragstart": (e) => { e.preventDefault(); }, "style": inlineThemeDisabled ? void 0 : cssVarsRef.value }, [createVNode("div", { "class": `${mergedClsPrefix}-color-picker-control` }, [createVNode(Pallete, { "clsPrefix": mergedClsPrefix, "rgba": rgba2, "displayedHue": displayedHue, "displayedSv": displayedSvRef.value, "onUpdateSV": handleUpdateSv, "onComplete": handleComplete }, null), createVNode("div", { "class": `${mergedClsPrefix}-color-picker-preview` }, [createVNode("div", { "class": `${mergedClsPrefix}-color-picker-preview__sliders` }, [createVNode(HueSlider, { "clsPrefix": mergedClsPrefix, "hue": displayedHue, "onUpdateHue": handleUpdateHue, "onComplete": handleComplete }, null), props.showAlpha ? createVNode(AlphaSlider, { "clsPrefix": mergedClsPrefix, "rgba": rgba2, "alpha": displayedAlphaRef.value, "onUpdateAlpha": handleUpdateAlpha, "onComplete": handleComplete }, null) : null]), props.showPreview ? createVNode(ColorPreview, { "clsPrefix": mergedClsPrefix, "mode": displayedModeRef.value, "color": rgbaRef.value && toHexString(rgbaRef.value), "onUpdateColor": (color) => doUpdateValue(color, "input") }, null) : null]), createVNode(ColorInput, { "clsPrefix": mergedClsPrefix, "showAlpha": props.showAlpha, "mode": displayedModeRef.value, "modes": modes2, "onUpdateMode": handleUpdateDisplayedMode, "value": mergedValueRef.value, "valueArr": mergedValueArrRef.value, "onUpdateValue": handleInputUpdateValue }, null), ((_a = props.swatches) == null ? void 0 : _a.length) && createVNode(ColorPickerSwatches, { "clsPrefix": mergedClsPrefix, "mode": displayedModeRef.value, "swatches": props.swatches, "onUpdateColor": (color) => doUpdateValue(color, "input") }, null)]), (actions == null ? void 0 : actions.length) ? createVNode("div", { "class": `${mergedClsPrefix}-color-picker-action` }, [actions.includes("confirm") && createVNode(resolveComponent("w-button"), { "size": "medium", "onClick": handleConfirm }, { default: () => t("colorPicker.confirm") }), actions.includes("clear") && createVNode(resolveComponent("w-button"), { "size": "medium", "onClick": handleClear, "disabled": !mergedValueRef.value }, { default: () => t("colorPicker.clear") })]) : null, slots.action ? createVNode("div", { "class": `${mergedClsPrefix}-color-picker-action` }, { default: slots.action }) : internalActions ? createVNode("div", { "class": `${mergedClsPrefix}-color-picker-action` }, [internalActions.includes("undo") && createVNode(resolveComponent("w-button"), { "size": "medium", "onClick": undo, "disabled": !undoableRef.value }, { default: () => t("colorPicker.undo") }), internalActions.includes("redo") && createVNode(resolveComponent("w-button"), { "size": "medium", "onClick": redo, "disabled": !redoableRef.value }, { default: () => t("colorPicker.redo") })]) : null]); } return { mergedSize: mergedSizeRef, mergedClsPrefix: mergedClsPrefixRef, namespace: namespaceRef, selfRef, hsla: hslaRef, rgba: rgbaRef, mergedShow: mergedShowRef, mergedDisabled: mergedDisabledRef, isMounted: useIsMounted(), adjustedTo: useAdjustedTo(props), mergedValue: mergedValueRef, handleTriggerClick() { doUpdateShow(true); }, handleClickOutside(e) { var _a; if ((_a = selfRef.value) == null ? void 0 : _a.contains(getPreciseEventTarget(e))) { return; } doUpdateShow(false); }, renderPanel, cssVars: inlineThemeDisabled ? void 0 : cssVarsRef, themeClass: themeClassHandle == null ? void 0 : themeClassHandle.themeClass, onRender: themeClassHandle == null ? void 0 : themeClassHandle.onRender }; }, render() { const { $slots, mergedClsPrefix, onRender, mergedSize } = this; onRender == null ? void 0 : onRender(); return createVNode("div", { "class": [this.themeClass, `${mergedClsPrefix}-color-picker ${mergedClsPrefix}-color-picker-${mergedSize}`], "ref": "selfRef", "style": this.cssVars }, [createVNode(VBinder, null, { default: () => [createVNode(VTarget, null, { default: () => createVNode(ColorPickerTrigger, { "clsPrefix": mergedClsPrefix, "value": this.mergedValue, "hsla": this.hsla, "disabled": this.mergedDisabled, "onClick": this.handleTriggerClick }, { label: $slots.label }) }), createVNode(VFollower, { "placement": this.placement, "show": this.mergedShow, "containerClass": this.namespace, "teleportDisabled": this.adjustedTo === useAdjustedTo.tdkey, "to": this.adjustedTo }, { default: () => this.mergedShow ? withDirectives(this.renderPanel(), [[clickoutside, this.handleClickOutside, void 0, { capture: true }]]) : null })] })]); } }); export { colorPickerProps, _ColorPicker as default };