@complex-suite/component-antd 4.10.12

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.
Files changed (51) hide show
  1. package/LayoutResizeObserver.ts +104 -0
  2. package/LocalResizeObserver.ts +46 -0
  3. package/README.md +67 -0
  4. package/antdConfig.ts +361 -0
  5. package/format.ts +458 -0
  6. package/history.md +325 -0
  7. package/icon.ts +65 -0
  8. package/index.test.ts +5 -0
  9. package/index.ts +55 -0
  10. package/package.json +39 -0
  11. package/plugin.ts +95 -0
  12. package/quick/QuickCascade.tsx +107 -0
  13. package/quick/QuickEdit.tsx +117 -0
  14. package/quick/QuickFloat.tsx +32 -0
  15. package/quick/QuickFloatModal.tsx +95 -0
  16. package/quick/QuickFloatValue.tsx +103 -0
  17. package/quick/QuickList.tsx +433 -0
  18. package/quick/data/FloatData.ts +77 -0
  19. package/src/AutoSpin.vue +39 -0
  20. package/src/AutoText.vue +101 -0
  21. package/src/ButtonView.tsx +62 -0
  22. package/src/CollapseArea.tsx +88 -0
  23. package/src/EditArea.tsx +205 -0
  24. package/src/EditView.tsx +179 -0
  25. package/src/FlexBox.tsx +74 -0
  26. package/src/FormList.tsx +226 -0
  27. package/src/ImageViewer.tsx +122 -0
  28. package/src/InfoArea.tsx +182 -0
  29. package/src/InfoView.tsx +150 -0
  30. package/src/MenuView.tsx +91 -0
  31. package/src/ModalView.tsx +274 -0
  32. package/src/MultipleImport.tsx +231 -0
  33. package/src/SearchArea.tsx +170 -0
  34. package/src/SelectText.vue +59 -0
  35. package/src/SimpleTable.tsx +256 -0
  36. package/src/SingleImport.tsx +189 -0
  37. package/src/TableView.tsx +415 -0
  38. package/src/components/AutoRender.tsx +19 -0
  39. package/src/components/ChoiceInfo.vue +73 -0
  40. package/src/components/PaginationView.tsx +103 -0
  41. package/src/components/TableMenu.tsx +93 -0
  42. package/src/dictionary/AutoEditItem.tsx +164 -0
  43. package/src/dictionary/AutoInfoItem.tsx +126 -0
  44. package/src/dictionary/AutoItem.tsx +219 -0
  45. package/src/icons/EmptyImage.vue +30 -0
  46. package/src/icons/ErrorImage.vue +30 -0
  47. package/src/style/index.css +304 -0
  48. package/tsconfig.json +8 -0
  49. package/type.ts +4 -0
  50. package/vitest.config.ts +11 -0
  51. package/widthCalculator.ts +20 -0
