Commit 1418dc6a597a8410711359f07ae66f0fea858977
1 parent
970d4049
feat(icon): added svg icon picker
Showing
12 changed files
with
378 additions
and
354 deletions
.vscode/settings.json
... | ... | @@ -105,17 +105,12 @@ |
105 | 105 | }, |
106 | 106 | "stylelint.enable": true, |
107 | 107 | "stylelint.packageManager": "yarn", |
108 | - "css.validate": true, | |
109 | - "less.validate": true, | |
110 | - "scss.validate": true, | |
111 | 108 | // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ |
112 | 109 | // =========================================== |
113 | 110 | // ================ Eslint =================== |
114 | 111 | // =========================================== |
115 | - // "eslint.enable": true, | |
116 | 112 | "eslint.alwaysShowStatus": true, |
117 | 113 | "eslint.options": { |
118 | - // 配置 | |
119 | 114 | "plugins": ["html", "vue", "javascript", "jsx", "typescript"], |
120 | 115 | "extensions": [".js", ".jsx", ".ts", ".tsx", ".vue"] |
121 | 116 | }, |
... | ... | @@ -127,7 +122,6 @@ |
127 | 122 | "html", |
128 | 123 | "vue" |
129 | 124 | ], |
130 | - // "eslint.autoFixOnSave": true, | |
131 | 125 | // =========================================== |
132 | 126 | // ================ Vetur ==================== |
133 | 127 | // =========================================== |
... | ... | @@ -139,7 +133,6 @@ |
139 | 133 | "vetur.format.defaultFormatter.ts": "prettier-tslint", |
140 | 134 | "vetur.format.defaultFormatter.js": "prettier", |
141 | 135 | "vetur.languageFeatures.codeActions": false, |
142 | - // "vetur.validation.script": false, | |
143 | 136 | "vetur.format.defaultFormatterOptions": { |
144 | 137 | "js-beautify-html": { |
145 | 138 | "wrap_attributes": "force-expand-multiline" |
... | ... | @@ -201,6 +194,6 @@ |
201 | 194 | "i18n-ally.namespace": true, |
202 | 195 | "i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}", |
203 | 196 | "i18n-ally.enabledParsers": ["ts"], |
204 | - "i18n-ally.sourceLanguage": "zh", | |
197 | + "i18n-ally.sourceLanguage": "en", | |
205 | 198 | "i18n-ally.enabledFrameworks": ["vue", "react"] |
206 | 199 | } | ... | ... |
CHANGELOG.zh_CN.md
package.json
... | ... | @@ -53,7 +53,7 @@ |
53 | 53 | "devDependencies": { |
54 | 54 | "@commitlint/cli": "^12.0.1", |
55 | 55 | "@commitlint/config-conventional": "^12.0.1", |
56 | - "@iconify/json": "^1.1.313", | |
56 | + "@iconify/json": "^1.1.314", | |
57 | 57 | "@ls-lint/ls-lint": "^1.9.2", |
58 | 58 | "@purge-icons/generated": "^0.7.0", |
59 | 59 | "@types/crypto-js": "^4.0.1", |
... | ... | @@ -110,7 +110,7 @@ |
110 | 110 | "vite-plugin-purge-icons": "^0.7.0", |
111 | 111 | "vite-plugin-pwa": "^0.5.6", |
112 | 112 | "vite-plugin-style-import": "^0.8.1", |
113 | - "vite-plugin-svg-icons": "^0.3.3", | |
113 | + "vite-plugin-svg-icons": "^0.3.4", | |
114 | 114 | "vite-plugin-theme": "^0.4.8", |
115 | 115 | "vite-plugin-windicss": "0.7.1", |
116 | 116 | "vue-eslint-parser": "^7.6.0", |
... | ... | @@ -120,7 +120,7 @@ |
120 | 120 | "//": "Used to install imagemin dependencies, because imagemin may not be installed in China.If it is abroad, you can delete it", |
121 | 121 | "bin-wrapper": "npm:bin-wrapper-china", |
122 | 122 | "esbuild": "0.8.57", |
123 | - "rollup": "2.40.0" | |
123 | + "rollup": "2.41.0" | |
124 | 124 | }, |
125 | 125 | "repository": { |
126 | 126 | "type": "git", | ... | ... |
src/components/Application/src/search/AppSearch.vue
src/components/Application/src/search/AppSearchFooter.vue
... | ... | @@ -14,14 +14,13 @@ |
14 | 14 | |
15 | 15 | <script lang="ts"> |
16 | 16 | import { defineComponent } from 'vue'; |
17 | - import Icon from '/@/components/Icon'; | |
18 | 17 | import AppSearchKeyItem from './AppSearchKeyItem.vue'; |
19 | 18 | |
20 | 19 | import { useDesign } from '/@/hooks/web/useDesign'; |
21 | 20 | import { useI18n } from '/@/hooks/web/useI18n'; |
22 | 21 | export default defineComponent({ |
23 | 22 | name: 'AppSearchFooter', |
24 | - components: { Icon, AppSearchKeyItem }, | |
23 | + components: { AppSearchKeyItem }, | |
25 | 24 | setup() { |
26 | 25 | const { prefixCls } = useDesign('app-search-footer'); |
27 | 26 | const { t } = useI18n(); | ... | ... |
src/components/Form/src/BasicForm.vue
... | ... | @@ -47,7 +47,7 @@ |
47 | 47 | nextTick, |
48 | 48 | } from 'vue'; |
49 | 49 | import { Form, Row } from 'ant-design-vue'; |
50 | - import FormItem from './components/FormItem'; | |
50 | + import FormItem from './components/FormItem.vue'; | |
51 | 51 | import FormAction from './components/FormAction.vue'; |
52 | 52 | |
53 | 53 | import { dateItemType } from './helper'; | ... | ... |
src/components/Form/src/components/FormItem.tsx renamed to src/components/Form/src/components/FormItem.vue
1 | -import type { PropType, Ref } from 'vue'; | |
2 | -import type { FormActionType, FormProps } from '../types/form'; | |
3 | -import type { FormSchema } from '../types/form'; | |
4 | -import type { ValidationRule } from 'ant-design-vue/lib/form/Form'; | |
5 | -import type { TableActionType } from '/@/components/Table'; | |
6 | - | |
7 | -import { defineComponent, computed, unref, toRefs } from 'vue'; | |
8 | -import { Form, Col } from 'ant-design-vue'; | |
9 | -import { componentMap } from '../componentMap'; | |
10 | -import { BasicHelp } from '/@/components/Basic'; | |
11 | - | |
12 | -import { isBoolean, isFunction } from '/@/utils/is'; | |
13 | -import { getSlot } from '/@/utils/helper/tsxHelper'; | |
14 | -import { createPlaceholderMessage, setComponentRuleType } from '../helper'; | |
15 | -import { upperFirst, cloneDeep } from 'lodash-es'; | |
16 | - | |
17 | -import { useItemLabelWidth } from '../hooks/useLabelWidth'; | |
18 | -import { useI18n } from '/@/hooks/web/useI18n'; | |
19 | - | |
20 | -export default defineComponent({ | |
21 | - name: 'BasicFormItem', | |
22 | - inheritAttrs: false, | |
23 | - props: { | |
24 | - schema: { | |
25 | - type: Object as PropType<FormSchema>, | |
26 | - default: () => {}, | |
1 | +<script lang="tsx"> | |
2 | + import type { PropType, Ref } from 'vue'; | |
3 | + import type { FormActionType, FormProps } from '../types/form'; | |
4 | + import type { FormSchema } from '../types/form'; | |
5 | + import type { ValidationRule } from 'ant-design-vue/lib/form/Form'; | |
6 | + import type { TableActionType } from '/@/components/Table'; | |
7 | + | |
8 | + import { defineComponent, computed, unref, toRefs } from 'vue'; | |
9 | + import { Form, Col } from 'ant-design-vue'; | |
10 | + import { componentMap } from '../componentMap'; | |
11 | + import { BasicHelp } from '/@/components/Basic'; | |
12 | + | |
13 | + import { isBoolean, isFunction } from '/@/utils/is'; | |
14 | + import { getSlot } from '/@/utils/helper/tsxHelper'; | |
15 | + import { createPlaceholderMessage, setComponentRuleType } from '../helper'; | |
16 | + import { upperFirst, cloneDeep } from 'lodash-es'; | |
17 | + | |
18 | + import { useItemLabelWidth } from '../hooks/useLabelWidth'; | |
19 | + import { useI18n } from '/@/hooks/web/useI18n'; | |
20 | + | |
21 | + export default defineComponent({ | |
22 | + name: 'BasicFormItem', | |
23 | + inheritAttrs: false, | |
24 | + props: { | |
25 | + schema: { | |
26 | + type: Object as PropType<FormSchema>, | |
27 | + default: () => {}, | |
28 | + }, | |
29 | + formProps: { | |
30 | + type: Object as PropType<FormProps>, | |
31 | + default: {}, | |
32 | + }, | |
33 | + allDefaultValues: { | |
34 | + type: Object as PropType<Recordable>, | |
35 | + default: {}, | |
36 | + }, | |
37 | + formModel: { | |
38 | + type: Object as PropType<Recordable>, | |
39 | + default: {}, | |
40 | + }, | |
41 | + setFormModel: { | |
42 | + type: Function as PropType<(key: string, value: any) => void>, | |
43 | + default: null, | |
44 | + }, | |
45 | + tableAction: { | |
46 | + type: Object as PropType<TableActionType>, | |
47 | + }, | |
48 | + formActionType: { | |
49 | + type: Object as PropType<FormActionType>, | |
50 | + }, | |
27 | 51 | }, |
28 | - formProps: { | |
29 | - type: Object as PropType<FormProps>, | |
30 | - default: {}, | |
31 | - }, | |
32 | - allDefaultValues: { | |
33 | - type: Object as PropType<Recordable>, | |
34 | - default: {}, | |
35 | - }, | |
36 | - formModel: { | |
37 | - type: Object as PropType<Recordable>, | |
38 | - default: {}, | |
39 | - }, | |
40 | - setFormModel: { | |
41 | - type: Function as PropType<(key: string, value: any) => void>, | |
42 | - default: null, | |
43 | - }, | |
44 | - tableAction: { | |
45 | - type: Object as PropType<TableActionType>, | |
46 | - }, | |
47 | - formActionType: { | |
48 | - type: Object as PropType<FormActionType>, | |
49 | - }, | |
50 | - }, | |
51 | - setup(props, { slots }) { | |
52 | - const { t } = useI18n(); | |
53 | - | |
54 | - const { schema, formProps } = toRefs(props) as { | |
55 | - schema: Ref<FormSchema>; | |
56 | - formProps: Ref<FormProps>; | |
57 | - }; | |
58 | - | |
59 | - const itemLabelWidthProp = useItemLabelWidth(schema, formProps); | |
60 | - | |
61 | - const getValues = computed(() => { | |
62 | - const { allDefaultValues, formModel, schema } = props; | |
63 | - const { mergeDynamicData } = props.formProps; | |
64 | - return { | |
65 | - field: schema.field, | |
66 | - model: formModel, | |
67 | - values: { | |
68 | - ...mergeDynamicData, | |
69 | - ...allDefaultValues, | |
70 | - ...formModel, | |
71 | - } as Recordable, | |
72 | - schema: schema, | |
52 | + setup(props, { slots }) { | |
53 | + const { t } = useI18n(); | |
54 | + | |
55 | + const { schema, formProps } = toRefs(props) as { | |
56 | + schema: Ref<FormSchema>; | |
57 | + formProps: Ref<FormProps>; | |
73 | 58 | }; |
74 | - }); | |
75 | 59 | |
76 | - const getComponentsProps = computed(() => { | |
77 | - const { schema, tableAction, formModel, formActionType } = props; | |
78 | - const { componentProps = {} } = schema; | |
79 | - if (!isFunction(componentProps)) { | |
80 | - return componentProps; | |
81 | - } | |
82 | - return componentProps({ schema, tableAction, formModel, formActionType }) ?? {}; | |
83 | - }); | |
84 | - | |
85 | - const getDisable = computed(() => { | |
86 | - const { disabled: globDisabled } = props.formProps; | |
87 | - const { dynamicDisabled } = props.schema; | |
88 | - const { disabled: itemDisabled = false } = unref(getComponentsProps); | |
89 | - let disabled = !!globDisabled || itemDisabled; | |
90 | - if (isBoolean(dynamicDisabled)) { | |
91 | - disabled = dynamicDisabled; | |
92 | - } | |
60 | + const itemLabelWidthProp = useItemLabelWidth(schema, formProps); | |
61 | + | |
62 | + const getValues = computed(() => { | |
63 | + const { allDefaultValues, formModel, schema } = props; | |
64 | + const { mergeDynamicData } = props.formProps; | |
65 | + return { | |
66 | + field: schema.field, | |
67 | + model: formModel, | |
68 | + values: { | |
69 | + ...mergeDynamicData, | |
70 | + ...allDefaultValues, | |
71 | + ...formModel, | |
72 | + } as Recordable, | |
73 | + schema: schema, | |
74 | + }; | |
75 | + }); | |
76 | + | |
77 | + const getComponentsProps = computed(() => { | |
78 | + const { schema, tableAction, formModel, formActionType } = props; | |
79 | + const { componentProps = {} } = schema; | |
80 | + if (!isFunction(componentProps)) { | |
81 | + return componentProps; | |
82 | + } | |
83 | + return componentProps({ schema, tableAction, formModel, formActionType }) ?? {}; | |
84 | + }); | |
85 | + | |
86 | + const getDisable = computed(() => { | |
87 | + const { disabled: globDisabled } = props.formProps; | |
88 | + const { dynamicDisabled } = props.schema; | |
89 | + const { disabled: itemDisabled = false } = unref(getComponentsProps); | |
90 | + let disabled = !!globDisabled || itemDisabled; | |
91 | + if (isBoolean(dynamicDisabled)) { | |
92 | + disabled = dynamicDisabled; | |
93 | + } | |
93 | 94 | |
94 | - if (isFunction(dynamicDisabled)) { | |
95 | - disabled = dynamicDisabled(unref(getValues)); | |
96 | - } | |
97 | - return disabled; | |
98 | - }); | |
99 | - | |
100 | - function getShow(): { isShow: boolean; isIfShow: boolean } { | |
101 | - const { show, ifShow } = props.schema; | |
102 | - const { showAdvancedButton } = props.formProps; | |
103 | - const itemIsAdvanced = showAdvancedButton | |
104 | - ? isBoolean(props.schema.isAdvanced) | |
105 | - ? props.schema.isAdvanced | |
106 | - : true | |
107 | - : true; | |
108 | - | |
109 | - let isShow = true; | |
110 | - let isIfShow = true; | |
111 | - | |
112 | - if (isBoolean(show)) { | |
113 | - isShow = show; | |
114 | - } | |
115 | - if (isBoolean(ifShow)) { | |
116 | - isIfShow = ifShow; | |
117 | - } | |
118 | - if (isFunction(show)) { | |
119 | - isShow = show(unref(getValues)); | |
120 | - } | |
121 | - if (isFunction(ifShow)) { | |
122 | - isIfShow = ifShow(unref(getValues)); | |
123 | - } | |
124 | - isShow = isShow && itemIsAdvanced; | |
125 | - return { isShow, isIfShow }; | |
126 | - } | |
127 | - | |
128 | - function handleRules(): ValidationRule[] { | |
129 | - const { | |
130 | - rules: defRules = [], | |
131 | - component, | |
132 | - rulesMessageJoinLabel, | |
133 | - label, | |
134 | - dynamicRules, | |
135 | - required, | |
136 | - } = props.schema; | |
137 | - | |
138 | - if (isFunction(dynamicRules)) { | |
139 | - return dynamicRules(unref(getValues)) as ValidationRule[]; | |
95 | + if (isFunction(dynamicDisabled)) { | |
96 | + disabled = dynamicDisabled(unref(getValues)); | |
97 | + } | |
98 | + return disabled; | |
99 | + }); | |
100 | + | |
101 | + function getShow(): { isShow: boolean; isIfShow: boolean } { | |
102 | + const { show, ifShow } = props.schema; | |
103 | + const { showAdvancedButton } = props.formProps; | |
104 | + const itemIsAdvanced = showAdvancedButton | |
105 | + ? isBoolean(props.schema.isAdvanced) | |
106 | + ? props.schema.isAdvanced | |
107 | + : true | |
108 | + : true; | |
109 | + | |
110 | + let isShow = true; | |
111 | + let isIfShow = true; | |
112 | + | |
113 | + if (isBoolean(show)) { | |
114 | + isShow = show; | |
115 | + } | |
116 | + if (isBoolean(ifShow)) { | |
117 | + isIfShow = ifShow; | |
118 | + } | |
119 | + if (isFunction(show)) { | |
120 | + isShow = show(unref(getValues)); | |
121 | + } | |
122 | + if (isFunction(ifShow)) { | |
123 | + isIfShow = ifShow(unref(getValues)); | |
124 | + } | |
125 | + isShow = isShow && itemIsAdvanced; | |
126 | + return { isShow, isIfShow }; | |
140 | 127 | } |
141 | 128 | |
142 | - let rules: ValidationRule[] = cloneDeep(defRules) as ValidationRule[]; | |
129 | + function handleRules(): ValidationRule[] { | |
130 | + const { | |
131 | + rules: defRules = [], | |
132 | + component, | |
133 | + rulesMessageJoinLabel, | |
134 | + label, | |
135 | + dynamicRules, | |
136 | + required, | |
137 | + } = props.schema; | |
138 | + | |
139 | + if (isFunction(dynamicRules)) { | |
140 | + return dynamicRules(unref(getValues)) as ValidationRule[]; | |
141 | + } | |
143 | 142 | |
144 | - if ((!rules || rules.length === 0) && required) { | |
145 | - rules = [{ required, type: 'string' }]; | |
146 | - } | |
143 | + let rules: ValidationRule[] = cloneDeep(defRules) as ValidationRule[]; | |
147 | 144 | |
148 | - const requiredRuleIndex: number = rules.findIndex( | |
149 | - (rule) => Reflect.has(rule, 'required') && !Reflect.has(rule, 'validator') | |
150 | - ); | |
151 | - const { rulesMessageJoinLabel: globalRulesMessageJoinLabel } = props.formProps; | |
152 | - if (requiredRuleIndex !== -1) { | |
153 | - const rule = rules[requiredRuleIndex]; | |
154 | - const { isShow } = getShow(); | |
155 | - if (!isShow) { | |
156 | - rule.required = false; | |
145 | + if ((!rules || rules.length === 0) && required) { | |
146 | + rules = [{ required, type: 'string' }]; | |
157 | 147 | } |
158 | - if (rule.required && component) { | |
159 | - if (!Reflect.has(rule, 'type')) { | |
160 | - rule.type = 'string'; | |
161 | - } | |
162 | - const joinLabel = Reflect.has(props.schema, 'rulesMessageJoinLabel') | |
163 | - ? rulesMessageJoinLabel | |
164 | - : globalRulesMessageJoinLabel; | |
165 | - | |
166 | - rule.message = | |
167 | - rule.message || createPlaceholderMessage(component) + `${joinLabel ? label : ''}`; | |
168 | 148 | |
169 | - if (component.includes('Input') || component.includes('Textarea')) { | |
170 | - rule.whitespace = true; | |
149 | + const requiredRuleIndex: number = rules.findIndex( | |
150 | + (rule) => Reflect.has(rule, 'required') && !Reflect.has(rule, 'validator') | |
151 | + ); | |
152 | + const { rulesMessageJoinLabel: globalRulesMessageJoinLabel } = props.formProps; | |
153 | + if (requiredRuleIndex !== -1) { | |
154 | + const rule = rules[requiredRuleIndex]; | |
155 | + const { isShow } = getShow(); | |
156 | + if (!isShow) { | |
157 | + rule.required = false; | |
158 | + } | |
159 | + if (rule.required && component) { | |
160 | + if (!Reflect.has(rule, 'type')) { | |
161 | + rule.type = 'string'; | |
162 | + } | |
163 | + const joinLabel = Reflect.has(props.schema, 'rulesMessageJoinLabel') | |
164 | + ? rulesMessageJoinLabel | |
165 | + : globalRulesMessageJoinLabel; | |
166 | + | |
167 | + rule.message = | |
168 | + rule.message || createPlaceholderMessage(component) + `${joinLabel ? label : ''}`; | |
169 | + | |
170 | + if (component.includes('Input') || component.includes('Textarea')) { | |
171 | + rule.whitespace = true; | |
172 | + } | |
173 | + | |
174 | + setComponentRuleType(rule, component); | |
171 | 175 | } |
176 | + } | |
172 | 177 | |
173 | - setComponentRuleType(rule, component); | |
178 | + // Maximum input length rule check | |
179 | + const characterInx = rules.findIndex((val) => val.max); | |
180 | + if (characterInx !== -1 && !rules[characterInx].validator) { | |
181 | + rules[characterInx].message = | |
182 | + rules[characterInx].message || | |
183 | + t('component.form.maxTip', [rules[characterInx].max] as Recordable); | |
174 | 184 | } |
185 | + return rules; | |
175 | 186 | } |
176 | 187 | |
177 | - // Maximum input length rule check | |
178 | - const characterInx = rules.findIndex((val) => val.max); | |
179 | - if (characterInx !== -1 && !rules[characterInx].validator) { | |
180 | - rules[characterInx].message = | |
181 | - rules[characterInx].message || | |
182 | - t('component.form.maxTip', [rules[characterInx].max] as Recordable); | |
183 | - } | |
184 | - return rules; | |
185 | - } | |
186 | - | |
187 | - function renderComponent() { | |
188 | - const { | |
189 | - renderComponentContent, | |
190 | - component, | |
191 | - field, | |
192 | - changeEvent = 'change', | |
193 | - valueField, | |
194 | - } = props.schema; | |
195 | - | |
196 | - const isCheck = component && ['Switch', 'Checkbox'].includes(component); | |
197 | - | |
198 | - const eventKey = `on${upperFirst(changeEvent)}`; | |
199 | - | |
200 | - const on = { | |
201 | - [eventKey]: (e: Nullable<Recordable>) => { | |
202 | - if (propsData[eventKey]) { | |
203 | - propsData[eventKey](e); | |
204 | - } | |
205 | - | |
206 | - const target = e ? e.target : null; | |
207 | - | |
208 | - const value = target ? (isCheck ? target.checked : target.value) : e; | |
209 | - props.setFormModel(field, value); | |
210 | - }, | |
211 | - }; | |
212 | - const Comp = componentMap.get(component) as typeof defineComponent; | |
213 | - | |
214 | - const { autoSetPlaceHolder, size } = props.formProps; | |
215 | - const propsData: Recordable = { | |
216 | - allowClear: true, | |
217 | - getPopupContainer: (trigger: Element) => trigger.parentNode, | |
218 | - size, | |
219 | - ...unref(getComponentsProps), | |
220 | - disabled: unref(getDisable), | |
221 | - }; | |
188 | + function renderComponent() { | |
189 | + const { | |
190 | + renderComponentContent, | |
191 | + component, | |
192 | + field, | |
193 | + changeEvent = 'change', | |
194 | + valueField, | |
195 | + } = props.schema; | |
196 | + | |
197 | + const isCheck = component && ['Switch', 'Checkbox'].includes(component); | |
198 | + | |
199 | + const eventKey = `on${upperFirst(changeEvent)}`; | |
200 | + | |
201 | + const on = { | |
202 | + [eventKey]: (e: Nullable<Recordable>) => { | |
203 | + if (propsData[eventKey]) { | |
204 | + propsData[eventKey](e); | |
205 | + } | |
206 | + | |
207 | + const target = e ? e.target : null; | |
208 | + | |
209 | + const value = target ? (isCheck ? target.checked : target.value) : e; | |
210 | + props.setFormModel(field, value); | |
211 | + }, | |
212 | + }; | |
213 | + const Comp = componentMap.get(component) as typeof defineComponent; | |
214 | + | |
215 | + const { autoSetPlaceHolder, size } = props.formProps; | |
216 | + const propsData: Recordable = { | |
217 | + allowClear: true, | |
218 | + getPopupContainer: (trigger: Element) => trigger.parentNode, | |
219 | + size, | |
220 | + ...unref(getComponentsProps), | |
221 | + disabled: unref(getDisable), | |
222 | + }; | |
223 | + | |
224 | + const isCreatePlaceholder = !propsData.disabled && autoSetPlaceHolder; | |
225 | + let placeholder; | |
226 | + // RangePicker place is an array | |
227 | + if (isCreatePlaceholder && component !== 'RangePicker' && component) { | |
228 | + placeholder = | |
229 | + unref(getComponentsProps)?.placeholder || createPlaceholderMessage(component); | |
230 | + } | |
231 | + propsData.placeholder = placeholder; | |
232 | + propsData.codeField = field; | |
233 | + propsData.formValues = unref(getValues); | |
234 | + | |
235 | + const bindValue: Recordable = { | |
236 | + [valueField || (isCheck ? 'checked' : 'value')]: props.formModel[field], | |
237 | + }; | |
238 | + | |
239 | + const compAttr: Recordable = { | |
240 | + ...propsData, | |
241 | + ...on, | |
242 | + ...bindValue, | |
243 | + }; | |
244 | + | |
245 | + if (!renderComponentContent) { | |
246 | + return <Comp {...compAttr} />; | |
247 | + } | |
248 | + const compSlot = isFunction(renderComponentContent) | |
249 | + ? { ...renderComponentContent(unref(getValues)) } | |
250 | + : { | |
251 | + default: () => renderComponentContent, | |
252 | + }; | |
222 | 253 | |
223 | - const isCreatePlaceholder = !propsData.disabled && autoSetPlaceHolder; | |
224 | - let placeholder; | |
225 | - // RangePicker place is an array | |
226 | - if (isCreatePlaceholder && component !== 'RangePicker' && component) { | |
227 | - placeholder = unref(getComponentsProps)?.placeholder || createPlaceholderMessage(component); | |
254 | + return <Comp {...compAttr}>{compSlot}</Comp>; | |
228 | 255 | } |
229 | - propsData.placeholder = placeholder; | |
230 | - propsData.codeField = field; | |
231 | - propsData.formValues = unref(getValues); | |
232 | - | |
233 | - const bindValue: Recordable = { | |
234 | - [valueField || (isCheck ? 'checked' : 'value')]: props.formModel[field], | |
235 | - }; | |
236 | 256 | |
237 | - const compAttr: Recordable = { | |
238 | - ...propsData, | |
239 | - ...on, | |
240 | - ...bindValue, | |
241 | - }; | |
242 | - | |
243 | - if (!renderComponentContent) { | |
244 | - return <Comp {...compAttr} />; | |
245 | - } | |
246 | - const compSlot = isFunction(renderComponentContent) | |
247 | - ? { ...renderComponentContent(unref(getValues)) } | |
248 | - : { | |
249 | - default: () => renderComponentContent, | |
250 | - }; | |
251 | - | |
252 | - return <Comp {...compAttr}>{compSlot}</Comp>; | |
253 | - } | |
254 | - | |
255 | - function renderLabelHelpMessage() { | |
256 | - const { label, helpMessage, helpComponentProps, subLabel } = props.schema; | |
257 | - const renderLabel = subLabel ? ( | |
258 | - <span> | |
259 | - {label} <span style="color:#00000073">{subLabel}</span> | |
260 | - </span> | |
261 | - ) : ( | |
262 | - label | |
263 | - ); | |
264 | - if (!helpMessage || (Array.isArray(helpMessage) && helpMessage.length === 0)) { | |
265 | - return renderLabel; | |
257 | + function renderLabelHelpMessage() { | |
258 | + const { label, helpMessage, helpComponentProps, subLabel } = props.schema; | |
259 | + const renderLabel = subLabel ? ( | |
260 | + <span> | |
261 | + {label} <span style="color:#00000073">{subLabel}</span> | |
262 | + </span> | |
263 | + ) : ( | |
264 | + label | |
265 | + ); | |
266 | + if (!helpMessage || (Array.isArray(helpMessage) && helpMessage.length === 0)) { | |
267 | + return renderLabel; | |
268 | + } | |
269 | + return ( | |
270 | + <span> | |
271 | + {renderLabel} | |
272 | + <BasicHelp placement="top" class="mx-1" text={helpMessage} {...helpComponentProps} /> | |
273 | + </span> | |
274 | + ); | |
266 | 275 | } |
267 | - return ( | |
268 | - <span> | |
269 | - {renderLabel} | |
270 | - <BasicHelp placement="top" class="mx-1" text={helpMessage} {...helpComponentProps} /> | |
271 | - </span> | |
272 | - ); | |
273 | - } | |
274 | - | |
275 | - function renderItem() { | |
276 | - const { itemProps, slot, render, field, suffix } = props.schema; | |
277 | - const { labelCol, wrapperCol } = unref(itemLabelWidthProp); | |
278 | - const { colon } = props.formProps; | |
279 | - | |
280 | - const getContent = () => { | |
281 | - return slot | |
282 | - ? getSlot(slots, slot, unref(getValues)) | |
283 | - : render | |
284 | - ? render(unref(getValues)) | |
285 | - : renderComponent(); | |
286 | - }; | |
287 | 276 | |
288 | - const showSuffix = !!suffix; | |
289 | - | |
290 | - const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix; | |
291 | - | |
292 | - return ( | |
293 | - <Form.Item | |
294 | - name={field} | |
295 | - colon={colon} | |
296 | - class={{ 'suffix-item': showSuffix }} | |
297 | - {...(itemProps as Recordable)} | |
298 | - label={renderLabelHelpMessage()} | |
299 | - rules={handleRules()} | |
300 | - labelCol={labelCol} | |
301 | - wrapperCol={wrapperCol} | |
302 | - > | |
303 | - <> | |
304 | - {getContent()} | |
305 | - {showSuffix && <span class="suffix">{getSuffix}</span>} | |
306 | - </> | |
307 | - </Form.Item> | |
308 | - ); | |
309 | - } | |
310 | - return () => { | |
311 | - const { colProps = {}, colSlot, renderColContent, component } = props.schema; | |
312 | - if (!componentMap.has(component)) return null; | |
313 | - | |
314 | - const { baseColProps = {} } = props.formProps; | |
315 | - | |
316 | - const realColProps = { ...baseColProps, ...colProps }; | |
317 | - const { isIfShow, isShow } = getShow(); | |
318 | - | |
319 | - const values = unref(getValues); | |
320 | - const getContent = () => { | |
321 | - return colSlot | |
322 | - ? getSlot(slots, colSlot, values) | |
323 | - : renderColContent | |
324 | - ? renderColContent(values) | |
325 | - : renderItem(); | |
277 | + function renderItem() { | |
278 | + const { itemProps, slot, render, field, suffix } = props.schema; | |
279 | + const { labelCol, wrapperCol } = unref(itemLabelWidthProp); | |
280 | + const { colon } = props.formProps; | |
281 | + | |
282 | + const getContent = () => { | |
283 | + return slot | |
284 | + ? getSlot(slots, slot, unref(getValues)) | |
285 | + : render | |
286 | + ? render(unref(getValues)) | |
287 | + : renderComponent(); | |
288 | + }; | |
289 | + | |
290 | + const showSuffix = !!suffix; | |
291 | + | |
292 | + const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix; | |
293 | + | |
294 | + return ( | |
295 | + <Form.Item | |
296 | + name={field} | |
297 | + colon={colon} | |
298 | + class={{ 'suffix-item': showSuffix }} | |
299 | + {...(itemProps as Recordable)} | |
300 | + label={renderLabelHelpMessage()} | |
301 | + rules={handleRules()} | |
302 | + labelCol={labelCol} | |
303 | + wrapperCol={wrapperCol} | |
304 | + > | |
305 | + <> | |
306 | + {getContent()} | |
307 | + {showSuffix && <span class="suffix">{getSuffix}</span>} | |
308 | + </> | |
309 | + </Form.Item> | |
310 | + ); | |
311 | + } | |
312 | + return () => { | |
313 | + const { colProps = {}, colSlot, renderColContent, component } = props.schema; | |
314 | + if (!componentMap.has(component)) return null; | |
315 | + | |
316 | + const { baseColProps = {} } = props.formProps; | |
317 | + | |
318 | + const realColProps = { ...baseColProps, ...colProps }; | |
319 | + const { isIfShow, isShow } = getShow(); | |
320 | + | |
321 | + const values = unref(getValues); | |
322 | + const getContent = () => { | |
323 | + return colSlot | |
324 | + ? getSlot(slots, colSlot, values) | |
325 | + : renderColContent | |
326 | + ? renderColContent(values) | |
327 | + : renderItem(); | |
328 | + }; | |
329 | + | |
330 | + return ( | |
331 | + isIfShow && ( | |
332 | + <Col {...realColProps} v-show={isShow}> | |
333 | + {getContent()} | |
334 | + </Col> | |
335 | + ) | |
336 | + ); | |
326 | 337 | }; |
327 | - | |
328 | - return ( | |
329 | - isIfShow && ( | |
330 | - <Col {...realColProps} v-show={isShow}> | |
331 | - {getContent()} | |
332 | - </Col> | |
333 | - ) | |
334 | - ); | |
335 | - }; | |
336 | - }, | |
337 | -}); | |
338 | + }, | |
339 | + }); | |
340 | +</script> | ... | ... |
src/components/Icon/src/IconPicker.vue
... | ... | @@ -30,16 +30,17 @@ |
30 | 30 | <li |
31 | 31 | v-for="icon in getPaginationList" |
32 | 32 | :key="icon" |
33 | - :class="currentSelect === icon ? 'bg-primary text-white' : ''" | |
34 | - class="p-2 w-1/8 cursor-pointer mr-1 mt-1 flex justify-center items-center border border-solid hover:bg-primary hover:text-white" | |
33 | + :class="currentSelect === icon ? 'border border-primary' : ''" | |
34 | + class="p-2 w-1/8 cursor-pointer mr-1 mt-1 flex justify-center items-center border border-solid hover:border-primary" | |
35 | 35 | @click="handleClick(icon)" |
36 | 36 | > |
37 | 37 | <!-- <Icon :icon="icon" :prefix="prefix" /> --> |
38 | - <Icon :icon="icon" /> | |
38 | + <SvgIcon v-if="isSvgMode" :name="icon" /> | |
39 | + <Icon :icon="icon" v-else /> | |
39 | 40 | </li> |
40 | 41 | </ul> |
41 | 42 | </ScrollContainer> |
42 | - <div class="flex py-2 items-center justify-center"> | |
43 | + <div class="flex py-2 items-center justify-center" v-if="getTotal >= pageSize"> | |
43 | 44 | <Pagination |
44 | 45 | showLessItems |
45 | 46 | size="small" |
... | ... | @@ -53,7 +54,11 @@ |
53 | 54 | ><div class="p-5"> <Empty /></div> |
54 | 55 | </template> |
55 | 56 | </template> |
56 | - <Icon :icon="currentSelect || 'ion:apps-outline'" class="cursor-pointer px-2 py-1" /> | |
57 | + | |
58 | + <span class="cursor-pointer px-2 py-1 flex items-center" v-if="isSvgMode && currentSelect"> | |
59 | + <SvgIcon :name="currentSelect" /> | |
60 | + </span> | |
61 | + <Icon :icon="currentSelect || 'ion:apps-outline'" class="cursor-pointer px-2 py-1" v-else /> | |
57 | 62 | </Popover> |
58 | 63 | </template> |
59 | 64 | </a-input> |
... | ... | @@ -66,6 +71,7 @@ |
66 | 71 | |
67 | 72 | import { Input, Popover, Pagination, Empty } from 'ant-design-vue'; |
68 | 73 | import Icon from './index.vue'; |
74 | + import SvgIcon from './SvgIcon.vue'; | |
69 | 75 | |
70 | 76 | import iconsData from '../data/icons.data'; |
71 | 77 | import { propTypes } from '/@/utils/propTypes'; |
... | ... | @@ -74,7 +80,7 @@ |
74 | 80 | import { useI18n } from '/@/hooks/web/useI18n'; |
75 | 81 | import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard'; |
76 | 82 | import { useMessage } from '/@/hooks/web/useMessage'; |
77 | - // import '@iconify/iconify'; | |
83 | + import svgIcons from 'vite-plugin-svg-icons/client'; | |
78 | 84 | |
79 | 85 | function getIcons() { |
80 | 86 | const data = iconsData as any; |
... | ... | @@ -88,25 +94,35 @@ |
88 | 94 | return result; |
89 | 95 | } |
90 | 96 | |
91 | - const icons = getIcons(); | |
97 | + function getSvgIcons() { | |
98 | + return svgIcons.map((icon) => icon.replace('icon-', '')); | |
99 | + } | |
100 | + | |
92 | 101 | export default defineComponent({ |
93 | 102 | name: 'IconPicker', |
94 | - components: { [Input.name]: Input, Icon, Popover, ScrollContainer, Pagination, Empty }, | |
103 | + components: { [Input.name]: Input, Icon, Popover, ScrollContainer, Pagination, Empty, SvgIcon }, | |
95 | 104 | inheritAttrs: false, |
96 | 105 | props: { |
97 | 106 | value: propTypes.string, |
98 | 107 | width: propTypes.string.def('100%'), |
99 | 108 | pageSize: propTypes.number.def(140), |
100 | 109 | copy: propTypes.bool.def(false), |
110 | + mode: propTypes | |
111 | + .oneOf<('svg' | 'iconify')[]>(['svg', 'iconify']) | |
112 | + .def('iconify'), | |
101 | 113 | }, |
102 | 114 | emits: ['change'], |
103 | 115 | setup(props, { emit }) { |
116 | + const isSvgMode = props.mode === 'svg'; | |
117 | + const icons = isSvgMode ? getSvgIcons() : getIcons(); | |
118 | + | |
104 | 119 | const currentSelect = ref(''); |
105 | 120 | const visible = ref(false); |
106 | 121 | const currentList = ref(icons); |
107 | 122 | |
108 | - const { prefixCls } = useDesign('icon-picker'); | |
109 | 123 | const { t } = useI18n(); |
124 | + const { prefixCls } = useDesign('icon-picker'); | |
125 | + | |
110 | 126 | const [debounceHandleSearchChange] = useDebounce(handleSearchChange, 100); |
111 | 127 | const { clipboardRef, isSuccessRef } = useCopyToClipboard(props.value); |
112 | 128 | const { createMessage } = useMessage(); |
... | ... | @@ -153,6 +169,7 @@ |
153 | 169 | t, |
154 | 170 | prefixCls, |
155 | 171 | visible, |
172 | + isSvgMode, | |
156 | 173 | getTotal, |
157 | 174 | getPaginationList, |
158 | 175 | handlePageChange, | ... | ... |
src/components/Tree/src/TreeHeader.vue
... | ... | @@ -24,7 +24,7 @@ |
24 | 24 | </template> |
25 | 25 | <script lang="ts"> |
26 | 26 | import type { PropType } from 'vue'; |
27 | - import { defineComponent, ref, computed } from 'vue'; | |
27 | + import { defineComponent, computed } from 'vue'; | |
28 | 28 | |
29 | 29 | import { Dropdown, Menu, Input } from 'ant-design-vue'; |
30 | 30 | import { Icon } from '/@/components/Icon'; | ... | ... |
src/design/index.less
src/views/demo/feat/icon/index.vue
... | ... | @@ -21,18 +21,24 @@ |
21 | 21 | </div> |
22 | 22 | </CollapseContainer> |
23 | 23 | |
24 | - <CollapseContainer title="svg Sprite" class="my-5"> | |
24 | + <CollapseContainer title="svg 雪碧图" class="my-5"> | |
25 | 25 | <div class="flex justify-around flex-wrap"> |
26 | 26 | <SvgIcon name="test" size="32" /> |
27 | 27 | </div> |
28 | 28 | </CollapseContainer> |
29 | 29 | |
30 | - <CollapseContainer title="图标选择器" class="my-5"> | |
30 | + <CollapseContainer title="图标选择器(Iconify)" class="my-5"> | |
31 | 31 | <div class="flex justify-around flex-wrap"> |
32 | 32 | <IconPicker /> |
33 | 33 | </div> |
34 | 34 | </CollapseContainer> |
35 | 35 | |
36 | + <CollapseContainer title="图标选择器(Svg)" class="my-5"> | |
37 | + <div class="flex justify-around flex-wrap"> | |
38 | + <IconPicker mode="svg" /> | |
39 | + </div> | |
40 | + </CollapseContainer> | |
41 | + | |
36 | 42 | <Alert |
37 | 43 | show-icon |
38 | 44 | message="推荐使用Iconify组件" | ... | ... |
yarn.lock
... | ... | @@ -1117,10 +1117,10 @@ |
1117 | 1117 | dependencies: |
1118 | 1118 | cross-fetch "^3.0.6" |
1119 | 1119 | |
1120 | -"@iconify/json@^1.1.313": | |
1121 | - version "1.1.313" | |
1122 | - resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.313.tgz#c225be3c5ce3280a2c34e753a65dc257b85b6652" | |
1123 | - integrity sha512-gv00rSX4apKE0i/fUjXp5+sBb8LHzzdJqrXkBNVby7Nl7yzRqeQ/EyY+7ixtSpEu3f1P/co/vrgdbZN6wlw6DA== | |
1120 | +"@iconify/json@^1.1.314": | |
1121 | + version "1.1.314" | |
1122 | + resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.314.tgz#43b417e5131b55e879f94b6fc40b09928eea42ad" | |
1123 | + integrity sha512-KDc2dtNnbUryuUWs4ov1e8xCcEjrU/9r3PLOsElzsRpMjaGe/RfpAvU1NkDlv7Mmriaah+Dj6SVoLeRSUB5q3g== | |
1124 | 1124 | |
1125 | 1125 | "@intlify/core-base@9.0.0": |
1126 | 1126 | version "9.0.0" |
... | ... | @@ -7680,10 +7680,10 @@ rollup-plugin-visualizer@^4.2.0: |
7680 | 7680 | source-map "^0.7.3" |
7681 | 7681 | yargs "^16.0.3" |
7682 | 7682 | |
7683 | -rollup@2.40.0, rollup@^0.63.4, rollup@^2.25.0, rollup@^2.38.5, rollup@^2.40.0: | |
7684 | - version "2.40.0" | |
7685 | - resolved "https://registry.npmjs.org/rollup/-/rollup-2.40.0.tgz#efc218eaede7ab590954df50f96195188999c304" | |
7686 | - integrity sha512-WiOGAPbXoHu+TOz6hyYUxIksOwsY/21TRWoO593jgYt8mvYafYqQl+axaA8y1z2HFazNUUrsMSjahV2A6/2R9A== | |
7683 | +rollup@2.41.0, rollup@^0.63.4, rollup@^2.25.0, rollup@^2.38.5, rollup@^2.40.0: | |
7684 | + version "2.41.0" | |
7685 | + resolved "https://registry.npmjs.org/rollup/-/rollup-2.41.0.tgz#b2a398bbabbf227738dedaef099e494aed468982" | |
7686 | + integrity sha512-Gk76XHTggulWPH95q8V62bw6uqDH6UGvbD6LOa3QUyhuMF3eOuaeDHR7SLm1T9faitkpNrqzUAVYx47klcMnlA== | |
7687 | 7687 | optionalDependencies: |
7688 | 7688 | fsevents "~2.3.1" |
7689 | 7689 | |
... | ... | @@ -9160,10 +9160,10 @@ vite-plugin-style-import@^0.8.1: |
9160 | 9160 | es-module-lexer "^0.4.1" |
9161 | 9161 | magic-string "^0.25.7" |
9162 | 9162 | |
9163 | -vite-plugin-svg-icons@^0.3.3: | |
9164 | - version "0.3.3" | |
9165 | - resolved "https://registry.npmjs.org/vite-plugin-svg-icons/-/vite-plugin-svg-icons-0.3.3.tgz#b699e1af244500d893cc32b48a772492c1fae72b" | |
9166 | - integrity sha512-ZI3FLspeM3PV0OE503m7/11jW5aSSCwxXUEcJZL3RwSYmpkLE0cSsM7UFZf0tx3cRoSB/JpeOlRIRH6G2BhWiQ== | |
9163 | +vite-plugin-svg-icons@^0.3.4: | |
9164 | + version "0.3.4" | |
9165 | + resolved "https://registry.npmjs.org/vite-plugin-svg-icons/-/vite-plugin-svg-icons-0.3.4.tgz#505aacff35f19d4e1c81f05a85bded0d6f1f6323" | |
9166 | + integrity sha512-N4KYqmyF/gnsYIBxvMTyotjWSdur/6EyycE6eJvM2m7oHHxe8Y+SZZlD+XTz8Nl+zfurXYDkrbbHAdtWlpJovw== | |
9167 | 9167 | dependencies: |
9168 | 9168 | debug "^4.3.2" |
9169 | 9169 | etag "^1.8.1" | ... | ... |