plain-design 1.0.0-beta.31 → 1.0.0-beta.32

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 (57) hide show
  1. package/dist/plain-design.commonjs.min.js +3 -3
  2. package/dist/plain-design.min.css +11 -6
  3. package/dist/plain-design.min.js +3 -3
  4. package/dist/report.html +2 -2
  5. package/package.json +3 -3
  6. package/src/packages/components/$previewer/ImagePreviewerFixedContainer.tsx +107 -0
  7. package/src/packages/components/$previewer/image-previewer-fixed-container.scss +18 -0
  8. package/src/packages/components/$previewer/index.tsx +52 -0
  9. package/src/packages/components/Application/service/useApplicationService.tsx +2 -0
  10. package/src/packages/components/Carousel/carousel.scss +391 -0
  11. package/src/packages/components/Carousel/index.tsx +569 -22
  12. package/src/packages/components/CarouselItem/index.tsx +77 -0
  13. package/src/packages/components/ImagePreviewer/ImagePreviewer.tsx +572 -0
  14. package/src/packages/components/ImagePreviewer/ImagePreviewerButtonBar.tsx +140 -0
  15. package/src/packages/components/ImagePreviewer/ImagePreviewerCarouselImage.tsx +54 -0
  16. package/src/packages/components/ImagePreviewer/ImagePreviewerGallery.tsx +202 -0
  17. package/src/packages/components/ImagePreviewer/PreviewerLoading.tsx +26 -0
  18. package/src/packages/components/ImagePreviewer/image-previewer.scss +244 -0
  19. package/src/packages/components/ImagePreviewer/image-previewer.utils.tsx +135 -0
  20. package/src/packages/components/ImagePreviewer/index.tsx +5 -0
  21. package/src/packages/components/ImagePreviewer/previewer-loading.scss +52 -0
  22. package/src/packages/components/Input/useMultipleInput.tsx +2 -79
  23. package/src/packages/components/Scroll/index.tsx +6 -6
  24. package/src/packages/components/SortList/index.tsx +191 -0
  25. package/src/packages/components/SortList/sort-list.scss +11 -0
  26. package/src/packages/components/StackCard/index.tsx +260 -0
  27. package/src/packages/components/StackCard/stack-card.scss +28 -0
  28. package/src/packages/components/StackCardItem/index.tsx +23 -0
  29. package/src/packages/components/Table/standard/PlcOperation/PlcOperation.tsx +1 -1
  30. package/src/packages/components/Table/standard/PlcTree/RenderPlcTreeNode.tsx +2 -1
  31. package/src/packages/components/Table/table/body/row.tsx +1 -1
  32. package/src/packages/components/Table/table/use/useTableDraggier.row.tsx +1 -1
  33. package/src/packages/components/Table/table/utils/createTableHooks.ts +1 -1
  34. package/src/packages/components/Tree/RenderTreeNode.tsx +2 -1
  35. package/src/packages/components/Tree/index.tsx +2 -1
  36. package/src/packages/components/VirtualList/index.tsx +12 -3
  37. package/src/packages/components/VirtualList/useVirtualList.tsx +129 -86
  38. package/src/packages/components/VirtualList/virtual-list.scss +31 -17
  39. package/src/packages/components/VirtualTable/index.tsx +1 -1
  40. package/src/packages/entry.tsx +5 -1
  41. package/src/packages/uses/useDragHorizontalScroll.ts +82 -0
  42. package/src/packages/utils/ComponentUtils.ts +10 -0
  43. package/src/packages/utils/buildCycleIndexList.ts +31 -0
  44. package/src/packages/utils/getDeviceInfo.ts +44 -44
  45. package/src/packages/utils/getRectAutoFormat.ts +9 -0
  46. package/src/packages/utils/notNull.ts +9 -0
  47. package/src/pages/index/app.scss +1 -1
  48. package/src/pages/index/components/normal/DemoCarousel.tsx +178 -73
  49. package/src/pages/index/components/normal/DemoKeepAlive.tsx +25 -25
  50. package/src/pages/index/components/normal/DemoSortList.tsx +70 -0
  51. package/src/pages/index/components/normal/DemoStackCard.tsx +356 -0
  52. package/src/pages/index/components/normal/DemoVirtualList.tsx +89 -3
  53. package/src/pages/index/components/service/DemoImagePreviewer.tsx +185 -0
  54. package/src/pages/index/home/AppHome.tsx +18 -3
  55. package/src/pages/index/home/menus.tsx +3 -1
  56. package/src/packages/components/CarouselGroup/carousel.scss +0 -143
  57. package/src/packages/components/CarouselGroup/index.tsx +0 -274
