plain-design 1.0.0-beta.66 → 1.0.0-beta.68

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plain-design",
3
- "version": "1.0.0-beta.66",
3
+ "version": "1.0.0-beta.68",
4
4
  "description": "",
5
5
  "main": "dist/plain-design.min.js",
6
6
  "module": "dist/plain-design.commonjs.min.js",
@@ -209,6 +209,7 @@
209
209
  }
210
210
  }
211
211
  }
212
+
212
213
  &:not(.form-vertical-label) {
213
214
  @include prefix(form-item) {
214
215
  .form-item-label {
@@ -216,4 +217,10 @@
216
217
  }
217
218
  }
218
219
  }
220
+
221
+ &.form-hide-label {
222
+ .form-item-label {
223
+ display: none;
224
+ }
225
+ }
219
226
  }
@@ -43,6 +43,7 @@ export const Form = designComponent({
43
43
  {
44
44
  ['form-vertical-label']: !!props.verticalLabel,
45
45
  ['form-column-center']: !!props.singleColumnCenter,
46
+ ['form-hide-label']: !!props.hideLabel,
46
47
  },
47
48
  ]);
48
49
 
@@ -42,6 +42,7 @@ export const FormLayoutPropsOption = {
42
42
  gutter: { type: Number }, // 列间隔
43
43
  rowGutter: { type: Number }, // 行间隔
44
44
  validateMessagePosition: { type: String as PropType<typeof FormValidateMessagePosition.TYPE> }, // 校验消息的位置
45
+ hideLabel: { type: Boolean }, // 隐藏form-item的label
45
46
  } as const;
46
47
 
47
48
  /**
@@ -152,6 +153,9 @@ export const useFormLayout = (() => {
152
153
  * @date 2022.9.4 23:21
153
154
  */
