plain-design 1.0.0-beta.43 → 1.0.0-beta.45

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 (49) hide show
  1. package/dist/plain-design.commonjs.min.js +27 -18
  2. package/dist/plain-design.min.css +18 -17
  3. package/dist/plain-design.min.js +27 -18
  4. package/dist/report.html +38 -38
  5. package/package.json +44 -44
  6. package/src/packages/components/Application/theme/theme.ts +26 -14
  7. package/src/packages/components/AutoLoadingObserver/index.tsx +172 -0
  8. package/src/packages/components/AutoTable/auto-table.scss +19 -8
  9. package/src/packages/components/AutoTable/filter/useTableOption.filter.search.tsx +3 -3
  10. package/src/packages/components/AutoTable/use/useTableOption.fill.tsx +2 -1
  11. package/src/packages/components/AutoTable/use/useTableOption.loading.tsx +8 -2
  12. package/src/packages/components/AutoTable/use/useTableOption.pagination.tsx +5 -0
  13. package/src/packages/components/Button/button.scss +5 -5
  14. package/src/packages/components/Button/index.tsx +68 -10
  15. package/src/packages/components/Cascade/cascade.scss +2 -2
  16. package/src/packages/components/CascadePanel/flat/cascade-flat-panel.scss +21 -34
  17. package/src/packages/components/CheckboxInner/checkbox-inner.scss +1 -0
  18. package/src/packages/components/DatePicker/date.scss +1 -1
  19. package/src/packages/components/Dialog/dialog.scss +4 -1
  20. package/src/packages/components/FilterFormSingle/index.tsx +7 -2
  21. package/src/packages/components/Form/form.scss +51 -1
  22. package/src/packages/components/Form/layout/useFormLayout.tsx +47 -13
  23. package/src/packages/components/Form/validate/useFormValidation.tsx +21 -16
  24. package/src/packages/components/FormItem/FormItemValidateMessage.tsx +16 -0
  25. package/src/packages/components/FormItem/index.tsx +24 -11
  26. package/src/packages/components/Input/index.scss +17 -5
  27. package/src/packages/components/Input/useMultipleInput.tsx +1 -1
  28. package/src/packages/components/InputNumber/number.scss +1 -1
  29. package/src/packages/components/Object/object.scss +9 -2
  30. package/src/packages/components/Select/SelectPanel.tsx +3 -0
  31. package/src/packages/components/Select/select.utils.tsx +1 -1
  32. package/src/packages/components/SelectGroup/index.tsx +37 -0
  33. package/src/packages/components/Space/index.tsx +30 -0
  34. package/src/packages/components/Space/space.scss +26 -0
  35. package/src/packages/components/Table/standard/PlcOperation/PlcOperation.tsx +1 -1
  36. package/src/packages/components/Table/standard/PlcOperation/outer-operation.scss +4 -4
  37. package/src/packages/components/Table/table/body/cell.tsx +17 -12
  38. package/src/packages/components/Table/table/table.scss +17 -14
  39. package/src/packages/components/Table/table/use/useTableFormEditor.tsx +2 -0
  40. package/src/packages/components/VirtualList/useVirtualList.tsx +16 -11
  41. package/src/packages/components/VirtualTable/virtual-table.scss +1 -1
  42. package/src/packages/components/createHttp/index.tsx +4 -1
  43. package/src/packages/components/useMessage/message.scss +2 -2
  44. package/src/packages/components/useNotice/notice.scss +1 -1
  45. package/src/packages/components/usePopup/PopupItem.tsx +14 -1
  46. package/src/packages/components/usePopup/popup-item.scss +5 -1
  47. package/src/packages/components/useTooltip/index.tsx +4 -0
  48. package/src/packages/entry.tsx +3 -0
  49. package/src/packages/uses/useCollapseStyles.tsx +55 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plain-design",
3
- "version": "1.0.0-beta.43",
3
+ "version": "1.0.0-beta.45",
4
4
  "description": "",
5
5
  "main": "dist/plain-design.min.js",
6
6
  "module": "dist/plain-design.commonjs.min.js",
@@ -29,63 +29,63 @@
29
29
  "@types/react-dom": "18.2.4"
30
30
  },
