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

Sign up to get free protection for your applications and to get access to all the features.
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/Icon/index.tsx +1 -1
  27. package/src/packages/components/Input/index.scss +17 -5
  28. package/src/packages/components/Input/useMultipleInput.tsx +1 -1
  29. package/src/packages/components/InputNumber/number.scss +1 -1
  30. package/src/packages/components/Object/object.scss +9 -2
  31. package/src/packages/components/Select/SelectPanel.tsx +3 -0
  32. package/src/packages/components/Select/select.utils.tsx +1 -1
  33. package/src/packages/components/SelectGroup/index.tsx +37 -0
  34. package/src/packages/components/Space/index.tsx +30 -0
  35. package/src/packages/components/Space/space.scss +26 -0
  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.44",
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
  );