@@ -0,0 +1,185 @@
1
+ import {designPage} from "plain-design-composition";
2
+ import {DemoRow} from "../../Demo/DemoRow";
3
+ import {$previewer} from "../../../../packages";
4
+ import {DemoLine} from "../../Demo/DemoLine";
5
+ import {ImagePreviewer} from "../../../../packages/components/ImagePreviewer";
6
+ import {createImagePreviewerOption} from "../../../../packages/components/ImagePreviewer/image-previewer.utils";
7
+
8
+ export const DemoDocument = designPage(() => {
9
+ return () => (
10
+ <DemoRow title="使用手册">
11
+ <p>1、默认情况下ImagePreviewer会撑满宽度,然后高度由图片自动撑开;下边第一个示例设置了宽度800px,高度自动由图片撑开,如果多张图片高度不一致,则由高度最大的图片撑开;</p>
12
+ <p>2、ImagePreviewer分为三个区域,一个是顶部的按钮栏,中间图片展示栏,底部的画廊栏;</p>
13
+ <p>3、可以使用鼠标滚动,或者点击按钮栏的放大缩小按钮对当前展示的图片进行缩放;</p>
14
+ <p>4、可以点击旋转按钮,对图片进行旋转;</p>
15
+ <p>5、缩放或者旋转之后可以拖拽图片调整查看具体的图片位置;</p>
16
+ <p>6。在没有缩放或者旋转的状态下,左右滑动来切换浏览的图片;</p>
17
+ <p>7、点击按钮栏的重置按钮,或者缩放图片为原始大小,会自动令图片回正,回正就是原始状态,此时可以左右滑动切换浏览图片;</p>
18
+ <p>8、点击左右按钮切换图片也会令图片回正;</p>
19
+ <p>9、底部画廊在超长溢出的情况下可以拖拽左右滚动,也可以使用鼠标滚动上下滚动,触摸板左右滚动也可以支持;</p>
20
+ <p>10、触摸板左右的按钮点击可以自动滚动到上一页,下一页;每次滚动距离为半页距离;</p>
21
+ <p>11、快捷键:ESC(关闭全屏浏览);左按键(上一张图);右按键(下一张图);滚轮向上(放大);滚轮向下(缩小);</p>
22
+ </DemoRow>
23
+ );
24
+ });
25
+
26
+ export const DemoImagePreviewer = designPage(() => {
27
+
28
+ const imageList = [
29
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/1.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
30
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/2.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
31
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/3.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
32
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/4.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
33
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/5.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
34
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/6.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
35
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/7.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
36
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/8.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
37
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/9.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
38
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/10.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
39
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/11.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
40
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/12.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
41
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/13.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
42
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/14.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
43
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/15.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
44
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/16.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
45
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/17.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
46
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/18.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
47
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/19.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
48
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/20.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
49
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/21.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
50
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/22.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=DemoImagePreviewer",
51
+ ];
52
+
53
+ const option = createImagePreviewerOption(imageList);
54
+ option.button = { close: false };
55
+ option.galleryHeight = 60;
56
+
57
+ return () => (
58
+ <DemoRow title="基本用法">
59
+ <div style={{ width: '500px', maxWidth: '100%' }}>
60
+ <ImagePreviewer option={option}/>
61
+ </div>
62
+ </DemoRow>
63
+ );
64
+ });
65
+
66
+ export const demoImagePreview = designPage(() => {
67
+
68
+ const imageList = [
69
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/mountains.jpg?x-oss-process=image/resize,h_1080,m_lfit",
70
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/pexels-pixabay-262367.jpg?x-oss-process=image/resize,h_1080,m_lfit",
71
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/pexels-athena-1586795.jpg?x-oss-process=image/resize,h_1080,m_lfit"
72
+ ];
73
+
74
+ return () => (
75
+ <DemoRow title="图片预览">
76
+ <DemoLine>
77
+ <p>1. 调用预览服务的时候如果传入原始的imageElement这个dom对象的话,初始会有一个放大动画</p>
78
+ <p>2. 双击可以关闭预览,或者ESC按键或者点击顶部的关闭按钮都可以关闭预览</p>
79
+ </DemoLine>
80
+ <DemoLine>
81
+ {imageList.map((item, index) => (
82
+ <img style={{ height: '100px' }} src={item} key={index} onClick={e => $previewer.preview({ current: index, urls: imageList }, e.currentTarget as any)}/>
83
+ ))}
84
+ </DemoLine>
85
+ </DemoRow>
86
+ );
87
+ });
88
+
89
+
90
+ export const demoImagePreview2 = designPage(() => {
91
+
92
+ const imageList = [
93
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/mountains.jpg??x-oss-process=image/resize,h_1080,m_lfit&v=1",
94
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/pexels-pixabay-262367.jpg??x-oss-process=image/resize,h_1080,m_lfit&v=1",
95
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/pexels-athena-1586795.jpg?x-oss-process=image/resize,h_1080,m_lfit&?v=1"
96
+ ];
97
+
98
+ return () => (
99
+ <DemoRow title="关闭时没有原始图片">
100
+ <p>关闭时没有原始图片的情况下,关闭动画会往底部缩小并且关闭</p>
101
+ {imageList.map((item, index) => (
102
+ index == 0 ? null : <img style={{ height: '100px' }} src={item} key={index} onClick={e => $previewer.preview({ current: index, urls: imageList }, e.currentTarget as any)}/>
103
+ ))}
104
+ </DemoRow>
105
+ );
106
+ });
107
+
108
+ export const demoImagePreview3 = designPage(() => {
109
+
110
+ const imageList = [
111
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/1.jpg?x-oss-process=image/resize,h_1080,m_lfit",
112
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/2.jpg?x-oss-process=image/resize,h_1080,m_lfit",
113
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/3.jpg?x-oss-process=image/resize,h_1080,m_lfit",
114
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/4.jpg?x-oss-process=image/resize,h_1080,m_lfit",
115
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/5.jpg?x-oss-process=image/resize,h_1080,m_lfit",
116
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/6.jpg?x-oss-process=image/resize,h_1080,m_lfit",
117
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/7.jpg?x-oss-process=image/resize,h_1080,m_lfit",
118
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/8.jpg?x-oss-process=image/resize,h_1080,m_lfit",
119
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/9.jpg?x-oss-process=image/resize,h_1080,m_lfit",
120
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/10.jpg?x-oss-process=image/resize,h_1080,m_lfit",
121
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/11.jpg?x-oss-process=image/resize,h_1080,m_lfit",
122
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/12.jpg?x-oss-process=image/resize,h_1080,m_lfit",
123
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/13.jpg?x-oss-process=image/resize,h_1080,m_lfit",
124
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/14.jpg?x-oss-process=image/resize,h_1080,m_lfit",
125
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/15.jpg?x-oss-process=image/resize,h_1080,m_lfit",
126
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/16.jpg?x-oss-process=image/resize,h_1080,m_lfit",
127
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/17.jpg?x-oss-process=image/resize,h_1080,m_lfit",
128
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/18.jpg?x-oss-process=image/resize,h_1080,m_lfit",
129
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/19.jpg?x-oss-process=image/resize,h_1080,m_lfit",
130
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/20.jpg?x-oss-process=image/resize,h_1080,m_lfit",
131
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/21.jpg?x-oss-process=image/resize,h_1080,m_lfit",
132
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/22.jpg?x-oss-process=image/resize,h_1080,m_lfit",
133
+ ];
134
+
135
+ return () => (
136
+ <DemoRow title="多图预览示例">
137
+ {imageList.map((item, index) => (
138
+ <img style={{ height: '100px' }} src={item} key={index} onClick={e => $previewer.preview({ current: index, urls: imageList }, e.currentTarget as any)}/>
139
+ ))}
140
+ </DemoRow>
141
+ );
142
+ });
143
+
144
+
145
+ export const demoImagePreview4 = designPage(() => {
146
+
147
+ const imageList = [
148
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/1.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
149
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/2.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
150
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/3.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
151
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/4.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
152
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/5.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
153
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/6.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
154
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/7.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
155
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/8.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
156
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/9.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
157
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/10.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
158
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/11.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
159
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/12.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
160
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/13.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
161
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/14.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
162
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/15.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
163
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/16.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
164
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/17.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
165
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/18.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
166
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/19.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
167
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/20.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
168
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/21.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
169
+ "https://plain-assets.oss-cn-guangzhou.aliyuncs.com/xiaomi_su7/22.jpg?x-oss-process=image/resize,h_1080,m_lfit&v=1",
170
+ ];
171
+
172
+ return () => (
173
+ <DemoRow title="无原始图预览示例">
174
+ <p>1. 没有加载过的图片url,第一次预览的时候会显示加载状态;</p>
175
+ <p>2. 画廊使用的是虚拟滚动,所以并不是所有图片会立即加载,画廊滚动的时候会预初始化下一页图片,也就是会预加载下一页</p>
176
+ <ul>
177
+ {imageList.map((item, index) => (
178
+ <li key={index} onClick={() => $previewer.preview({ current: index, urls: imageList })} style={{ lineHeight: '40px' }}>
179
+ ITEM_${item}
180
+ </li>
181
+ ))}
182
+ </ul>
183
+ </DemoRow>
184
+ );
185
+ });
@@ -1,14 +1,29 @@
1
- import {designPage} from "plain-design-composition";
1
+ import {designPage, onBeforeUnmount, reactive} from "plain-design-composition";
2
2
  import {AppMenu} from "./AppMenu";