31
31
  "dependencies": {
32
- "@types/color": "^3.0.3",
33
- "@types/react-transition-group": "^4.4.1",
34
- "color": "^4.2.3",
35
- "dayjs": "^1.10.4",
32
+ "@types/color": "3.0.6",
33
+ "@types/react-transition-group": "4.4.10",
34
+ "color": "4.2.3",
35
+ "dayjs": "1.11.10",
36
36
  "plain-icons": "0.0.7",
37
37
  "plain-utils": "0.1.57",
38
- "react-flip-move": "^3.0.4",
39
- "react-transition-group": "^4.4.1"
38
+ "react-flip-move": "3.0.5",
39
+ "react-transition-group": "4.4.5"
40
40
  },
41
41
  "devDependencies": {
42
- "@babel/plugin-proposal-optional-chaining": "^7.21.0",
43
- "@babel/plugin-transform-class-properties": "^7.22.3",
44
- "@babel/preset-env": "^7.13.15",
45
- "@babel/preset-react": "^7.13.13",
46
- "@babel/preset-typescript": "^7.13.0",
42
+ "@babel/plugin-proposal-optional-chaining": "7.21.0",
43
+ "@babel/plugin-transform-class-properties": "7.23.3",
44
+ "@babel/preset-env": "7.23.7",
45
+ "@babel/preset-react":"7.23.3",
46
+ "@babel/preset-typescript": "7.23.3",
47
47
  "@types/classnames": "^2.2.11",
48
48
  "@types/react": "18.2.4",
49
49
  "@types/react-dom": "18.2.4",
50
- "@typescript-eslint/eslint-plugin": "^4.18.0",
51
- "@typescript-eslint/parser": "^4.18.0",
52
- "@vue/cli-plugin-babel": "~4.5.0",
53
- "@vue/cli-plugin-eslint": "~4.5.0",
54
- "@vue/cli-plugin-typescript": "~4.5.0",
55
- "@vue/cli-service": "~4.5.0",
56
- "@vue/compiler-sfc": "^3.2.21",
50
+ "@typescript-eslint/eslint-plugin": "4.33.0",
51
+ "@typescript-eslint/parser": "4.33.0",
52
+ "@vue/cli-plugin-babel": "4.5.19",
53
+ "@vue/cli-plugin-eslint": "4.5.19",
54
+ "@vue/cli-plugin-typescript": "4.5.19",
55
+ "@vue/cli-service": "4.5.19",
56
+ "@vue/compiler-sfc": "3.4.3",
57
57
  "@vue/eslint-config-typescript": "^7.0.0",
58
- "autoprefixer": "^8.6.5",
59
- "axios": "^0.21.1",
60
- "babel-plugin-import": "^1.13.3",
61
- "babel-plugin-syntax-jsx": "^6.18.0",
62
- "core-js": "^3.8.3",
58
+ "autoprefixer": "8.6.5",
59
+ "axios": "1.6.8",
60
+ "babel-plugin-import": "1.13.8",
61
+ "babel-plugin-syntax-jsx": "6.18.0",
62
+ "core-js": "3.35.0",
63
63
  "cross-env": "^7.0.3",
64
64
  "css-loader": "3.6.0",
65
- "eslint": "^6.7.2",
66
- "eslint-plugin-vue": "^7.0.0",
65
+ "eslint": "6.8.0",
66
+ "eslint-plugin-vue": "7.20.0",
67
67
  "exceljs": "^4.2.1",
68
68
  "file-saver": "^2.0.5",
69
- "fork-ts-checker-webpack-plugin": "^6.2.4",
70
- "mini-css-extract-plugin": "^1.4.1",
69
+ "fork-ts-checker-webpack-plugin": "6.5.3",
70
+ "mini-css-extract-plugin": "1.6.2",
71
71
  "mockjs": "^1.1.0",
72
- "plain-design-composition": "^0.0.186",
73
- "postcss": "^8.2.13",
74
- "postcss-loader": "^4.2.0",
75
- "qs": "^6.10.1",
76
- "react": "^18.0.0",
77
- "react-dom": "^18.0.0",
78
- "sass": "~1.32.13",
79
- "sass-loader": "^8.0.2",
80
- "style-loader": "^2.0.0",
81
- "ts-loader": "^9.4.2",
82
- "ts-node": "^9.1.1",
83
- "tslib": "^2.5.0",
72
+ "plain-design-composition": "^0.0.189",
73
+ "postcss": "8.4.32",
74
+ "postcss-loader": "4.3.0",
75
+ "qs": "6.11.2",
76
+ "react": "18.2.0",
77
+ "react-dom": "18.2.0",
78
+ "sass": "1.32.13",
79
+ "sass-loader": "8.0.2",
80
+ "style-loader": "2.0.0",
81
+ "ts-loader": "9.5.1",
82
+ "ts-node": "9.1.1",
83
+ "tslib": "2.6.2",
84
84
  "typescript": "^4.9.5",
85
- "url-loader": "^4.1.1",
86
- "vue": "^3.2.21",
87
- "vue-template-compiler": "^2.6.12",
85
+ "url-loader": "4.1.1",
86
+ "vue": "3.4.3",
87
+ "vue-template-compiler": "2.7.16",
88
88
  "webpack-bundle-analyzer": "^4.4.1",
89
- "webpack-cli": "^4.6.0"
89
+ "webpack-cli": "4.10.0"
90
90
  }