154
155
  const labelWidth = computed((): number | string => {
156
+ if (form.props.hideLabel) {
157
+ return 0;
158
+ }
155
159
  /*纵向文本表单情况下,文本宽度占用整行*/
156
160
  if (form.props.verticalLabel) {
157
161
  return '100%';
@@ -233,7 +237,7 @@ export const useFormLayout = (() => {
233
237
  */
234
238
  const labelStyles = useStyles(style => {
235
239
  if (!form.isSingleColumn.value) {
236
- if (!!labelWidth.value && !form.props.verticalLabel) {
240
+ if (labelWidth.value != null && !form.props.verticalLabel) {
237
241
  style.width = unit(labelWidth.value);
238
242
  }
239
243
  }
@@ -245,7 +249,7 @@ export const useFormLayout = (() => {
245
249
  */
246
250
  const contentStyles = useStyles(style => {
247
251
  if (!form.isSingleColumn.value) {
248
- if (!!labelWidth.value && !form.props.verticalLabel) {
252
+ if (labelWidth.value != null && !form.props.verticalLabel) {
249
253
  style.width = `calc(100% - ${unit(labelWidth.value)})`;
250
254
  }
251
255
  } else {
@@ -7,9 +7,6 @@ import './theme-locale-selector.scss';
7
7
 
8
8
  export const ThemeLocaleSelector = designComponent({
9
9
  name: 'theme-locale-selector',
10
- props: {
11
- i18nManager: {},
12
- },
13
10
  setup({}) {
14
11
  const classes = useClassCache(() => [
15
12
  getComponentCls('theme-selector'),
@@ -0,0 +1,139 @@
1
+ import {pathJoin} from "plain-utils/string/pathJoin";
2
+ import {PlainObject} from "plain-utils/utils/event";
3
+ import qs from "qs";
4
+
5
+ /**
6
+ * 拦截ajax请求,模拟数据mock
7
+ * @author 韦胜健
8
+ * @date 2024/5/6 14:34
9
+ */
10
+ export function createRequestInterceptor({ baseURL }: { baseURL?: string }) {
11
+
12
+ baseURL = pathJoin(baseURL, '/');
13
+
14
+ const requestInterceptors: iRequestInterceptor[] = [];
15
+
16
+ /*拦截send方法,如果检测到url需要mock,则返回mock结果*/
17
+ const _send = XMLHttpRequest.prototype.send;
18
+ /*在调用xhr.open的时候保存url,因为在send的时候xhr.responseURL是空的*/
19
+ const _open = XMLHttpRequest.prototype.open;
20
+
21
+ // @ts-ignore
22
+ XMLHttpRequest.prototype.open = function (method, url, async, username, password) {
23
+ // @ts-ignore
24
+ this._openData = { method, url, async, username, password };
25
+ return _open.apply(this, [method, url, async, username, password]);
26
+ };
27
+
28
+ XMLHttpRequest.prototype.send = function (data: any) {
29
+ // @ts-ignore
30
+ const responseURL: string = this._openData.url;
31
+ // console.log('xhr send interceptor -> ', this, `(${responseURL})`, data);
32
+
33
+ /*计算请求url以及url参数,此时url为完整的可能带baseURL的完整路径*/
34
+ let { url: _url, param } = ((): { url: string, param: PlainObject | undefined } => {
35
+ const separatorIndex = responseURL.indexOf('?');
36
+ if (separatorIndex === -1) {
37
+ return {
38
+ url: responseURL,
39
+ param: undefined
40
+ };
41
+ } else {
42
+ return {
43
+ url: responseURL.slice(0, separatorIndex),
44
+ param: qs.parse(responseURL.slice(separatorIndex + 1))
45
+ };
46
+ }
47
+ })();
48
+
49
+ // console.log({ _url, param });
50
+
51
+ _url = pathJoin(_url, '/');
52
+
53
+ // console.log({ _url, param });
54
+
55
+ /*计算url相对于baseURL的相对路径,以及标识isMatchBaseURL,是否匹配baseURL*/
56
+ const { url, isMatchBaseURL } = ((): { url: string, isMatchBaseURL: boolean } => {
57
+ if (!baseURL) {
58
+ return { url: _url, isMatchBaseURL: false };
59
+ } else {
60
+ if (_url == baseURL) {
61
+ return { url: '/', isMatchBaseURL: true };
62
+ } else {
63
+ if (_url.indexOf(baseURL) === 0) {
64
+ return {
65
+ url: _url.slice(baseURL.length),
66
+ isMatchBaseURL: true,
67
+ };
68
+ } else {
69
+ return {
70
+ url: _url,
71
+ isMatchBaseURL: false,
72
+ };
73
+ }
74
+ }
75
+ }
76
+ })();
77
+
78
+ // console.log({ url, isMatchBaseURL });
79
+
80
+ /*判断本次请求是否需要mock*/
81
+ const requestInterceptor = requestInterceptors.find(i => {return typeof i.url === "string" ? i.url == url : i.url.test(url);});
82
+
83
+ if (!!requestInterceptor) {
84
+ if (typeof data === "string") {
85
+ try {
86
+ data = JSON.parse(data);
87
+ } catch (e) {
88
+ try {
89
+ data = qs.parse(data);
90
+ } catch (e) {
91
+ data = undefined;
92
+ }
93
+ }
94
+ }
95
+ Promise.resolve(requestInterceptor.handler({ url, isMatchBaseURL, param, data })).then((respData: any) => {
96
+ // @ts-ignore
97
+ // this.readyState = 4;
98
+ // @ts-ignore
99
+ // this.responseText = JSON.stringify(respData);
100
+ // @ts-ignore
101
+ Object.defineProperty(this, 'responseText', {
102
+ get(): any {
103
+ return respData;
104
+ }
105
+ });
106
+ // @ts-ignore
107
+ this.onloadend();
108
+ });
109
+ } else {
110
+ return _send.apply(this, [data]);
111
+ }
112
+ };
113
+
114
+ function intercept(url: iRequestInterceptor['url'], handler: iRequestInterceptor['handler']): () => void
115
+ function intercept(config: iRequestInterceptor): () => void
116
+ function intercept(config: iRequestInterceptor | iRequestInterceptor['url'], handler?: iRequestInterceptor["handler"]) {
117
+ const _config: iRequestInterceptor = typeof config === "string" || config instanceof RegExp ?
118
+ { url: config, handler: handler! } :
119
+ config;
120
+ requestInterceptors.push(_config);
121
+ return () => {
122
+ const index = requestInterceptors.indexOf(_config);
123
+ index > -1 && requestInterceptors.splice(index, 1);
124
+ };
125
+ };
126
+
127
+ return {
128
+ intercept,
129
+ };
130
+ }
131
+
132
+ export interface iRequestInterceptor {
133
+ /*要拦截的url,可以是字符串,也可以是正则表达式*/
134
+ url: string | RegExp,
135
+ /*自定义处理请求并且返回请求结果,支持异步*/
136
+ handler: (requestConfig: { url: string, isMatchBaseURL: boolean, param: PlainObject | undefined, data: PlainObject | undefined }) => PlainObject | Promise<PlainObject>
137
+ }
138
+
139
+ export default createRequestInterceptor;
@@ -226,4 +226,27 @@
226
226
  @include whenShow {.popup-item-body{transform: initial}}
227
227
  /*@formatter:on*/
228
228
  }
229
+
230
+ &.popup-item-animation-clip {
231
+ /*@formatter:off*/
232
+ &,& .popup-item-content {transition: all ease 200ms;}
233
+ &[data-direction=top] {
234
+ @include whenShow { opacity: 1; .popup-item-content { clip-path: polygon(-0% 0,100% 0,100% 100%,-0% 100%); } }
235
+ @include whenNotShow { opacity: 0; .popup-item-content { clip-path: polygon(-0% 100%,100% 100%,100% 100%,-0% 100%); } }
236
+ }
237
+ &[data-direction=bottom] {
238
+ @include whenShow { opacity: 1; .popup-item-content { clip-path: polygon(-0% 0,100% 0,100% 100%,-0% 100%); } }
239
+ @include whenNotShow { opacity: 0; .popup-item-content { clip-path: polygon(-0% 0,100% 0,100% 0,-0% 0); } }
240
+ }
241
+ &[data-direction=left] {
242
+ @include whenShow { opacity: 1; .popup-item-content { clip-path: polygon(100% 0,100% 100%,-0% 100%,-0% 0%); } }
243
+ @include whenNotShow { opacity: 0; .popup-item-content { clip-path: polygon(100% 0%,100% 100%,100% 100%,100% 0%); } }
244
+ }
245
+ &[data-direction=right] {
246
+ @include whenShow { opacity: 1; .popup-item-content { clip-path: polygon(0% 0,0% 100%,100% 100%,100% 0%); } }
247
+ @include whenNotShow { opacity: 0; .popup-item-content { clip-path: polygon(0% 0%,0% 100%,0% 100%,0% 0%); } }
248
+ }
249
+ /*@formatter:on*/
250
+ }
229
251
  }
252
+
@@ -43,7 +43,7 @@ export type iPopupTrigger = typeof ePopupTrigger.TYPE
43
43
  * @author 韦胜健
44
44
  * @date 2023.5.13 22:11
45
45
  */
46
- export const ePopupAnimation = createEnum(['fade', 'drop', 'scale', 'scale-y', 'slide'] as const);
46
+ export const ePopupAnimation = createEnum(['fade', 'drop', 'scale', 'scale-y', 'slide', 'clip'] as const);
47
47
  export type iPopupAnimation = typeof ePopupAnimation.TYPE
48
48
 
49
49
  /*---------------------------------------popup utils-------------------------------------------*/
@@ -218,6 +218,8 @@ export {useStyle, StyleProps, ThemeShape, ThemeSize, ThemeStatus} from './uses/u
218
218
  export type {tStyleComputed, UseStyleProvideData} from './uses/useStyle';
219
219
  export {AutoLoadingObserver} from './components/AutoLoadingObserver';
220
220
  export {lighter, darken} from './utils/color.utils';
221
+ export {createRequestInterceptor} from './components/createRequestInterceptor';
222
+ export type{iRequestInterceptor} from './components/createRequestInterceptor';
221
223
 
222
224
  // @ts-ignore
223
225
  setComponentPrefix(globalComponentPrefix);
@@ -131,7 +131,7 @@ export const i18n = (() => {
131
131
  */
132
132
  const use = (lang: string, locale: any) => {
133
133
  state.currentLang = lang;
134
- state.langs[lang] = deepmerge(state.langs[lang], locale);
134
+ if (!!locale) {state.langs[lang] = deepmerge(state.langs[lang], locale);}
135
135
  hooks.onChangeLang.exec(undefined);
136
136
  };
137
137
  /**
@@ -140,7 +140,7 @@ export const i18n = (() => {
140
140
  * @date 2023/10/11 9:30
141
141
  */
142
142
  const switchTo = async (lang: string, loadMethod?: () => any) => {
143
- let locale = !loadMethod ? state.langs[lang] : await loadMethod();
143
+ let locale = !loadMethod ? undefined : await loadMethod();
144
144
  use(lang, locale);
145
145
  };
146
146
  /**
@@ -148,9 +148,7 @@ export const i18n = (() => {
148
148
  * @author 韦胜健
149
149
  * @date 2023/10/11 9:30
150
150
  */
151
- const getCurrentLanguage = () => {
152
- return state.currentLang;
153
- };
151
+ const getCurrentLanguage = () => {return state.currentLang;};
154
152
  /**
155
153
  * 设置语言
156
154
  * @author 韦胜健
@@ -213,9 +211,11 @@ export const i18n = (() => {
213
211
  return result;
214
212
  };
215
213
 
216
- const cache = createCache<string>('@@I18N_LANG');
217
-
218
- if (cache.get()) {switchTo(cache.get()!);}
214
+ const applyCache = () => {
215
+ const cache = createCache<string>('@@I18N_LANG');
216
+ if (cache.get()) {switchTo(cache.get()!);}
217
+ hooks.onChangeLang.use(() => {cache.set(state.currentLang);});
218
+ };
219
219
 
220
220
  return {
221
221
  $t,
@@ -228,6 +228,7 @@ export const i18n = (() => {
228
228
  DEFAULT_LANG,
229
229
  state,
230
230
  hooks,
231
+ applyCache,
231
232
  };
232
233
  })();
233
234
 
@@ -35,6 +35,7 @@ export function useCollapseStyles(
35
35
  if (!state.isMount) {
36
36
  return;
37
37
  }
38
+ await delay(23);
38
39
  state.styles = inactive();
39
40
  state.onTransitionEnd = () => {
40
41
  state.isMount = false;