echo-library-vue 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +226 -0
- package/dist/components/Button/index.d.ts +6 -0
- package/dist/components/Button/index.vue.d.ts +56 -0
- package/dist/components/Button/types.d.ts +11 -0
- package/dist/components/ColorPicker/constant.d.ts +1 -0
- package/dist/components/ColorPicker/index.d.ts +6 -0
- package/dist/components/ColorPicker/index.vue.d.ts +54 -0
- package/dist/components/ColorPicker/types.d.ts +11 -0
- package/dist/components/ColorPicker/utils.d.ts +156 -0
- package/dist/components/Dropdown/index.d.ts +6 -0
- package/dist/components/Dropdown/index.vue.d.ts +53 -0
- package/dist/components/Dropdown/types.d.ts +44 -0
- package/dist/components/Icon/index.d.ts +6 -0
- package/dist/components/Icon/index.vue.d.ts +44 -0
- package/dist/components/Icon/types.d.ts +6 -0
- package/dist/components/Input/index.d.ts +6 -0
- package/dist/components/Input/index.vue.d.ts +67 -0
- package/dist/components/Input/types.d.ts +14 -0
- package/dist/index.d.ts +598 -0
- package/dist/index.esm.js +676 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/style.css +1 -0
- package/package.json +120 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../packages/components/Icon/index.vue","../packages/components/Button/index.vue","../packages/components/ColorPicker/constant.ts","../packages/components/ColorPicker/utils.ts","../packages/components/ColorPicker/index.vue","../packages/components/Dropdown/index.vue","../packages/components/Input/index.vue","../packages/index.ts"],"sourcesContent":["<template>\n <i :class=\"iconClasses\" :style=\"iconStyles\" @click=\"handleClick\">\n <slot />\n </i>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { IconProps } from './types.ts'\n\n// 定义组件属性\nconst props = withDefaults(defineProps<IconProps>(), {\n size: 16,\n color: 'currentColor',\n spin: false,\n})\n\n// 定义事件\nconst emit = defineEmits<{\n click: [event: MouseEvent]\n}>()\n\n// 计算图标样式类\nconst iconClasses = computed(() => [\n 'echo-icon',\n `echo-icon--${props.name}`,\n {\n 'echo-icon--spin': props.spin,\n },\n])\n\n// 计算图标样式\nconst iconStyles = computed(() => ({\n fontSize: typeof props.size === 'number' ? `${props.size}px` : props.size,\n color: props.color,\n}))\n\n// 处理点击事件\nconst handleClick = (event: MouseEvent) => {\n emit('click', event)\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.echo-icon {\n display: inline-block;\n font-style: normal;\n line-height: 1;\n vertical-align: middle;\n transition: all 0.2s ease-in-out;\n\n &--spin {\n animation: spin 1s linear infinite;\n }\n\n // 常用图标样式\n &--loading {\n &::before {\n content: '⟳';\n }\n }\n\n &--close {\n &::before {\n content: '×';\n }\n }\n\n &--search {\n &::before {\n content: '🔍';\n }\n }\n\n &--user {\n &::before {\n content: '👤';\n }\n }\n\n &--home {\n &::before {\n content: '🏠';\n }\n }\n\n &--settings {\n &::before {\n content: '⚙️';\n }\n }\n\n &--heart {\n &::before {\n content: '❤️';\n }\n }\n\n &--star {\n &::before {\n content: '⭐';\n }\n }\n\n &--check {\n &::before {\n content: '✓';\n }\n }\n\n &--plus {\n &::before {\n content: '+';\n }\n }\n\n &--minus {\n &::before {\n content: '−';\n }\n }\n\n &--arrow-up {\n &::before {\n content: '↑';\n }\n }\n\n &--arrow-down {\n &::before {\n content: '↓';\n }\n }\n\n &--arrow-left {\n &::before {\n content: '←';\n }\n }\n\n &--arrow-right {\n &::before {\n content: '→';\n }\n }\n}\n\n@keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n</style>\n","<template>\n <button :class=\"buttonClasses\" :disabled=\"disabled || loading\" @click=\"handleClick\">\n <EchoIcon\n v-if=\"loading\"\n name=\"loading\"\n class=\"echo-button__loading\"\n :class=\"{ 'echo-button__loading--spinning': loading }\"\n />\n <EchoIcon v-else-if=\"icon\" :name=\"icon\" class=\"echo-button__icon\" />\n <span v-if=\"$slots.default\" class=\"echo-button__text\">\n <slot />\n </span>\n </button>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport EchoIcon from '../Icon'\nimport type { ButtonProps } from './types.ts'\n\n// 定义组件属性\nconst props = withDefaults(defineProps<ButtonProps>(), {\n type: 'primary',\n size: 'medium',\n disabled: false,\n loading: false,\n round: false,\n plain: false,\n icon: '',\n})\n\n// 定义事件\nconst emit = defineEmits<{\n click: [event: MouseEvent]\n}>()\n\n// 计算按钮样式类\nconst buttonClasses = computed(() => [\n 'echo-button',\n `echo-button--${props.type}`,\n `echo-button--${props.size}`,\n {\n 'echo-button--disabled': props.disabled,\n 'echo-button--loading': props.loading,\n 'echo-button--round': props.round,\n 'echo-button--plain': props.plain,\n },\n])\n\n// 处理点击事件\nconst handleClick = (event: MouseEvent) => {\n if (props.disabled || props.loading) {\n return\n }\n emit('click', event)\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.echo-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n border: 1px solid transparent;\n border-radius: var(--echo-border-radius, 6px);\n font-size: var(--echo-font-size, 14px);\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease-in-out;\n outline: none;\n user-select: none;\n\n &:focus {\n outline: 2px solid var(--echo-primary-color, #1890ff);\n outline-offset: 2px;\n }\n\n // 尺寸变体\n &--small {\n padding: 6px 12px;\n font-size: 12px;\n min-height: 28px;\n }\n\n &--medium {\n padding: 8px 16px;\n font-size: 14px;\n min-height: 32px;\n }\n\n &--large {\n padding: 12px 20px;\n font-size: 16px;\n min-height: 40px;\n }\n\n // 类型变体\n &--primary {\n background-color: var(--echo-primary-color, #1890ff);\n color: white;\n border-color: var(--echo-primary-color, #1890ff);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-primary-hover, #40a9ff);\n border-color: var(--echo-primary-hover, #40a9ff);\n }\n\n &.echo-button--plain {\n background-color: transparent;\n color: var(--echo-primary-color, #1890ff);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-primary-color, #1890ff);\n color: white;\n }\n }\n }\n\n &--secondary {\n background-color: var(--echo-secondary-color, #f5f5f5);\n color: var(--echo-text-color, #333);\n border-color: var(--echo-border-color, #d9d9d9);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-secondary-hover, #e6e6e6);\n border-color: var(--echo-secondary-hover, #bfbfbf);\n }\n }\n\n &--success {\n background-color: var(--echo-success-color, #52c41a);\n color: white;\n border-color: var(--echo-success-color, #52c41a);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-success-hover, #73d13d);\n border-color: var(--echo-success-hover, #73d13d);\n }\n }\n\n &--warning {\n background-color: var(--echo-warning-color, #faad14);\n color: white;\n border-color: var(--echo-warning-color, #faad14);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-warning-hover, #ffc53d);\n border-color: var(--echo-warning-hover, #ffc53d);\n }\n }\n\n &--danger {\n background-color: var(--echo-danger-color, #ff4d4f);\n color: white;\n border-color: var(--echo-danger-color, #ff4d4f);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-danger-hover, #ff7875);\n border-color: var(--echo-danger-hover, #ff7875);\n }\n }\n\n &--info {\n background-color: var(--echo-info-color, #1890ff);\n color: white;\n border-color: var(--echo-info-color, #1890ff);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-info-hover, #40a9ff);\n border-color: var(--echo-info-hover, #40a9ff);\n }\n }\n\n // 状态变体\n &--disabled {\n opacity: 0.6;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n &--round {\n border-radius: 50px;\n }\n\n // 加载状态\n &--loading {\n cursor: wait;\n }\n\n &__loading {\n &--spinning {\n animation: spin 1s linear infinite;\n }\n }\n\n &__icon {\n flex-shrink: 0;\n }\n\n &__text {\n line-height: 1;\n }\n}\n\n@keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n</style>\n","export const DEFAULT_COLORS = [\n '#FFFFFF',\n '#000000',\n '#FF0000',\n '#00FF00',\n '#0000FF',\n '#FF1900',\n '#F47365',\n '#F89C5A',\n '#FAC858',\n '#73B06F',\n '#6ECBE6',\n '#926383',\n '#C89616',\n '#8E00A7',\n '#BF3DCE',\n '#FC3CAD',\n '#FF89CF',\n '#5D61FF',\n '#00BEFF',\n '#1BC7B1',\n]\n","/**\n * 颜色工具函数\n * 用于颜色格式之间的转换\n */\n\n/**\n * HEX 转 RGB\n * @param hex\n * @returns RGB对象 {r, g, b}\n */\nexport const hexToRgb = (hex: string): { r: number; g: number; b: number } | null => {\n // 移除#号\n const cleanHex = hex.replace('#', '')\n\n // 验证格式\n if (!/^[0-9A-Fa-f]{6}$/.test(cleanHex)) {\n return null\n }\n\n const r = parseInt(cleanHex.substring(0, 2), 16)\n const g = parseInt(cleanHex.substring(2, 4), 16)\n const b = parseInt(cleanHex.substring(4, 6), 16)\n\n return { r, g, b }\n}\n\n/**\n * rgb转hex\n * @param r 红色值 0-255\n * @param g 绿色值 0-255\n * @param b 蓝色值 0-255\n * @returnd HEX颜色值\n */\nexport const rgbToHex = (r: number, g: number, b: number): string => {\n const toHex = (n: number) => {\n const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16)\n return hex.length === 1 ? `0${hex}` : hex\n }\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`.toUpperCase()\n}\n\n/**\n * RGB 转 HSL\n * @param r 红色值 0-255\n * @param g 绿色值 0-255\n * @param b 蓝色值 0-255\n * @returns HSL对象 {h, s, l}, h: 0-360, s: 0-100, l: 0-100\n */\nexport const rgbToHsl = (r: number, g: number, b: number): { h: number; s: number; l: number } => {\n r /= 255\n g /= 255\n b /= 255\n\n const max = Math.max(r, g, b)\n const min = Math.min(r, g, b)\n let h = 0\n let s = 0\n const l = (max + min) / 2\n\n if (max !== min) {\n const d = max - min\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min)\n\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6\n break\n case g:\n h = ((b - r) / d + 2) / 6\n break\n case b:\n h = ((r - g) / d + 4) / 6\n break\n }\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n }\n}\n\n/**\n * HSL 转 RGB\n * @param h 色相 0-360\n * @param s 饱和度 0-100\n * @param l 明度 0-100\n * @returns RGB对象 {r, g, b}\n */\nexport function hslToRgb(h: number, s: number, l: number): { r: number; g: number; b: number } {\n h /= 360\n s /= 100\n l /= 100\n\n let r, g, b\n\n if (s === 0) {\n r = g = b = l // 无色彩\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1\n if (t > 1) t -= 1\n if (t < 1 / 6) return p + (q - p) * 6 * t\n if (t < 1 / 2) return q\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6\n return p\n }\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s\n const p = 2 * l - q\n\n r = hue2rgb(p, q, h + 1 / 3)\n g = hue2rgb(p, q, h)\n b = hue2rgb(p, q, h - 1 / 3)\n }\n\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n }\n}\n\n/**\n * HEX 转 HSL\n * @param hex HEX颜色值\n * @returns HSL对象\n */\nexport function hexToHsl(hex: string): { h: number; s: number; l: number } | null {\n const rgb = hexToRgb(hex)\n if (!rgb) return null\n return rgbToHsl(rgb.r, rgb.g, rgb.b)\n}\n\n/**\n * HSL 转 HEX\n * @param h 色相\n * @param s 饱和度\n * @param l 明度\n * @returns HEX颜色值\n */\nexport function hslToHex(h: number, s: number, l: number): string {\n const rgb = hslToRgb(h, s, l)\n return rgbToHex(rgb.r, rgb.g, rgb.b)\n}\n\n/**\n * 验证 HEX 颜色格式\n * @param hex HEX颜色值\n * @returns 是否为有效格式\n */\nexport function isValidHex(hex: string): boolean {\n const cleanHex = hex.replace('#', '')\n return /^[0-9A-Fa-f]{6}$/.test(cleanHex) || /^[0-9A-Fa-f]{8}$/.test(cleanHex)\n}\n\n/**\n * HEX 转 RGBA\n * @param hex HEX颜色值(支持 #RRGGBB 或 #RRGGBBAA)\n * @param alpha 透明度 0-1,如果不提供则从hex中解析\n * @returns RGBA对象 {r, g, b, a}\n */\nexport function hexToRgba(\n hex: string,\n alpha?: number\n): { r: number; g: number; b: number; a: number } | null {\n const cleanHex = hex.replace('#', '')\n\n // 支持 6 位或 8 位 HEX\n if (!/^[0-9A-Fa-f]{6}$/.test(cleanHex) && !/^[0-9A-Fa-f]{8}$/.test(cleanHex)) {\n return null\n }\n\n const r = parseInt(cleanHex.substring(0, 2), 16)\n const g = parseInt(cleanHex.substring(2, 4), 16)\n const b = parseInt(cleanHex.substring(4, 6), 16)\n\n // 如果提供了 alpha 参数,使用它;否则从 8 位 HEX 中解析\n let a = alpha !== undefined ? alpha : 1\n if (cleanHex.length === 8) {\n a = parseInt(cleanHex.substring(6, 8), 16) / 255\n }\n\n return { r, g, b, a }\n}\n\n/**\n * RGBA 转 HEX(8位带透明度)\n * @param r 红色值 0-255\n * @param g 绿色值 0-255\n * @param b 蓝色值 0-255\n * @param a 透明度 0-1\n * @returns HEX颜色值 #RRGGBBAA\n */\nexport function rgbaToHex(r: number, g: number, b: number, a: number = 1): string {\n const toHex = (n: number) => {\n const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16)\n return hex.length === 1 ? '0' + hex : hex\n }\n\n const alphaHex = toHex(a * 255)\n return `#${toHex(r)}${toHex(g)}${toHex(b)}${alphaHex}`.toUpperCase()\n}\n\n/**\n * RGBA 转 HEX(6位不带透明度)\n * @param r 红色值 0-255\n * @param g 绿色值 0-255\n * @param b 蓝色值 0-255\n * @returns HEX颜色值 #RRGGBB\n */\nexport function rgbToHexWithoutAlpha(r: number, g: number, b: number): string {\n return rgbToHex(r, g, b)\n}\n\n/**\n * HSL 转 RGBA\n * @param h 色相 0-360\n * @param s 饱和度 0-100\n * @param l 明度 0-100\n * @param a 透明度 0-1\n * @returns RGBA对象\n */\nexport function hslaToRgba(\n h: number,\n s: number,\n l: number,\n a: number = 1\n): { r: number; g: number; b: number; a: number } {\n const rgb = hslToRgb(h, s, l)\n return { ...rgb, a }\n}\n\n/**\n * RGBA 转 HSL\n * @param r 红色值 0-255\n * @param g 绿色值 0-255\n * @param b 蓝色值 0-255\n * @param a 透明度 0-1\n * @returns HSLA对象 {h, s, l, a}\n */\nexport function rgbaToHsla(\n r: number,\n g: number,\n b: number,\n a: number = 1\n): { h: number; s: number; l: number; a: number } {\n const hsl = rgbToHsl(r, g, b)\n return { ...hsl, a }\n}\n\n/**\n * HSL 转 RGBA HEX(8位)\n * @param h 色相\n * @param s 饱和度\n * @param l 明度\n * @param a 透明度\n * @returns HEX颜色值 #RRGGBBAA\n */\nexport function hslaToHex(h: number, s: number, l: number, a: number = 1): string {\n const rgba = hslaToRgba(h, s, l, a)\n return rgbaToHex(rgba.r, rgba.g, rgba.b, rgba.a)\n}\n\n/**\n * HEX 转 HSLA\n * @param hex HEX颜色值(支持 #RRGGBB 或 #RRGGBBAA)\n * @returns HSLA对象\n */\nexport function hexToHsla(hex: string): { h: number; s: number; l: number; a: number } | null {\n const rgba = hexToRgba(hex)\n if (!rgba) return null\n return rgbaToHsla(rgba.r, rgba.g, rgba.b, rgba.a)\n}\n\n/**\n * RGBA 转 CSS rgba 字符串\n * @param r 红色值 0-255\n * @param g 绿色值 0-255\n * @param b 蓝色值 0-255\n * @param a 透明度 0-1\n * @returns CSS rgba 字符串\n */\nexport function rgbaToCss(r: number, g: number, b: number, a: number = 1): string {\n return `rgba(${r}, ${g}, ${b}, ${a})`\n}\n","<template>\n <div ref=\"colorPickerRef\" class=\"color-picker\" :class=\"[`color-picker--${theme}`]\">\n <!-- 头部 -->\n <!-- <div class=\"color-picker__header\">\n <div class=\"color-picker__header__mode-switch\">\n <EchoDropdown :items=\"modeItems\" @select=\"handleModeSelect\">\n <span>模式切换</span>\n </EchoDropdown>\n </div>\n </div> -->\n <!-- 主颜色选择区域 -->\n <div class=\"color-picker__main\">\n <!-- 饱和度和明度选择面板 -->\n <div\n ref=\"saturationPanelRef\"\n class=\"color-picker__saturation-panel\"\n :style=\"{ background: `linear-gradient(to right, #fff, hsl(${hsl.h}, 100%, 50%))` }\"\n @mousedown=\"handleSaturationMouseDown\"\n >\n <div\n class=\"color-picker__saturation-panel-black\"\n :style=\"{ background: `linear-gradient(to bottom, transparent, #000)` }\"\n >\n <div\n class=\"color-picker__saturation-panel-pointer\"\n :style=\"{\n left: `${hsl.s}%`,\n top: `${100 - hsl.l}%`,\n background: currentColorHex,\n }\"\n ></div>\n </div>\n </div>\n <!-- 色相选择条 -->\n <div ref=\"hueBarRef\" class=\"color-picker__hue-bar\" @mousedown=\"handleHueMouseDown\">\n <div\n class=\"color-picker__hue-bar-pointer\"\n :style=\"{ left: `${(hsl.h / 360) * 100}%` }\"\n ></div>\n </div>\n <!-- 透明度选择器 -->\n <div ref=\"alphaBarRef\" class=\"color-picker__alpha-bar\" @mousedown=\"handleAlphaMouseDown\">\n <div\n class=\"color-picker__alpha-bar-bg\"\n :style=\"{\n background: `linear-gradient(to right, transparent, ${currentColorHex})`,\n }\"\n ></div>\n <div class=\"color-picker__alpha-bar-pointer\" :style=\"{ left: `${alpha * 100}%` }\"></div>\n </div>\n </div>\n <!-- 底部控制区域 -->\n <div class=\"color-picker__controls\">\n <!-- 颜色预览 -->\n <div class=\"color-picker__controls__preview\" :style=\"{ background: currentColorRgba }\"></div>\n <!-- 颜色输入框 -->\n <div class=\"color-picker__controls__input-group\">\n <input\n type=\"text\"\n name=\"color-input\"\n v-model=\"colorInput\"\n class=\"color-picker__controls__input-group__input\"\n :placeholder=\"alpha < 1 ? '#000000FF' : '#000000'\"\n @input=\"handleInputChange\"\n />\n </div>\n <!-- 吸色器 -->\n <div class=\"color-picker__controls__eyedropper\">\n <button\n class=\"color-picker__controls__eyedropper-btn\"\n @click=\"handleEyeDropper\"\n :disabled=\"!isEyeDropperSupported\"\n title=\"吸取颜色\"\n >\n <svg\n t=\"1768013548643\"\n class=\"icon\"\n viewBox=\"0 0 1109 1024\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n p-id=\"1740\"\n width=\"40\"\n height=\"40\"\n >\n <path\n d=\"M968.525486 0c22.934274 0 45.015973 9.122555 61.214903 25.15097l53.200696 52.518635a85.257525 85.257525 0 0 1 0 121.321459l-123.367639 121.918261 20.206033 19.950261 4.689164 5.200709a54.564816 54.564816 0 0 1-4.689164 72.724669l-39.218461 38.706916a56.269967 56.269967 0 0 1-78.777953 0.085258l-1.278863-1.278863-486.990984 479.147291a125.072789 125.072789 0 0 1-71.786836 35.381873l-10.230903 0.937833-20.035519 19.609231a109.300147 109.300147 0 0 1-176.056789-30.692709c-17.90408-38.024856-11.850796-83.04083 15.346354-115.012402l6.394315-6.820602 19.95026-19.609231c1.449378-27.197151 11.936054-52.944923 29.669619-73.577244l6.991117-7.502662L660.74582 258.756589l-5.456481-5.371224-9.719358-9.548843-4.689164-5.200709a54.650074 54.650074 0 0 1 4.689164-72.809927l39.047946-38.621658a56.269967 56.269967 0 0 1 78.863211 0l20.206033 19.95026L907.140068 25.236227c16.369445-16.19893 38.365886-25.236227 61.385418-25.236227z\"\n fill=\"#64666F\"\n p-id=\"1741\"\n ></path>\n <path\n d=\"M699.111707 292.433311L227.637592 763.05485a68.802823 68.802823 0 0 0-19.097685 37.342796l-0.682061 6.991117-1.193605 20.717579-33.76198 33.847238a52.00709 52.00709 0 0 0-1.70515 70.337458 51.580803 51.580803 0 0 0 69.57014 7.502662l5.115452-4.518649 34.10301-34.10301 20.632321-1.02309a66.330355 66.330355 0 0 0 38.792174-15.090582l5.285966-4.859679 471.3036-470.536281-116.80281-117.314355H699.111707z\"\n fill=\"#F7F8FA\"\n p-id=\"1742\"\n ></path>\n </svg>\n </button>\n </div>\n </div>\n <!-- 颜色列表 -->\n <div class=\"color-picker__color-list\">\n <div\n class=\"color-picker__color-list__item\"\n v-for=\"(color, index) in defaultColors\"\n :key=\"index\"\n :style=\"{ backgroundColor: color }\"\n :title=\"color\"\n @click=\"handleColorSelect(color)\"\n ></div>\n </div>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { DEFAULT_COLORS } from './constant.ts'\nimport { ColorPickerProps } from './types.ts'\nimport { hexToHsla, hslaToHex, hslaToRgba, isValidHex, rgbaToCss, rgbaToHsla } from './utils'\n\nconst props = withDefaults(defineProps<ColorPickerProps>(), {\n theme: 'light',\n type: 'hex',\n mode: 'solid',\n showAlpha: true,\n showEyeDropper: true,\n showPickerMode: true,\n showColorList: true,\n defaultColors: () => DEFAULT_COLORS,\n})\n\nconst emit = defineEmits<{\n (e: 'update:color', color: string): void\n (e: 'colorChange', color: string): void\n}>()\n\nconst hsl = ref({\n h: 0, // 色相 0-360\n s: 0, // 饱和度 0-100\n l: 0, // 明度 0-100\n})\n\nconst colorInput = ref('')\nconst alpha = ref(1)\nconst isEyeDropperSupported = ref(true)\n\nconst colorPickerRef = ref<HTMLDivElement | null>(null)\nconst saturationPanelRef = ref<HTMLDivElement | null>(null)\nconst hueBarRef = ref<HTMLDivElement | null>(null)\nconst alphaBarRef = ref<HTMLDivElement | null>(null)\n// const modeItems = ref([\n// { key: 'solid', label: '实色' },\n// { key: 'gradient', label: '渐变' },\n// ])\n\nconst currentColor = computed<string>(() => {\n switch (props.type) {\n case 'hex':\n return alpha.value === 1 ? currentColorHex.value : currentColorFullHex.value\n case 'rgb':\n return alpha.value === 1 ? currentColorRgb.value : currentColorRgba.value\n case 'hsl':\n return alpha.value === 1 ? currentColorHsl.value : currentColorFullHsl.value\n default:\n return ''\n }\n})\nconst currentColorRgb = computed(() => {\n return `rgb(${hsl.value.h}, ${hsl.value.s}%, ${hsl.value.l}%)`\n})\nconst currentColorRgba = computed(() => {\n const rgba = hslaToRgba(hsl.value.h, hsl.value.s, hsl.value.l, alpha.value)\n return rgbaToCss(rgba.r, rgba.g, rgba.b, rgba.a)\n})\nconst currentColorHex = computed(() => {\n return hslaToHex(hsl.value.h, hsl.value.s, hsl.value.l, alpha.value)\n})\n// 当前颜色的完整 HEX(含透明度)\nconst currentColorFullHex = computed(() => {\n return hslaToHex(hsl.value.h, hsl.value.s, hsl.value.l, alpha.value)\n})\n\nconst currentColorHsl = computed(() => {\n return `hsl(${hsl.value.h}, ${hsl.value.s}%, ${hsl.value.l}%)`\n})\nconst currentColorFullHsl = computed(() => {\n return `hsla(${hsl.value.h}, ${hsl.value.s}%, ${hsl.value.l}%, ${alpha.value})`\n})\n\nconst parseColor = (color: string): { h: number; s: number; l: number; a: number } | null => {\n switch (props.type) {\n case 'hex':\n return hexToHsla(color)\n case 'rgb':\n const [r, g, b, a = 1] = color.split(',').map(Number)\n return rgbaToHsla(r, g, b, a)\n case 'hsl':\n console.log(7777, color)\n return null\n // return hslToHsla(color);\n // return color.split(',').map(Number);\n default:\n return null\n }\n}\n\n// const handleModeSelect = (item: DropdownItem) => {\n// console.log(8888, item)\n// }\n\nwatch(\n () => props.color,\n newColor => {\n if (newColor) {\n const hsla = parseColor(newColor)\n if (hsla) {\n const { h, s, l, a } = hsla\n hsl.value.h = h\n hsl.value.s = s\n hsl.value.l = l\n alpha.value = a\n }\n colorInput.value = newColor\n }\n }\n)\n\nwatch([currentColorHex, alpha], () => {\n const outputHex = alpha.value === 1 ? currentColorHex.value : currentColorFullHex.value\n if (outputHex !== props.color) {\n emit('update:color', outputHex)\n emit('colorChange', outputHex)\n colorInput.value = outputHex\n }\n})\n\n// 饱和度选择面板鼠标按下\nlet isSaturationDragging = false\nlet saturationAnimationFrame: number | null = null\nconst updateSaturationPosition = (e: MouseEvent) => {\n if (!saturationPanelRef.value) return\n const rect = saturationPanelRef.value?.getBoundingClientRect()\n const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width))\n const y = Math.max(0, Math.min(e.clientY - rect.top, rect.height))\n\n hsl.value.s = Math.round((x / rect.width) * 100)\n hsl.value.l = Math.round((1 - y / rect.height) * 100)\n}\nconst handleSaturationMouseDown = (e: MouseEvent) => {\n e.preventDefault()\n isSaturationDragging = true\n updateSaturationPosition(e)\n\n const handleMouseMover = (e: MouseEvent) => {\n if (!isSaturationDragging) return\n e.preventDefault()\n if (saturationAnimationFrame) {\n cancelAnimationFrame(saturationAnimationFrame)\n saturationAnimationFrame = null\n }\n saturationAnimationFrame = requestAnimationFrame(() => {\n updateSaturationPosition(e)\n })\n }\n\n const handleMouseUp = () => {\n if (!isSaturationDragging) return\n isSaturationDragging = false\n if (saturationAnimationFrame) {\n cancelAnimationFrame(saturationAnimationFrame)\n saturationAnimationFrame = null\n }\n colorPickerRef.value?.removeEventListener('mousemove', handleMouseMover)\n colorPickerRef.value?.removeEventListener('mouseup', handleMouseUp)\n }\n\n colorPickerRef.value?.addEventListener('mousemove', handleMouseMover)\n colorPickerRef.value?.addEventListener('mouseup', handleMouseUp)\n}\n\n// 色相选择条\nlet isHueDragging = false\nlet hueAnimationFrame: number | null = null\nconst updateHuePosition = (e: MouseEvent) => {\n if (!hueBarRef.value) return\n\n const rect = hueBarRef.value?.getBoundingClientRect()\n const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width))\n hsl.value.h = Math.round((x / rect.width) * 360)\n}\nconst handleHueMouseDown = (e: MouseEvent) => {\n e.preventDefault()\n isHueDragging = true\n updateHuePosition(e)\n\n const handleMouseMover = (e: MouseEvent) => {\n if (!isHueDragging) return\n e.preventDefault()\n if (hueAnimationFrame) {\n cancelAnimationFrame(hueAnimationFrame)\n hueAnimationFrame = null\n }\n hueAnimationFrame = requestAnimationFrame(() => {\n updateHuePosition(e)\n })\n }\n\n const handleMouseUp = () => {\n if (!isHueDragging) return\n isHueDragging = false\n if (hueAnimationFrame) {\n cancelAnimationFrame(hueAnimationFrame)\n hueAnimationFrame = null\n }\n colorPickerRef.value?.removeEventListener('mousemove', handleMouseMover)\n colorPickerRef.value?.removeEventListener('mouseup', handleMouseUp)\n }\n colorPickerRef.value?.addEventListener('mousemove', handleMouseMover)\n colorPickerRef.value?.addEventListener('mouseup', handleMouseUp)\n}\n\n// 透明度选择条\nlet isAlphaDragging = false\nlet alphaAnimationFrame: number | null = null\nconst updateAlphaPosition = (e: MouseEvent) => {\n if (!alphaBarRef.value) return\n const rect = alphaBarRef.value?.getBoundingClientRect()\n const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width))\n alpha.value = Math.round((x / rect.width) * 100) / 100\n}\nconst handleAlphaMouseDown = (e: MouseEvent) => {\n e.preventDefault()\n isAlphaDragging = true\n updateAlphaPosition(e)\n\n const handleMouseMover = (e: MouseEvent) => {\n if (!isAlphaDragging) return\n e.preventDefault()\n if (alphaAnimationFrame) {\n cancelAnimationFrame(alphaAnimationFrame)\n alphaAnimationFrame = null\n }\n alphaAnimationFrame = requestAnimationFrame(() => {\n updateAlphaPosition(e)\n })\n }\n const handleMouseUp = () => {\n if (!isAlphaDragging) return\n isAlphaDragging = false\n if (alphaAnimationFrame) {\n cancelAnimationFrame(alphaAnimationFrame)\n alphaAnimationFrame = null\n }\n colorPickerRef.value?.removeEventListener('mousemove', handleMouseMover)\n colorPickerRef.value?.removeEventListener('mouseup', handleMouseUp)\n }\n colorPickerRef.value?.addEventListener('mousemove', handleMouseMover)\n colorPickerRef.value?.addEventListener('mouseup', handleMouseUp)\n}\n\n// 输入框内容变化\nconst handleInputChange = (e: Event) => {\n const value = (e.target as HTMLInputElement).value\n const hsla = parseColor(colorInput.value)\n if (hsla) {\n const { h, s, l, a } = hsla\n hsl.value.h = h\n hsl.value.s = s\n hsl.value.l = l\n alpha.value = a\n }\n colorInput.value = value.trim().toUpperCase()\n}\n\n// 吸取颜色\nconst handleEyeDropper = async () => {\n if (!isEyeDropperSupported.value) return\n try {\n const eyeDropper = new (window as any).EyeDropper()\n const result = await eyeDropper.open()\n if (result.sRGBHex) {\n const hsla = parseColor(result.sRGBHex)\n if (hsla) {\n const { h, s, l, a } = hsla\n hsl.value.h = h\n hsl.value.s = s\n hsl.value.l = l\n alpha.value = a\n }\n }\n } catch (error: any) {\n if (error.name !== 'AbortError') {\n console.error('颜色拾取失败', error)\n }\n }\n}\n\n// 选择颜色\nconst handleColorSelect = (color: string) => {\n if (!isValidHex(color)) return\n\n const hsla = parseColor(color)\n\n if (hsla) {\n const { h, s, l, a } = hsla\n hsl.value.h = h\n hsl.value.s = s\n hsl.value.l = l\n alpha.value = a\n }\n colorInput.value = currentColor.value\n}\n\nonMounted(() => {\n isEyeDropperSupported.value = !!(window as any).EyeDropper\n\n if (props.color && isValidHex(props.color)) {\n const hsla = parseColor(props.color)\n if (hsla) {\n const { h, s, l, a } = hsla\n hsl.value.h = h\n hsl.value.s = s\n hsl.value.l = l\n alpha.value = a\n }\n colorInput.value = props.color\n }\n})\n</script>\n<style lang=\"scss\" scoped>\n.color-picker {\n box-sizing: border-box;\n width: 220px;\n padding: 12px;\n border-radius: 6px;\n &__header {\n display: flex;\n justify-content: space-end;\n gap: 8px;\n align-items: center;\n margin-bottom: 12px;\n font-size: 10px;\n }\n &__main {\n margin-bottom: 12px;\n }\n &__saturation-panel {\n position: relative;\n width: 100%;\n height: 180px;\n margin-bottom: 8px;\n overflow: hidden;\n cursor: crosshair;\n border-radius: 4px;\n &-black {\n position: relative;\n width: 100%;\n height: 100%;\n }\n &-pointer {\n position: absolute;\n width: 12px;\n height: 12px;\n pointer-events: none;\n border: 2px solid #fff;\n border-radius: 50%;\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);\n transform: translate(-50%, -50%);\n }\n }\n &__hue-bar {\n position: relative;\n width: 100%;\n height: 10px;\n margin-bottom: 8px;\n cursor: pointer;\n background: linear-gradient(\n to right,\n #ff0000 0%,\n #ffff00 17%,\n #00ff00 33%,\n #00ffff 50%,\n #0000ff 67%,\n #ff00ff 83%,\n #ff0000 100%\n );\n border-radius: 6px;\n &-pointer {\n position: absolute;\n top: 50%;\n width: 12px;\n height: 12px;\n pointer-events: none;\n background: #fff;\n border: 2px solid rgba(0, 0, 0, 0.3);\n border-radius: 50%;\n box-shadow:\n 0 0 0 1px rgb(255 255 255 / 80%),\n 0 0 0 2px rgb(255 255 255 / 40%),\n 0 0 4px rgb(255 255 255 / 30%),\n 0 1px 2px rgb(0 0 0 / 20%);\n transform: translate(-50%, -50%);\n }\n }\n &__alpha-bar {\n position: relative;\n width: 100%;\n height: 10px;\n cursor: pointer;\n background-image:\n linear-gradient(45deg, #cccccc 25%, transparent 25%),\n linear-gradient(-45deg, #cccccc 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, #cccccc 75%),\n linear-gradient(-45deg, transparent 75%, #cccccc 75%);\n background-position:\n 0 0,\n 0 4px,\n 4px -4px,\n -4px 0;\n background-size: 8px 8px;\n border-radius: 6px;\n &-bg {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border-radius: 5px;\n }\n &-pointer {\n position: absolute;\n top: 50%;\n width: 12px;\n height: 12px;\n pointer-events: none;\n background: #fff;\n border: 2px solid rgb(0 0 0 / 30%);\n border-radius: 50%;\n box-shadow:\n 0 0 0 1px rgb(255 255 255 / 80%),\n 0 0 0 2px rgb(255 255 255 / 40%),\n 0 0 4px rgb(255 255 255 / 30%),\n 0 1px 2px rgb(0 0 0 / 20%);\n transform: translate(-50%, -50%);\n }\n }\n\n &__controls {\n display: flex;\n gap: 8px;\n align-items: center;\n &__preview {\n position: relative;\n width: 24px;\n height: 24px;\n display: block;\n overflow: hidden;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 4px;\n &-bg {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-image:\n linear-gradient(45deg, #cccccc 25%, transparent 25%),\n linear-gradient(-45deg, #cccccc 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, #cccccc 75%),\n linear-gradient(-45deg, transparent 75%, #cccccc 75%);\n background-position:\n 0 0,\n 0 4px,\n 4px -4px,\n -4px 0;\n background-size: 8px 8px;\n }\n &-color {\n position: relative;\n z-index: 1;\n width: 100%;\n height: 100%;\n }\n }\n &__input-group {\n flex: 1;\n height: 24px;\n padding: 0 8px;\n background: #fff;\n border: 1px solid rgba(0, 0, 0, 0.3);\n border-radius: 4px;\n outline: none;\n &__input {\n width: 100%;\n height: 100%;\n font-size: 12px;\n line-height: 24px;\n color: #000;\n background: transparent;\n border: none;\n outline: none;\n\n &:focus {\n border-color: rgb(255 255 255 / 30%);\n }\n &::placeholder {\n color: rgb(255 255 255 / 30%);\n }\n }\n }\n &__eyedropper {\n width: 24px;\n height: 24px;\n display: block;\n overflow: hidden;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 4px;\n &-btn {\n width: 100%;\n height: 100%;\n display: flex;\n padding: 4px;\n cursor: pointer;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n border: none;\n outline: none;\n }\n }\n }\n &__color-list {\n display: grid;\n grid-template-columns: repeat(10, 1fr);\n gap: 4px;\n margin-top: 8px;\n &__item {\n width: 100%;\n aspect-ratio: 1;\n cursor: pointer;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 3px;\n transition: all 0.2s;\n &:hover {\n z-index: 1;\n border-color: rgba(0, 0, 0, 0.3);\n transform: scale(1.1);\n }\n }\n }\n\n &--dark {\n background-color: #1a1a1a;\n border: 1px solid #333;\n }\n &--light {\n background-color: #fff;\n border: 1px solid #ddd;\n }\n\n &--dark &__header {\n color: #fff;\n }\n &--dark &__controls {\n &__preview {\n border-color: rgba(255, 255, 255, 0.3);\n }\n }\n &--dark &__color-list {\n &__item {\n border-color: rgba(255, 255, 255, 0.3);\n }\n }\n}\n</style>\n","<template>\n <div ref=\"dropdownRef\" class=\"echo-dropdown\" :class=\"[dropdownClass]\">\n <!-- 触发器插槽 -->\n <div\n ref=\"triggerRef\"\n class=\"echo-dropdown__trigger\"\n :class=\"{ 'is-disabled': disabled }\"\n @click=\"handleTriggerClick\"\n @mouseenter=\"handleTriggerMouseEnter\"\n @mouseleave=\"handleTriggerMouseLeave\"\n >\n <slot name=\"default\">\n <span>下拉菜单</span>\n <template v-if=\"icon\">\n <component :is=\"icon\" class=\"echo-dropdown__trigger__icon\" />\n </template>\n <svg-icon v-else name=\"arrow-down\" class=\"echo-dropdown__trigger__icon\" />\n </slot>\n </div>\n <!-- 下拉菜单面板 -->\n <Transition name=\"echo-dropdown-fade\">\n <div\n v-if=\"visible\"\n ref=\"menuRef\"\n class=\"echo-dropdown__menu\"\n :class=\"[menuClasses]\"\n :style=\"menuStyle\"\n @mouseenter=\"handleMenuMouseEnter\"\n @mouseleave=\"handleMenuMouseLeave\"\n >\n <ul class=\"echo-dropdown__menu__list\">\n <template v-if=\"items && items.length > 0\">\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.key\"\n class=\"echo-dropdown__menu__list__item\"\n :class=\"[\n {\n 'is-disabled': item.disabled,\n 'is-divider': item.divider,\n 'is-checked': item.checked,\n },\n ]\"\n @click=\"handleItemClick(item, index)\"\n >\n <template v-if=\"item.icon\">\n <component :is=\"item.icon\" class=\"echo-dropdown__menu__list__item__icon\" />\n </template>\n <span class=\"echo-dropdown__menu__list__item__label\">{{ item.label }}</span>\n </li>\n </template>\n <slot v-else name=\"menu\"></slot>\n </ul>\n </div>\n </Transition>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport { computed, onUnmounted, ref, watch } from 'vue'\nimport { DropdownEmits, DropdownItem, DropdownProps } from './types.ts'\n\nconst props = withDefaults(defineProps<DropdownProps>(), {\n trigger: 'click',\n placement: 'bottom-start',\n disabled: false,\n items: () => [],\n hideOnClick: true,\n})\n\nconst emit = defineEmits<DropdownEmits>()\n\nconst visible = ref(false)\nconst dropdownRef = ref<HTMLElement | null>(null)\nconst triggerRef = ref<HTMLElement | null>(null)\nconst menuRef = ref<HTMLElement | null>(null)\n\nconst dropdownClass = computed(() => ({\n 'is-disabled': props.disabled,\n 'is-visible': visible.value,\n}))\n\nconst menuClasses = computed(() => {\n const placement = props.placement || 'bottom-start'\n return [`echo-dropdown__menu--${placement}`]\n})\n\nconst menuStyle = computed(() => {\n const styles: Record<string, string> = {}\n return styles\n})\n\n// const getPopupContainer = () => {\n// return props.getPopupContainer ? props.getPopupContainer() : dropdownRef.value\n// }\n\nconst handleTriggerClick = () => {\n if (props.disabled) return\n if (props.trigger === 'click') {\n visible.value = !visible.value\n }\n}\n\nconst handleTriggerMouseEnter = () => {\n if (props.disabled) return\n if (props.trigger === 'hover') {\n visible.value = true\n }\n}\n\nconst handleTriggerMouseLeave = () => {\n if (props.trigger === 'hover') {\n // 延迟关闭,避免快速移动时闪烁\n setTimeout(() => {\n if (!isMouseInMenu.value) {\n visible.value = false\n }\n }, 100)\n }\n}\n\n// 处理菜单鼠标进入\nconst isMouseInMenu = ref(false)\nconst handleMenuMouseEnter = () => {\n isMouseInMenu.value = true\n}\nconst handleMenuMouseLeave = () => {\n isMouseInMenu.value = false\n if (props.trigger === 'hover') {\n hideMenu()\n }\n}\n\n// 显示菜单\n// const showMenu = async () => {\n// if (props.disabled || visible.value) return\n// visible.value = true\n// emit('openChange', true)\n// await nextTick()\n// emit('openChange', true)\n// }\n\n// 隐藏菜单\nconst hideMenu = () => {\n if (!visible.value) return\n visible.value = false\n emit('openChange', false)\n}\n\n// 切换菜单显示状态\n// const toggleMenu = async () => {\n// if (props.disabled) return\n// if (visible.value) {\n// hideMenu()\n// } else {\n// showMenu()\n// }\n// }\n\n// 处理菜单项点击\nconst handleItemClick = (item: DropdownItem, index: number) => {\n if (item.disabled) return\n emit('select', item, index)\n if (props.hideOnClick) {\n hideMenu()\n }\n}\n\n// 更新菜单位置\nconst updateMenuPosition = () => {\n if (!triggerRef.value || !menuRef.value) return\n\n const triggerRect = triggerRef.value?.getBoundingClientRect()\n const menuRect = menuRef.value.getBoundingClientRect()\n const placement = props.placement || 'bottom-start'\n\n let top = 0\n let left = 0\n\n // 根据placement计算位置\n if (placement.includes('bottom')) {\n top = triggerRect.bottom + window.scrollY\n } else if (placement.includes('top')) {\n top = triggerRect.top - menuRect.height + window.scrollY\n } else {\n top = triggerRect.top\n }\n\n if (placement.includes('start') || placement.includes('left')) {\n left = triggerRect.left + window.scrollX\n } else if (placement.includes('end') || placement.includes('right')) {\n left = triggerRect.right - menuRect.width + window.scrollX\n } else {\n left = triggerRect.left + (triggerRect.width - menuRect.width) / 2\n }\n\n // 边界检测,防止菜单超出视口\n const viewportWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n if (left < 0) left = 8\n // 左边超出视口\n if (left + menuRect.width > viewportWidth) {\n left = viewportWidth - menuRect.width - 8\n }\n if (top < 0) top = 8\n // 上边超出视口\n if (top + menuRect.height > viewportHeight) {\n top = viewportHeight - menuRect.height - 8\n }\n\n // 更新菜单位置\n menuRef.value.style.left = `${left}px`\n menuRef.value.style.top = `${top}px`\n}\n\n// 点击外部关闭菜单\nconst handleClickOutside = (event: MouseEvent) => {\n if (\n dropdownRef.value &&\n !dropdownRef.value.contains(event.target as Node) &&\n visible.value &&\n props.trigger === 'click'\n ) {\n hideMenu()\n }\n}\n\n// 监听窗口大小变化\nconst handleResize = () => {\n if (visible.value) {\n updateMenuPosition()\n }\n}\n\n// 监听visible变化,更新位置\nwatch(visible, newVal => {\n if (newVal) {\n document.addEventListener('click', handleClickOutside)\n window.addEventListener('resize', handleResize)\n window.addEventListener('scroll', updateMenuPosition, true)\n } else {\n document.removeEventListener('click', handleClickOutside)\n window.removeEventListener('resize', handleResize)\n window.removeEventListener('scroll', updateMenuPosition, true)\n }\n})\n\nonUnmounted(() => {\n document.removeEventListener('click', handleClickOutside)\n window.removeEventListener('resize', handleResize)\n window.removeEventListener('scroll', updateMenuPosition, true)\n})\n</script>\n<style lang=\"scss\" scoped>\n.echo-dropdown {\n position: relative;\n display: inline-block;\n &.is-disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n &.is-visible {\n z-index: 1000;\n }\n &__trigger {\n cursor: pointer;\n user-select: none; // 禁止用户选择文本\n &.is-disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n }\n &__menu {\n position: fixed;\n z-index: 1000;\n background: #fff;\n border-radius: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n padding: 4px 0;\n margin: 0;\n min-width: 120px;\n max-height: 300px;\n overflow-y: auto;\n\n &__list {\n list-style: none;\n margin: 0;\n padding: 0;\n\n &__item {\n display: flex;\n gap: 8px;\n align-items: center;\n padding: 8px 12px;\n cursor: pointer;\n transition: all 0.2s;\n color: #333;\n font-size: 14px;\n line-height: 1.5;\n\n &:hover:not(.is-disabled) {\n background-color: #f5f7fa;\n }\n &.is-disabled {\n cursor: not-allowed;\n color: #c0c4cc;\n }\n &.is-divider {\n border-top: 1px solid #e4e7ed;\n margin-top: 4px;\n padding-top: 4px;\n }\n\n &__icon {\n flex-shrink: 0; // 不压缩图标\n }\n &__label {\n flex: 1; // 填充剩余空间\n white-space: nowrap; // 不换行\n overflow: hidden; // 超出隐藏\n text-overflow: ellipsis; // 超出显示省略号\n }\n }\n }\n }\n}\n\n.echo-dropdown-fade-enter-active,\n.echo-dropdown-fade-leave-active {\n transition:\n opacity 0.2s,\n transform 0.2s;\n}\n.echo-dropdown-fade-enter-from,\n.echo-dropdown-fade-leave-to {\n opacity: 0;\n transform: translateY(-10px) scale(0.95);\n}\n</style>\n","<template>\n <div :class=\"wrapperClasses\">\n <div class=\"echo-input__wrapper\">\n <EchoIcon v-if=\"prefixIcon\" :name=\"prefixIcon\" class=\"echo-input__prefix-icon\" />\n <input\n ref=\"inputRef\"\n :class=\"inputClasses\"\n :type=\"type\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n :maxlength=\"maxlength\"\n @input=\"handleInput\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n @keydown=\"handleKeydown\"\n />\n <EchoIcon v-if=\"suffixIcon\" :name=\"suffixIcon\" class=\"echo-input__suffix-icon\" />\n <button\n v-if=\"clearable && modelValue\"\n type=\"button\"\n class=\"echo-input__clear\"\n @click=\"handleClear\"\n >\n <EchoIcon name=\"close\" />\n </button>\n </div>\n <div v-if=\"showWordLimit && maxlength\" class=\"echo-input__word-limit\">\n {{ currentLength }}/{{ maxlength }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport EchoIcon from '../Icon'\nimport type { InputProps } from './types'\n\n// 定义组件属性\nconst props = withDefaults(defineProps<InputProps>(), {\n modelValue: '',\n type: 'text',\n placeholder: '',\n disabled: false,\n readonly: false,\n clearable: false,\n size: 'medium',\n prefixIcon: '',\n suffixIcon: '',\n maxlength: undefined,\n showWordLimit: false,\n})\n\n// 定义事件\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number]\n focus: [event: FocusEvent]\n blur: [event: FocusEvent]\n clear: []\n}>()\n\n// 输入框引用\nconst inputRef = ref<HTMLInputElement>()\n\n// 计算当前长度\nconst currentLength = computed(() => {\n return String(props.modelValue).length\n})\n\n// 计算包装器样式类\nconst wrapperClasses = computed(() => [\n 'echo-input',\n `echo-input--${props.size}`,\n {\n 'echo-input--disabled': props.disabled,\n 'echo-input--with-prefix': props.prefixIcon,\n 'echo-input--with-suffix': props.suffixIcon || props.clearable,\n },\n])\n\n// 计算输入框样式类\nconst inputClasses = computed(() => [\n 'echo-input__inner',\n {\n 'echo-input__inner--disabled': props.disabled,\n },\n])\n\n// 处理输入事件\nconst handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement\n const value = target.value\n emit('update:modelValue', value)\n}\n\n// 处理焦点事件\nconst handleFocus = (event: FocusEvent) => {\n emit('focus', event)\n}\n\n// 处理失焦事件\nconst handleBlur = (event: FocusEvent) => {\n emit('blur', event)\n}\n\n// 处理键盘事件\nconst handleKeydown = (_event: KeyboardEvent) => {\n // 可以在这里添加键盘快捷键处理\n}\n\n// 处理清除事件\nconst handleClear = () => {\n emit('update:modelValue', '')\n emit('clear')\n inputRef.value?.focus()\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.echo-input {\n display: inline-block;\n width: 100%;\n position: relative;\n\n // 尺寸变体\n &--small {\n .echo-input__wrapper {\n height: 28px;\n }\n\n .echo-input__inner {\n font-size: 12px;\n padding: 4px 8px;\n }\n }\n\n &--medium {\n .echo-input__wrapper {\n height: 32px;\n }\n\n .echo-input__inner {\n font-size: 14px;\n padding: 6px 12px;\n }\n }\n\n &--large {\n .echo-input__wrapper {\n height: 40px;\n }\n\n .echo-input__inner {\n font-size: 16px;\n padding: 8px 16px;\n }\n }\n\n // 状态变体\n &--disabled {\n .echo-input__wrapper {\n background-color: var(--echo-disabled-bg, #f5f5f5);\n cursor: not-allowed;\n }\n\n .echo-input__inner {\n cursor: not-allowed;\n color: var(--echo-disabled-color, #c0c4cc);\n }\n }\n\n &--with-prefix {\n .echo-input__inner {\n padding-left: 32px;\n }\n }\n\n &--with-suffix {\n .echo-input__inner {\n padding-right: 32px;\n }\n }\n\n &__wrapper {\n position: relative;\n display: flex;\n align-items: center;\n background-color: white;\n border: 1px solid var(--echo-border-color, #d9d9d9);\n border-radius: var(--echo-border-radius, 6px);\n transition: all 0.2s ease-in-out;\n\n &:hover {\n border-color: var(--echo-primary-color, #1890ff);\n }\n\n &:focus-within {\n border-color: var(--echo-primary-color, #1890ff);\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n }\n }\n\n &__inner {\n flex: 1;\n border: none;\n outline: none;\n background: transparent;\n color: var(--echo-text-color, #333);\n line-height: 1.5;\n\n &::placeholder {\n color: var(--echo-placeholder-color, #c0c4cc);\n }\n\n &--disabled {\n background-color: transparent;\n color: var(--echo-disabled-color, #c0c4cc);\n }\n }\n\n &__prefix-icon,\n &__suffix-icon {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n color: var(--echo-icon-color, #c0c4cc);\n font-size: 16px;\n pointer-events: none;\n }\n\n &__prefix-icon {\n left: 8px;\n }\n\n &__suffix-icon {\n right: 8px;\n }\n\n &__clear {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n background: none;\n border: none;\n cursor: pointer;\n color: var(--echo-icon-color, #c0c4cc);\n font-size: 14px;\n padding: 2px;\n border-radius: 50%;\n transition: all 0.2s ease-in-out;\n\n &:hover {\n background-color: var(--echo-hover-bg, #f5f5f5);\n color: var(--echo-text-color, #333);\n }\n }\n\n &__word-limit {\n margin-top: 4px;\n font-size: 12px;\n color: var(--echo-text-secondary, #666);\n text-align: right;\n }\n}\n</style>\n","/**\n * 组件库入口文件\n * 导出所有组件\n * 导出组件类型\n * 默认安装函数\n */\n\nimport type { App } from 'vue'\nimport { Button } from './components/Button'\nimport { ColorPicker } from './components/ColorPicker'\nimport { Dropdown } from './components/Dropdown'\nimport { Icon } from './components/Icon'\nimport { Input } from './components/Input'\n\n// 导出所有组件\nexport { Button, ColorPicker, Dropdown, Icon, Input }\n\nexport const EchoButton = Button\nexport const EchoInput = Input\nexport const EchoColorPicker = ColorPicker\nexport const EchoDropdown = Dropdown\nexport const EchoIcon = Icon\n\n// 导出组件类型\nexport type { ButtonProps, ButtonSize, ButtonType } from './components/Button'\nexport type { ColorPickerProps } from './components/ColorPicker'\nexport type { DropdownItem, DropdownProps } from './components/Dropdown'\nexport type { IconProps } from './components/Icon'\nexport type { InputProps, InputType } from './components/Input'\n\n// 默认安装函数\nexport const EchoLibrary = {\n install(app: App) {\n app.component('EchoColorPicker', ColorPicker)\n app.component('EchoDropdown', Dropdown)\n app.component('EchoIcon', Icon)\n app.component('EchoInput', Input)\n app.component('EchoButton', Button)\n },\n}\n"],"names":["props","__props","emit","__emit","iconClasses","computed","iconStyles","handleClick","event","_createElementBlock","_renderSlot","_ctx","buttonClasses","_createBlock","_unref","EchoIcon","_normalizeClass","$slots","_openBlock","_hoisted_2","DEFAULT_COLORS","rgbToHsl","r","g","b","max","min","h","l","d","hslToRgb","s","hue2rgb","p","q","t","isValidHex","hex","cleanHex","hexToRgba","alpha","a","rgbaToHex","toHex","n","alphaHex","hslaToRgba","rgbaToHsla","hslaToHex","rgba","hexToHsla","rgbaToCss","hsl","ref","colorInput","isEyeDropperSupported","colorPickerRef","saturationPanelRef","hueBarRef","alphaBarRef","currentColor","currentColorHex","currentColorFullHex","currentColorRgb","currentColorRgba","currentColorHsl","currentColorFullHsl","parseColor","color","watch","newColor","hsla","outputHex","isSaturationDragging","saturationAnimationFrame","updateSaturationPosition","e","rect","_a","x","y","handleSaturationMouseDown","handleMouseMover","handleMouseUp","_b","isHueDragging","hueAnimationFrame","updateHuePosition","handleHueMouseDown","isAlphaDragging","alphaAnimationFrame","updateAlphaPosition","handleAlphaMouseDown","handleInputChange","value","handleEyeDropper","result","error","handleColorSelect","onMounted","_createElementVNode","_hoisted_1","_normalizeStyle","_hoisted_3","_hoisted_4","$event","_hoisted_6","_hoisted_8","_Fragment","_renderList","index","visible","dropdownRef","triggerRef","menuRef","dropdownClass","menuClasses","menuStyle","handleTriggerClick","handleTriggerMouseEnter","handleTriggerMouseLeave","isMouseInMenu","handleMenuMouseEnter","handleMenuMouseLeave","hideMenu","handleItemClick","item","updateMenuPosition","triggerRect","menuRect","placement","top","left","viewportWidth","viewportHeight","handleClickOutside","handleResize","newVal","onUnmounted","_cache","_resolveDynamicComponent","_component_svg_icon","_createVNode","_Transition","_toDisplayString","inputRef","currentLength","wrapperClasses","inputClasses","handleInput","handleFocus","handleBlur","handleKeydown","_event","handleClear","EchoButton","Button","EchoInput","Input","EchoColorPicker","ColorPicker","EchoDropdown","Dropdown","Icon","EchoLibrary","app"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(k,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(k=typeof globalThis<"u"?globalThis:k||self,e(k.EchoLibrary={},k.Vue))})(this,function(k,e){"use strict";const K=e.defineComponent({__name:"index",props:{name:{},size:{default:16},color:{default:"currentColor"},spin:{type:Boolean,default:!1}},emits:["click"],setup(o,{emit:a}){const n=o,s=a,t=e.computed(()=>["echo-icon",`echo-icon--${n.name}`,{"echo-icon--spin":n.spin}]),d=e.computed(()=>({fontSize:typeof n.size=="number"?`${n.size}px`:n.size,color:n.color})),c=m=>{s("click",m)};return(m,h)=>(e.openBlock(),e.createElementBlock("i",{class:e.normalizeClass(t.value),style:e.normalizeStyle(d.value),onClick:c},[e.renderSlot(m.$slots,"default",{},void 0,!0)],6))}}),I=(o,a)=>{const n=o.__vccOpts||o;for(const[s,t]of a)n[s]=t;return n},L=I(K,[["__scopeId","data-v-cf0db90e"]]),J=["disabled"],Q={key:2,class:"echo-button__text"},T=I(e.defineComponent({__name:"index",props:{type:{default:"primary"},size:{default:"medium"},disabled:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},round:{type:Boolean,default:!1},plain:{type:Boolean,default:!1},icon:{default:""}},emits:["click"],setup(o,{emit:a}){const n=o,s=a,t=e.computed(()=>["echo-button",`echo-button--${n.type}`,`echo-button--${n.size}`,{"echo-button--disabled":n.disabled,"echo-button--loading":n.loading,"echo-button--round":n.round,"echo-button--plain":n.plain}]),d=c=>{n.disabled||n.loading||s("click",c)};return(c,m)=>(e.openBlock(),e.createElementBlock("button",{class:e.normalizeClass(t.value),disabled:o.disabled||o.loading,onClick:d},[o.loading?(e.openBlock(),e.createBlock(e.unref(L),{key:0,name:"loading",class:e.normalizeClass(["echo-button__loading",{"echo-button__loading--spinning":o.loading}])},null,8,["class"])):o.icon?(e.openBlock(),e.createBlock(e.unref(L),{key:1,name:o.icon,class:"echo-button__icon"},null,8,["name"])):e.createCommentVNode("",!0),c.$slots.default?(e.openBlock(),e.createElementBlock("span",Q,[e.renderSlot(c.$slots,"default",{},void 0,!0)])):e.createCommentVNode("",!0)],10,J))}}),[["__scopeId","data-v-131d4d78"]]),Z=["#FFFFFF","#000000","#FF0000","#00FF00","#0000FF","#FF1900","#F47365","#F89C5A","#FAC858","#73B06F","#6ECBE6","#926383","#C89616","#8E00A7","#BF3DCE","#FC3CAD","#FF89CF","#5D61FF","#00BEFF","#1BC7B1"],ee=(o,a,n)=>{o/=255,a/=255,n/=255;const s=Math.max(o,a,n),t=Math.min(o,a,n);let d=0,c=0;const m=(s+t)/2;if(s!==t){const h=s-t;switch(c=m>.5?h/(2-s-t):h/(s+t),s){case o:d=((a-n)/h+(a<n?6:0))/6;break;case a:d=((n-o)/h+2)/6;break;case n:d=((o-a)/h+4)/6;break}}return{h:Math.round(d*360),s:Math.round(c*100),l:Math.round(m*100)}};function te(o,a,n){o/=360,a/=100,n/=100;let s,t,d;if(a===0)s=t=d=n;else{const c=(C,$,y)=>(y<0&&(y+=1),y>1&&(y-=1),y<.16666666666666666?C+($-C)*6*y:y<.5?$:y<.6666666666666666?C+($-C)*(.6666666666666666-y)*6:C),m=n<.5?n*(1+a):n+a-n*a,h=2*n-m;s=c(h,m,o+1/3),t=c(h,m,o),d=c(h,m,o-1/3)}return{r:Math.round(s*255),g:Math.round(t*255),b:Math.round(d*255)}}function W(o){const a=o.replace("#","");return/^[0-9A-Fa-f]{6}$/.test(a)||/^[0-9A-Fa-f]{8}$/.test(a)}function ne(o,a){const n=o.replace("#","");if(!/^[0-9A-Fa-f]{6}$/.test(n)&&!/^[0-9A-Fa-f]{8}$/.test(n))return null;const s=parseInt(n.substring(0,2),16),t=parseInt(n.substring(2,4),16),d=parseInt(n.substring(4,6),16);let c=1;return n.length===8&&(c=parseInt(n.substring(6,8),16)/255),{r:s,g:t,b:d,a:c}}function oe(o,a,n,s=1){const t=c=>{const m=Math.round(Math.max(0,Math.min(255,c))).toString(16);return m.length===1?"0"+m:m},d=t(s*255);return`#${t(o)}${t(a)}${t(n)}${d}`.toUpperCase()}function q(o,a,n,s=1){return{...te(o,a,n),a:s}}function Y(o,a,n,s=1){return{...ee(o,a,n),a:s}}function j(o,a,n,s=1){const t=q(o,a,n,s);return oe(t.r,t.g,t.b,t.a)}function le(o){const a=ne(o);return a?Y(a.r,a.g,a.b,a.a):null}function ae(o,a,n,s=1){return`rgba(${o}, ${a}, ${n}, ${s})`}const re={class:"color-picker__main"},ce={class:"color-picker__saturation-panel-black",style:{background:"linear-gradient(to bottom, transparent, #000)"}},se={class:"color-picker__controls"},ie={class:"color-picker__controls__input-group"},de=["placeholder"],ue={class:"color-picker__controls__eyedropper"},me=["disabled"],he={class:"color-picker__color-list"},fe=["title","onClick"],P=I(e.defineComponent({__name:"index",props:{color:{},theme:{default:"light"},type:{default:"hex"},mode:{default:"solid"},showAlpha:{type:Boolean,default:!0},showEyeDropper:{type:Boolean,default:!0},showPickerMode:{type:Boolean,default:!0},showColorList:{type:Boolean,default:!0},defaultColors:{default:()=>Z}},emits:["update:color","colorChange"],setup(o,{emit:a}){const n=o,s=a,t=e.ref({h:0,s:0,l:0}),d=e.ref(""),c=e.ref(1),m=e.ref(!0),h=e.ref(null),C=e.ref(null),$=e.ref(null),y=e.ref(null),R=e.computed(()=>{switch(n.type){case"hex":return c.value===1?V.value:H.value;case"rgb":return c.value===1?b.value:N.value;case"hsl":return c.value===1?S.value:X.value;default:return""}}),b=e.computed(()=>`rgb(${t.value.h}, ${t.value.s}%, ${t.value.l}%)`),N=e.computed(()=>{const l=q(t.value.h,t.value.s,t.value.l,c.value);return ae(l.r,l.g,l.b,l.a)}),V=e.computed(()=>j(t.value.h,t.value.s,t.value.l,c.value)),H=e.computed(()=>j(t.value.h,t.value.s,t.value.l,c.value)),S=e.computed(()=>`hsl(${t.value.h}, ${t.value.s}%, ${t.value.l}%)`),X=e.computed(()=>`hsla(${t.value.h}, ${t.value.s}%, ${t.value.l}%, ${c.value})`),F=l=>{switch(n.type){case"hex":return le(l);case"rgb":const[r,i,u,g=1]=l.split(",").map(Number);return Y(r,i,u,g);case"hsl":return console.log(7777,l),null;default:return null}};e.watch(()=>n.color,l=>{if(l){const r=F(l);if(r){const{h:i,s:u,l:g,a:p}=r;t.value.h=i,t.value.s=u,t.value.l=g,c.value=p}d.value=l}}),e.watch([V,c],()=>{const l=c.value===1?V.value:H.value;l!==n.color&&(s("update:color",l),s("colorChange",l),d.value=l)});let z=!1,M=null;const _=l=>{var g;if(!C.value)return;const r=(g=C.value)==null?void 0:g.getBoundingClientRect(),i=Math.max(0,Math.min(l.clientX-r.left,r.width)),u=Math.max(0,Math.min(l.clientY-r.top,r.height));t.value.s=Math.round(i/r.width*100),t.value.l=Math.round((1-u/r.height)*100)},w=l=>{var u,g;l.preventDefault(),z=!0,_(l);const r=p=>{z&&(p.preventDefault(),M&&(cancelAnimationFrame(M),M=null),M=requestAnimationFrame(()=>{_(p)}))},i=()=>{var p,B;z&&(z=!1,M&&(cancelAnimationFrame(M),M=null),(p=h.value)==null||p.removeEventListener("mousemove",r),(B=h.value)==null||B.removeEventListener("mouseup",i))};(u=h.value)==null||u.addEventListener("mousemove",r),(g=h.value)==null||g.addEventListener("mouseup",i)};let E=!1,f=null;const v=l=>{var u;if(!$.value)return;const r=(u=$.value)==null?void 0:u.getBoundingClientRect(),i=Math.max(0,Math.min(l.clientX-r.left,r.width));t.value.h=Math.round(i/r.width*360)},A=l=>{var u,g;l.preventDefault(),E=!0,v(l);const r=p=>{E&&(p.preventDefault(),f&&(cancelAnimationFrame(f),f=null),f=requestAnimationFrame(()=>{v(p)}))},i=()=>{var p,B;E&&(E=!1,f&&(cancelAnimationFrame(f),f=null),(p=h.value)==null||p.removeEventListener("mousemove",r),(B=h.value)==null||B.removeEventListener("mouseup",i))};(u=h.value)==null||u.addEventListener("mousemove",r),(g=h.value)==null||g.addEventListener("mouseup",i)};let D=!1,x=null;const G=l=>{var u;if(!y.value)return;const r=(u=y.value)==null?void 0:u.getBoundingClientRect(),i=Math.max(0,Math.min(l.clientX-r.left,r.width));c.value=Math.round(i/r.width*100)/100},Me=l=>{var u,g;l.preventDefault(),D=!0,G(l);const r=p=>{D&&(p.preventDefault(),x&&(cancelAnimationFrame(x),x=null),x=requestAnimationFrame(()=>{G(p)}))},i=()=>{var p,B;D&&(D=!1,x&&(cancelAnimationFrame(x),x=null),(p=h.value)==null||p.removeEventListener("mousemove",r),(B=h.value)==null||B.removeEventListener("mouseup",i))};(u=h.value)==null||u.addEventListener("mousemove",r),(g=h.value)==null||g.addEventListener("mouseup",i)},Fe=l=>{const r=l.target.value,i=F(d.value);if(i){const{h:u,s:g,l:p,a:B}=i;t.value.h=u,t.value.s=g,t.value.l=p,c.value=B}d.value=r.trim().toUpperCase()},xe=async()=>{if(m.value)try{const r=await new window.EyeDropper().open();if(r.sRGBHex){const i=F(r.sRGBHex);if(i){const{h:u,s:g,l:p,a:B}=i;t.value.h=u,t.value.s=g,t.value.l=p,c.value=B}}}catch(l){l.name!=="AbortError"&&console.error("颜色拾取失败",l)}},Ve=l=>{if(!W(l))return;const r=F(l);if(r){const{h:i,s:u,l:g,a:p}=r;t.value.h=i,t.value.s=u,t.value.l=g,c.value=p}d.value=R.value};return e.onMounted(()=>{if(m.value=!!window.EyeDropper,n.color&&W(n.color)){const l=F(n.color);if(l){const{h:r,s:i,l:u,a:g}=l;t.value.h=r,t.value.s=i,t.value.l=u,c.value=g}d.value=n.color}}),(l,r)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"colorPickerRef",ref:h,class:e.normalizeClass(["color-picker",[`color-picker--${o.theme}`]])},[e.createElementVNode("div",re,[e.createElementVNode("div",{ref_key:"saturationPanelRef",ref:C,class:"color-picker__saturation-panel",style:e.normalizeStyle({background:`linear-gradient(to right, #fff, hsl(${t.value.h}, 100%, 50%))`}),onMousedown:w},[e.createElementVNode("div",ce,[e.createElementVNode("div",{class:"color-picker__saturation-panel-pointer",style:e.normalizeStyle({left:`${t.value.s}%`,top:`${100-t.value.l}%`,background:V.value})},null,4)])],36),e.createElementVNode("div",{ref_key:"hueBarRef",ref:$,class:"color-picker__hue-bar",onMousedown:A},[e.createElementVNode("div",{class:"color-picker__hue-bar-pointer",style:e.normalizeStyle({left:`${t.value.h/360*100}%`})},null,4)],544),e.createElementVNode("div",{ref_key:"alphaBarRef",ref:y,class:"color-picker__alpha-bar",onMousedown:Me},[e.createElementVNode("div",{class:"color-picker__alpha-bar-bg",style:e.normalizeStyle({background:`linear-gradient(to right, transparent, ${V.value})`})},null,4),e.createElementVNode("div",{class:"color-picker__alpha-bar-pointer",style:e.normalizeStyle({left:`${c.value*100}%`})},null,4)],544)]),e.createElementVNode("div",se,[e.createElementVNode("div",{class:"color-picker__controls__preview",style:e.normalizeStyle({background:N.value})},null,4),e.createElementVNode("div",ie,[e.withDirectives(e.createElementVNode("input",{type:"text",name:"color-input","onUpdate:modelValue":r[0]||(r[0]=i=>d.value=i),class:"color-picker__controls__input-group__input",placeholder:c.value<1?"#000000FF":"#000000",onInput:Fe},null,40,de),[[e.vModelText,d.value]])]),e.createElementVNode("div",ue,[e.createElementVNode("button",{class:"color-picker__controls__eyedropper-btn",onClick:xe,disabled:!m.value,title:"吸取颜色"},[...r[1]||(r[1]=[e.createElementVNode("svg",{t:"1768013548643",class:"icon",viewBox:"0 0 1109 1024",version:"1.1",xmlns:"http://www.w3.org/2000/svg","p-id":"1740",width:"40",height:"40"},[e.createElementVNode("path",{d:"M968.525486 0c22.934274 0 45.015973 9.122555 61.214903 25.15097l53.200696 52.518635a85.257525 85.257525 0 0 1 0 121.321459l-123.367639 121.918261 20.206033 19.950261 4.689164 5.200709a54.564816 54.564816 0 0 1-4.689164 72.724669l-39.218461 38.706916a56.269967 56.269967 0 0 1-78.777953 0.085258l-1.278863-1.278863-486.990984 479.147291a125.072789 125.072789 0 0 1-71.786836 35.381873l-10.230903 0.937833-20.035519 19.609231a109.300147 109.300147 0 0 1-176.056789-30.692709c-17.90408-38.024856-11.850796-83.04083 15.346354-115.012402l6.394315-6.820602 19.95026-19.609231c1.449378-27.197151 11.936054-52.944923 29.669619-73.577244l6.991117-7.502662L660.74582 258.756589l-5.456481-5.371224-9.719358-9.548843-4.689164-5.200709a54.650074 54.650074 0 0 1 4.689164-72.809927l39.047946-38.621658a56.269967 56.269967 0 0 1 78.863211 0l20.206033 19.95026L907.140068 25.236227c16.369445-16.19893 38.365886-25.236227 61.385418-25.236227z",fill:"#64666F","p-id":"1741"}),e.createElementVNode("path",{d:"M699.111707 292.433311L227.637592 763.05485a68.802823 68.802823 0 0 0-19.097685 37.342796l-0.682061 6.991117-1.193605 20.717579-33.76198 33.847238a52.00709 52.00709 0 0 0-1.70515 70.337458 51.580803 51.580803 0 0 0 69.57014 7.502662l5.115452-4.518649 34.10301-34.10301 20.632321-1.02309a66.330355 66.330355 0 0 0 38.792174-15.090582l5.285966-4.859679 471.3036-470.536281-116.80281-117.314355H699.111707z",fill:"#F7F8FA","p-id":"1742"})],-1)])],8,me)])]),e.createElementVNode("div",he,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.defaultColors,(i,u)=>(e.openBlock(),e.createElementBlock("div",{class:"color-picker__color-list__item",key:u,style:e.normalizeStyle({backgroundColor:i}),title:i,onClick:g=>Ve(i)},null,12,fe))),128))])],2))}}),[["__scopeId","data-v-df743242"]]),pe={class:"echo-dropdown__menu__list"},ge=["onClick"],_e={class:"echo-dropdown__menu__list__item__label"},U=I(e.defineComponent({__name:"index",props:{trigger:{default:"click"},placement:{default:"bottom-start"},items:{default:()=>[]},disabled:{type:Boolean,default:!1},getPopupContainer:{},className:{},style:{},hideOnClick:{type:Boolean,default:!0},icon:{}},emits:["select","openChange"],setup(o,{emit:a}){const n=o,s=a,t=e.ref(!1),d=e.ref(null),c=e.ref(null),m=e.ref(null),h=e.computed(()=>({"is-disabled":n.disabled,"is-visible":t.value})),C=e.computed(()=>[`echo-dropdown__menu--${n.placement||"bottom-start"}`]),$=e.computed(()=>({})),y=()=>{n.disabled||n.trigger==="click"&&(t.value=!t.value)},R=()=>{n.disabled||n.trigger==="hover"&&(t.value=!0)},b=()=>{n.trigger==="hover"&&setTimeout(()=>{N.value||(t.value=!1)},100)},N=e.ref(!1),V=()=>{N.value=!0},H=()=>{N.value=!1,n.trigger==="hover"&&S()},S=()=>{t.value&&(t.value=!1,s("openChange",!1))},X=(_,w)=>{_.disabled||(s("select",_,w),n.hideOnClick&&S())},F=()=>{var x;if(!c.value||!m.value)return;const _=(x=c.value)==null?void 0:x.getBoundingClientRect(),w=m.value.getBoundingClientRect(),E=n.placement||"bottom-start";let f=0,v=0;E.includes("bottom")?f=_.bottom+window.scrollY:E.includes("top")?f=_.top-w.height+window.scrollY:f=_.top,E.includes("start")||E.includes("left")?v=_.left+window.scrollX:E.includes("end")||E.includes("right")?v=_.right-w.width+window.scrollX:v=_.left+(_.width-w.width)/2;const A=window.innerWidth,D=window.innerHeight;v<0&&(v=8),v+w.width>A&&(v=A-w.width-8),f<0&&(f=8),f+w.height>D&&(f=D-w.height-8),m.value.style.left=`${v}px`,m.value.style.top=`${f}px`},z=_=>{d.value&&!d.value.contains(_.target)&&t.value&&n.trigger==="click"&&S()},M=()=>{t.value&&F()};return e.watch(t,_=>{_?(document.addEventListener("click",z),window.addEventListener("resize",M),window.addEventListener("scroll",F,!0)):(document.removeEventListener("click",z),window.removeEventListener("resize",M),window.removeEventListener("scroll",F,!0))}),e.onUnmounted(()=>{document.removeEventListener("click",z),window.removeEventListener("resize",M),window.removeEventListener("scroll",F,!0)}),(_,w)=>{const E=e.resolveComponent("svg-icon");return e.openBlock(),e.createElementBlock("div",{ref_key:"dropdownRef",ref:d,class:e.normalizeClass(["echo-dropdown",[h.value]])},[e.createElementVNode("div",{ref_key:"triggerRef",ref:c,class:e.normalizeClass(["echo-dropdown__trigger",{"is-disabled":o.disabled}]),onClick:y,onMouseenter:R,onMouseleave:b},[e.renderSlot(_.$slots,"default",{},()=>[w[0]||(w[0]=e.createElementVNode("span",null,"下拉菜单",-1)),o.icon?(e.openBlock(),e.createBlock(e.resolveDynamicComponent(o.icon),{key:0,class:"echo-dropdown__trigger__icon"})):(e.openBlock(),e.createBlock(E,{key:1,name:"arrow-down",class:"echo-dropdown__trigger__icon"}))],!0)],34),e.createVNode(e.Transition,{name:"echo-dropdown-fade"},{default:e.withCtx(()=>[t.value?(e.openBlock(),e.createElementBlock("div",{key:0,ref_key:"menuRef",ref:m,class:e.normalizeClass(["echo-dropdown__menu",[C.value]]),style:e.normalizeStyle($.value),onMouseenter:V,onMouseleave:H},[e.createElementVNode("ul",pe,[o.items&&o.items.length>0?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:0},e.renderList(o.items,(f,v)=>(e.openBlock(),e.createElementBlock("li",{key:f.key,class:e.normalizeClass(["echo-dropdown__menu__list__item",[{"is-disabled":f.disabled,"is-divider":f.divider,"is-checked":f.checked}]]),onClick:A=>X(f,v)},[f.icon?(e.openBlock(),e.createBlock(e.resolveDynamicComponent(f.icon),{key:0,class:"echo-dropdown__menu__list__item__icon"})):e.createCommentVNode("",!0),e.createElementVNode("span",_e,e.toDisplayString(f.label),1)],10,ge))),128)):e.renderSlot(_.$slots,"menu",{key:1},void 0,!0)])],38)):e.createCommentVNode("",!0)]),_:3})],2)}}}),[["__scopeId","data-v-f896e925"]]),ke={class:"echo-input__wrapper"},ye=["type","value","placeholder","disabled","readonly","maxlength"],be={key:0,class:"echo-input__word-limit"},O=I(e.defineComponent({__name:"index",props:{modelValue:{default:""},type:{default:"text"},placeholder:{default:""},disabled:{type:Boolean,default:!1},readonly:{type:Boolean,default:!1},clearable:{type:Boolean,default:!1},size:{default:"medium"},prefixIcon:{default:""},suffixIcon:{default:""},maxlength:{default:void 0},showWordLimit:{type:Boolean,default:!1}},emits:["update:modelValue","focus","blur","clear"],setup(o,{emit:a}){const n=o,s=a,t=e.ref(),d=e.computed(()=>String(n.modelValue).length),c=e.computed(()=>["echo-input",`echo-input--${n.size}`,{"echo-input--disabled":n.disabled,"echo-input--with-prefix":n.prefixIcon,"echo-input--with-suffix":n.suffixIcon||n.clearable}]),m=e.computed(()=>["echo-input__inner",{"echo-input__inner--disabled":n.disabled}]),h=b=>{const V=b.target.value;s("update:modelValue",V)},C=b=>{s("focus",b)},$=b=>{s("blur",b)},y=b=>{},R=()=>{var b;s("update:modelValue",""),s("clear"),(b=t.value)==null||b.focus()};return(b,N)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(c.value)},[e.createElementVNode("div",ke,[o.prefixIcon?(e.openBlock(),e.createBlock(e.unref(L),{key:0,name:o.prefixIcon,class:"echo-input__prefix-icon"},null,8,["name"])):e.createCommentVNode("",!0),e.createElementVNode("input",{ref_key:"inputRef",ref:t,class:e.normalizeClass(m.value),type:o.type,value:o.modelValue,placeholder:o.placeholder,disabled:o.disabled,readonly:o.readonly,maxlength:o.maxlength,onInput:h,onFocus:C,onBlur:$,onKeydown:y},null,42,ye),o.suffixIcon?(e.openBlock(),e.createBlock(e.unref(L),{key:1,name:o.suffixIcon,class:"echo-input__suffix-icon"},null,8,["name"])):e.createCommentVNode("",!0),o.clearable&&o.modelValue?(e.openBlock(),e.createElementBlock("button",{key:2,type:"button",class:"echo-input__clear",onClick:R},[e.createVNode(e.unref(L),{name:"close"})])):e.createCommentVNode("",!0)]),o.showWordLimit&&o.maxlength?(e.openBlock(),e.createElementBlock("div",be,e.toDisplayString(d.value)+"/"+e.toDisplayString(o.maxlength),1)):e.createCommentVNode("",!0)],2))}}),[["__scopeId","data-v-52972a06"]]),we=T,Ce=O,Ee=P,ve=U,Be=L,$e={install(o){o.component("EchoColorPicker",P),o.component("EchoDropdown",U),o.component("EchoIcon",L),o.component("EchoInput",O),o.component("EchoButton",T)}};k.Button=T,k.ColorPicker=P,k.Dropdown=U,k.EchoButton=we,k.EchoColorPicker=Ee,k.EchoDropdown=ve,k.EchoIcon=Be,k.EchoInput=Ce,k.EchoLibrary=$e,k.Icon=L,k.Input=O,Object.defineProperty(k,Symbol.toStringTag,{value:"Module"})});
|
|
2
|
+
//# sourceMappingURL=index.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../packages/components/Icon/index.vue","../packages/components/Button/index.vue","../packages/components/ColorPicker/constant.ts","../packages/components/ColorPicker/utils.ts","../packages/components/ColorPicker/index.vue","../packages/components/Dropdown/index.vue","../packages/components/Input/index.vue","../packages/index.ts"],"sourcesContent":["<template>\n <i :class=\"iconClasses\" :style=\"iconStyles\" @click=\"handleClick\">\n <slot />\n </i>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { IconProps } from './types.ts'\n\n// 定义组件属性\nconst props = withDefaults(defineProps<IconProps>(), {\n size: 16,\n color: 'currentColor',\n spin: false,\n})\n\n// 定义事件\nconst emit = defineEmits<{\n click: [event: MouseEvent]\n}>()\n\n// 计算图标样式类\nconst iconClasses = computed(() => [\n 'echo-icon',\n `echo-icon--${props.name}`,\n {\n 'echo-icon--spin': props.spin,\n },\n])\n\n// 计算图标样式\nconst iconStyles = computed(() => ({\n fontSize: typeof props.size === 'number' ? `${props.size}px` : props.size,\n color: props.color,\n}))\n\n// 处理点击事件\nconst handleClick = (event: MouseEvent) => {\n emit('click', event)\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.echo-icon {\n display: inline-block;\n font-style: normal;\n line-height: 1;\n vertical-align: middle;\n transition: all 0.2s ease-in-out;\n\n &--spin {\n animation: spin 1s linear infinite;\n }\n\n // 常用图标样式\n &--loading {\n &::before {\n content: '⟳';\n }\n }\n\n &--close {\n &::before {\n content: '×';\n }\n }\n\n &--search {\n &::before {\n content: '🔍';\n }\n }\n\n &--user {\n &::before {\n content: '👤';\n }\n }\n\n &--home {\n &::before {\n content: '🏠';\n }\n }\n\n &--settings {\n &::before {\n content: '⚙️';\n }\n }\n\n &--heart {\n &::before {\n content: '❤️';\n }\n }\n\n &--star {\n &::before {\n content: '⭐';\n }\n }\n\n &--check {\n &::before {\n content: '✓';\n }\n }\n\n &--plus {\n &::before {\n content: '+';\n }\n }\n\n &--minus {\n &::before {\n content: '−';\n }\n }\n\n &--arrow-up {\n &::before {\n content: '↑';\n }\n }\n\n &--arrow-down {\n &::before {\n content: '↓';\n }\n }\n\n &--arrow-left {\n &::before {\n content: '←';\n }\n }\n\n &--arrow-right {\n &::before {\n content: '→';\n }\n }\n}\n\n@keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n</style>\n","<template>\n <button :class=\"buttonClasses\" :disabled=\"disabled || loading\" @click=\"handleClick\">\n <EchoIcon\n v-if=\"loading\"\n name=\"loading\"\n class=\"echo-button__loading\"\n :class=\"{ 'echo-button__loading--spinning': loading }\"\n />\n <EchoIcon v-else-if=\"icon\" :name=\"icon\" class=\"echo-button__icon\" />\n <span v-if=\"$slots.default\" class=\"echo-button__text\">\n <slot />\n </span>\n </button>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport EchoIcon from '../Icon'\nimport type { ButtonProps } from './types.ts'\n\n// 定义组件属性\nconst props = withDefaults(defineProps<ButtonProps>(), {\n type: 'primary',\n size: 'medium',\n disabled: false,\n loading: false,\n round: false,\n plain: false,\n icon: '',\n})\n\n// 定义事件\nconst emit = defineEmits<{\n click: [event: MouseEvent]\n}>()\n\n// 计算按钮样式类\nconst buttonClasses = computed(() => [\n 'echo-button',\n `echo-button--${props.type}`,\n `echo-button--${props.size}`,\n {\n 'echo-button--disabled': props.disabled,\n 'echo-button--loading': props.loading,\n 'echo-button--round': props.round,\n 'echo-button--plain': props.plain,\n },\n])\n\n// 处理点击事件\nconst handleClick = (event: MouseEvent) => {\n if (props.disabled || props.loading) {\n return\n }\n emit('click', event)\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.echo-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n border: 1px solid transparent;\n border-radius: var(--echo-border-radius, 6px);\n font-size: var(--echo-font-size, 14px);\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease-in-out;\n outline: none;\n user-select: none;\n\n &:focus {\n outline: 2px solid var(--echo-primary-color, #1890ff);\n outline-offset: 2px;\n }\n\n // 尺寸变体\n &--small {\n padding: 6px 12px;\n font-size: 12px;\n min-height: 28px;\n }\n\n &--medium {\n padding: 8px 16px;\n font-size: 14px;\n min-height: 32px;\n }\n\n &--large {\n padding: 12px 20px;\n font-size: 16px;\n min-height: 40px;\n }\n\n // 类型变体\n &--primary {\n background-color: var(--echo-primary-color, #1890ff);\n color: white;\n border-color: var(--echo-primary-color, #1890ff);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-primary-hover, #40a9ff);\n border-color: var(--echo-primary-hover, #40a9ff);\n }\n\n &.echo-button--plain {\n background-color: transparent;\n color: var(--echo-primary-color, #1890ff);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-primary-color, #1890ff);\n color: white;\n }\n }\n }\n\n &--secondary {\n background-color: var(--echo-secondary-color, #f5f5f5);\n color: var(--echo-text-color, #333);\n border-color: var(--echo-border-color, #d9d9d9);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-secondary-hover, #e6e6e6);\n border-color: var(--echo-secondary-hover, #bfbfbf);\n }\n }\n\n &--success {\n background-color: var(--echo-success-color, #52c41a);\n color: white;\n border-color: var(--echo-success-color, #52c41a);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-success-hover, #73d13d);\n border-color: var(--echo-success-hover, #73d13d);\n }\n }\n\n &--warning {\n background-color: var(--echo-warning-color, #faad14);\n color: white;\n border-color: var(--echo-warning-color, #faad14);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-warning-hover, #ffc53d);\n border-color: var(--echo-warning-hover, #ffc53d);\n }\n }\n\n &--danger {\n background-color: var(--echo-danger-color, #ff4d4f);\n color: white;\n border-color: var(--echo-danger-color, #ff4d4f);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-danger-hover, #ff7875);\n border-color: var(--echo-danger-hover, #ff7875);\n }\n }\n\n &--info {\n background-color: var(--echo-info-color, #1890ff);\n color: white;\n border-color: var(--echo-info-color, #1890ff);\n\n &:hover:not(:disabled) {\n background-color: var(--echo-info-hover, #40a9ff);\n border-color: var(--echo-info-hover, #40a9ff);\n }\n }\n\n // 状态变体\n &--disabled {\n opacity: 0.6;\n cursor: not-allowed;\n pointer-events: none;\n }\n\n &--round {\n border-radius: 50px;\n }\n\n // 加载状态\n &--loading {\n cursor: wait;\n }\n\n &__loading {\n &--spinning {\n animation: spin 1s linear infinite;\n }\n }\n\n &__icon {\n flex-shrink: 0;\n }\n\n &__text {\n line-height: 1;\n }\n}\n\n@keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n</style>\n","export const DEFAULT_COLORS = [\n '#FFFFFF',\n '#000000',\n '#FF0000',\n '#00FF00',\n '#0000FF',\n '#FF1900',\n '#F47365',\n '#F89C5A',\n '#FAC858',\n '#73B06F',\n '#6ECBE6',\n '#926383',\n '#C89616',\n '#8E00A7',\n '#BF3DCE',\n '#FC3CAD',\n '#FF89CF',\n '#5D61FF',\n '#00BEFF',\n '#1BC7B1',\n]\n","/**\n * 颜色工具函数\n * 用于颜色格式之间的转换\n */\n\n/**\n * HEX 转 RGB\n * @param hex\n * @returns RGB对象 {r, g, b}\n */\nexport const hexToRgb = (hex: string): { r: number; g: number; b: number } | null => {\n // 移除#号\n const cleanHex = hex.replace('#', '')\n\n // 验证格式\n if (!/^[0-9A-Fa-f]{6}$/.test(cleanHex)) {\n return null\n }\n\n const r = parseInt(cleanHex.substring(0, 2), 16)\n const g = parseInt(cleanHex.substring(2, 4), 16)\n const b = parseInt(cleanHex.substring(4, 6), 16)\n\n return { r, g, b }\n}\n\n/**\n * rgb转hex\n * @param r 红色值 0-255\n * @param g 绿色值 0-255\n * @param b 蓝色值 0-255\n * @returnd HEX颜色值\n */\nexport const rgbToHex = (r: number, g: number, b: number): string => {\n const toHex = (n: number) => {\n const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16)\n return hex.length === 1 ? `0${hex}` : hex\n }\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`.toUpperCase()\n}\n\n/**\n * RGB 转 HSL\n * @param r 红色值 0-255\n * @param g 绿色值 0-255\n * @param b 蓝色值 0-255\n * @returns HSL对象 {h, s, l}, h: 0-360, s: 0-100, l: 0-100\n */\nexport const rgbToHsl = (r: number, g: number, b: number): { h: number; s: number; l: number } => {\n r /= 255\n g /= 255\n b /= 255\n\n const max = Math.max(r, g, b)\n const min = Math.min(r, g, b)\n let h = 0\n let s = 0\n const l = (max + min) / 2\n\n if (max !== min) {\n const d = max - min\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min)\n\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6\n break\n case g:\n h = ((b - r) / d + 2) / 6\n break\n case b:\n h = ((r - g) / d + 4) / 6\n break\n }\n }\n\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n }\n}\n\n/**\n * HSL 转 RGB\n * @param h 色相 0-360\n * @param s 饱和度 0-100\n * @param l 明度 0-100\n * @returns RGB对象 {r, g, b}\n */\nexport function hslToRgb(h: number, s: number, l: number): { r: number; g: number; b: number } {\n h /= 360\n s /= 100\n l /= 100\n\n let r, g, b\n\n if (s === 0) {\n r = g = b = l // 无色彩\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1\n if (t > 1) t -= 1\n if (t < 1 / 6) return p + (q - p) * 6 * t\n if (t < 1 / 2) return q\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6\n return p\n }\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s\n const p = 2 * l - q\n\n r = hue2rgb(p, q, h + 1 / 3)\n g = hue2rgb(p, q, h)\n b = hue2rgb(p, q, h - 1 / 3)\n }\n\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n }\n}\n\n/**\n * HEX 转 HSL\n * @param hex HEX颜色值\n * @returns HSL对象\n */\nexport function hexToHsl(hex: string): { h: number; s: number; l: number } | null {\n const rgb = hexToRgb(hex)\n if (!rgb) return null\n return rgbToHsl(rgb.r, rgb.g, rgb.b)\n}\n\n/**\n * HSL 转 HEX\n * @param h 色相\n * @param s 饱和度\n * @param l 明度\n * @returns HEX颜色值\n */\nexport function hslToHex(h: number, s: number, l: number): string {\n const rgb = hslToRgb(h, s, l)\n return rgbToHex(rgb.r, rgb.g, rgb.b)\n}\n\n/**\n * 验证 HEX 颜色格式\n * @param hex HEX颜色值\n * @returns 是否为有效格式\n */\nexport function isValidHex(hex: string): boolean {\n const cleanHex = hex.replace('#', '')\n return /^[0-9A-Fa-f]{6}$/.test(cleanHex) || /^[0-9A-Fa-f]{8}$/.test(cleanHex)\n}\n\n/**\n * HEX 转 RGBA\n * @param hex HEX颜色值(支持 #RRGGBB 或 #RRGGBBAA)\n * @param alpha 透明度 0-1,如果不提供则从hex中解析\n * @returns RGBA对象 {r, g, b, a}\n */\nexport function hexToRgba(\n hex: string,\n alpha?: number\n): { r: number; g: number; b: number; a: number } | null {\n const cleanHex = hex.replace('#', '')\n\n // 支持 6 位或 8 位 HEX\n if (!/^[0-9A-Fa-f]{6}$/.test(cleanHex) && !/^[0-9A-Fa-f]{8}$/.test(cleanHex)) {\n return null\n }\n\n const r = parseInt(cleanHex.substring(0, 2), 16)\n const g = parseInt(cleanHex.substring(2, 4), 16)\n const b = parseInt(cleanHex.substring(4, 6), 16)\n\n // 如果提供了 alpha 参数,使用它;否则从 8 位 HEX 中解析\n let a = alpha !== undefined ? alpha : 1\n if (cleanHex.length === 8) {\n a = parseInt(cleanHex.substring(6, 8), 16) / 255\n }\n\n return { r, g, b, a }\n}\n\n/**\n * RGBA 转 HEX(8位带透明度)\n * @param r 红色值 0-255\n * @param g 绿色值 0-255\n * @param b 蓝色值 0-255\n * @param a 透明度 0-1\n * @returns HEX颜色值 #RRGGBBAA\n */\nexport function rgbaToHex(r: number, g: number, b: number, a: number = 1): string {\n const toHex = (n: number) => {\n const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16)\n return hex.length === 1 ? '0' + hex : hex\n }\n\n const alphaHex = toHex(a * 255)\n return `#${toHex(r)}${toHex(g)}${toHex(b)}${alphaHex}`.toUpperCase()\n}\n\n/**\n * RGBA 转 HEX(6位不带透明度)\n * @param r 红色值 0-255\n * @param g 绿色值 0-255\n * @param b 蓝色值 0-255\n * @returns HEX颜色值 #RRGGBB\n */\nexport function rgbToHexWithoutAlpha(r: number, g: number, b: number): string {\n return rgbToHex(r, g, b)\n}\n\n/**\n * HSL 转 RGBA\n * @param h 色相 0-360\n * @param s 饱和度 0-100\n * @param l 明度 0-100\n * @param a 透明度 0-1\n * @returns RGBA对象\n */\nexport function hslaToRgba(\n h: number,\n s: number,\n l: number,\n a: number = 1\n): { r: number; g: number; b: number; a: number } {\n const rgb = hslToRgb(h, s, l)\n return { ...rgb, a }\n}\n\n/**\n * RGBA 转 HSL\n * @param r 红色值 0-255\n * @param g 绿色值 0-255\n * @param b 蓝色值 0-255\n * @param a 透明度 0-1\n * @returns HSLA对象 {h, s, l, a}\n */\nexport function rgbaToHsla(\n r: number,\n g: number,\n b: number,\n a: number = 1\n): { h: number; s: number; l: number; a: number } {\n const hsl = rgbToHsl(r, g, b)\n return { ...hsl, a }\n}\n\n/**\n * HSL 转 RGBA HEX(8位)\n * @param h 色相\n * @param s 饱和度\n * @param l 明度\n * @param a 透明度\n * @returns HEX颜色值 #RRGGBBAA\n */\nexport function hslaToHex(h: number, s: number, l: number, a: number = 1): string {\n const rgba = hslaToRgba(h, s, l, a)\n return rgbaToHex(rgba.r, rgba.g, rgba.b, rgba.a)\n}\n\n/**\n * HEX 转 HSLA\n * @param hex HEX颜色值(支持 #RRGGBB 或 #RRGGBBAA)\n * @returns HSLA对象\n */\nexport function hexToHsla(hex: string): { h: number; s: number; l: number; a: number } | null {\n const rgba = hexToRgba(hex)\n if (!rgba) return null\n return rgbaToHsla(rgba.r, rgba.g, rgba.b, rgba.a)\n}\n\n/**\n * RGBA 转 CSS rgba 字符串\n * @param r 红色值 0-255\n * @param g 绿色值 0-255\n * @param b 蓝色值 0-255\n * @param a 透明度 0-1\n * @returns CSS rgba 字符串\n */\nexport function rgbaToCss(r: number, g: number, b: number, a: number = 1): string {\n return `rgba(${r}, ${g}, ${b}, ${a})`\n}\n","<template>\n <div ref=\"colorPickerRef\" class=\"color-picker\" :class=\"[`color-picker--${theme}`]\">\n <!-- 头部 -->\n <!-- <div class=\"color-picker__header\">\n <div class=\"color-picker__header__mode-switch\">\n <EchoDropdown :items=\"modeItems\" @select=\"handleModeSelect\">\n <span>模式切换</span>\n </EchoDropdown>\n </div>\n </div> -->\n <!-- 主颜色选择区域 -->\n <div class=\"color-picker__main\">\n <!-- 饱和度和明度选择面板 -->\n <div\n ref=\"saturationPanelRef\"\n class=\"color-picker__saturation-panel\"\n :style=\"{ background: `linear-gradient(to right, #fff, hsl(${hsl.h}, 100%, 50%))` }\"\n @mousedown=\"handleSaturationMouseDown\"\n >\n <div\n class=\"color-picker__saturation-panel-black\"\n :style=\"{ background: `linear-gradient(to bottom, transparent, #000)` }\"\n >\n <div\n class=\"color-picker__saturation-panel-pointer\"\n :style=\"{\n left: `${hsl.s}%`,\n top: `${100 - hsl.l}%`,\n background: currentColorHex,\n }\"\n ></div>\n </div>\n </div>\n <!-- 色相选择条 -->\n <div ref=\"hueBarRef\" class=\"color-picker__hue-bar\" @mousedown=\"handleHueMouseDown\">\n <div\n class=\"color-picker__hue-bar-pointer\"\n :style=\"{ left: `${(hsl.h / 360) * 100}%` }\"\n ></div>\n </div>\n <!-- 透明度选择器 -->\n <div ref=\"alphaBarRef\" class=\"color-picker__alpha-bar\" @mousedown=\"handleAlphaMouseDown\">\n <div\n class=\"color-picker__alpha-bar-bg\"\n :style=\"{\n background: `linear-gradient(to right, transparent, ${currentColorHex})`,\n }\"\n ></div>\n <div class=\"color-picker__alpha-bar-pointer\" :style=\"{ left: `${alpha * 100}%` }\"></div>\n </div>\n </div>\n <!-- 底部控制区域 -->\n <div class=\"color-picker__controls\">\n <!-- 颜色预览 -->\n <div class=\"color-picker__controls__preview\" :style=\"{ background: currentColorRgba }\"></div>\n <!-- 颜色输入框 -->\n <div class=\"color-picker__controls__input-group\">\n <input\n type=\"text\"\n name=\"color-input\"\n v-model=\"colorInput\"\n class=\"color-picker__controls__input-group__input\"\n :placeholder=\"alpha < 1 ? '#000000FF' : '#000000'\"\n @input=\"handleInputChange\"\n />\n </div>\n <!-- 吸色器 -->\n <div class=\"color-picker__controls__eyedropper\">\n <button\n class=\"color-picker__controls__eyedropper-btn\"\n @click=\"handleEyeDropper\"\n :disabled=\"!isEyeDropperSupported\"\n title=\"吸取颜色\"\n >\n <svg\n t=\"1768013548643\"\n class=\"icon\"\n viewBox=\"0 0 1109 1024\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n p-id=\"1740\"\n width=\"40\"\n height=\"40\"\n >\n <path\n d=\"M968.525486 0c22.934274 0 45.015973 9.122555 61.214903 25.15097l53.200696 52.518635a85.257525 85.257525 0 0 1 0 121.321459l-123.367639 121.918261 20.206033 19.950261 4.689164 5.200709a54.564816 54.564816 0 0 1-4.689164 72.724669l-39.218461 38.706916a56.269967 56.269967 0 0 1-78.777953 0.085258l-1.278863-1.278863-486.990984 479.147291a125.072789 125.072789 0 0 1-71.786836 35.381873l-10.230903 0.937833-20.035519 19.609231a109.300147 109.300147 0 0 1-176.056789-30.692709c-17.90408-38.024856-11.850796-83.04083 15.346354-115.012402l6.394315-6.820602 19.95026-19.609231c1.449378-27.197151 11.936054-52.944923 29.669619-73.577244l6.991117-7.502662L660.74582 258.756589l-5.456481-5.371224-9.719358-9.548843-4.689164-5.200709a54.650074 54.650074 0 0 1 4.689164-72.809927l39.047946-38.621658a56.269967 56.269967 0 0 1 78.863211 0l20.206033 19.95026L907.140068 25.236227c16.369445-16.19893 38.365886-25.236227 61.385418-25.236227z\"\n fill=\"#64666F\"\n p-id=\"1741\"\n ></path>\n <path\n d=\"M699.111707 292.433311L227.637592 763.05485a68.802823 68.802823 0 0 0-19.097685 37.342796l-0.682061 6.991117-1.193605 20.717579-33.76198 33.847238a52.00709 52.00709 0 0 0-1.70515 70.337458 51.580803 51.580803 0 0 0 69.57014 7.502662l5.115452-4.518649 34.10301-34.10301 20.632321-1.02309a66.330355 66.330355 0 0 0 38.792174-15.090582l5.285966-4.859679 471.3036-470.536281-116.80281-117.314355H699.111707z\"\n fill=\"#F7F8FA\"\n p-id=\"1742\"\n ></path>\n </svg>\n </button>\n </div>\n </div>\n <!-- 颜色列表 -->\n <div class=\"color-picker__color-list\">\n <div\n class=\"color-picker__color-list__item\"\n v-for=\"(color, index) in defaultColors\"\n :key=\"index\"\n :style=\"{ backgroundColor: color }\"\n :title=\"color\"\n @click=\"handleColorSelect(color)\"\n ></div>\n </div>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue'\nimport { DEFAULT_COLORS } from './constant.ts'\nimport { ColorPickerProps } from './types.ts'\nimport { hexToHsla, hslaToHex, hslaToRgba, isValidHex, rgbaToCss, rgbaToHsla } from './utils'\n\nconst props = withDefaults(defineProps<ColorPickerProps>(), {\n theme: 'light',\n type: 'hex',\n mode: 'solid',\n showAlpha: true,\n showEyeDropper: true,\n showPickerMode: true,\n showColorList: true,\n defaultColors: () => DEFAULT_COLORS,\n})\n\nconst emit = defineEmits<{\n (e: 'update:color', color: string): void\n (e: 'colorChange', color: string): void\n}>()\n\nconst hsl = ref({\n h: 0, // 色相 0-360\n s: 0, // 饱和度 0-100\n l: 0, // 明度 0-100\n})\n\nconst colorInput = ref('')\nconst alpha = ref(1)\nconst isEyeDropperSupported = ref(true)\n\nconst colorPickerRef = ref<HTMLDivElement | null>(null)\nconst saturationPanelRef = ref<HTMLDivElement | null>(null)\nconst hueBarRef = ref<HTMLDivElement | null>(null)\nconst alphaBarRef = ref<HTMLDivElement | null>(null)\n// const modeItems = ref([\n// { key: 'solid', label: '实色' },\n// { key: 'gradient', label: '渐变' },\n// ])\n\nconst currentColor = computed<string>(() => {\n switch (props.type) {\n case 'hex':\n return alpha.value === 1 ? currentColorHex.value : currentColorFullHex.value\n case 'rgb':\n return alpha.value === 1 ? currentColorRgb.value : currentColorRgba.value\n case 'hsl':\n return alpha.value === 1 ? currentColorHsl.value : currentColorFullHsl.value\n default:\n return ''\n }\n})\nconst currentColorRgb = computed(() => {\n return `rgb(${hsl.value.h}, ${hsl.value.s}%, ${hsl.value.l}%)`\n})\nconst currentColorRgba = computed(() => {\n const rgba = hslaToRgba(hsl.value.h, hsl.value.s, hsl.value.l, alpha.value)\n return rgbaToCss(rgba.r, rgba.g, rgba.b, rgba.a)\n})\nconst currentColorHex = computed(() => {\n return hslaToHex(hsl.value.h, hsl.value.s, hsl.value.l, alpha.value)\n})\n// 当前颜色的完整 HEX(含透明度)\nconst currentColorFullHex = computed(() => {\n return hslaToHex(hsl.value.h, hsl.value.s, hsl.value.l, alpha.value)\n})\n\nconst currentColorHsl = computed(() => {\n return `hsl(${hsl.value.h}, ${hsl.value.s}%, ${hsl.value.l}%)`\n})\nconst currentColorFullHsl = computed(() => {\n return `hsla(${hsl.value.h}, ${hsl.value.s}%, ${hsl.value.l}%, ${alpha.value})`\n})\n\nconst parseColor = (color: string): { h: number; s: number; l: number; a: number } | null => {\n switch (props.type) {\n case 'hex':\n return hexToHsla(color)\n case 'rgb':\n const [r, g, b, a = 1] = color.split(',').map(Number)\n return rgbaToHsla(r, g, b, a)\n case 'hsl':\n console.log(7777, color)\n return null\n // return hslToHsla(color);\n // return color.split(',').map(Number);\n default:\n return null\n }\n}\n\n// const handleModeSelect = (item: DropdownItem) => {\n// console.log(8888, item)\n// }\n\nwatch(\n () => props.color,\n newColor => {\n if (newColor) {\n const hsla = parseColor(newColor)\n if (hsla) {\n const { h, s, l, a } = hsla\n hsl.value.h = h\n hsl.value.s = s\n hsl.value.l = l\n alpha.value = a\n }\n colorInput.value = newColor\n }\n }\n)\n\nwatch([currentColorHex, alpha], () => {\n const outputHex = alpha.value === 1 ? currentColorHex.value : currentColorFullHex.value\n if (outputHex !== props.color) {\n emit('update:color', outputHex)\n emit('colorChange', outputHex)\n colorInput.value = outputHex\n }\n})\n\n// 饱和度选择面板鼠标按下\nlet isSaturationDragging = false\nlet saturationAnimationFrame: number | null = null\nconst updateSaturationPosition = (e: MouseEvent) => {\n if (!saturationPanelRef.value) return\n const rect = saturationPanelRef.value?.getBoundingClientRect()\n const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width))\n const y = Math.max(0, Math.min(e.clientY - rect.top, rect.height))\n\n hsl.value.s = Math.round((x / rect.width) * 100)\n hsl.value.l = Math.round((1 - y / rect.height) * 100)\n}\nconst handleSaturationMouseDown = (e: MouseEvent) => {\n e.preventDefault()\n isSaturationDragging = true\n updateSaturationPosition(e)\n\n const handleMouseMover = (e: MouseEvent) => {\n if (!isSaturationDragging) return\n e.preventDefault()\n if (saturationAnimationFrame) {\n cancelAnimationFrame(saturationAnimationFrame)\n saturationAnimationFrame = null\n }\n saturationAnimationFrame = requestAnimationFrame(() => {\n updateSaturationPosition(e)\n })\n }\n\n const handleMouseUp = () => {\n if (!isSaturationDragging) return\n isSaturationDragging = false\n if (saturationAnimationFrame) {\n cancelAnimationFrame(saturationAnimationFrame)\n saturationAnimationFrame = null\n }\n colorPickerRef.value?.removeEventListener('mousemove', handleMouseMover)\n colorPickerRef.value?.removeEventListener('mouseup', handleMouseUp)\n }\n\n colorPickerRef.value?.addEventListener('mousemove', handleMouseMover)\n colorPickerRef.value?.addEventListener('mouseup', handleMouseUp)\n}\n\n// 色相选择条\nlet isHueDragging = false\nlet hueAnimationFrame: number | null = null\nconst updateHuePosition = (e: MouseEvent) => {\n if (!hueBarRef.value) return\n\n const rect = hueBarRef.value?.getBoundingClientRect()\n const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width))\n hsl.value.h = Math.round((x / rect.width) * 360)\n}\nconst handleHueMouseDown = (e: MouseEvent) => {\n e.preventDefault()\n isHueDragging = true\n updateHuePosition(e)\n\n const handleMouseMover = (e: MouseEvent) => {\n if (!isHueDragging) return\n e.preventDefault()\n if (hueAnimationFrame) {\n cancelAnimationFrame(hueAnimationFrame)\n hueAnimationFrame = null\n }\n hueAnimationFrame = requestAnimationFrame(() => {\n updateHuePosition(e)\n })\n }\n\n const handleMouseUp = () => {\n if (!isHueDragging) return\n isHueDragging = false\n if (hueAnimationFrame) {\n cancelAnimationFrame(hueAnimationFrame)\n hueAnimationFrame = null\n }\n colorPickerRef.value?.removeEventListener('mousemove', handleMouseMover)\n colorPickerRef.value?.removeEventListener('mouseup', handleMouseUp)\n }\n colorPickerRef.value?.addEventListener('mousemove', handleMouseMover)\n colorPickerRef.value?.addEventListener('mouseup', handleMouseUp)\n}\n\n// 透明度选择条\nlet isAlphaDragging = false\nlet alphaAnimationFrame: number | null = null\nconst updateAlphaPosition = (e: MouseEvent) => {\n if (!alphaBarRef.value) return\n const rect = alphaBarRef.value?.getBoundingClientRect()\n const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width))\n alpha.value = Math.round((x / rect.width) * 100) / 100\n}\nconst handleAlphaMouseDown = (e: MouseEvent) => {\n e.preventDefault()\n isAlphaDragging = true\n updateAlphaPosition(e)\n\n const handleMouseMover = (e: MouseEvent) => {\n if (!isAlphaDragging) return\n e.preventDefault()\n if (alphaAnimationFrame) {\n cancelAnimationFrame(alphaAnimationFrame)\n alphaAnimationFrame = null\n }\n alphaAnimationFrame = requestAnimationFrame(() => {\n updateAlphaPosition(e)\n })\n }\n const handleMouseUp = () => {\n if (!isAlphaDragging) return\n isAlphaDragging = false\n if (alphaAnimationFrame) {\n cancelAnimationFrame(alphaAnimationFrame)\n alphaAnimationFrame = null\n }\n colorPickerRef.value?.removeEventListener('mousemove', handleMouseMover)\n colorPickerRef.value?.removeEventListener('mouseup', handleMouseUp)\n }\n colorPickerRef.value?.addEventListener('mousemove', handleMouseMover)\n colorPickerRef.value?.addEventListener('mouseup', handleMouseUp)\n}\n\n// 输入框内容变化\nconst handleInputChange = (e: Event) => {\n const value = (e.target as HTMLInputElement).value\n const hsla = parseColor(colorInput.value)\n if (hsla) {\n const { h, s, l, a } = hsla\n hsl.value.h = h\n hsl.value.s = s\n hsl.value.l = l\n alpha.value = a\n }\n colorInput.value = value.trim().toUpperCase()\n}\n\n// 吸取颜色\nconst handleEyeDropper = async () => {\n if (!isEyeDropperSupported.value) return\n try {\n const eyeDropper = new (window as any).EyeDropper()\n const result = await eyeDropper.open()\n if (result.sRGBHex) {\n const hsla = parseColor(result.sRGBHex)\n if (hsla) {\n const { h, s, l, a } = hsla\n hsl.value.h = h\n hsl.value.s = s\n hsl.value.l = l\n alpha.value = a\n }\n }\n } catch (error: any) {\n if (error.name !== 'AbortError') {\n console.error('颜色拾取失败', error)\n }\n }\n}\n\n// 选择颜色\nconst handleColorSelect = (color: string) => {\n if (!isValidHex(color)) return\n\n const hsla = parseColor(color)\n\n if (hsla) {\n const { h, s, l, a } = hsla\n hsl.value.h = h\n hsl.value.s = s\n hsl.value.l = l\n alpha.value = a\n }\n colorInput.value = currentColor.value\n}\n\nonMounted(() => {\n isEyeDropperSupported.value = !!(window as any).EyeDropper\n\n if (props.color && isValidHex(props.color)) {\n const hsla = parseColor(props.color)\n if (hsla) {\n const { h, s, l, a } = hsla\n hsl.value.h = h\n hsl.value.s = s\n hsl.value.l = l\n alpha.value = a\n }\n colorInput.value = props.color\n }\n})\n</script>\n<style lang=\"scss\" scoped>\n.color-picker {\n box-sizing: border-box;\n width: 220px;\n padding: 12px;\n border-radius: 6px;\n &__header {\n display: flex;\n justify-content: space-end;\n gap: 8px;\n align-items: center;\n margin-bottom: 12px;\n font-size: 10px;\n }\n &__main {\n margin-bottom: 12px;\n }\n &__saturation-panel {\n position: relative;\n width: 100%;\n height: 180px;\n margin-bottom: 8px;\n overflow: hidden;\n cursor: crosshair;\n border-radius: 4px;\n &-black {\n position: relative;\n width: 100%;\n height: 100%;\n }\n &-pointer {\n position: absolute;\n width: 12px;\n height: 12px;\n pointer-events: none;\n border: 2px solid #fff;\n border-radius: 50%;\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);\n transform: translate(-50%, -50%);\n }\n }\n &__hue-bar {\n position: relative;\n width: 100%;\n height: 10px;\n margin-bottom: 8px;\n cursor: pointer;\n background: linear-gradient(\n to right,\n #ff0000 0%,\n #ffff00 17%,\n #00ff00 33%,\n #00ffff 50%,\n #0000ff 67%,\n #ff00ff 83%,\n #ff0000 100%\n );\n border-radius: 6px;\n &-pointer {\n position: absolute;\n top: 50%;\n width: 12px;\n height: 12px;\n pointer-events: none;\n background: #fff;\n border: 2px solid rgba(0, 0, 0, 0.3);\n border-radius: 50%;\n box-shadow:\n 0 0 0 1px rgb(255 255 255 / 80%),\n 0 0 0 2px rgb(255 255 255 / 40%),\n 0 0 4px rgb(255 255 255 / 30%),\n 0 1px 2px rgb(0 0 0 / 20%);\n transform: translate(-50%, -50%);\n }\n }\n &__alpha-bar {\n position: relative;\n width: 100%;\n height: 10px;\n cursor: pointer;\n background-image:\n linear-gradient(45deg, #cccccc 25%, transparent 25%),\n linear-gradient(-45deg, #cccccc 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, #cccccc 75%),\n linear-gradient(-45deg, transparent 75%, #cccccc 75%);\n background-position:\n 0 0,\n 0 4px,\n 4px -4px,\n -4px 0;\n background-size: 8px 8px;\n border-radius: 6px;\n &-bg {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border-radius: 5px;\n }\n &-pointer {\n position: absolute;\n top: 50%;\n width: 12px;\n height: 12px;\n pointer-events: none;\n background: #fff;\n border: 2px solid rgb(0 0 0 / 30%);\n border-radius: 50%;\n box-shadow:\n 0 0 0 1px rgb(255 255 255 / 80%),\n 0 0 0 2px rgb(255 255 255 / 40%),\n 0 0 4px rgb(255 255 255 / 30%),\n 0 1px 2px rgb(0 0 0 / 20%);\n transform: translate(-50%, -50%);\n }\n }\n\n &__controls {\n display: flex;\n gap: 8px;\n align-items: center;\n &__preview {\n position: relative;\n width: 24px;\n height: 24px;\n display: block;\n overflow: hidden;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 4px;\n &-bg {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-image:\n linear-gradient(45deg, #cccccc 25%, transparent 25%),\n linear-gradient(-45deg, #cccccc 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, #cccccc 75%),\n linear-gradient(-45deg, transparent 75%, #cccccc 75%);\n background-position:\n 0 0,\n 0 4px,\n 4px -4px,\n -4px 0;\n background-size: 8px 8px;\n }\n &-color {\n position: relative;\n z-index: 1;\n width: 100%;\n height: 100%;\n }\n }\n &__input-group {\n flex: 1;\n height: 24px;\n padding: 0 8px;\n background: #fff;\n border: 1px solid rgba(0, 0, 0, 0.3);\n border-radius: 4px;\n outline: none;\n &__input {\n width: 100%;\n height: 100%;\n font-size: 12px;\n line-height: 24px;\n color: #000;\n background: transparent;\n border: none;\n outline: none;\n\n &:focus {\n border-color: rgb(255 255 255 / 30%);\n }\n &::placeholder {\n color: rgb(255 255 255 / 30%);\n }\n }\n }\n &__eyedropper {\n width: 24px;\n height: 24px;\n display: block;\n overflow: hidden;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 4px;\n &-btn {\n width: 100%;\n height: 100%;\n display: flex;\n padding: 4px;\n cursor: pointer;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n border: none;\n outline: none;\n }\n }\n }\n &__color-list {\n display: grid;\n grid-template-columns: repeat(10, 1fr);\n gap: 4px;\n margin-top: 8px;\n &__item {\n width: 100%;\n aspect-ratio: 1;\n cursor: pointer;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 3px;\n transition: all 0.2s;\n &:hover {\n z-index: 1;\n border-color: rgba(0, 0, 0, 0.3);\n transform: scale(1.1);\n }\n }\n }\n\n &--dark {\n background-color: #1a1a1a;\n border: 1px solid #333;\n }\n &--light {\n background-color: #fff;\n border: 1px solid #ddd;\n }\n\n &--dark &__header {\n color: #fff;\n }\n &--dark &__controls {\n &__preview {\n border-color: rgba(255, 255, 255, 0.3);\n }\n }\n &--dark &__color-list {\n &__item {\n border-color: rgba(255, 255, 255, 0.3);\n }\n }\n}\n</style>\n","<template>\n <div ref=\"dropdownRef\" class=\"echo-dropdown\" :class=\"[dropdownClass]\">\n <!-- 触发器插槽 -->\n <div\n ref=\"triggerRef\"\n class=\"echo-dropdown__trigger\"\n :class=\"{ 'is-disabled': disabled }\"\n @click=\"handleTriggerClick\"\n @mouseenter=\"handleTriggerMouseEnter\"\n @mouseleave=\"handleTriggerMouseLeave\"\n >\n <slot name=\"default\">\n <span>下拉菜单</span>\n <template v-if=\"icon\">\n <component :is=\"icon\" class=\"echo-dropdown__trigger__icon\" />\n </template>\n <svg-icon v-else name=\"arrow-down\" class=\"echo-dropdown__trigger__icon\" />\n </slot>\n </div>\n <!-- 下拉菜单面板 -->\n <Transition name=\"echo-dropdown-fade\">\n <div\n v-if=\"visible\"\n ref=\"menuRef\"\n class=\"echo-dropdown__menu\"\n :class=\"[menuClasses]\"\n :style=\"menuStyle\"\n @mouseenter=\"handleMenuMouseEnter\"\n @mouseleave=\"handleMenuMouseLeave\"\n >\n <ul class=\"echo-dropdown__menu__list\">\n <template v-if=\"items && items.length > 0\">\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.key\"\n class=\"echo-dropdown__menu__list__item\"\n :class=\"[\n {\n 'is-disabled': item.disabled,\n 'is-divider': item.divider,\n 'is-checked': item.checked,\n },\n ]\"\n @click=\"handleItemClick(item, index)\"\n >\n <template v-if=\"item.icon\">\n <component :is=\"item.icon\" class=\"echo-dropdown__menu__list__item__icon\" />\n </template>\n <span class=\"echo-dropdown__menu__list__item__label\">{{ item.label }}</span>\n </li>\n </template>\n <slot v-else name=\"menu\"></slot>\n </ul>\n </div>\n </Transition>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport { computed, onUnmounted, ref, watch } from 'vue'\nimport { DropdownEmits, DropdownItem, DropdownProps } from './types.ts'\n\nconst props = withDefaults(defineProps<DropdownProps>(), {\n trigger: 'click',\n placement: 'bottom-start',\n disabled: false,\n items: () => [],\n hideOnClick: true,\n})\n\nconst emit = defineEmits<DropdownEmits>()\n\nconst visible = ref(false)\nconst dropdownRef = ref<HTMLElement | null>(null)\nconst triggerRef = ref<HTMLElement | null>(null)\nconst menuRef = ref<HTMLElement | null>(null)\n\nconst dropdownClass = computed(() => ({\n 'is-disabled': props.disabled,\n 'is-visible': visible.value,\n}))\n\nconst menuClasses = computed(() => {\n const placement = props.placement || 'bottom-start'\n return [`echo-dropdown__menu--${placement}`]\n})\n\nconst menuStyle = computed(() => {\n const styles: Record<string, string> = {}\n return styles\n})\n\n// const getPopupContainer = () => {\n// return props.getPopupContainer ? props.getPopupContainer() : dropdownRef.value\n// }\n\nconst handleTriggerClick = () => {\n if (props.disabled) return\n if (props.trigger === 'click') {\n visible.value = !visible.value\n }\n}\n\nconst handleTriggerMouseEnter = () => {\n if (props.disabled) return\n if (props.trigger === 'hover') {\n visible.value = true\n }\n}\n\nconst handleTriggerMouseLeave = () => {\n if (props.trigger === 'hover') {\n // 延迟关闭,避免快速移动时闪烁\n setTimeout(() => {\n if (!isMouseInMenu.value) {\n visible.value = false\n }\n }, 100)\n }\n}\n\n// 处理菜单鼠标进入\nconst isMouseInMenu = ref(false)\nconst handleMenuMouseEnter = () => {\n isMouseInMenu.value = true\n}\nconst handleMenuMouseLeave = () => {\n isMouseInMenu.value = false\n if (props.trigger === 'hover') {\n hideMenu()\n }\n}\n\n// 显示菜单\n// const showMenu = async () => {\n// if (props.disabled || visible.value) return\n// visible.value = true\n// emit('openChange', true)\n// await nextTick()\n// emit('openChange', true)\n// }\n\n// 隐藏菜单\nconst hideMenu = () => {\n if (!visible.value) return\n visible.value = false\n emit('openChange', false)\n}\n\n// 切换菜单显示状态\n// const toggleMenu = async () => {\n// if (props.disabled) return\n// if (visible.value) {\n// hideMenu()\n// } else {\n// showMenu()\n// }\n// }\n\n// 处理菜单项点击\nconst handleItemClick = (item: DropdownItem, index: number) => {\n if (item.disabled) return\n emit('select', item, index)\n if (props.hideOnClick) {\n hideMenu()\n }\n}\n\n// 更新菜单位置\nconst updateMenuPosition = () => {\n if (!triggerRef.value || !menuRef.value) return\n\n const triggerRect = triggerRef.value?.getBoundingClientRect()\n const menuRect = menuRef.value.getBoundingClientRect()\n const placement = props.placement || 'bottom-start'\n\n let top = 0\n let left = 0\n\n // 根据placement计算位置\n if (placement.includes('bottom')) {\n top = triggerRect.bottom + window.scrollY\n } else if (placement.includes('top')) {\n top = triggerRect.top - menuRect.height + window.scrollY\n } else {\n top = triggerRect.top\n }\n\n if (placement.includes('start') || placement.includes('left')) {\n left = triggerRect.left + window.scrollX\n } else if (placement.includes('end') || placement.includes('right')) {\n left = triggerRect.right - menuRect.width + window.scrollX\n } else {\n left = triggerRect.left + (triggerRect.width - menuRect.width) / 2\n }\n\n // 边界检测,防止菜单超出视口\n const viewportWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n if (left < 0) left = 8\n // 左边超出视口\n if (left + menuRect.width > viewportWidth) {\n left = viewportWidth - menuRect.width - 8\n }\n if (top < 0) top = 8\n // 上边超出视口\n if (top + menuRect.height > viewportHeight) {\n top = viewportHeight - menuRect.height - 8\n }\n\n // 更新菜单位置\n menuRef.value.style.left = `${left}px`\n menuRef.value.style.top = `${top}px`\n}\n\n// 点击外部关闭菜单\nconst handleClickOutside = (event: MouseEvent) => {\n if (\n dropdownRef.value &&\n !dropdownRef.value.contains(event.target as Node) &&\n visible.value &&\n props.trigger === 'click'\n ) {\n hideMenu()\n }\n}\n\n// 监听窗口大小变化\nconst handleResize = () => {\n if (visible.value) {\n updateMenuPosition()\n }\n}\n\n// 监听visible变化,更新位置\nwatch(visible, newVal => {\n if (newVal) {\n document.addEventListener('click', handleClickOutside)\n window.addEventListener('resize', handleResize)\n window.addEventListener('scroll', updateMenuPosition, true)\n } else {\n document.removeEventListener('click', handleClickOutside)\n window.removeEventListener('resize', handleResize)\n window.removeEventListener('scroll', updateMenuPosition, true)\n }\n})\n\nonUnmounted(() => {\n document.removeEventListener('click', handleClickOutside)\n window.removeEventListener('resize', handleResize)\n window.removeEventListener('scroll', updateMenuPosition, true)\n})\n</script>\n<style lang=\"scss\" scoped>\n.echo-dropdown {\n position: relative;\n display: inline-block;\n &.is-disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n &.is-visible {\n z-index: 1000;\n }\n &__trigger {\n cursor: pointer;\n user-select: none; // 禁止用户选择文本\n &.is-disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n }\n &__menu {\n position: fixed;\n z-index: 1000;\n background: #fff;\n border-radius: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n padding: 4px 0;\n margin: 0;\n min-width: 120px;\n max-height: 300px;\n overflow-y: auto;\n\n &__list {\n list-style: none;\n margin: 0;\n padding: 0;\n\n &__item {\n display: flex;\n gap: 8px;\n align-items: center;\n padding: 8px 12px;\n cursor: pointer;\n transition: all 0.2s;\n color: #333;\n font-size: 14px;\n line-height: 1.5;\n\n &:hover:not(.is-disabled) {\n background-color: #f5f7fa;\n }\n &.is-disabled {\n cursor: not-allowed;\n color: #c0c4cc;\n }\n &.is-divider {\n border-top: 1px solid #e4e7ed;\n margin-top: 4px;\n padding-top: 4px;\n }\n\n &__icon {\n flex-shrink: 0; // 不压缩图标\n }\n &__label {\n flex: 1; // 填充剩余空间\n white-space: nowrap; // 不换行\n overflow: hidden; // 超出隐藏\n text-overflow: ellipsis; // 超出显示省略号\n }\n }\n }\n }\n}\n\n.echo-dropdown-fade-enter-active,\n.echo-dropdown-fade-leave-active {\n transition:\n opacity 0.2s,\n transform 0.2s;\n}\n.echo-dropdown-fade-enter-from,\n.echo-dropdown-fade-leave-to {\n opacity: 0;\n transform: translateY(-10px) scale(0.95);\n}\n</style>\n","<template>\n <div :class=\"wrapperClasses\">\n <div class=\"echo-input__wrapper\">\n <EchoIcon v-if=\"prefixIcon\" :name=\"prefixIcon\" class=\"echo-input__prefix-icon\" />\n <input\n ref=\"inputRef\"\n :class=\"inputClasses\"\n :type=\"type\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :readonly=\"readonly\"\n :maxlength=\"maxlength\"\n @input=\"handleInput\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n @keydown=\"handleKeydown\"\n />\n <EchoIcon v-if=\"suffixIcon\" :name=\"suffixIcon\" class=\"echo-input__suffix-icon\" />\n <button\n v-if=\"clearable && modelValue\"\n type=\"button\"\n class=\"echo-input__clear\"\n @click=\"handleClear\"\n >\n <EchoIcon name=\"close\" />\n </button>\n </div>\n <div v-if=\"showWordLimit && maxlength\" class=\"echo-input__word-limit\">\n {{ currentLength }}/{{ maxlength }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport EchoIcon from '../Icon'\nimport type { InputProps } from './types'\n\n// 定义组件属性\nconst props = withDefaults(defineProps<InputProps>(), {\n modelValue: '',\n type: 'text',\n placeholder: '',\n disabled: false,\n readonly: false,\n clearable: false,\n size: 'medium',\n prefixIcon: '',\n suffixIcon: '',\n maxlength: undefined,\n showWordLimit: false,\n})\n\n// 定义事件\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number]\n focus: [event: FocusEvent]\n blur: [event: FocusEvent]\n clear: []\n}>()\n\n// 输入框引用\nconst inputRef = ref<HTMLInputElement>()\n\n// 计算当前长度\nconst currentLength = computed(() => {\n return String(props.modelValue).length\n})\n\n// 计算包装器样式类\nconst wrapperClasses = computed(() => [\n 'echo-input',\n `echo-input--${props.size}`,\n {\n 'echo-input--disabled': props.disabled,\n 'echo-input--with-prefix': props.prefixIcon,\n 'echo-input--with-suffix': props.suffixIcon || props.clearable,\n },\n])\n\n// 计算输入框样式类\nconst inputClasses = computed(() => [\n 'echo-input__inner',\n {\n 'echo-input__inner--disabled': props.disabled,\n },\n])\n\n// 处理输入事件\nconst handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement\n const value = target.value\n emit('update:modelValue', value)\n}\n\n// 处理焦点事件\nconst handleFocus = (event: FocusEvent) => {\n emit('focus', event)\n}\n\n// 处理失焦事件\nconst handleBlur = (event: FocusEvent) => {\n emit('blur', event)\n}\n\n// 处理键盘事件\nconst handleKeydown = (_event: KeyboardEvent) => {\n // 可以在这里添加键盘快捷键处理\n}\n\n// 处理清除事件\nconst handleClear = () => {\n emit('update:modelValue', '')\n emit('clear')\n inputRef.value?.focus()\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.echo-input {\n display: inline-block;\n width: 100%;\n position: relative;\n\n // 尺寸变体\n &--small {\n .echo-input__wrapper {\n height: 28px;\n }\n\n .echo-input__inner {\n font-size: 12px;\n padding: 4px 8px;\n }\n }\n\n &--medium {\n .echo-input__wrapper {\n height: 32px;\n }\n\n .echo-input__inner {\n font-size: 14px;\n padding: 6px 12px;\n }\n }\n\n &--large {\n .echo-input__wrapper {\n height: 40px;\n }\n\n .echo-input__inner {\n font-size: 16px;\n padding: 8px 16px;\n }\n }\n\n // 状态变体\n &--disabled {\n .echo-input__wrapper {\n background-color: var(--echo-disabled-bg, #f5f5f5);\n cursor: not-allowed;\n }\n\n .echo-input__inner {\n cursor: not-allowed;\n color: var(--echo-disabled-color, #c0c4cc);\n }\n }\n\n &--with-prefix {\n .echo-input__inner {\n padding-left: 32px;\n }\n }\n\n &--with-suffix {\n .echo-input__inner {\n padding-right: 32px;\n }\n }\n\n &__wrapper {\n position: relative;\n display: flex;\n align-items: center;\n background-color: white;\n border: 1px solid var(--echo-border-color, #d9d9d9);\n border-radius: var(--echo-border-radius, 6px);\n transition: all 0.2s ease-in-out;\n\n &:hover {\n border-color: var(--echo-primary-color, #1890ff);\n }\n\n &:focus-within {\n border-color: var(--echo-primary-color, #1890ff);\n box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);\n }\n }\n\n &__inner {\n flex: 1;\n border: none;\n outline: none;\n background: transparent;\n color: var(--echo-text-color, #333);\n line-height: 1.5;\n\n &::placeholder {\n color: var(--echo-placeholder-color, #c0c4cc);\n }\n\n &--disabled {\n background-color: transparent;\n color: var(--echo-disabled-color, #c0c4cc);\n }\n }\n\n &__prefix-icon,\n &__suffix-icon {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n color: var(--echo-icon-color, #c0c4cc);\n font-size: 16px;\n pointer-events: none;\n }\n\n &__prefix-icon {\n left: 8px;\n }\n\n &__suffix-icon {\n right: 8px;\n }\n\n &__clear {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n background: none;\n border: none;\n cursor: pointer;\n color: var(--echo-icon-color, #c0c4cc);\n font-size: 14px;\n padding: 2px;\n border-radius: 50%;\n transition: all 0.2s ease-in-out;\n\n &:hover {\n background-color: var(--echo-hover-bg, #f5f5f5);\n color: var(--echo-text-color, #333);\n }\n }\n\n &__word-limit {\n margin-top: 4px;\n font-size: 12px;\n color: var(--echo-text-secondary, #666);\n text-align: right;\n }\n}\n</style>\n","/**\n * 组件库入口文件\n * 导出所有组件\n * 导出组件类型\n * 默认安装函数\n */\n\nimport type { App } from 'vue'\nimport { Button } from './components/Button'\nimport { ColorPicker } from './components/ColorPicker'\nimport { Dropdown } from './components/Dropdown'\nimport { Icon } from './components/Icon'\nimport { Input } from './components/Input'\n\n// 导出所有组件\nexport { Button, ColorPicker, Dropdown, Icon, Input }\n\nexport const EchoButton = Button\nexport const EchoInput = Input\nexport const EchoColorPicker = ColorPicker\nexport const EchoDropdown = Dropdown\nexport const EchoIcon = Icon\n\n// 导出组件类型\nexport type { ButtonProps, ButtonSize, ButtonType } from './components/Button'\nexport type { ColorPickerProps } from './components/ColorPicker'\nexport type { DropdownItem, DropdownProps } from './components/Dropdown'\nexport type { IconProps } from './components/Icon'\nexport type { InputProps, InputType } from './components/Input'\n\n// 默认安装函数\nexport const EchoLibrary = {\n install(app: App) {\n app.component('EchoColorPicker', ColorPicker)\n app.component('EchoDropdown', Dropdown)\n app.component('EchoIcon', Icon)\n app.component('EchoInput', Input)\n app.component('EchoButton', Button)\n },\n}\n"],"names":["props","__props","emit","__emit","iconClasses","computed","iconStyles","handleClick","event","_createElementBlock","_renderSlot","_ctx","buttonClasses","_createBlock","_unref","EchoIcon","_normalizeClass","$slots","_openBlock","_hoisted_2","DEFAULT_COLORS","rgbToHsl","r","g","b","max","min","h","s","l","d","hslToRgb","hue2rgb","p","q","t","isValidHex","hex","cleanHex","hexToRgba","alpha","a","rgbaToHex","toHex","n","alphaHex","hslaToRgba","rgbaToHsla","hslaToHex","rgba","hexToHsla","rgbaToCss","hsl","ref","colorInput","isEyeDropperSupported","colorPickerRef","saturationPanelRef","hueBarRef","alphaBarRef","currentColor","currentColorHex","currentColorFullHex","currentColorRgb","currentColorRgba","currentColorHsl","currentColorFullHsl","parseColor","color","watch","newColor","hsla","outputHex","isSaturationDragging","saturationAnimationFrame","updateSaturationPosition","e","rect","_a","x","y","handleSaturationMouseDown","handleMouseMover","handleMouseUp","_b","isHueDragging","hueAnimationFrame","updateHuePosition","handleHueMouseDown","isAlphaDragging","alphaAnimationFrame","updateAlphaPosition","handleAlphaMouseDown","handleInputChange","value","handleEyeDropper","result","error","handleColorSelect","onMounted","_createElementVNode","_hoisted_1","_normalizeStyle","_hoisted_3","_hoisted_4","$event","_hoisted_6","_hoisted_8","_Fragment","_renderList","index","visible","dropdownRef","triggerRef","menuRef","dropdownClass","menuClasses","menuStyle","handleTriggerClick","handleTriggerMouseEnter","handleTriggerMouseLeave","isMouseInMenu","handleMenuMouseEnter","handleMenuMouseLeave","hideMenu","handleItemClick","item","updateMenuPosition","triggerRect","menuRect","placement","top","left","viewportWidth","viewportHeight","handleClickOutside","handleResize","newVal","onUnmounted","_cache","_resolveDynamicComponent","_component_svg_icon","_createVNode","_Transition","_toDisplayString","inputRef","currentLength","wrapperClasses","inputClasses","handleInput","handleFocus","handleBlur","handleKeydown","_event","handleClear","EchoButton","Button","EchoInput","Input","EchoColorPicker","ColorPicker","EchoDropdown","Dropdown","Icon","EchoLibrary","app"],"mappings":"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"}
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@charset "UTF-8";.echo-icon[data-v-cf0db90e]{display:inline-block;font-style:normal;line-height:1;vertical-align:middle;transition:all .2s ease-in-out}.echo-icon--spin[data-v-cf0db90e]{animation:spin-cf0db90e 1s linear infinite}.echo-icon--loading[data-v-cf0db90e]:before{content:"⟳"}.echo-icon--close[data-v-cf0db90e]:before{content:"×"}.echo-icon--search[data-v-cf0db90e]:before{content:"🔍"}.echo-icon--user[data-v-cf0db90e]:before{content:"👤"}.echo-icon--home[data-v-cf0db90e]:before{content:"🏠"}.echo-icon--settings[data-v-cf0db90e]:before{content:"⚙️"}.echo-icon--heart[data-v-cf0db90e]:before{content:"❤️"}.echo-icon--star[data-v-cf0db90e]:before{content:"⭐"}.echo-icon--check[data-v-cf0db90e]:before{content:"✓"}.echo-icon--plus[data-v-cf0db90e]:before{content:"+"}.echo-icon--minus[data-v-cf0db90e]:before{content:"−"}.echo-icon--arrow-up[data-v-cf0db90e]:before{content:"↑"}.echo-icon--arrow-down[data-v-cf0db90e]:before{content:"↓"}.echo-icon--arrow-left[data-v-cf0db90e]:before{content:"←"}.echo-icon--arrow-right[data-v-cf0db90e]:before{content:"→"}@keyframes spin-cf0db90e{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.echo-button[data-v-131d4d78]{display:inline-flex;align-items:center;justify-content:center;gap:8px;border:1px solid transparent;border-radius:var(--echo-border-radius, 6px);font-size:var(--echo-font-size, 14px);font-weight:500;cursor:pointer;transition:all .2s ease-in-out;outline:none;-webkit-user-select:none;user-select:none}.echo-button[data-v-131d4d78]:focus{outline:2px solid var(--echo-primary-color, #1890ff);outline-offset:2px}.echo-button--small[data-v-131d4d78]{padding:6px 12px;font-size:12px;min-height:28px}.echo-button--medium[data-v-131d4d78]{padding:8px 16px;font-size:14px;min-height:32px}.echo-button--large[data-v-131d4d78]{padding:12px 20px;font-size:16px;min-height:40px}.echo-button--primary[data-v-131d4d78]{background-color:var(--echo-primary-color, #1890ff);color:#fff;border-color:var(--echo-primary-color, #1890ff)}.echo-button--primary[data-v-131d4d78]:hover:not(:disabled){background-color:var(--echo-primary-hover, #40a9ff);border-color:var(--echo-primary-hover, #40a9ff)}.echo-button--primary.echo-button--plain[data-v-131d4d78]{background-color:transparent;color:var(--echo-primary-color, #1890ff)}.echo-button--primary.echo-button--plain[data-v-131d4d78]:hover:not(:disabled){background-color:var(--echo-primary-color, #1890ff);color:#fff}.echo-button--secondary[data-v-131d4d78]{background-color:var(--echo-secondary-color, #f5f5f5);color:var(--echo-text-color, #333);border-color:var(--echo-border-color, #d9d9d9)}.echo-button--secondary[data-v-131d4d78]:hover:not(:disabled){background-color:var(--echo-secondary-hover, #e6e6e6);border-color:var(--echo-secondary-hover, #bfbfbf)}.echo-button--success[data-v-131d4d78]{background-color:var(--echo-success-color, #52c41a);color:#fff;border-color:var(--echo-success-color, #52c41a)}.echo-button--success[data-v-131d4d78]:hover:not(:disabled){background-color:var(--echo-success-hover, #73d13d);border-color:var(--echo-success-hover, #73d13d)}.echo-button--warning[data-v-131d4d78]{background-color:var(--echo-warning-color, #faad14);color:#fff;border-color:var(--echo-warning-color, #faad14)}.echo-button--warning[data-v-131d4d78]:hover:not(:disabled){background-color:var(--echo-warning-hover, #ffc53d);border-color:var(--echo-warning-hover, #ffc53d)}.echo-button--danger[data-v-131d4d78]{background-color:var(--echo-danger-color, #ff4d4f);color:#fff;border-color:var(--echo-danger-color, #ff4d4f)}.echo-button--danger[data-v-131d4d78]:hover:not(:disabled){background-color:var(--echo-danger-hover, #ff7875);border-color:var(--echo-danger-hover, #ff7875)}.echo-button--info[data-v-131d4d78]{background-color:var(--echo-info-color, #1890ff);color:#fff;border-color:var(--echo-info-color, #1890ff)}.echo-button--info[data-v-131d4d78]:hover:not(:disabled){background-color:var(--echo-info-hover, #40a9ff);border-color:var(--echo-info-hover, #40a9ff)}.echo-button--disabled[data-v-131d4d78]{opacity:.6;cursor:not-allowed;pointer-events:none}.echo-button--round[data-v-131d4d78]{border-radius:50px}.echo-button--loading[data-v-131d4d78]{cursor:wait}.echo-button__loading--spinning[data-v-131d4d78]{animation:spin-131d4d78 1s linear infinite}.echo-button__icon[data-v-131d4d78]{flex-shrink:0}.echo-button__text[data-v-131d4d78]{line-height:1}@keyframes spin-131d4d78{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.color-picker[data-v-df743242]{box-sizing:border-box;width:220px;padding:12px;border-radius:6px}.color-picker__header[data-v-df743242]{display:flex;justify-content:space-end;gap:8px;align-items:center;margin-bottom:12px;font-size:10px}.color-picker__main[data-v-df743242]{margin-bottom:12px}.color-picker__saturation-panel[data-v-df743242]{position:relative;width:100%;height:180px;margin-bottom:8px;overflow:hidden;cursor:crosshair;border-radius:4px}.color-picker__saturation-panel-black[data-v-df743242]{position:relative;width:100%;height:100%}.color-picker__saturation-panel-pointer[data-v-df743242]{position:absolute;width:12px;height:12px;pointer-events:none;border:2px solid #fff;border-radius:50%;box-shadow:0 0 0 1px #0000004d;transform:translate(-50%,-50%)}.color-picker__hue-bar[data-v-df743242]{position:relative;width:100%;height:10px;margin-bottom:8px;cursor:pointer;background:linear-gradient(to right,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red);border-radius:6px}.color-picker__hue-bar-pointer[data-v-df743242]{position:absolute;top:50%;width:12px;height:12px;pointer-events:none;background:#fff;border:2px solid rgba(0,0,0,.3);border-radius:50%;box-shadow:0 0 0 1px #fffc,0 0 0 2px #fff6,0 0 4px #ffffff4d,0 1px 2px #0003;transform:translate(-50%,-50%)}.color-picker__alpha-bar[data-v-df743242]{position:relative;width:100%;height:10px;cursor:pointer;background-image:linear-gradient(45deg,#cccccc 25%,transparent 25%),linear-gradient(-45deg,#cccccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#cccccc 75%),linear-gradient(-45deg,transparent 75%,#cccccc 75%);background-position:0 0,0 4px,4px -4px,-4px 0;background-size:8px 8px;border-radius:6px}.color-picker__alpha-bar-bg[data-v-df743242]{position:absolute;top:0;left:0;width:100%;height:100%;border-radius:5px}.color-picker__alpha-bar-pointer[data-v-df743242]{position:absolute;top:50%;width:12px;height:12px;pointer-events:none;background:#fff;border:2px solid rgba(0,0,0,.3);border-radius:50%;box-shadow:0 0 0 1px #fffc,0 0 0 2px #fff6,0 0 4px #ffffff4d,0 1px 2px #0003;transform:translate(-50%,-50%)}.color-picker__controls[data-v-df743242]{display:flex;gap:8px;align-items:center}.color-picker__controls__preview[data-v-df743242]{position:relative;width:24px;height:24px;display:block;overflow:hidden;border:1px solid rgba(0,0,0,.2);border-radius:4px}.color-picker__controls__preview-bg[data-v-df743242]{position:absolute;top:0;left:0;width:100%;height:100%;background-image:linear-gradient(45deg,#cccccc 25%,transparent 25%),linear-gradient(-45deg,#cccccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#cccccc 75%),linear-gradient(-45deg,transparent 75%,#cccccc 75%);background-position:0 0,0 4px,4px -4px,-4px 0;background-size:8px 8px}.color-picker__controls__preview-color[data-v-df743242]{position:relative;z-index:1;width:100%;height:100%}.color-picker__controls__input-group[data-v-df743242]{flex:1;height:24px;padding:0 8px;background:#fff;border:1px solid rgba(0,0,0,.3);border-radius:4px;outline:none}.color-picker__controls__input-group__input[data-v-df743242]{width:100%;height:100%;font-size:12px;line-height:24px;color:#000;background:transparent;border:none;outline:none}.color-picker__controls__input-group__input[data-v-df743242]:focus{border-color:#ffffff4d}.color-picker__controls__input-group__input[data-v-df743242]::placeholder{color:#ffffff4d}.color-picker__controls__eyedropper[data-v-df743242]{width:24px;height:24px;display:block;overflow:hidden;border:1px solid rgba(0,0,0,.2);border-radius:4px}.color-picker__controls__eyedropper-btn[data-v-df743242]{width:100%;height:100%;display:flex;padding:4px;cursor:pointer;align-items:center;justify-content:center;overflow:hidden;border:none;outline:none}.color-picker__color-list[data-v-df743242]{display:grid;grid-template-columns:repeat(10,1fr);gap:4px;margin-top:8px}.color-picker__color-list__item[data-v-df743242]{width:100%;aspect-ratio:1;cursor:pointer;border:1px solid rgba(0,0,0,.2);border-radius:3px;transition:all .2s}.color-picker__color-list__item[data-v-df743242]:hover{z-index:1;border-color:#0000004d;transform:scale(1.1)}.color-picker--dark[data-v-df743242]{background-color:#1a1a1a;border:1px solid #333}.color-picker--light[data-v-df743242]{background-color:#fff;border:1px solid #ddd}.color-picker--dark .color-picker__header[data-v-df743242]{color:#fff}.color-picker--dark .color-picker__controls__preview[data-v-df743242],.color-picker--dark .color-picker__color-list__item[data-v-df743242]{border-color:#ffffff4d}.echo-dropdown[data-v-f896e925]{position:relative;display:inline-block}.echo-dropdown.is-disabled[data-v-f896e925]{cursor:not-allowed;opacity:.6}.echo-dropdown.is-visible[data-v-f896e925]{z-index:1000}.echo-dropdown__trigger[data-v-f896e925]{cursor:pointer;-webkit-user-select:none;user-select:none}.echo-dropdown__trigger.is-disabled[data-v-f896e925]{cursor:not-allowed;opacity:.6}.echo-dropdown__menu[data-v-f896e925]{position:fixed;z-index:1000;background:#fff;border-radius:4px;box-shadow:0 2px 8px #0000001a;padding:4px 0;margin:0;min-width:120px;max-height:300px;overflow-y:auto}.echo-dropdown__menu__list[data-v-f896e925]{list-style:none;margin:0;padding:0}.echo-dropdown__menu__list__item[data-v-f896e925]{display:flex;gap:8px;align-items:center;padding:8px 12px;cursor:pointer;transition:all .2s;color:#333;font-size:14px;line-height:1.5}.echo-dropdown__menu__list__item[data-v-f896e925]:hover:not(.is-disabled){background-color:#f5f7fa}.echo-dropdown__menu__list__item.is-disabled[data-v-f896e925]{cursor:not-allowed;color:#c0c4cc}.echo-dropdown__menu__list__item.is-divider[data-v-f896e925]{border-top:1px solid #e4e7ed;margin-top:4px;padding-top:4px}.echo-dropdown__menu__list__item__icon[data-v-f896e925]{flex-shrink:0}.echo-dropdown__menu__list__item__label[data-v-f896e925]{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.echo-dropdown-fade-enter-active[data-v-f896e925],.echo-dropdown-fade-leave-active[data-v-f896e925]{transition:opacity .2s,transform .2s}.echo-dropdown-fade-enter-from[data-v-f896e925],.echo-dropdown-fade-leave-to[data-v-f896e925]{opacity:0;transform:translateY(-10px) scale(.95)}.echo-input[data-v-52972a06]{display:inline-block;width:100%;position:relative}.echo-input--small .echo-input__wrapper[data-v-52972a06]{height:28px}.echo-input--small .echo-input__inner[data-v-52972a06]{font-size:12px;padding:4px 8px}.echo-input--medium .echo-input__wrapper[data-v-52972a06]{height:32px}.echo-input--medium .echo-input__inner[data-v-52972a06]{font-size:14px;padding:6px 12px}.echo-input--large .echo-input__wrapper[data-v-52972a06]{height:40px}.echo-input--large .echo-input__inner[data-v-52972a06]{font-size:16px;padding:8px 16px}.echo-input--disabled .echo-input__wrapper[data-v-52972a06]{background-color:var(--echo-disabled-bg, #f5f5f5);cursor:not-allowed}.echo-input--disabled .echo-input__inner[data-v-52972a06]{cursor:not-allowed;color:var(--echo-disabled-color, #c0c4cc)}.echo-input--with-prefix .echo-input__inner[data-v-52972a06]{padding-left:32px}.echo-input--with-suffix .echo-input__inner[data-v-52972a06]{padding-right:32px}.echo-input__wrapper[data-v-52972a06]{position:relative;display:flex;align-items:center;background-color:#fff;border:1px solid var(--echo-border-color, #d9d9d9);border-radius:var(--echo-border-radius, 6px);transition:all .2s ease-in-out}.echo-input__wrapper[data-v-52972a06]:hover{border-color:var(--echo-primary-color, #1890ff)}.echo-input__wrapper[data-v-52972a06]:focus-within{border-color:var(--echo-primary-color, #1890ff);box-shadow:0 0 0 2px #1890ff33}.echo-input__inner[data-v-52972a06]{flex:1;border:none;outline:none;background:transparent;color:var(--echo-text-color, #333);line-height:1.5}.echo-input__inner[data-v-52972a06]::placeholder{color:var(--echo-placeholder-color, #c0c4cc)}.echo-input__inner--disabled[data-v-52972a06]{background-color:transparent;color:var(--echo-disabled-color, #c0c4cc)}.echo-input__prefix-icon[data-v-52972a06],.echo-input__suffix-icon[data-v-52972a06]{position:absolute;top:50%;transform:translateY(-50%);color:var(--echo-icon-color, #c0c4cc);font-size:16px;pointer-events:none}.echo-input__prefix-icon[data-v-52972a06]{left:8px}.echo-input__suffix-icon[data-v-52972a06]{right:8px}.echo-input__clear[data-v-52972a06]{position:absolute;right:8px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;color:var(--echo-icon-color, #c0c4cc);font-size:14px;padding:2px;border-radius:50%;transition:all .2s ease-in-out}.echo-input__clear[data-v-52972a06]:hover{background-color:var(--echo-hover-bg, #f5f5f5);color:var(--echo-text-color, #333)}.echo-input__word-limit[data-v-52972a06]{margin-top:4px;font-size:12px;color:var(--echo-text-secondary, #666);text-align:right}
|
package/package.json
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "echo-library-vue",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "一个基于 Vue 3 + TypeScript 的现代化组件库",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.umd.js",
|
|
7
|
+
"module": "dist/index.esm.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"dev": "vite",
|
|
14
|
+
"build": "vue-tsc && vite build",
|
|
15
|
+
"build:lib": "vue-tsc && vite build --config vite.lib.config.ts",
|
|
16
|
+
"preview": "vite preview",
|
|
17
|
+
"test": "vitest",
|
|
18
|
+
"test:ui": "vitest --ui",
|
|
19
|
+
"test:coverage": "vitest --coverage",
|
|
20
|
+
"test:run": "vitest run",
|
|
21
|
+
"test:watch": "vitest --watch",
|
|
22
|
+
"docs:dev": "vitepress dev docs",
|
|
23
|
+
"docs:build": "vitepress build docs",
|
|
24
|
+
"docs:preview": "vitepress preview docs",
|
|
25
|
+
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
|
26
|
+
"format": "prettier --write packages/",
|
|
27
|
+
"type-check": "vue-tsc --noEmit",
|
|
28
|
+
"clean": "rimraf dist",
|
|
29
|
+
"prepare": "husky install",
|
|
30
|
+
"prepublishOnly": "npm run build:lib",
|
|
31
|
+
"commit": "git-cz",
|
|
32
|
+
"commitlint": "commitlint --edit",
|
|
33
|
+
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,vue,json,scss,css,md}\" --ignore-path .prettierignore",
|
|
34
|
+
"lint:check": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --ignore-path .gitignore",
|
|
35
|
+
"ci:format": "prettier --check \"**/*.{js,jsx,ts,tsx,vue,json,scss,css,md}\" --ignore-path .prettierignore"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"vue",
|
|
39
|
+
"vue3",
|
|
40
|
+
"typescript",
|
|
41
|
+
"component-library",
|
|
42
|
+
"ui-components"
|
|
43
|
+
],
|
|
44
|
+
"author": "Echo",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@commitlint/cli": "^19.8.1",
|
|
48
|
+
"@commitlint/config-conventional": "^19.8.1",
|
|
49
|
+
"@types/node": "^20.10.0",
|
|
50
|
+
"@typescript-eslint/eslint-plugin": "^6.13.0",
|
|
51
|
+
"@typescript-eslint/parser": "^6.13.0",
|
|
52
|
+
"@vitejs/plugin-vue": "^4.5.0",
|
|
53
|
+
"@vitest/coverage-v8": "^1.6.1",
|
|
54
|
+
"@vitest/ui": "^1.0.0",
|
|
55
|
+
"@vue/eslint-config-prettier": "^8.0.0",
|
|
56
|
+
"@vue/eslint-config-typescript": "^12.0.0",
|
|
57
|
+
"@vue/test-utils": "^2.4.0",
|
|
58
|
+
"commitizen": "^4.3.1",
|
|
59
|
+
"cz-conventional-changelog": "^3.3.0",
|
|
60
|
+
"eslint": "^8.54.0",
|
|
61
|
+
"eslint-plugin-vue": "^9.18.0",
|
|
62
|
+
"husky": "^9.1.7",
|
|
63
|
+
"jsdom": "^23.0.0",
|
|
64
|
+
"lint-staged": "^16.1.2",
|
|
65
|
+
"prettier": "^3.1.0",
|
|
66
|
+
"rimraf": "^5.0.0",
|
|
67
|
+
"sass": "^1.69.0",
|
|
68
|
+
"typescript": "~5.3.0",
|
|
69
|
+
"unplugin-auto-import": "^20.3.0",
|
|
70
|
+
"unplugin-vue-components": "^30.0.0",
|
|
71
|
+
"vite": "^5.0.0",
|
|
72
|
+
"vite-plugin-dts": "^3.7.0",
|
|
73
|
+
"vitepress": "^1.0.0",
|
|
74
|
+
"vitest": "^1.0.0",
|
|
75
|
+
"vue-tsc": "^1.8.0"
|
|
76
|
+
},
|
|
77
|
+
"dependencies": {
|
|
78
|
+
"vue": "^3.3.0"
|
|
79
|
+
},
|
|
80
|
+
"peerDependencies": {
|
|
81
|
+
"vue": "^3.3.0"
|
|
82
|
+
},
|
|
83
|
+
"engines": {
|
|
84
|
+
"node": ">=16.0.0",
|
|
85
|
+
"npm": ">=8.0.0"
|
|
86
|
+
},
|
|
87
|
+
"lint-staged": {
|
|
88
|
+
"*.{js,jsx,ts,tsx,vue}": [
|
|
89
|
+
"prettier --write"
|
|
90
|
+
],
|
|
91
|
+
"*.{json,md,scss,css}": [
|
|
92
|
+
"prettier --write"
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
"config": {
|
|
96
|
+
"commitizen": {
|
|
97
|
+
"path": "cz-conventional-changelog"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"exports": {
|
|
101
|
+
".": {
|
|
102
|
+
"import": "./dist/index.esm.js",
|
|
103
|
+
"require": "./dist/index.umd.js",
|
|
104
|
+
"types": "./dist/index.d.ts"
|
|
105
|
+
},
|
|
106
|
+
"./style.css": "./dist/style.css"
|
|
107
|
+
},
|
|
108
|
+
"sideEffects": [
|
|
109
|
+
"**/*.css",
|
|
110
|
+
"**/*.scss"
|
|
111
|
+
],
|
|
112
|
+
"repository": {
|
|
113
|
+
"type": "git",
|
|
114
|
+
"url": "https://github.com/1193082625/echo-library-vue.git"
|
|
115
|
+
},
|
|
116
|
+
"bugs": {
|
|
117
|
+
"url": "https://github.com/1193082625/echo-library-vue/issues"
|
|
118
|
+
},
|
|
119
|
+
"homepage": "https://github.com/1193082625/echo-library-vue#readme"
|
|
120
|
+
}
|