From e0a0dea76f9a21097e11df2fdd803cf3ba89d63d Mon Sep 17 00:00:00 2001 From: "jlj05024111@163.com" Date: Thu, 5 Dec 2024 16:26:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=A2=9C=E8=89=B2=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=99=A8=E6=96=B0=E5=A2=9E=E6=94=AF=E6=8C=81=E4=B8=A4=E7=A7=8D?= =?UTF-8?q?=E5=A4=9A=E9=80=89=E6=A8=A1=E5=BC=8F=EF=BC=8C=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E5=8F=82=E6=95=B0MULTIPLE=3Dtrue?= =?UTF-8?q?=E5=8D=B3=E5=8F=AF=EF=BC=8C=E9=BB=98=E8=AE=A4=E6=83=85=E5=86=B5?= =?UTF-8?q?=E4=B8=8B=E4=B8=BA=E4=B8=8B=E6=8B=89=E9=80=89=E6=8B=A9=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E9=A2=9C=E8=89=B2=E6=95=B0=E7=BB=84=EF=BC=8C=E5=BD=93?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E7=BC=96=E8=BE=91=E5=99=A8=E5=8F=82=E6=95=B0?= =?UTF-8?q?CUSTOM=3Dtrue=E6=97=B6=EF=BC=8C=E5=8F=AF=E4=BB=A5=E6=BF=80?= =?UTF-8?q?=E6=B4=BB=E5=8F=A6=E4=B8=80=E7=A7=8D=E5=A4=9A=E9=80=89=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=EF=BC=8C=E8=AF=A5=E6=A8=A1=E5=BC=8F=E4=B8=8B=E5=8F=AF?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E4=B8=80=E4=B8=AA=E9=A2=9C=E8=89=B2?= =?UTF-8?q?=E6=95=B0=E7=BB=84=E4=B8=AD=E6=89=80=E6=9C=89=E9=A1=B9=E7=9A=84?= =?UTF-8?q?=E9=A2=9C=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 + .../ibiz-color-mpicker-custom.scss | 69 +++++ .../ibiz-color-mpicker-custom.tsx | 210 +++++++++++++ .../ibiz-color-mpicker-default.scss | 42 +++ .../ibiz-color-mpicker-default.tsx | 278 ++++++++++++++++++ .../ibiz-color-picker/ibiz-color-picker.tsx | 69 ++++- src/locale/en/index.ts | 10 + src/locale/zh-CN/index.ts | 10 + 8 files changed, 686 insertions(+), 4 deletions(-) create mode 100644 src/editor/color-picker/ibiz-color-mpicker-custom/ibiz-color-mpicker-custom.scss create mode 100644 src/editor/color-picker/ibiz-color-mpicker-custom/ibiz-color-mpicker-custom.tsx create mode 100644 src/editor/color-picker/ibiz-color-mpicker-default/ibiz-color-mpicker-default.scss create mode 100644 src/editor/color-picker/ibiz-color-mpicker-default/ibiz-color-mpicker-default.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cc60008d..846bc9cae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ ## [Unreleased] ### Added + +- 颜色选择器新增支持两种多选模式,设置编辑器参数MULTIPLE=true即可,默认情况下为下拉选择一个颜色数组,当设置编辑器参数CUSTOM=true时,可以激活另一种多选模式,该模式下可自定义一个颜色数组中所有项的颜色 - 新增自定义视图和门户视图预置刷新功能 ### Fixed diff --git a/src/editor/color-picker/ibiz-color-mpicker-custom/ibiz-color-mpicker-custom.scss b/src/editor/color-picker/ibiz-color-mpicker-custom/ibiz-color-mpicker-custom.scss new file mode 100644 index 000000000..a3797536f --- /dev/null +++ b/src/editor/color-picker/ibiz-color-mpicker-custom/ibiz-color-mpicker-custom.scss @@ -0,0 +1,69 @@ +@include b('color-mpicker-custom') { + display: flex; + gap: getCssVar(spacing, base); + @include e('tabs') { + flex-shrink: 0; + @include m('tab') { + height: 30px; + cursor: pointer; + + @include when('selected') { + color: getCssVar(color, primary); + } + } + } + @include e('anchor') { + position: relative; + height: max-content; + + &::before { + position: absolute; + top: 0; + right: -10px; + width: 3px; + height: 50%; + content: ''; + background-color: getCssVar(color, primary); + transition: all ease 0.3s; + } + + &::after { + position: absolute; + top: 0; + right: -10px; + width: 3px; + height: 100%; + content: ''; + background-color: getCssVar(color, border); + } + + @include when('select-text') { + &::before { + top: 50%; + } + } + } + @include e('content') { + flex: 1; + padding: 0 getCssVar(spacing, base); + } + @include e('color-list') { + display: flex; + flex-wrap: wrap; + gap: getCssVar(spacing, extra-tight); + @include m('add') { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + cursor: pointer; + border: 1px solid getCssVar(color, border); + border-radius: 4px; + + &:hover{ + border-color: getCssVar(color,primary); + } + } + } +} diff --git a/src/editor/color-picker/ibiz-color-mpicker-custom/ibiz-color-mpicker-custom.tsx b/src/editor/color-picker/ibiz-color-mpicker-custom/ibiz-color-mpicker-custom.tsx new file mode 100644 index 000000000..b85b2980a --- /dev/null +++ b/src/editor/color-picker/ibiz-color-mpicker-custom/ibiz-color-mpicker-custom.tsx @@ -0,0 +1,210 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +import { useNamespace } from '@ibiz-template/vue3-util'; +import { defineComponent, ref, watch } from 'vue'; +import './ibiz-color-mpicker-custom.scss'; + +export const IBizColorMPickerCustom = defineComponent({ + name: 'IBizColorMPickerCustom', + props: { + value: { + type: Array, + }, + readonly: { + type: Boolean, + default: false, + }, + disabled: { + type: Boolean, + default: false, + }, + }, + emits: ['change'], + setup(props, { emit }) { + const ns = useNamespace('color-mpicker-custom'); + + // 选择类型 + const tabs: IData[] = [ + { + text: ibiz.i18n.t('editor.colorPicker.selector'), + value: 'select', + }, + { + text: ibiz.i18n.t('editor.colorPicker.textValue'), + value: 'write', + }, + ]; + + // 默认提供待选颜色 + const predefineColors = ref([ + '#000000', + '#2C2C2C', + '#50555C', + '#ACB3BF', + '#D0D3D9', + '#C4C4C4', + '#DADADA', + '#E5E5E5', + '#F0F0F0', + '#F24E1E', + '#E99C58', + '#FFC700', + '#FF4D00', + '#FF00D6', + '#D82E57', + '#8E1DE8', + '#0ACF83', + '#18A0FB', + '#A259FF', + '#907CFF', + ]); + + // 颜色列表 + const items = ref([]); + + // 当前选中类型--选择器,文本值 + const curSelect = ref('select'); + + // 文本框的值 + const colorStr = ref(''); + + // 颜色选择 + const onColorChange = (index: number, value: string) => { + items.value[index] = value; + emit('change', items.value); + }; + + // 切换类型 + const onSelect = (value: string) => { + curSelect.value = value; + if (value === 'select') { + // 切换到选择器 + const list = colorStr.value.split(','); + items.value = list.filter((item: string) => { + return /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/.test(item); + }); + } else { + // 切换到文本值 + colorStr.value = items.value.toString(); + } + }; + + // 新增颜色项 + const onAdd = () => { + if (props.readonly || props.disabled) { + return; + } + items.value.push('#FFFFFF'); + emit('change', items.value); + }; + + // 文本域失去焦点 + const onBlur = () => { + if (curSelect.value === 'select') { + emit('change', items.value); + } else { + const list = colorStr.value.split(','); + items.value = list.filter((item: string) => { + return /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/.test(item); + }); + emit('change', items.value); + } + }; + + // 绘制颜色选择列表 + const renderColorList = () => { + return items.value.map((item: string, index: number) => { + return ( +
+ onColorChange(index, value)} + /> +
+ ); + }); + }; + + // 监听值变化 + watch( + () => props.value, + () => { + if (!props.value || props.value.length === 0) { + colorStr.value = ''; + items.value = []; + } else { + items.value = props.value; + colorStr.value = items.value.toString(); + } + }, + { immediate: true, deep: true }, + ); + + return { + ns, + tabs, + curSelect, + colorStr, + renderColorList, + onSelect, + onAdd, + onBlur, + }; + }, + render() { + return ( +
+
+
+ {this.tabs.map((tab: IData) => { + return ( +
this.onSelect(tab.value)} + > + {tab.text} +
+ ); + })} +
+
+
+ {this.curSelect === 'select' ? ( +
+ {this.renderColorList()} +
+ +
+
+ ) : ( +
+ +
+ )} +
+
+ ); + }, +}); diff --git a/src/editor/color-picker/ibiz-color-mpicker-default/ibiz-color-mpicker-default.scss b/src/editor/color-picker/ibiz-color-mpicker-default/ibiz-color-mpicker-default.scss new file mode 100644 index 000000000..28bf6414d --- /dev/null +++ b/src/editor/color-picker/ibiz-color-mpicker-default/ibiz-color-mpicker-default.scss @@ -0,0 +1,42 @@ +@include b(color-mpicker-default-template-color-picker) { + .el-select__prefix { + display: flex; + } + @include e(icon) { + display: block; + width: calc( + getCssVar('spacing', 'base-tight') + getCssVar('spacing', 'super-tight') + ); + height: calc( + getCssVar('spacing', 'base-tight') + getCssVar('spacing', 'super-tight') + ); + margin-right: getCssVar('spacing', 'tight'); + border-radius: getCssVar(border, radius, extra, small); + + &:last-of-type { + margin-right: getCssVar('spacing', 'none'); + } + } +} +@include b(color-mpicker-default-template-color-picker-option) { + display: flex; + align-items: center; +} + +.el-popper.is-light { + @include b(color-mpicker-default-popper) { + .el-select-dropdown__list { + margin: getCssVar('spacing', 'base-tight') getCssVar('spacing', 'none') !important; + } + + .el-select-dropdown__item { + height: getCssVar('height-control', 'large'); + padding: getCssVar('spacing', 'none') getCssVar('spacing', 'base-loose'); + line-height: getCssVar('height-control', 'large'); + + &.selected { + background-color: getCssVar(color, primary, light, default); + } + } + } +} diff --git a/src/editor/color-picker/ibiz-color-mpicker-default/ibiz-color-mpicker-default.tsx b/src/editor/color-picker/ibiz-color-mpicker-default/ibiz-color-mpicker-default.tsx new file mode 100644 index 000000000..a9db71ba6 --- /dev/null +++ b/src/editor/color-picker/ibiz-color-mpicker-default/ibiz-color-mpicker-default.tsx @@ -0,0 +1,278 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +import { useNamespace } from '@ibiz-template/vue3-util'; +import { defineComponent, ref, watch, computed, PropType } from 'vue'; +import './ibiz-color-mpicker-default.scss'; + +export const IBizColorMPickerDefault = defineComponent({ + name: 'IBizColorMPickerDefault', + props: { + value: { + type: [Array, String], + }, + customColorList: { + type: String, + }, + type: { + type: String as PropType<'ITEM' | 'ITEMS'>, + default: 'ITEMS', + }, + readonly: { + type: Boolean, + default: false, + }, + disabled: { + type: Boolean, + default: false, + }, + }, + emits: ['change'], + setup(props, { emit }) { + const ns = useNamespace('color-mpicker-default'); + + // 选择的类型 + const curType = ref('default'); + + // 选择的模板颜色 + const curTemplateColor = ref(''); + + const showTemplateList = ref(false); + + // 颜色类型 + const colorType: IData[] = [ + { + text: ibiz.i18n.t('editor.colorPicker.systemColor'), + value: 'default', + }, + { + text: ibiz.i18n.t('editor.colorPicker.templateColor'), + value: 'template', + }, + ]; + + // 模板配色 + const templateColorList = computed(() => { + if (props.customColorList) { + return JSON.parse(props.customColorList); + } + return [ + { + text: ibiz.i18n.t('editor.colorPicker.simpleBlue'), + value: + props.type === 'ITEM' + ? ['#6698FF'] + : [ + '#6698FF', + '#73DEB3', + '#7585A2', + '#F7BE21', + '#EE734A', + '#83D0EE', + ], + }, + { + text: ibiz.i18n.t('editor.colorPicker.autumnOrange'), + value: + props.type === 'ITEM' + ? ['#EE734A'] + : [ + '#EE734A', + '#7585A2', + '#FEC103', + '#9EB411', + '#CD8050', + '#DAD5B5', + ], + }, + { + text: ibiz.i18n.t('editor.colorPicker.Macaroon'), + value: + props.type === 'ITEM' + ? ['#467CE6'] + : [ + '#467CE6', + '#CD74CA', + '#4997CC', + '#BCBFE3', + '#666CEB', + '#82BC9A', + ], + }, + { + text: ibiz.i18n.t('editor.colorPicker.mintGreen'), + value: + props.type === 'ITEM' + ? ['#118299'] + : [ + '#118299', + '#13B3B3', + '#73DEB3', + '#FEC103', + '#9EB411', + '#83D0EE', + ], + }, + ]; + }); + + // 模板颜色切换 + const handleTemplateColorChange = () => { + const temmpVal = JSON.parse(curTemplateColor.value); + emit('change', temmpVal); + }; + + // 类型切换 + const handleSchemeChange = () => { + if (curType.value === 'default') { + showTemplateList.value = false; + emit('change', templateColorList.value[0]?.value?.[0]); + } else { + showTemplateList.value = true; + } + }; + + watch( + () => props.value, + () => { + if (props.value) { + if (typeof props.value === 'string') { + // 系统的 + curType.value = 'default'; + showTemplateList.value = false; + } else { + // 模板的 + curType.value = 'template'; + showTemplateList.value = true; + if (props.value.length > 0) { + curTemplateColor.value = JSON.stringify(props.value); + } + } + } else { + curType.value = 'default'; + showTemplateList.value = false; + } + }, + { + immediate: true, + deep: true, + }, + ); + + return { + ns, + curType, + curTemplateColor, + showTemplateList, + colorType, + templateColorList, + handleTemplateColorChange, + handleSchemeChange, + }; + }, + render() { + return ( +
+ + {{ + default: () => { + return this.colorType.map(scheme => { + return ( + + ); + }); + }, + }} + + {this.showTemplateList && ( + + {{ + default: () => { + return this.templateColorList.map((color: IData) => { + return ( + + {{ + default: () => { + return ( +
+ {Array.isArray(color.value) ? ( + color.value.map(item => ( +
+ )) + ) : ( +
+ )} + +
+ {color.text} +
+
+ ); + }, + }} +
+ ); + }); + }, + prefix: () => { + if (this.curTemplateColor) { + const colors = JSON.parse(this.curTemplateColor); + return Array.isArray(colors) ? ( + colors.map(item => ( +
+ )) + ) : ( +
+ {colors[0]} +
+ ); + } + }, + }} +
+ )} +
+ ); + }, +}); diff --git a/src/editor/color-picker/ibiz-color-picker/ibiz-color-picker.tsx b/src/editor/color-picker/ibiz-color-picker/ibiz-color-picker.tsx index d1cdfea9d..252597a7e 100644 --- a/src/editor/color-picker/ibiz-color-picker/ibiz-color-picker.tsx +++ b/src/editor/color-picker/ibiz-color-picker/ibiz-color-picker.tsx @@ -6,6 +6,8 @@ import { } from '@ibiz-template/vue3-util'; import './ibiz-color-picker.scss'; import { ColorPickerEditorController } from '../color-picker-editor.controller'; +import { IBizColorMPickerCustom } from '../ibiz-color-mpicker-custom/ibiz-color-mpicker-custom'; +import { IBizColorMPickerDefault } from '../ibiz-color-mpicker-default/ibiz-color-mpicker-default'; export const IBizColorPicker = defineComponent({ name: 'IBizColorPicker', @@ -16,10 +18,26 @@ export const IBizColorPicker = defineComponent({ const c = props.controller; - const currentVal = ref(''); + const currentVal = ref(''); const colorPicker: Ref = ref(null); + // 是否多选 + const multiple = c.editorParams?.MULTIPLE === 'true'; + + // 是否自定义模式 + const isCustom = c.editorParams?.CUSTOM === 'true'; + + // 设置下拉选择的颜色数组是否仅有一个,TYPE值为ITEM | ITEMS + const type = c.editorParams?.TYPE; + + // 自定义颜色列表值,这个值格式是一个字符串json数组, + /** + * 配置示例: + * CUSTOMCOLORLIST = [{"text":"颜色名字","value":["#123123","#111222","#333322","#11ff33"]}] + */ + const customColorList = c.editorParams?.CUSTOMCOLORLIST || ''; + const predefineColors = ref([ '#000000', '#2C2C2C', @@ -59,7 +77,17 @@ export const IBizColorPicker = defineComponent({ () => props.value, (newVal, oldVal) => { if (newVal !== oldVal) { - if (!newVal) { + if (multiple) { + if (!newVal) { + if (isCustom) { + currentVal.value = []; + } else { + currentVal.value = ''; + } + } else { + currentVal.value = newVal; + } + } else if (!newVal) { currentVal.value = ''; } else { currentVal.value = newVal; @@ -69,6 +97,7 @@ export const IBizColorPicker = defineComponent({ { immediate: true }, ); + // 值改变抛值 const handleChange = (e: string | null) => { emit('change', e); }; @@ -99,6 +128,10 @@ export const IBizColorPicker = defineComponent({ emit('blur', e); }; + const onChange = (value: string | string[]) => { + emit('change', value); + }; + return { ns, c, @@ -106,18 +139,46 @@ export const IBizColorPicker = defineComponent({ predefineColors, contentStyle, colorPicker, + multiple, + isCustom, + customColorList, + type, handleChange, showPicker, onFocus, onBlur, showFormDefaultContent, + onChange, }; }, render() { + if (this.multiple) { + if (this.isCustom) { + return ( + + ); + } + return ( + + ); + } + let content = null; if (this.readonly) { // 只读显示 - content = `${this.currentVal}`; + content = `${this.currentVal?.toString()}`; } else { // 编辑态显示 content = ( @@ -151,7 +212,7 @@ export const IBizColorPicker = defineComponent({ this.readonly ? this.ns.m('readonly') : '', this.ns.is('show-default', this.showFormDefaultContent), ]} - style={{ color: this.currentVal || '' }} + style={{ color: (this.currentVal as string) || '' }} > {content} diff --git a/src/locale/en/index.ts b/src/locale/en/index.ts index 008848b08..1a9bd500b 100644 --- a/src/locale/en/index.ts +++ b/src/locale/en/index.ts @@ -658,6 +658,16 @@ export default { emojiPicker: { addEmoji: 'Add emoji', }, + colorPicker: { + systemColor: 'System Color', + templateColor: 'Template Color', + simpleBlue: 'Simple Blue', + autumnOrange: 'Autumn Orange', + Macaroon: 'Macaroon', + mintGreen: 'Mint Green', + selector: 'Selector', + textValue: 'Text', + }, }, panelComponent: { authUserinfo: { diff --git a/src/locale/zh-CN/index.ts b/src/locale/zh-CN/index.ts index 029122329..db2c76187 100644 --- a/src/locale/zh-CN/index.ts +++ b/src/locale/zh-CN/index.ts @@ -614,6 +614,16 @@ export default { emojiPicker: { addEmoji: '添加表情', }, + colorPicker: { + systemColor: '系统配色', + templateColor: '模板配色', + simpleBlue: '简约蓝', + autumnOrange: '秋日橙', + Macaroon: '马卡龙', + mintGreen: '薄荷绿', + selector: '选择器', + textValue: '文本值', + }, }, panelComponent: { authUserinfo: { -- Gitee