plain-design 1.0.0-beta.65 → 1.0.0-beta.67

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plain-design",
3
- "version": "1.0.0-beta.65",
3
+ "version": "1.0.0-beta.67",
4
4
  "description": "",
5
5
  "main": "dist/plain-design.min.js",
6
6
  "module": "dist/plain-design.commonjs.min.js",
@@ -1,4 +1,4 @@
1
- import {designComponent} from "plain-design-composition";
1
+ import {designComponent, getComponentCls, useClassCache} from "plain-design-composition";
2
2
  import Dropdown from "../Dropdown";
3
3
  import {ThemeColor} from "../ThemeColor";
4
4
  import PageThemeUtils from "../PageThemeUtils";
@@ -9,6 +9,12 @@ export const ThemeColorSelector = designComponent({
9
9
  name: 'theme-color-selector',
10
10
  inheritPropsType: Dropdown,
11
11
  setup({}) {
12
+
13
+ const classes = useClassCache(() => [
14
+ getComponentCls('theme-selector'),
15
+ getComponentCls('theme-color-selector'),
16
+ ]);
17
+
12
18
  return () => (
13
19
  <Dropdown
14
20
  trigger="hover"
@@ -16,7 +22,7 @@ export const ThemeColorSelector = designComponent({
16
22
  placement="bottom"
17
23
  v-slots={{
18
24
  default: () => (
19
- <div className="theme-color-selector">
25
+ <div className={classes.value}>
20
26
  <ThemeColor primaryKey={PageThemeUtils.state.primaryKey!}/>
21
27
  </div>
22
28
  ),
@@ -1,4 +1,4 @@
1
- import {designComponent, getComponentCls} from "plain-design-composition";
1
+ import {designComponent, getComponentCls, useClassCache} from "plain-design-composition";
2
2
  import i18n from "../i18n";
3
3
  import Tooltip from "../Tooltip";
4
4
  import PageThemeUtils from "../PageThemeUtils";
@@ -9,9 +9,13 @@ export const ThemeDarkSelector = designComponent({
9
9
  name: 'theme-dark-selector',
10
10
  setup() {
11
11
  const toggleDarkTheme = () => {PageThemeUtils.toggle();};
12
+ const classes = useClassCache(() => [
13
+ getComponentCls('theme-selector'),
14
+ getComponentCls('theme-dark-selector'),
15
+ ]);
12
16
  return () => (
13
17
  <Tooltip message={i18n.$it('theme.darkOrLight').d("深浅主题")}>
14
- <div className={getComponentCls('theme-dark-selector')} onClick={toggleDarkTheme}>
18
+ <div className={classes.value} onClick={toggleDarkTheme}>
15
19
  <Icon icon={PageThemeUtils.state.dark ? 'pi-sun' : 'pi-moon'}/>
16
20
  </div>
17
21
  </Tooltip>
@@ -1,4 +1,4 @@
1
- import {designComponent, getComponentCls} from "plain-design-composition";
1
+ import {designComponent, getComponentCls, useClassCache} from "plain-design-composition";
2
2
  import Dropdown from "../Dropdown";
3
3
  import DropdownOption from "../DropdownOption";
4
4
  import Icon from "../Icon";
@@ -11,13 +11,17 @@ export const ThemeLocaleSelector = designComponent({
11
11
  i18nManager: {},
12
12
  },
13
13
  setup({}) {
14
+ const classes = useClassCache(() => [
15
+ getComponentCls('theme-selector'),
16
+ getComponentCls('theme-locale-selector'),
17
+ ]);
14
18
  return () => (
15
19
  <Dropdown trigger="hover" align="center" placement="bottom" hideOnClickReference={false} v-slots={{
16
20
  popper: () => i18n.state.localeOptions.map(opt => (
17
21
  <DropdownOption label={opt.label} key={opt.label} onClick={() => i18n.switchTo(opt.key, () => opt.lang)}/>
18
22
  )),
19
23
  default: () => (
20
- <div className={getComponentCls('theme-locale-selector')}>
24
+ <div className={classes.value}>
21
25
  <Icon icon="pi-language"/>
22
26
  </div>
23
27
  )
@@ -1,4 +1,4 @@
1
- import {computed, designComponent, getComponentCls} from "plain-design-composition";
1
+ import {computed, designComponent, getComponentCls, useClassCache} from "plain-design-composition";
2
2
  import Dropdown from "../Dropdown";
3
3
  import DropdownOption from "../DropdownOption";
4
4
  import i18n from "../i18n";
@@ -19,6 +19,11 @@ export const ThemeShapeSelector = designComponent({
19
19
 
20
20
  const toggleShape = (val: any) => {PageThemeUtils.shape(val);};
21
21
 
22
+ const classes = useClassCache(() => [
23
+ getComponentCls('theme-selector'),
24
+ getComponentCls('theme-shape-selector'),
25
+ ]);
26
+
22
27
  return () => (
23
28
  <Dropdown
24
29
  trigger="hover"
@@ -26,7 +31,7 @@ export const ThemeShapeSelector = designComponent({
26
31
  placement="bottom"
27
32
  v-slots={{
28
33
  default: () => (
29
- <div className={getComponentCls('theme-shape-selector')}>
34
+ <div className={classes.value}>
30
35
  <Icon icon="pi-copy"/>
31
36
  </div>
32
37
  ),
@@ -1,4 +1,4 @@
1
- import {computed, designComponent, getComponentCls} from "plain-design-composition";
1
+ import {computed, designComponent, getComponentCls, useClassCache} from "plain-design-composition";
2
2
  import Dropdown from "../Dropdown";
3
3
  import DropdownOption from "../DropdownOption";
4
4
  import i18n from "../i18n";
@@ -20,13 +20,17 @@ export const ThemeSizeSelector = designComponent({
20
20
 
21
21
  const toggleSize = (val: any) => {PageThemeUtils.size(val);};
22
22
 
23
+ const classes = useClassCache(() => [
24
+ getComponentCls('theme-selector'),
25
+ getComponentCls('theme-size-selector'),
26
+ ]);
23
27
  return () => (
24
28
  <Dropdown trigger="hover" align="center" placement="bottom" hideOnClickReference={false} v-slots={{
25
29
  popper: () => sizeOptions.value.map(opt => (
26
30
  <DropdownOption label={opt.label} val={opt.val} key={opt.val} onClick={() => toggleSize(opt.val)}/>
27
31
  )),
28
32
  default: () => (
29
- <div className={getComponentCls('theme-size-selector')}>
33
+ <div className={classes.value}>
30
34
  <Icon icon="pi-font-colors"/>
31
35
  </div>
32
36
  )
@@ -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);
@@ -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;