3
3
  import {AppHead} from "./AppHead";
4
4
  import {AppContent} from "./AppContent";
5
+ import {clearDeviceInfo, eDeviceType, getDeviceInfo} from "../../../packages/utils/getDeviceInfo";
6
+ import {addWindowListener} from "plain-utils/dom/addWindowListener";
7
+ import {delay} from "plain-utils/utils/delay";
5
8
 
6
9
  export const AppHome = designPage(() => {
10
+
11
+ const state = reactive({
12
+ deviceType: getDeviceInfo().deviceType
13
+ });
14
+
15
+ onBeforeUnmount(
16
+ addWindowListener('resize', async () => {
17
+ clearDeviceInfo();
18
+ state.deviceType = getDeviceInfo().deviceType;
19
+ })
20
+ );
21
+
7
22
  return () => (
8
23
  <div className="app-home">
9
24
  <AppHead/>
10
- <div className="app-body">
11
- <AppMenu/>
25
+ <div className="app-body" style={{ paddingLeft: state.deviceType !== eDeviceType.desktop ? '0' : undefined }}>
26
+ {state.deviceType === eDeviceType.desktop && <AppMenu/>}
12
27
  <AppContent/>
13
28
  </div>
14
29
  </div>
@@ -90,6 +90,7 @@ export const MenuGroups: MenuGroup[] = [
90
90
  name: '视图', children: [
91
91
  { name: 'List', title: '列表', page: '/normal/DemoList', complete: true },
92
92
  { name: 'VirtualList', title: '虚拟列表', page: '/normal/DemoVirtualList', complete: true },
93
+ { name: 'SortList', title: '排序列表', page: '/normal/DemoSortList', complete: true },
93
94
  { name: 'Progress', title: '进度条', page: '/normal/DemoProgress', complete: true },
94
95
  { name: 'Tree', title: '树形组件', page: '/normal/DemoTree', complete: true },
95
96
  // {name: 'Virtual Tree', title: '虚拟树', page: '/normal/virtual-tree', complete: false},
@@ -116,6 +117,7 @@ export const MenuGroups: MenuGroup[] = [
116
117
  { name: 'Popup', title: '悬浮框', page: '/normal/DemoPopup', complete: true },
117
118
  { name: 'Card', title: '卡片', page: '/normal/DemoCard', complete: true },
118
119
  { name: 'Carousel', title: '轮播', page: '/normal/DemoCarousel', complete: true },
120
+ { name: 'StackCard', title: '堆叠卡片', page: '/normal/DemoStackCard', complete: true },
119
121
  { name: 'Collapse', title: '折叠面板', page: '/normal/DemoCollapse', complete: true },
120
122
  { name: 'Layout', title: '布局', page: '/normal/DemoLayout', complete: true },
121
123
  { name: 'Alert', title: '提示信息', page: '/normal/DemoAlert', complete: true },
@@ -135,7 +137,7 @@ export const MenuGroups: MenuGroup[] = [
135
137
  { name: '$file', title: '文件服务', page: '/service/DemoFileService', complete: true },
136
138
  // { name: '$popper', title: '浮层服务', page: '/service/DemoPopperService', complete: false },
137
139
  { name: '$popup', title: '弹出服务', page: '/service/DemoPopupService', complete: true },
138
- // {name: '$image', title: '图片服务', page: '/service/image-service', complete: false},
140
+ { name: '$previewer', title: '预览服务', page: '/service/DemoImagePreviewer', complete: true },
139
141
  ]
140
142
  },
141
143
  {
@@ -1,143 +0,0 @@
1
- @include prefix(carousel-group) {
2
- position: relative;
3
-
4
- &:not(.carousel-vertical) {
5
- overflow-x: hidden;
6
- }
7
-
8
- .#{componentName(carousel)}, .carousel-cover, .carousel-operator, .carousel-indicator {
9
- position: absolute;
10
- top: 0;
11
- left: 0;
12
- right: 0;
13
- bottom: 0;
14
- pointer-events: none;
15
-
16
- &.carousel-cover, &.carousel-operator, &.carousel-indicator {
17
- z-index: 99;
18
- }
19
- }
20
-
21
- .#{componentName(carousel)} {
22
- &.carousel-animating {
23
- transition: transform ease 600ms;
24
- }
25
-
26
- pointer-events: auto;
27
- }
28
-
29
- .carousel-cover {
30
- pointer-events: auto;
31
- }
32
-
33
- .carousel-operator {
34
- display: flex;
35
- align-items: center;
36
- justify-content: space-between;
37
- padding: 0 20px;
38
-
39
- .carousel-operator-btn {
40
- transition: background-color 300ms linear;
41
- cursor: pointer;
42
- pointer-events: auto;
43
- background-color: rgba(#000000, 0.2);
44
- color: white;
45
- width: 36px;
46
- height: 36px;
47
- border-radius: 36px;
48
- display: flex;
49
- align-items: center;
50
- justify-content: center;
51
- user-select: none;
52
-
53
- &:hover:not(:active) {
54
- background-color: rgba(#ffffff, 0.65);
55
- }
56
- }
57
- }
58
-
59
- .carousel-indicator {
60
- top: initial;
61
- display: flex;
62
- align-items: center;
63
- justify-content: center;
64
- padding: 20px;
65
- flex-wrap: nowrap;
66
-
67
- .carousel-indicator-item {
68
- pointer-events: auto;
69
- width: 20px;
70
- height: 2px;
71
- background-color: plv(background-color);
72
- opacity: 0.6;
73
- transition: all 200ms linear;
74
- cursor: pointer;
75
-
76
- &:not(:last-child) {
77
- margin-right: 8px;
78
- }
79
-
80
- &.carousel-indicator-item-active {
81
- opacity: 1;
82
- width: 30px;
83
- height: 4px;
84
- }
85
-
86
- &:hover {
87
- opacity: 0.8;
88
- }
89
- }
90
- }
91
-
92
- &.carousel-vertical {
93
- overflow-y: hidden;
94
-
95
- .carousel-operator {
96
- flex-direction: column;
97
- padding: 20px;
98
- align-items: flex-end;
99
-
100
- .carousel-operator-btn:nth-child(1) {
101
- transform: rotate(90deg);
102
- }
103
-
104
- .carousel-operator-btn:nth-child(2) {
105
- transform: rotate(90deg);
106
- }
107
- }
108
-
109
- .carousel-indicator {
110
- flex-direction: column;
111
- padding: 20px 36px;
112
- left: initial;
113
- top: 0;
114
-
115
- .carousel-indicator-item {
116
- height: 8px;
117
- width: 2px;
118
- margin-right: 0;
119
-
120
- &.carousel-indicator-item-active {
121
- height: 16px;
122
- width: 4px;
123
- }
124
-
125
- &:not(:last-child) {
126
- margin-bottom: 4px;
127
- }
128
- }
129
- }
130
- }
131
-
132
- &.carousel-card {
133
- .#{componentName(carousel)} {
134
- right: initial;
135
- }
136
-
137
- .carousel-indicator {
138
- .carousel-indicator-item {
139
- background-color: rgba(black, 0.5);
140
- }
141
- }
142
- }
143
- }
@@ -1,274 +0,0 @@
1
- import {classnames, computed, designComponent, getComponentCls, onMounted, reactive, useClasses, useCollect, useModel, useRefs, useStyles, watch} from "plain-design-composition";
2
- import {unit} from "plain-utils/string/unit";
3
- import {throttle} from "plain-utils/utils/throttle";
4
- import Icon from "../Icon";
5
- import {Carousel} from "../Carousel";
6
- import './carousel.scss';
7
-
8
- export const CarouselGroup = designComponent({
9
- name: 'carousel-group',
10
- props: {
11
- modelValue: { type: [String, Number] }, // 双向绑定值
12
- height: { type: [Number, String], default: 225 }, // 轮播高度
13
- autoplay: { type: Number, default: 3000 }, // 自定播放时间,为0则取消自动播放
14
- disabledOperator: { type: Boolean }, // 禁用前后按钮
15
- disabledIndicator: { type: Boolean }, // 禁用指示器
16
- indicatorTrigger: { type: String, default: 'click' }, // 指示器激活触发器:click。hover
17
- vertical: { type: Boolean }, // 轮播方向为纵向
18
- card: { type: Boolean }, // 卡片形式的切换
19
- cardScale: { type: Number, default: 0.64 }, // 卡片形式轮播的时候,缩小比例
20
- },
21
- inheritPropsType: HTMLDivElement,
22
- scopeSlots: {
23
- indicator: (scope: { val: string, index: number, active: boolean }) => {},
24
- },
25
- slots: ['cover', 'default'],
26
- emits: {
27
- onUpdateModelValue: (val: string | number | undefined | null) => true,
28
- },
29
- setup({ props, slots, scopeSlots, event: { emit } }) {
30
-
31
- /*子元素*/
32
- const items = CarouselCollector.parent();
33
-
34
- const { refs, onRef } = useRefs({
35
- el: HTMLDivElement
36
- });
37
- const state = reactive({
38
- width: 0, // 容器宽度
39
- height: 0, // 容器高度
40
- autoplayTimer: null as null | number, // 自动播放定时器
41
- prevActiveIndex: null as null | number, // 上一个激活的index,当元素个数为3时,需要通过这个属性优化动画
42
- });
43
-
44
- /*双向绑定值*/
45
- const model = useModel(() => props.modelValue, emit.onUpdateModelValue);
46
- /*子元素val数组*/
47
- const vals = computed(() => items.map(item => String(item.itemVal)!));
48
- /*当前激活的元素的val值*/
49
- const activeVal = computed(() => {
50
- if (vals.value.length === 0) {
51
- return null;
52
- }
53
- if (model.value != null) {
54
- return String(model.value);
55
- } else {
56
- return vals.value[0];
57
- }
58
- });
59
- /*当前激活的元素的val的在 数组中的索引*/
60
- const activeIndex = computed(() => {
61
- if (!activeVal.value) {
62
- return 0;
63
- }
64
- return vals.value.indexOf(activeVal.value);
65
- });
66
-
67
- /*实际渲染的,排序过的val数组*/
68
- const sortVals = computed(() => {
69
- const valArray = vals.value;
70
- let prev = valArray.slice(0, activeIndex.value);
71
- let next = valArray.slice(activeIndex.value + 1);
72
-
73
- if (Math.abs(prev.length - next.length) > 1) {
74
- if (prev.length > next.length) {
75
- while (prev.length - next.length > 1) {
76
- next.push(prev.shift()!);
77
- }
78
- } else {
79
- while (next.length - prev.length > 1) {
80
- prev.unshift(next.pop()!);
81
- }
82
- }
83
- }
84
- return [...prev, activeVal.value, ...next];
85
- });
86
-
87
- const classes = useClasses(() => [
88
- getComponentCls('carousel-group'),
89
- {
90
- 'carousel-vertical': props.vertical,
91
- 'carousel-card': props.card,
92
- }
93
- ]);
94
- const styles = useStyles(style => {
95
- style.height = unit(props.height);
96
- });
97
-
98
- const utils = {
99
- /**
100
- * 子元素的左偏移位置
101
- * @author 韦胜健
102
- * @date 2020/11/22 23:19
103
- */
104
- getItemStyles: (val: any) => {
105
- if (!state.width) {
106
- return null;
107
- }
108
- /*当前val在sortVals中的索引*/
109
- const sortIndex = sortVals.value.indexOf(String(val));
110
- /*激活val在sortVals中的索引*/
111
- const activeSortIndex = sortVals.value.indexOf(String(activeVal.value));
112
-
113
- /*当前val与激活val在sortVal的间距*/
114
- let duration = sortIndex - activeSortIndex;
115
-
116
- const style = {
117
- zIndex: sortVals.value.length - Math.abs(duration),
118
- } as any;
119
-
120
- if (!props.vertical) {
121
- if (!props.card) {
122
- /*非卡片形式的轮播*/
123
- style.transform = `translateX(${duration * state.width}px)`;
124
- } else {
125
- style.width = `${props.cardScale * 100}%`;
126
- style.height = `${props.cardScale * 100}%`;
127
-
128
- /*卡片轮播*/
129
- let left = duration * state.width * (props.cardScale) + (state.width * (1 - props.cardScale) / 2);
130
- left += (sortIndex > activeSortIndex ? -1 : 1) * Math.abs(sortIndex - activeSortIndex) * state.width * 0.125;
131
- style.transform = `translateX(${left}px) translateY(${state.height * ((1 - props.cardScale) / 2)}px) scale(${sortIndex === activeSortIndex ? '1' : '0.83'})`;
132
- }
133
- } else {
134
- /*纵向非卡片形式的轮播*/
135
- style.transform = `translateY(${duration * state.height}px)`;
136
- }
137
-
138
- return style;
139
- },
140
- /**
141
- * 重置自动播放定时器
142
- * @author 韦胜健
143
- * @date 2020/11/22 23:19
144
- */
145
- resetAutoplayTimer: (autoplay: number | null) => {
146
- /*无论怎么样都要清理掉定时器*/
147
- if (!!state.autoplayTimer) {
148
- clearInterval(state.autoplayTimer);
149
- state.autoplayTimer = null;
150
- }
151
- /*如果autoplay有值,重新设定一个自动播放定时器*/
152
- if (!!autoplay) {
153
- state.autoplayTimer = setInterval(methods.next, autoplay) as any as number;
154
- }
155
- },
156
- /**
157
- * 子元素是否需要动画(当元素为3时,只有prevActiveIndex以及activeIndex的元素需要动画,另一个需要立刻移动到对应的位置)
158
- * @author 韦胜健
159
- * @date 2020/11/22 23:20
160
- */
161
- isAnimating: (val: any) => {
162
- if (vals.value.length !== 3 && !props.card) {
163
- return true;
164
- }
165
- let index = vals.value.indexOf(val);
166
- return index === state.prevActiveIndex || index === activeIndex.value;
167
- },
168
- };
169
-
170
- const methods = {
171
- /**
172
- * 显示上一个元素
173
- * @author 韦胜健
174
- * @date 2020/11/22 23:21
175
- */
176
- prev: () => {
177
- state.prevActiveIndex = activeIndex.value;
178
- model.value = sortVals.value[sortVals.value.indexOf(activeVal.value) - 1]!;
179
- },
180
- /**
181
- * 显示下一个元素
182
- * @author 韦胜健
183
- * @date 2020/11/22 23:21
184
- */
185
- next: () => {
186
- state.prevActiveIndex = activeIndex.value;
187
- model.value = sortVals.value[sortVals.value.indexOf(activeVal.value) + 1]!;
188
- },
189
- /**
190
- * 显示特定元素
191
- * @author 韦胜健
192
- * @date 2020/11/22 23:21
193
- */
194
- show: (val: any) => {
195
- state.prevActiveIndex = activeIndex.value;
196
- model.value = val;
197
-
198
- utils.resetAutoplayTimer(props.autoplay);
199
- },
200
- };
201
-
202
- const handler = {
203
- onPrev: throttle(() => {
204
- utils.resetAutoplayTimer(props.autoplay);
205
- methods.prev();
206
- }, 500, { trailing: true, leading: true }),
207
- onNext: throttle(() => {
208
- utils.resetAutoplayTimer(props.autoplay);
209
- methods.next();
210
- }, 500, { trailing: true, leading: true }),
211
- onIndicator: (index: number) => {
212
- methods.show(vals.value[index]);
213
- },
214
- };
215
-
216
- onMounted(() => {
217
- state.width = refs.el!.offsetWidth;
218
- state.height = refs.el!.offsetHeight;
219
- });
220
-
221
- watch(() => props.autoplay, utils.resetAutoplayTimer, { immediate: true });
222
-
223
- return {
224
- refer: {
225
- refs,
226
- utils,
227
- methods,
228
- },
229
- render: () => (
230
- <div className={classes.value} style={styles.value} ref={onRef.el}>
231
- {slots.default()}
232
- {slots.cover.isExist() && <div className="carousel-cover">
233
- {slots.cover()}
234
- </div>}
235
-
236
- {!props.disabledOperator && <div className="carousel-operator">
237
- <div className="carousel-operator-btn carousel-operator-prev" onClick={handler.onPrev}>
238
- <Icon icon="pi-left"/>
239
- </div>
240
- <div className="carousel-operator-btn carousel-operator-next" onClick={handler.onNext}>
241
- <Icon icon="pi-right"/>
242
- </div>
243
- </div>}
244
-
245
- {!props.disabledIndicator && <div className="carousel-indicator">
246
- {items.map((item, index) => (
247
- scopeSlots.indicator({ val: String(item.itemVal), index, active: index === activeIndex.value }, (
248
- <div
249
- {...{
250
- [props.indicatorTrigger === 'hover' ? 'onMouseEnter' : 'onClick']: () => handler.onIndicator(index)
251
- }}
252
- className={classnames(
253
- [
254
- 'carousel-indicator-item',
255
- {
256
- 'carousel-indicator-item-active': index === activeIndex.value,
257
- }
258
- ]
259
- )} key={index}/>
260
- ))
261
- ))}
262
- </div>}
263
- </div>
264
- )
265
- };
266
- },
267
- });
268
-
269
- export default CarouselGroup;
270
-
271
- export const CarouselCollector = useCollect(() => ({
272
- parent: CarouselGroup,
273
- child: Carousel,
274
- }));