91
91
  }
@@ -67,7 +67,7 @@ function createOtherVars(prefix: string | null, referenceVariable: (name: string
67
67
 
68
68
  return {
69
69
  /*---------------------------------------base-------------------------------------------*/
70
- 'font-family': "Inter,-apple-system,BlinkMacSystemFont,PingFang SC,Hiragino Sans GB,noto sans,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif",
70
+ 'font-family': `v-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`,
71
71
  'scrollbar-size': '9px',
72
72
  'border-color': "rgba(0, 0, 0, .06)",
73
73
  'background-color': "#ffffff",
@@ -75,7 +75,7 @@ function createOtherVars(prefix: string | null, referenceVariable: (name: string
75
75
  'background-hover': referenceVariable("gray-2"),
76
76
  'scrollbar-color': referenceVariable("gray-3"),
77
77
  'loading-mask-color': 'rgba(255,255,255,0.5)',
78
- 'line-height': 'plv(line-height)',
78
+ 'line-height': '1.5715',
79
79
 
80
80
  'font-size-mini': '12px',
81
81
  'font-size-small': '12px',
@@ -88,12 +88,17 @@ function createOtherVars(prefix: string | null, referenceVariable: (name: string
88
88
  'text-3': 'rgba(0,0,0,0.45)',
89
89
  'text-4': 'rgba(0,0,0,0.25)',
90
90
  'text-placeholder': 'rgba(0,0,0,0.35)',
91
+ /*---------------------------------------background-color-------------------------------------------*/
92
+ 'bg-1': '#f2f3f5',
93
+ 'bg-2': '#FFFFFF',
94
+ 'bg-3': '#FFFFFF',
95
+ 'bg-4': '#FFFFFF',
91
96
  /*---------------------------------------margin-------------------------------------------*/
92
97
  /*height of sizes*/
93
- 'margin-mini': '12px',
98
+ 'margin-mini': '8px',
94
99
  'margin-small': '12px',
95
100
  'margin-normal': '16px',
96
- 'margin-large': '16px',
101
+ 'margin-large': '20px',
97
102
  /*---------------------------------------box-------------------------------------------*/
98
103
  /*min-width of sizes*/
99
104
  'box-size-mini-min-width': '',
@@ -101,10 +106,10 @@ function createOtherVars(prefix: string | null, referenceVariable: (name: string
101
106
  'box-size-normal-min-width': '68px',
102
107
  'box-size-large-min-width': '88px',
103
108
  /*height of sizes*/
104
- 'box-size-mini-height': '24px',
105
- 'box-size-small-height': '28px',
106
- 'box-size-normal-height': '32px',
107
- 'box-size-large-height': '36px',
109
+ 'box-size-mini-height': '26px',
110
+ 'box-size-small-height': '30px',
111
+ 'box-size-normal-height': '34px',
112
+ 'box-size-large-height': '40px',
108
113
  /*padding x of sizes*/
109
114
  'box-size-mini-padding': '0 11px',
110
115
  'box-size-small-padding': '0 15px',
@@ -121,7 +126,15 @@ function createOtherVars(prefix: string | null, referenceVariable: (name: string
121
126
  'box-size-normal-border-radius': '2px',
122
127
  'box-size-large-border-radius': '2px',
123
128
  /*---------------------------------------input-------------------------------------------*/
124
- 'input-padding-x': '11px',
129
+ 'input-padding-x-mini': '9px',
130
+ 'input-padding-x-small': '11px',
131
+ 'input-padding-x-normal': '13px',
132
+ 'input-padding-x-large': '15px',
133
+
134
+ 'input-clear-size-mini': '16px',
135
+ 'input-clear-size-small': '18px',
136
+ 'input-clear-size-normal': '21px',
137
+ 'input-clear-size-large': '23px',
125
138
  /*---------------------------------------dialog-------------------------------------------*/
126
139
  'dialog-mask-color': 'rgba(0,0,0,0.3)',
127
140
  'dialog-head-padding-x': '20px',
@@ -161,11 +174,6 @@ function createOtherVars(prefix: string | null, referenceVariable: (name: string
161
174
  'dropdown-size-normal-padding-y': '6px',
162
175
  'dropdown-size-large-padding-x': '10px',
163
176
  'dropdown-size-large-padding-y': '6px',
164
- /*---------------------------------------input-------------------------------------------*/
165
- 'input-clear-size-mini': '16px',
166
- 'input-clear-size-small': '16px',
167
- 'input-clear-size-normal': '20px',
168
- 'input-clear-size-large': '20px',
169
177
  /*---------------------------------------tag-------------------------------------------*/
170
178
  'tag-size-mini-height': '20px',
171
179
  'tag-size-small-height': '22px',
@@ -244,6 +252,10 @@ export function createThemeConfigurationData(prefix: string | null, config?: Dee
244
252
  'text-2': 'rgba(255,255,255,0.65)',
245
253
  'text-3': 'rgba(255,255,255,0.45)',
246
254
  'text-4': 'rgba(255,255,255,0.25)',
255
+ 'bg-1': '#101014',
256
+ 'bg-2': '#18181c',
257
+ 'bg-3': '#18181c',
258
+ 'bg-4': '#242429',
247
259
  'text-placeholder': 'rgba(255,255,255,0.35)',
248
260
  'dialog-mask-color': 'rgba(0,0,0,0.75)',
249
261
  // 'table-head-background': '#252527',
@@ -0,0 +1,172 @@
1
+ import {computed, createCounter, onBeforeUnmount, reactive} from "plain-design-composition";
2
+ import {delay} from "plain-utils/utils/delay";
3
+
4
+ export const AutoLoadingObserver = (() => {
5
+
6
+ const globalState = reactive({
7
+ /**
8
+ * 当前激活的observer,比如点击按钮的话,emit click事件之前激活这个按钮的observer,emit click之后清除这个observer
9
+ * @author 韦胜健
10
+ * @date 2024/3/20 16:11
11
+ */
12
+ currentObserver: null as null | { observerId: string },
13
+ /**
14
+ * 正在loading的observerId,值是一个数字,是subjectId;激活observer的时候可能会一次性并发执行多个异步任务,所以这里值是一个数字,当值清空的时候意味着关闭observer的加载状态
15
+ * @author 韦胜健
16
+ * @date 2024/3/20 16:11
17
+ */
18
+ loadingMap: {} as Record<string, string[] | undefined>
19
+ });
20
+
21
+ const utils = {
22
+ /*创建一个observerId*/
23
+ nextObserverId: createCounter('auto_loading_observer'),
24
+ /*创建一个subjectId*/
25
+ nextSubjectId: createCounter('auto_loading_subject'),
26
+ };
27
+
28
+ /**
29
+ * 创建一个observer,要记得组件销毁的时候执行dispose
30
+ * @author 韦胜健
31
+ * @date 2024/3/20 16:13
32
+ */
33
+ const useObserver = () => {
34
+ const observerId = utils.nextObserverId();
35
+ const tapStart = () => {globalState.currentObserver = { observerId };};
36
+ const tapEnd = () => {globalState.currentObserver = null;};
37
+ const isLoading = computed(() => !!globalState.loadingMap[observerId]?.length);
38
+ onBeforeUnmount(() => isLoading.effect.stop());
39
+ return reactive({ tapStart, tapEnd, isLoading });
40
+ };
41
+
42
+ /**
43
+ * 一个异步任务执行时,调用这个subject
44
+ * @author 韦胜健
45
+ * @date 2024/3/20 16:14
46
+ */
47
+ const subject = (promise: Promise<any>) => {
48
+ /*没有激活的observer,证明当前异步任务不需要开启loading*/
49
+ if (!globalState.currentObserver) {return;}
50
+
51
+ /*为本次执行异步任务创建一个subjectId*/
52
+ const subjectId = utils.nextSubjectId();
53
+ /*当前激活的observerId*/
54
+ const { observerId } = globalState.currentObserver;
55
+
56
+ /*关联subjectId与observerId,开启observer的加载状态*/
57
+ if (!globalState.loadingMap[observerId]) {
58
+ globalState.loadingMap = { ...globalState.loadingMap, [observerId]: [subjectId] };
59
+ } else {
60
+ globalState.loadingMap[observerId]!.push(subjectId);
61
+ }
62
+
63
+ const startDatetime = Date.now(); // 异步任务执行开始时间
64
+ const minDatetime = 1000; // loading最小时间
65
+
66
+ /*不论成功或者失败,都解除关联subjectId与observerId*/
67
+ promise.finally(async () => {
68
+
69
+ /*异步任务执行结束之后,立即将observe放回去,因为可能是串行执行的异步任务,下一个异步任务也要延续这个observe的loading状态*/
70
+ globalState.currentObserver = { observerId };
71
+ delay().then(() => {globalState.currentObserver = null;});
72
+
73
+ /*如果耗费时间小于最小时间,则等待剩余的时间再关闭loading*/
74
+ const waitDatetime = startDatetime + minDatetime - Date.now();
75
+ if (waitDatetime > 0) {await delay(waitDatetime);}
76
+
77
+ const index = globalState.loadingMap[observerId]?.indexOf(subjectId);
78
+ if (index != null && index > -1) {
79
+ const arr = [...globalState.loadingMap[observerId]!];
80
+ arr.splice(index, 1);
81
+ if (arr.length) {
82
+ globalState.loadingMap[observerId] = arr;
83
+ } else {
84
+ const map = { ...globalState.loadingMap };
85
+ delete map[observerId];
86
+ globalState.loadingMap = map;
87
+ }
88
+ }
89
+
90
+ });
91
+ };
92
+
93
+ const request = (id: string, duraiton?: number) => {
94
+
95
+ const duration = duraiton || (Math.random() * 2000 + 1000);
96
+ const promise = delay(duration).then(() => {
97
+ console.log('request:', id);
98
+ return { id, duration };
99
+ });
100
+ AutoLoadingObserver.subject(promise);
101
+
102
+ return promise;
103
+ };
104
+
105
+ return {
106
+ useObserver,
107
+ subject,
108
+ globalState,
109
+ request,
110
+ };
111
+ })();
112
+
113
+
114
+ /*export const NextTick = (() => {
115
+
116
+ const generateNextTickId = createCounter('next_tick');
117
+ const nextTickMap = {} as Record<string, boolean | undefined>;
118
+
119
+ function clearNextTick(id: string) {
120
+ delete nextTickMap[id];
121
+ }
122
+
123
+ function setNextTick(fn: SimpleFunction) {
124
+ const id = generateNextTickId();
125
+ nextTickMap[id] = true;
126
+ console.log('nextTickMap', nextTickMap);
127
+
128
+ delay().then(() => {
129
+ if (id in nextTickMap) {
130
+ fn();
131
+ delete nextTickMap[id];
132
+ }
133
+ });
134
+
135
+ return id;
136
+ }
137
+
138
+ return {
139
+ clearNextTick,
140
+ setNextTick,
141
+ };
142
+ })();
143
+
144
+ export const NextTick_TEST = (() => {
145
+
146
+ const generateNextTickId = createCounter('next_tick');
147
+ const nextTickMap = {} as Record<string, boolean | undefined>;
148
+
149
+ function clearNextTick(id: string) {
150
+ delete nextTickMap[id];
151
+ }
152
+
153
+ function setNextTick(fn: SimpleFunction) {
154
+ const id = generateNextTickId();
155
+ nextTickMap[id] = true;
156
+ console.log('nextTickMap', nextTickMap);
157
+
158
+ delay(1000).then(() => {
159
+ if (id in nextTickMap) {
160
+ fn();
161
+ delete nextTickMap[id];
162
+ }
163
+ });
164
+
165
+ return id;
166
+ }
167
+
168
+ return {
169
+ clearNextTick,
170
+ setNextTick,
171
+ };
172
+ })();*/
@@ -2,6 +2,16 @@
2
2
  position: relative;
3
3
 
4
4
  @include sizeMixin(auto-table, (font-size)) {
5
+ .table-operation-bar {
6
+ .table-operation-bar-left {
7
+ @include comp(input-group) {
8
+ display: inline-flex;
9
+ & + button {
10
+ margin-left: $margin;
11
+ }
12
+ }
13
+ }
14
+ }
5
15
  }
6
16
 
7
17
  .virtual-table-head-table {
@@ -19,14 +29,9 @@
19
29
  }
20
30
  }
21
31
  .table-operation-bar {
22
- .table-operation-bar-left {
23
- @include comp(input-group) {
24
- display: inline-flex;
25
- & + button {
26
- margin-left: 4px;
27
- }
28
- }
29
- }
32
+ position: relative;
33
+ /*virtual-table-head-table-wrapper的z-index是4*/
34
+ z-index: 5;
30
35
  }
31
36
 
32
37
  &.filter-form-expanded {
@@ -63,6 +68,12 @@
63
68
  }
64
69
  }
65
70
  }
71
+
72
+ &.auto-table-loading {
73
+ .table-empty {
74
+ display: none;
75
+ }
76
+ }
66
77
  }
67
78
 
68
79
  @include comp(auto-table-tips) {
@@ -51,8 +51,8 @@ export const useTableOptionFilterSearch = AutoModule.createRegistration((
51
51
  * @author 韦胜健
52
52
  * @date 2023.1.8 19:06
53
53
  */
54
- onNormalSearch: () => {
55
- methods.pageMethods.reload();
54
+ onNormalSearch: async () => {
55
+ await methods.pageMethods.reload();
56
56
  },
57
57
  /**
58
58
  * 当设置面板中的搜索栏值变化时取出来变化的值,更新到外部的filter form single组件实例中
@@ -136,7 +136,7 @@ export const useTableOptionFilterSearch = AutoModule.createRegistration((
136
136
  {...{
137
137
  filterOptions: filterOptions.value,
138
138
  initialState: state.data,
139
- onSearch: handler.onNormalSearch,
139
+ handleSearch: handler.onNormalSearch,
140
140
  ...config.searchAttrs,
141
141
  }}
142
142
  />
@@ -80,6 +80,7 @@ export const useTableOptionFill = AutoModule.createRegistration((
80
80
  };
81
81
  })();
82
82
 
83
+ await delay(73)
83
84
  /**
84
85
  * 计算可以用来渲染行的高度
85
86
  * parent.top+parent.height可以得到父节点底边界的top值;
@@ -101,7 +102,7 @@ export const useTableOptionFill = AutoModule.createRegistration((
101
102
  });*/
102
103
 
103
104
  /*计算撑满高度的行数*/
104
- const showRows = Math.floor(availableHeight / bodyRowHeight) - 1;
105
+ const showRows = Math.floor(availableHeight / bodyRowHeight);
105
106
 
106
107
  /*更新分页查询信息*/
107
108
  pagination.state.size = showRows;
@@ -19,8 +19,10 @@ export const useTableOptionLoading = AutoModule.createRegistration(({ hooks }) =
19
19
  metas: [] as iTableOptionLoadingMeta[],
20
20
  });
21
21
 
22
+ const isLoading = () => !!state.metas.length;
23
+
22
24
  hooks.onTableRender.use({
23
- processor: ({ list, render }) => {!!state.metas.length && list.push({ render, key: 'loading', seq: 0 });},
25
+ processor: ({ list, render }) => {isLoading() && list.push({ render, key: 'loading', seq: 0 });},
24
26
  render: () => (
25
27
  !!state.metas.length && <div className="auto-table-loading-wrapper">
26
28
  {(() => {
@@ -40,6 +42,10 @@ export const useTableOptionLoading = AutoModule.createRegistration(({ hooks }) =
40
42
  )
41
43
  });
42
44
 
45
+ hooks.onTableClass.use((classList) => {
46
+ isLoading() && classList.push('auto-table-loading');
47
+ });
48
+
43
49
  const minTimerDuration = 500;
44
50
 
45
51
  const loading = (meta?: Omit<iTableOptionLoadingMeta, 'id'>) => {
@@ -59,7 +65,7 @@ export const useTableOptionLoading = AutoModule.createRegistration(({ hooks }) =
59
65
  };
60
66
  };
61
67
 
62
- return { state, loading };
68
+ return { state, loading, isLoading };
63
69
  });
64
70
 
65
71
  const nextLoadingId = createCounter('auto_table_loading');
@@ -71,6 +71,11 @@ export const useTableOptionPagination = AutoModule.createRegistration((
71
71
  pageSizeOptions: deepcopy(config.pageSizeOptions),
72
72
  });
73
73
 
74
+ if (!!config.showRows && state.pageSizeOptions.indexOf(config.showRows) === -1) {
75
+ const index = state.pageSizeOptions.findIndex(i => i > config.showRows);
76
+ state.pageSizeOptions.splice(index, 0, config.showRows);
77
+ }
78
+
74
79
  const handler = {
75
80
  onSizeChange: async (size: number) => {await methods.changeSize(size);},
76
81
  onJump: async (page: number) => {await methods.jump(page);},
@@ -147,11 +147,11 @@
147
147
  top: 1px;
148
148
  }
149
149
 
150
- &:not(.button-icon-only) {
151
- & > .button-icon {
152
- margin-right: 4px;
153
- }
154
- }
150
+ //&:not(.button-icon-only) {
151
+ // & > .button-icon {
152
+ // margin-right: 4px;
153
+ // }
154
+ //}
155
155
 
156
156
  &.button-no-padding {
157
157
  padding: 0;
@@ -1,5 +1,5 @@
1
1
  import './button.scss';
2
- import {computed, designComponent, getComponentCls, iHTMLButtonElement, mergeAttrs, PropType, reactive, useClasses, useNumber, useRefs, useStyles, watch} from "plain-design-composition";
2
+ import {computed, designComponent, getComponentCls, iHTMLButtonElement, mergeAttrs, PropType, reactive, StyleProperties, useClasses, useNumber, useRefs, useStyles, watch} from "plain-design-composition";
3
3
  import {EditProps, useEdit} from "../../uses/useEdit";
4
4
  import {StyleProps, ThemeMode, ThemeStatus, useStyle} from "../../uses/useStyle";
5
5
  import {throttle} from "plain-utils/utils/throttle";
@@ -8,6 +8,8 @@ import {useClickWave} from "../../directives/ClickWave";
8
8
  import {Icon} from "../Icon";
9
9
  import {Loading} from "../Loading";
10
10
  import {ButtonGroup} from "../ButtonGroup";
11
+ import {AutoLoadingObserver} from "../AutoLoadingObserver";
12
+ import {useCollapseStyles} from "../../uses/useCollapseStyles";
11
13
 
12
14
  export const Button = designComponent({
13
15
  name: '-button',
@@ -22,7 +24,7 @@ export const Button = designComponent({
22
24
  block: { type: Boolean }, // 块级元素
23
25
  throttleClick: { type: [Number, Boolean] }, // click节流
24
26
  asyncHandler: { type: Function as PropType<(e: MouseEvent) => void> }, // 异步处理函数,会自动开启关闭loading状态
25
-
27
+ autoLoading: { type: Boolean, default: true, }, // 是否自动检测异步任务的执行并且开启loading
26
28
  ...EditProps,
27
29
  ...StyleProps,
28
30
 
@@ -41,7 +43,14 @@ export const Button = designComponent({
41
43
  });
42
44
  const { numberState } = useNumber(props, ['width']);
43
45
  const { styleComputed } = useStyle();
44
- const { editState, editComputed } = useEdit();
46
+ const autoLoadingObserver = AutoLoadingObserver.useObserver();
47
+ const { editState, editComputed } = useEdit({
48
+ adjust: (ret) => {
49
+ if (props.autoLoading && autoLoadingObserver.isLoading && !ret.loading) {
50
+ ret.loading = true;
51
+ }
52
+ }
53
+ });
45
54
 
46
55
  const group = ButtonGroup.use.inject(null);
47
56
  const mode = computed(() => props.mode || group?.props.mode || 'flat');
@@ -49,6 +58,11 @@ export const Button = designComponent({
49
58
 
50
59
  const state = reactive({
51
60
  handleClick: null as ((e: MouseEvent) => void) | null,
61
+ handleClickWrapper: (e: MouseEvent) => {
62
+ props.autoLoading && autoLoadingObserver.tapStart();
63
+ state.handleClick?.(e);
64
+ props.autoLoading && autoLoadingObserver.tapEnd();
65
+ },
52
66
  handleClickInner: async (e: MouseEvent) => {
53
67
  // e.stopPropagation();
54
68
  if (!editComputed.value.editable) {
@@ -101,14 +115,50 @@ export const Button = designComponent({
101
115
  'button-block': !!props.block,
102
116
  'button-disabled': !!editComputed.value.disabled,
103
117
  'button-readonly': !!editComputed.value.readonly,
104
- 'button-icon-only': !!props.icon && !props.label,
118
+ 'button-icon-only': buttonIconOnly.value,
105
119
  },
106
120
  ]));
107
121
 
108
- const styles = useStyles(style => {style.width = unit(numberState.width);});
122
+ const buttonIconOnly = computed(() => !!props.icon && !props.label);
123
+
124
+ const styles = useStyles(style => {
125
+ style.width = unit(numberState.width);
126
+ });
109
127
 
110
128
  useClickWave({ elGetter: () => refs.el, optionsGetter: () => ({ size: () => styleComputed.value.size, disabled: !editComputed.value.editable }), });
111
129
 
130
+ const { loadingCollapse, iconCollapse } = (() => {
131
+ const active = () => ({
132
+ height: '1em',
133
+ width: '1em',
134
+ transition: 'all 300ms ease',
135
+ transformOrigin: 'center',
136
+ paddingRight: !buttonIconOnly.value ? '4px' : '',
137
+ transform: 'scale(1)'
138
+ });
139
+ const inactive = (): StyleProperties => ({
140
+ height: '0',
141
+ width: '0',
142
+ transition: 'all 300ms ease',
143
+ transformOrigin: 'center',
144
+ paddingRight: !buttonIconOnly.value ? '0' : '',
145
+ transform: 'scale(0)'
146
+ });
147
+ /*没有icon的时候,单独处理loading,有icon的情况下,loading在icon中渲染*/
148
+ const loadingCollapse = useCollapseStyles({
149
+ isShow: () => !!editComputed.value.loading && !props.icon,
150
+ active,
151
+ inactive,
152
+ });
153
+ /*有icon的时候一直显示icon*/
154
+ const iconCollapse = useCollapseStyles({
155
+ isShow: () => !!props.icon,
156
+ active,
157
+ inactive,
158
+ });
159
+ return { loadingCollapse, iconCollapse };
160
+ })();
161
+
112
162
  return {
113
163
  refer: {
114
164
  refs,
@@ -124,19 +174,27 @@ export const Button = designComponent({
124
174
  },
125
175
  props.nativeAttrs,
126
176
  {
127
- onClick: state.handleClick!,
177
+ onClick: state.handleClickWrapper!,
128
178
  type: props.type as any,
129
179
  disabled: editComputed.value.disabled!,
130
180
  readOnly: editComputed.value.readonly || props.customReadonly,
131
181
  }
132
182
  )}
133
183
  >
134
- {(editComputed.value.loading || props.icon) && (
135
- <span className="button-icon">
136
- {!!editComputed.value.loading && <Loading type="kappa"/>}
137
- {(!!props.icon && !editComputed.value.loading) ? <Icon icon={props.icon} style={{ verticalAlign: '' }}/> : null}
184
+ {/*没有icon的时候,单独处理loading,有icon的情况下,loading在icon中渲染*/}
185
+ {!props.icon && loadingCollapse.show && (
186
+ <span className="button-icon" style={loadingCollapse.styles} onTransitionEnd={loadingCollapse.onTransitionEnd} key="loading">
187
+ <Loading type="kappa"/>
138
188
  </span>
139
189
  )}
190
+ {iconCollapse.show && (
191
+ <span className="button-icon" style={iconCollapse.styles} onTransitionEnd={iconCollapse.onTransitionEnd} key="icon">
192
+ {editComputed.value.loading ?
193
+ <Loading type="kappa"/> :
194
+ <Icon icon={props.icon} style={{ verticalAlign: '' }}/>}
195
+ </span>
196
+ )}
197
+
140
198
  {slots.default(!props.icon && props.label?.length === 2 ? props.label.split('').join(' ') : props.label)}
141
199
  </button>
142
200
  );