@@ -0,0 +1,88 @@
1
+ import { defineComponent, h, nextTick, onBeforeMount, onMounted, PropType, ref, VNode } from "vue"
2
+ import { dataConfig } from "@complex-suite/data"
3
+ import LocalResizeObserver from "../LocalResizeObserver"
4
+
5
+ export interface CollapseAreaProps {
6
+ height: number
7
+ collapse?: boolean
8
+ render?: (payload: { needCollapse: boolean, collapse: boolean }) => VNode | VNode[] | null
9
+ }
10
+
11
+ export default defineComponent({
12
+ name: 'CollapseArea',
13
+ props: {
14
+ height: {
15
+ type: Number,
16
+ required: true
17
+ },
18
+ collapse: {
19
+ type: Boolean,
20
+ required: false
21
+ },
22
+ render: {
23
+ type: Function as PropType<CollapseAreaProps['render']>,
24
+ required: false
25
+ }
26
+ },
27
+ setup(props) {
28
+ const contentRef = ref<Element>()
29
+ const needCollapse = ref(false)
30
+ const onResize = function(entry: ResizeObserverEntry) {
31
+ if (contentRef.value) {
32
+ const contentHeight = entry.borderBoxSize[0].blockSize
33
+ needCollapse.value = contentHeight > props.height
34
+ }
35
+ }
36
+ const resizeObserver = new LocalResizeObserver(onResize)
37
+ onMounted(() => {
38
+ nextTick(() => {
39
+ resizeObserver.observe(contentRef.value!)
40
+ })
41
+ })
42
+ onBeforeMount(() => {
43
+ resizeObserver.disconnect()
44
+ })
45
+ return {
46
+ contentRef,
47
+ needCollapse
48
+ }
49
+ },
50
+ methods: {
51
+ $renderArea() {
52
+ if (this.render) {
53
+ return this.render({
54
+ needCollapse: this.needCollapse,
55
+ collapse: this.collapse
56
+ })
57
+ } else if (this.$slots.default) {
58
+ return this.$slots.default({
59
+ needCollapse: this.needCollapse,
60
+ collapse: this.collapse
61
+ })
62
+ }
63
+ return null
64
+ },
65
+ renderArea() {
66
+ const area = this.$renderArea()
67
+ if (area) {
68
+ return h('div', {
69
+ class: 'complex-collapse-area-content',
70
+ ref: 'contentRef'
71
+ }, [
72
+ area
73
+ ])
74
+ }
75
+ return null
76
+ }
77
+ },
78
+ render() {
79
+ return h('div', {
80
+ class: 'complex-collapse-area' + ((this.collapse && this.needCollapse) ? ' complex-collapse-area-collapsed' : ''),
81
+ style: {
82
+ height: (this.collapse && this.needCollapse) ? dataConfig.formatPixel(this.height) : undefined
83
+ }
84
+ }, [
85
+ this.renderArea()
86
+ ])
87
+ }
88
+ })
@@ -0,0 +1,205 @@
1
+ import { defineComponent, h, PropType } from "vue"
2
+ import { getEnv } from "@complex-suite/utils"
3
+ import { DictionaryValue, FormValue, ObserveList } from "@complex-suite/data"
4
+ import EditView from "./EditView"
5
+ import type { EditViewDefaultProps } from "./EditView"
6
+ import type { InfoAreaDefaultProps } from "./InfoArea"
7
+ import type { AutoItemPayloadType } from "./dictionary/AutoItem"
8
+ import antdConfig from "../antdConfig"
9
+
10
+ export type EditAreaDataType = undefined | Record<PropertyKey, unknown>
11
+
12
+ export interface EditAreaSubmitOption {
13
+ targetData: Record<PropertyKey, unknown>
14
+ originData: EditAreaDataType
15
+ type: string
16
+ }
17
+
18
+ export type EditAreaProps = EditViewDefaultProps & InfoAreaDefaultProps & {
19
+ form?: FormValue
20
+ }
21
+
22
+ export interface EditAreaOption extends EditAreaProps {
23
+ ref?: string
24
+ onMenu?: (prop: string, payload: AutoItemPayloadType<'edit'>) => unknown
25
+ onEnter?: (prop: string, payload: AutoItemPayloadType<'edit'>) => unknown
26
+ }
27
+
28
+ export default defineComponent({
29
+ name: 'EditArea',
30
+ emits: {
31
+ menu: (prop: string, _payload: AutoItemPayloadType<'edit'>) => {
32
+ return !!prop
33
+ },
34
+ enter: (prop: string, _payload: AutoItemPayloadType<'edit'>) => {
35
+ return !!prop
36
+ }
37
+ },
38
+ props: {
39
+ dictionary: {
40
+ type: Object as PropType<EditAreaProps['dictionary']>,
41
+ required: true
42
+ },
43
+ type: {
44
+ type: String,
45
+ required: false
46
+ },
47
+ observe: {
48
+ type: Boolean,
49
+ required: false,
50
+ default: () => {
51
+ return antdConfig.edit.observe
52
+ }
53
+ },
54
+ inline: {
55
+ type: Boolean,
56
+ required: false,
57
+ default: () => {
58
+ return antdConfig.edit.inline
59
+ }
60
+ },
61
+ form: {
62
+ type: Object as PropType<EditAreaProps['form']>,
63
+ required: false
64
+ },
65
+ formProps: { // form-model-view设置项
66
+ type: Object as PropType<EditAreaProps['formProps']>,
67
+ required: false
68
+ },
69
+ menu: {
70
+ type: Object as PropType<EditAreaProps['menu']>,
71
+ required: false
72
+ },
73
+ labelAlign: { // label 标签的文本对齐方式
74
+ type: String as PropType<EditAreaProps['labelAlign']>,
75
+ required: false
76
+ },
77
+ gridParse: {
78
+ type: Object as PropType<EditAreaProps['gridParse']>,
79
+ required: false
80
+ },
81
+ gridRowProps: { // form-model-view设置项
82
+ type: Object as PropType<EditAreaProps['gridRowProps']>,
83
+ required: false
84
+ },
85
+ onInit: {
86
+ type: Function as PropType<EditAreaProps['onInit']>,
87
+ required: false
88
+ },
89
+ enter: {
90
+ type: Boolean,
91
+ required: false
92
+ },
93
+ disabled: {
94
+ type: Boolean,
95
+ required: false
96
+ },
97
+ loading: {
98
+ type: Boolean,
99
+ required: false
100
+ },
101
+ },
102
+ data() {
103
+ return {
104
+ localType: undefined as undefined | string,
105
+ localForm: new FormValue(),
106
+ data: undefined as EditAreaDataType,
107
+ dictionaryList: [] as DictionaryValue[],
108
+ observeList: undefined as undefined | ObserveList,
109
+ }
110
+ },
111
+ computed: {
112
+ currentType() {
113
+ return this.localType || this.type
114
+ },
115
+ currentForm() {
116
+ return this.form || this.localForm
117
+ }
118
+ },
119
+ mounted() {
120
+ if (this.type) {
121
+ this.$show()
122
+ }
123
+ },
124
+ beforeUnmount() {
125
+ if (this.observeList) {
126
+ this.observeList.reset()
127
+ this.observeList = undefined
128
+ }
129
+ },
130
+ methods: {
131
+ $show(type?: string, data?: EditAreaDataType) {
132
+ this.localType = type
133
+ this.data = data || undefined
134
+ this.init()
135
+ },
136
+ init() {
137
+ this.dictionaryList = this.dictionary.getList(this.currentType!)
138
+ const observeList = this.dictionary.getObserveList(this.currentType!, this.dictionaryList as DictionaryValue[], this.observe)
139
+ this.dictionary.parseData(this.dictionaryList as DictionaryValue[], this.currentForm, this.currentType!, this.data, '$edit').then(() => {
140
+ // data生成完成后再进行list赋值,避免list提前赋值导致的EditView提前加载导致的数据为空的加载
141
+ if (this.onInit) {
142
+ this.onInit(observeList, this.currentForm, this.currentType!, this)
143
+ }
144
+ this.observeList = observeList
145
+ if (this.observe) {
146
+ this.observeList!.startObserve(this.currentForm.getData(), this.currentType!)
147
+ } else if (getEnv('real') === 'development') {
148
+ // 开发环境下
149
+ const list: string[] = []
150
+ this.observeList.$map.forEach(item => {
151
+ if (item.$observe) {
152
+ list.push(item.$prop)
153
+ }
154
+ })
155
+ if (list.length > 0) {
156
+ console.error(`[${list.join('/')}]模块存在observe监控函数,当前observe未开启,请确认!`)
157
+ }
158
+ }
159
+ this.$nextTick(() => {
160
+ this.currentForm.clearValidate()
161
+ })
162
+ })
163
+ },
164
+ $submit(): Promise<EditAreaSubmitOption> {
165
+ return new Promise((resolve, reject) => {
166
+ this.currentForm.validate().then(() => {
167
+ const postData = this.dictionary.collectData(this.currentForm.getData(), this.dictionaryList as DictionaryValue[], this.currentType!, this.observe ? (this.observeList as ObserveList) : undefined)
168
+ resolve({ targetData: postData, originData: this.data, type: this.currentType! })
169
+ }).catch(err => {
170
+ reject(err)
171
+ })
172
+ })
173
+ },
174
+ renderEdit() {
175
+ if (this.observeList) {
176
+ const form = h(EditView, {
177
+ form: this.currentForm!,
178
+ list: this.observeList as ObserveList,
179
+ menu: this.menu,
180
+ type: this.currentType!,
181
+ labelAlign: this.labelAlign!,
182
+ gridParse: this.inline ? undefined : (this.gridParse || this.dictionary.$layout.grid.getValue(this.currentType)),
183
+ gridRowProps: this.gridRowProps!,
184
+ formProps: this.formProps,
185
+ enter: this.enter,
186
+ collapse: this.dictionary.$collapse,
187
+ disabled: this.disabled,
188
+ loading: this.loading,
189
+ onMenu: (prop: string, payload: AutoItemPayloadType<'edit'>) => {
190
+ this.$emit('menu', prop, payload)
191
+ },
192
+ onEnter: (prop: string, payload: AutoItemPayloadType<'edit'>) => {
193
+ this.$emit('enter', prop, payload)
194
+ }
195
+ })
196
+ return form
197
+ } else {
198
+ return null
199
+ }
200
+ }
201
+ },
202
+ render() {
203
+ return h('div', { class: 'complex-edit-area' }, [this.renderEdit()])
204
+ }
205
+ })
@@ -0,0 +1,179 @@
1
+ import { defineComponent, h, PropType, markRaw } from "vue"
2
+ import { Col, Form, Row } from "ant-design-vue"
3
+ import type { FormProps } from "ant-design-vue"
4
+ import { mergeData } from "@complex-suite/utils"
5
+ import { FormValue, ObserveList, DefaultInfo } from "@complex-suite/data"
6
+ import AutoItem from "./dictionary/AutoItem"
7
+ import type { AutoItemPayloadType, AutoItemProps, AutoItemParser } from "./dictionary/AutoItem"
8
+ import type { InfoViewDefaultProps } from "./InfoView"
9
+ import antdConfig from "../antdConfig"
10
+
11
+ export interface EditViewDefaultProps extends InfoViewDefaultProps {
12
+ formProps?: FormProps
13
+ choice?: number
14
+ enter?: boolean
15
+ }
16
+
17
+ export interface EditViewProps extends EditViewDefaultProps {
18
+ form: FormValue
19
+ list: ObserveList
20
+ type: string
21
+ }
22
+
23
+ export default defineComponent({
24
+ name: 'EditView',
25
+ emits: {
26
+ menu: (prop: string, _payload: AutoItemPayloadType<'edit'>) => {
27
+ return !!prop
28
+ },
29
+ enter: (prop: string, _payload: AutoItemPayloadType<'edit'>) => {
30
+ return !!prop
31
+ }
32
+ },
33
+ props: {
34
+ form: {
35
+ type: Object as PropType<EditViewProps['form']>,
36
+ required: true
37
+ },
38
+ list: {
39
+ type: Object as PropType<EditViewProps['list']>,
40
+ required: true
41
+ },
42
+ menu: {
43
+ type: Object as PropType<EditViewProps['menu']>,
44
+ required: false
45
+ },
46
+ type: {
47
+ type: String,
48
+ required: true
49
+ },
50
+ labelAlign: { // label 标签的文本对齐方式
51
+ type: String as PropType<EditViewProps['labelAlign']>,
52
+ required: false,
53
+ default: 'right'
54
+ },
55
+ gridParse: {
56
+ type: Object as PropType<EditViewProps['gridParse']>,
57
+ required: false
58
+ },
59
+ gridRowProps: { // form-model-view设置项
60
+ type: Object as PropType<EditViewProps['gridRowProps']>,
61
+ required: false
62
+ },
63
+ formProps: { // form-model-view设置项
64
+ type: Object as PropType<EditViewProps['formProps']>,
65
+ required: false
66
+ },
67
+ choice: {
68
+ type: Number,
69
+ required: false
70
+ },
71
+ enter: {
72
+ type: Boolean,
73
+ required: false
74
+ },
75
+ collapse: {
76
+ type: Boolean,
77
+ required: false
78
+ },
79
+ disabled: {
80
+ type: Boolean,
81
+ required: false
82
+ },
83
+ loading: {
84
+ type: Boolean,
85
+ required: false
86
+ }
87
+ },
88
+ computed: {
89
+ currentFormProps() {
90
+ const formProps = {
91
+ ref: 'form',
92
+ model: this.form.data,
93
+ layout: this.gridParse ? 'horizontal' : 'inline',
94
+ labelAlign: this.labelAlign
95
+ }
96
+ return mergeData(formProps, this.formProps!)
97
+ },
98
+ concatList() {
99
+ if (this.menu && this.menu.length > 0) {
100
+ return this.list.data.concat(this.menu)
101
+ } else {
102
+ return this.list.data
103
+ }
104
+ },
105
+ currentList() {
106
+ return this.concatList.filter(item => (!item.$hidden && !item.$frozen))
107
+ }
108
+ },
109
+ mounted () {
110
+ this.form.setRef(this.$refs[this.currentFormProps.ref])
111
+ },
112
+ methods: {
113
+ triggerEnter(prop: string, payload: AutoItemPayloadType<AutoItemParser>) {
114
+ if (this.enter) {
115
+ this.$emit('enter', prop, payload)
116
+ }
117
+ },
118
+ parseGrid(data: DefaultInfo) {
119
+ return antdConfig.parseGrid(this.gridParse!.parseData(data.$grid, 'main', this.type))
120
+ },
121
+ getItemProps(data: DefaultInfo, index: number) {
122
+ return {
123
+ parser: 'edit',
124
+ target: data,
125
+ index: index,
126
+ list: this.list,
127
+ type: this.type,
128
+ choice: this.choice,
129
+ gridParse: this.gridParse,
130
+ collapse: this.collapse,
131
+ disabled: this.disabled,
132
+ loading: this.loading,
133
+ form: this.form,
134
+ data: undefined,
135
+ parent: markRaw(this)
136
+ } as AutoItemProps<'edit'>
137
+ },
138
+ renderItem(item: DefaultInfo, index: number) {
139
+ return h(AutoItem, this.getItemProps(item, index))
140
+ },
141
+ renderList() {
142
+ if (!this.gridParse) {
143
+ return this.currentList.map((item, index) => {
144
+ return this.renderItem(item, index)
145
+ })
146
+ } else {
147
+ return this.currentList.map((item, index) => {
148
+ return h(Col, this.parseGrid(item), {
149
+ default: () => this.renderItem(item, index)
150
+ })
151
+ })
152
+ }
153
+ }
154
+ },
155
+ /**
156
+ * 主要模板
157
+
158
+ * @returns {VNode}
159
+ */
160
+ render() {
161
+ const layoutClass = `complex-edit-${this.gridParse ? 'grid' : 'inline'}`
162
+ const list = this.renderList()
163
+ const render = h(Form, {
164
+ class: `complex-edit ${layoutClass}`,
165
+ ...this.currentFormProps
166
+ }, {
167
+ default: () => {
168
+ if (!this.gridParse) {
169
+ return list
170
+ } else {
171
+ return h(Row, { ...this.gridRowProps }, {
172
+ default: () => list
173
+ })
174
+ }
175
+ }
176
+ })
177
+ return render
178
+ }
179
+ })
@@ -0,0 +1,74 @@
1
+ import { PropType, defineComponent, h } from 'vue'
2
+ import { dataConfig } from "@complex-suite/data"
3
+
4
+ const paddingPropList = ['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft'] as const
5
+
6
+ export default defineComponent({
7
+ name: 'FlexBox',
8
+ props: {
9
+ direction: {
10
+ type: String as PropType<'row' | 'column'>,
11
+ validator(value: string) {
12
+ return ['row', 'column'].includes(value)
13
+ },
14
+ required: false,
15
+ default: 'row'
16
+ },
17
+ height: {
18
+ type: Number,
19
+ required: true
20
+ },
21
+ width: {
22
+ type: Number,
23
+ required: true
24
+ },
25
+ paddingTop: {
26
+ type: Number,
27
+ required: false,
28
+ default: 0
29
+ },
30
+ paddingRight: {
31
+ type: Number,
32
+ required: false,
33
+ default: 0
34
+ },
35
+ paddingBottom: {
36
+ type: Number,
37
+ required: false,
38
+ default: 0
39
+ },
40
+ paddingLeft: {
41
+ type: Number,
42
+ required: false,
43
+ default: 0
44
+ }
45
+ },
46
+ render() {
47
+ const content = []
48
+ const contentHeight = this.height - this.paddingTop - this.paddingBottom
49
+ const contentWidth = this.width - this.paddingLeft - this.paddingRight
50
+ if (this.$slots) {
51
+ for (const prop in this.$slots) {
52
+ content.push(this.$slots[prop]?.({
53
+ width: contentWidth,
54
+ height: contentHeight
55
+ }))
56
+ }
57
+ }
58
+ const style = {
59
+ width: dataConfig.formatPixel(this.width),
60
+ height: dataConfig.formatPixel(this.height)
61
+ } as Record<string, string>
62
+ paddingPropList.forEach(paddingProp => {
63
+ const paddingValue = this[paddingProp]
64
+ if (paddingValue) {
65
+ style[paddingProp] = dataConfig.formatPixel(paddingValue)
66
+ }
67
+ })
68
+ const render = h('div', {
69
+ class: ['complex-flex-box', 'complex-flex-box-' + this.direction],
70
+ style: style
71
+ }, content)
72
+ return render
73
+ }
74
+ })