@king-design/intact 3.5.2 → 3.6.0

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 (260) hide show
  1. package/components/.DS_Store +0 -0
  2. package/components/button/index.md +1 -0
  3. package/components/cascader/index.spec.ts +7 -6
  4. package/components/datepicker/basepicker.ts +26 -267
  5. package/components/datepicker/calendar.ts +8 -2
  6. package/components/datepicker/calendar.vdt +23 -6
  7. package/components/datepicker/dayjs.ts +8 -2
  8. package/components/datepicker/demos/multiple.md +1 -1
  9. package/components/datepicker/demos/yearMonth.md +1 -1
  10. package/components/datepicker/helpers.ts +10 -12
  11. package/components/datepicker/index.md +2 -2
  12. package/components/datepicker/index.spec.ts +619 -190
  13. package/components/datepicker/index.ts +22 -21
  14. package/components/datepicker/index.vdt +47 -42
  15. package/components/datepicker/shortcuts.ts +1 -1
  16. package/components/datepicker/styles.ts +112 -4
  17. package/components/datepicker/useConfirm.ts +82 -0
  18. package/components/datepicker/useDisabled.ts +31 -33
  19. package/components/datepicker/useFormats.ts +10 -4
  20. package/components/datepicker/useHighlight.ts +81 -0
  21. package/components/datepicker/useKeyboards.ts +2 -1
  22. package/components/datepicker/useMergeRange.ts +54 -0
  23. package/components/datepicker/useMonths.ts +6 -3
  24. package/components/datepicker/usePanel.ts +19 -19
  25. package/components/datepicker/useQuarters.ts +47 -0
  26. package/components/datepicker/useShowDate.ts +14 -3
  27. package/components/datepicker/useStatus.ts +34 -15
  28. package/components/datepicker/useValue.ts +41 -39
  29. package/components/datepicker/useValueBase.ts +309 -0
  30. package/components/datepicker/useWeeks.ts +58 -0
  31. package/components/datepicker/useYears.ts +7 -3
  32. package/components/descriptions/.DS_Store +0 -0
  33. package/components/dialog/useFixBody.ts +7 -64
  34. package/components/dropdown/dropdown.ts +5 -4
  35. package/components/dropdown/index.md +1 -0
  36. package/components/dropdown/item.ts +1 -1
  37. package/components/dropdown/useKeyboard.ts +0 -1
  38. package/components/ellipsis/styles.ts +4 -0
  39. package/components/form/styles.ts +1 -0
  40. package/components/input/index.spec.ts +42 -0
  41. package/components/input/index.ts +8 -0
  42. package/components/input/index.vdt +3 -4
  43. package/components/input/useAutoWidth.ts +19 -1
  44. package/components/menu/.DS_Store +0 -0
  45. package/components/menu/demos/.DS_Store +0 -0
  46. package/components/scrollSelect/index.spec.ts +3 -3
  47. package/components/scrollSelect/useMouseEvents.ts +24 -10
  48. package/components/select/base.ts +3 -2
  49. package/components/select/base.vdt +3 -1
  50. package/components/select/demos/creatable.md +13 -0
  51. package/components/select/index.md +1 -0
  52. package/components/select/index.spec.ts +225 -6
  53. package/components/select/option.ts +10 -1
  54. package/components/select/select.ts +3 -0
  55. package/components/select/styles.ts +3 -1
  56. package/components/select/useFilterable.ts +1 -1
  57. package/components/select/useInput.ts +7 -9
  58. package/components/select/useSearchable.ts +2 -2
  59. package/components/table/.DS_Store +0 -0
  60. package/components/table/index.spec.ts +69 -1
  61. package/components/table/useStickyHeader.ts +1 -1
  62. package/components/timepicker/demos/step.md +1 -1
  63. package/components/timepicker/index.spec.ts +145 -27
  64. package/components/timepicker/panelPicker.ts +10 -4
  65. package/components/timepicker/panelPicker.vdt +5 -3
  66. package/components/timepicker/useConfirm.ts +33 -0
  67. package/components/timepicker/useDefaultValue.ts +30 -0
  68. package/components/timepicker/useDisabled.ts +17 -4
  69. package/components/timepicker/useFormats.ts +1 -1
  70. package/components/timepicker/useValue.ts +22 -19
  71. package/components/tour/.DS_Store +0 -0
  72. package/components/tour/demos/basic.md +73 -0
  73. package/components/tour/demos/beforeChange.md +109 -0
  74. package/components/tour/demos/closable.md +70 -0
  75. package/components/tour/demos/custom.md +98 -0
  76. package/components/tour/demos/customText.md +94 -0
  77. package/components/tour/demos/declarative.md +72 -0
  78. package/components/tour/demos/events.md +101 -0
  79. package/components/tour/demos/maskClosable.md +76 -0
  80. package/components/tour/demos/notarget.md +59 -0
  81. package/components/tour/index.md +48 -0
  82. package/components/tour/index.spec.ts +259 -0
  83. package/components/tour/index.ts +2 -0
  84. package/components/tour/step.ts +55 -0
  85. package/components/tour/step.vdt +75 -0
  86. package/components/tour/styles.ts +283 -0
  87. package/components/tour/tour.ts +107 -0
  88. package/components/tour/tour.vdt +83 -0
  89. package/components/tour/useArrow.ts +46 -0
  90. package/components/tour/useFixBody.ts +22 -0
  91. package/components/tour/useHighlight.ts +36 -0
  92. package/components/tour/useMaskClosable.ts +26 -0
  93. package/components/tour/useNavigation.ts +46 -0
  94. package/components/tour/usePosition.ts +91 -0
  95. package/components/tour/useSteps.ts +80 -0
  96. package/components/virtualList/.DS_Store +0 -0
  97. package/components/virtualList/demos/.DS_Store +0 -0
  98. package/es/components/cascader/index.spec.js +18 -19
  99. package/es/components/datepicker/basepicker.d.ts +6 -25
  100. package/es/components/datepicker/basepicker.js +22 -234
  101. package/es/components/datepicker/calendar.d.ts +36 -6
  102. package/es/components/datepicker/calendar.js +4 -0
  103. package/es/components/datepicker/calendar.vdt.js +21 -5
  104. package/es/components/datepicker/dayjs.d.ts +2 -2
  105. package/es/components/datepicker/dayjs.js +6 -0
  106. package/es/components/datepicker/helpers.d.ts +8 -7
  107. package/es/components/datepicker/helpers.js +2 -3
  108. package/es/components/datepicker/index.d.ts +26 -19
  109. package/es/components/datepicker/index.js +21 -13
  110. package/es/components/datepicker/index.spec.js +1389 -633
  111. package/es/components/datepicker/index.vdt.js +43 -46
  112. package/es/components/datepicker/shortcuts.d.ts +1 -1
  113. package/es/components/datepicker/styles.d.ts +22 -0
  114. package/es/components/datepicker/styles.js +26 -4
  115. package/es/components/datepicker/useConfirm.d.ts +6 -0
  116. package/es/components/datepicker/useConfirm.js +65 -0
  117. package/es/components/datepicker/useDisabled.d.ts +7 -5
  118. package/es/components/datepicker/useDisabled.js +22 -27
  119. package/es/components/datepicker/useFormats.d.ts +2 -2
  120. package/es/components/datepicker/useFormats.js +9 -3
  121. package/es/components/datepicker/useHighlight.d.ts +14 -0
  122. package/es/components/datepicker/useHighlight.js +60 -0
  123. package/es/components/datepicker/useKeyboards.js +2 -1
  124. package/es/components/datepicker/useMergeRange.d.ts +5 -0
  125. package/es/components/datepicker/useMergeRange.js +45 -0
  126. package/es/components/datepicker/useMonths.js +5 -3
  127. package/es/components/datepicker/usePanel.d.ts +1 -10
  128. package/es/components/datepicker/usePanel.js +19 -32
  129. package/es/components/datepicker/useQuarters.d.ts +15 -0
  130. package/es/components/datepicker/useQuarters.js +36 -0
  131. package/es/components/datepicker/useShowDate.js +10 -2
  132. package/es/components/datepicker/useStatus.d.ts +1 -1
  133. package/es/components/datepicker/useStatus.js +33 -16
  134. package/es/components/datepicker/useValue.d.ts +12 -6
  135. package/es/components/datepicker/useValue.js +49 -45
  136. package/es/components/datepicker/useValueBase.d.ts +28 -0
  137. package/es/components/datepicker/useValueBase.js +277 -0
  138. package/es/components/datepicker/useWeeks.d.ts +19 -0
  139. package/es/components/datepicker/useWeeks.js +48 -0
  140. package/es/components/datepicker/useYears.js +6 -3
  141. package/es/components/dialog/useFixBody.js +6 -58
  142. package/es/components/dropdown/dropdown.d.ts +1 -0
  143. package/es/components/dropdown/dropdown.js +7 -4
  144. package/es/components/ellipsis/styles.js +1 -1
  145. package/es/components/form/styles.js +1 -1
  146. package/es/components/input/index.d.ts +2 -0
  147. package/es/components/input/index.js +6 -0
  148. package/es/components/input/index.spec.js +45 -0
  149. package/es/components/input/index.vdt.js +4 -3
  150. package/es/components/input/useAutoWidth.d.ts +2 -0
  151. package/es/components/input/useAutoWidth.js +19 -1
  152. package/es/components/scrollSelect/index.spec.js +4 -6
  153. package/es/components/scrollSelect/useMouseEvents.js +22 -9
  154. package/es/components/select/base.d.ts +1 -1
  155. package/es/components/select/base.js +3 -2
  156. package/es/components/select/base.vdt.js +5 -2
  157. package/es/components/select/index.spec.js +329 -82
  158. package/es/components/select/option.d.ts +1 -0
  159. package/es/components/select/option.js +10 -2
  160. package/es/components/select/select.d.ts +1 -0
  161. package/es/components/select/select.js +4 -2
  162. package/es/components/select/styles.d.ts +79 -0
  163. package/es/components/select/styles.js +1 -0
  164. package/es/components/select/useFilterable.js +2 -1
  165. package/es/components/select/useInput.d.ts +1 -1
  166. package/es/components/select/useInput.js +7 -4
  167. package/es/components/select/useSearchable.js +1 -0
  168. package/es/components/table/index.spec.js +84 -6
  169. package/es/components/table/useStickyHeader.js +1 -1
  170. package/es/components/timepicker/index.spec.js +298 -128
  171. package/es/components/timepicker/panelPicker.d.ts +23 -17
  172. package/es/components/timepicker/panelPicker.js +7 -4
  173. package/es/components/timepicker/panelPicker.vdt.js +8 -4
  174. package/es/components/timepicker/selectPicker.d.ts +5 -4
  175. package/es/components/timepicker/useConfirm.d.ts +6 -0
  176. package/es/components/timepicker/useConfirm.js +19 -0
  177. package/es/components/timepicker/useDefaultValue.d.ts +4 -0
  178. package/es/components/timepicker/useDefaultValue.js +27 -0
  179. package/es/components/timepicker/useDisabled.d.ts +7 -4
  180. package/es/components/timepicker/useDisabled.js +13 -4
  181. package/es/components/timepicker/useFormats.d.ts +1 -1
  182. package/es/components/timepicker/useValue.d.ts +14 -8
  183. package/es/components/timepicker/useValue.js +14 -15
  184. package/es/components/tour/index.d.ts +2 -0
  185. package/es/components/tour/index.js +2 -0
  186. package/es/components/tour/index.spec.d.ts +1 -0
  187. package/es/components/tour/index.spec.js +356 -0
  188. package/es/components/tour/step.d.ts +23 -0
  189. package/es/components/tour/step.js +46 -0
  190. package/es/components/tour/step.vdt.js +74 -0
  191. package/es/components/tour/styles.d.ts +7 -0
  192. package/es/components/tour/styles.js +84 -0
  193. package/es/components/tour/tour.d.ts +73 -0
  194. package/es/components/tour/tour.js +70 -0
  195. package/es/components/tour/tour.vdt.js +66 -0
  196. package/es/components/tour/useArrow.d.ts +4 -0
  197. package/es/components/tour/useArrow.js +40 -0
  198. package/es/components/tour/useFixBody.d.ts +4 -0
  199. package/es/components/tour/useFixBody.js +17 -0
  200. package/es/components/tour/useHighlight.d.ts +4 -0
  201. package/es/components/tour/useHighlight.js +31 -0
  202. package/es/components/tour/useMaskClosable.d.ts +1 -0
  203. package/es/components/tour/useMaskClosable.js +25 -0
  204. package/es/components/tour/useNavigation.d.ts +5 -0
  205. package/es/components/tour/useNavigation.js +103 -0
  206. package/es/components/tour/usePosition.d.ts +6 -0
  207. package/es/components/tour/usePosition.js +93 -0
  208. package/es/components/tour/useSteps.d.ts +6 -0
  209. package/es/components/tour/useSteps.js +68 -0
  210. package/es/hooks/useFixBody.d.ts +11 -0
  211. package/es/hooks/useFixBody.js +72 -0
  212. package/es/index.d.ts +3 -2
  213. package/es/index.js +3 -2
  214. package/es/site/data/components/datepicker/demos/multiple/react.js +2 -2
  215. package/es/site/data/components/select/demos/creatable/index.d.ts +1 -0
  216. package/es/site/data/components/select/demos/creatable/index.js +2 -1
  217. package/es/site/data/components/select/demos/creatable/react.d.ts +1 -0
  218. package/es/site/data/components/select/demos/creatable/react.js +31 -2
  219. package/es/site/data/components/tour/demos/basic/index.d.ts +17 -0
  220. package/es/site/data/components/tour/demos/basic/index.js +46 -0
  221. package/es/site/data/components/tour/demos/basic/react.d.ts +16 -0
  222. package/es/site/data/components/tour/demos/basic/react.js +82 -0
  223. package/es/site/data/components/tour/demos/beforeChange/index.d.ts +20 -0
  224. package/es/site/data/components/tour/demos/beforeChange/index.js +69 -0
  225. package/es/site/data/components/tour/demos/beforeChange/react.d.ts +19 -0
  226. package/es/site/data/components/tour/demos/beforeChange/react.js +129 -0
  227. package/es/site/data/components/tour/demos/closable/index.d.ts +18 -0
  228. package/es/site/data/components/tour/demos/closable/index.js +42 -0
  229. package/es/site/data/components/tour/demos/closable/react.d.ts +17 -0
  230. package/es/site/data/components/tour/demos/closable/react.js +85 -0
  231. package/es/site/data/components/tour/demos/custom/index.d.ts +11 -0
  232. package/es/site/data/components/tour/demos/custom/index.js +35 -0
  233. package/es/site/data/components/tour/demos/custom/react.d.ts +11 -0
  234. package/es/site/data/components/tour/demos/custom/react.js +108 -0
  235. package/es/site/data/components/tour/demos/customText/index.d.ts +33 -0
  236. package/es/site/data/components/tour/demos/customText/index.js +55 -0
  237. package/es/site/data/components/tour/demos/customText/react.d.ts +33 -0
  238. package/es/site/data/components/tour/demos/customText/react.js +99 -0
  239. package/es/site/data/components/tour/demos/declarative/index.d.ts +11 -0
  240. package/es/site/data/components/tour/demos/declarative/index.js +36 -0
  241. package/es/site/data/components/tour/demos/declarative/react.d.ts +10 -0
  242. package/es/site/data/components/tour/demos/declarative/react.js +80 -0
  243. package/es/site/data/components/tour/demos/events/index.d.ts +18 -0
  244. package/es/site/data/components/tour/demos/events/index.js +58 -0
  245. package/es/site/data/components/tour/demos/events/react.d.ts +18 -0
  246. package/es/site/data/components/tour/demos/events/react.js +101 -0
  247. package/es/site/data/components/tour/demos/maskClosable/index.d.ts +18 -0
  248. package/es/site/data/components/tour/demos/maskClosable/index.js +47 -0
  249. package/es/site/data/components/tour/demos/maskClosable/react.d.ts +17 -0
  250. package/es/site/data/components/tour/demos/maskClosable/react.js +95 -0
  251. package/es/site/data/components/tour/demos/notarget/index.d.ts +11 -0
  252. package/es/site/data/components/tour/demos/notarget/index.js +35 -0
  253. package/es/site/data/components/tour/demos/notarget/react.d.ts +10 -0
  254. package/es/site/data/components/tour/demos/notarget/react.js +61 -0
  255. package/es/site/data/components/tour/index.d.ts +57 -0
  256. package/es/site/data/components/tour/index.js +32 -0
  257. package/hooks/useFixBody.ts +87 -0
  258. package/index.ts +3 -2
  259. package/package.json +2 -2
  260. package/styles/.DS_Store +0 -0
@@ -0,0 +1,283 @@
1
+ import {css} from '@emotion/css';
2
+ import {theme, setDefault} from '../../styles/theme';
3
+ import {deepDefaults} from '../../styles/utils';
4
+ import {cache} from '../utils';
5
+
6
+ const defaults = {
7
+ minWidth: '280px',
8
+ maxWidth: '400px',
9
+ gap: '8px',
10
+ get color() { return theme.color.text },
11
+ bgColor: '#fff',
12
+ padding: {
13
+ body: '16px',
14
+ header: '12px 16px',
15
+ footer: '12px 16px',
16
+ },
17
+ fontSize: {
18
+ title: '16px',
19
+ content: '12px',
20
+ },
21
+ border: '1px solid var(--kui-color-border)',
22
+ arrow: {
23
+ size: '8px',
24
+ offset: '10px',
25
+ borderColor: 'rgba(221, 221, 221, .5)',
26
+ },
27
+
28
+ mask: {
29
+ color: 'rgba(0, 0, 0, 0.5)',
30
+ targetPadding: '8px',
31
+ targetBorderRadius: '4px',
32
+ },
33
+
34
+ // dark
35
+ dark: {
36
+ get bgColor() { return theme.color.title },
37
+ color: '#fff',
38
+ get arrowBorderColor() { return theme.color.title },
39
+ },
40
+ };
41
+
42
+ let tour: typeof defaults;
43
+ setDefault(() => {
44
+ tour = deepDefaults(theme, {tour: defaults}).tour;
45
+ makeStyles?.clearCache();
46
+ });
47
+
48
+ export type Theme = 'dark' | 'light';
49
+ export const themes: Theme[] = ['dark', 'light'];
50
+
51
+ const directionMap = {
52
+ top: 'bottom',
53
+ bottom: 'top',
54
+ left: 'right',
55
+ right: 'left',
56
+ };
57
+
58
+ export const makeStyles = cache(function makeStyles(k: string) {
59
+ const arrowLong = tour.arrow.size;
60
+ const arrowShort = `calc(${arrowLong} - 1px)`;
61
+
62
+ return css`
63
+ .${k}-tour {
64
+ position: fixed;
65
+ top: 0;
66
+ left: 0;
67
+ width: 100%;
68
+ height: 100%;
69
+ z-index: 1000;
70
+ pointer-events: none;
71
+ }
72
+
73
+ .${k}-tour-target-highlight {
74
+ position: fixed;
75
+ box-shadow: 0 0 0 9999px ${tour.mask.color};
76
+ border-radius: ${tour.mask.targetBorderRadius};
77
+ z-index: 999;
78
+ pointer-events: none;
79
+ transition: all 0.3s ease;
80
+
81
+ &.${k}-hoverable {
82
+ pointer-events: auto;
83
+ cursor: pointer;
84
+
85
+ &:hover {
86
+ box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.65);
87
+ &:after {
88
+ content: '';
89
+ position: absolute;
90
+ top: -4px;
91
+ left: -4px;
92
+ right: -4px;
93
+ bottom: -4px;
94
+ border: 2px solid rgba(255, 255, 255, 0.5);
95
+ border-radius: ${tour.mask.targetBorderRadius};
96
+ animation: pulse 1.5s infinite;
97
+ }
98
+ }
99
+ }
100
+ }
101
+
102
+ @keyframes pulse {
103
+ 0% {
104
+ transform: scale(1);
105
+ opacity: 0.8;
106
+ }
107
+ 50% {
108
+ transform: scale(1.05);
109
+ opacity: 0.5;
110
+ }
111
+ 100% {
112
+ transform: scale(1);
113
+ opacity: 0.8;
114
+ }
115
+ }
116
+
117
+ .${k}-tour-step-wrapper {
118
+ position: absolute;
119
+ z-index: 1000;
120
+ filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.15));
121
+ pointer-events: auto;
122
+
123
+ /* 居中显示样式 */
124
+ &.${k}-tour-centered {
125
+ position: fixed !important;
126
+ top: 50% !important;
127
+ left: 50% !important;
128
+ transform: translate(-50%, -50%) !important;
129
+ }
130
+ }
131
+
132
+ .${k}-tour-step {
133
+ background: #fff;
134
+ border-radius: 4px;
135
+ padding: 0;
136
+ min-width: 240px;
137
+ max-width: 400px;
138
+ position: relative;
139
+ }
140
+
141
+ .${k}-tour-step-container {
142
+ display: flex;
143
+ flex-direction: column;
144
+ }
145
+
146
+ .${k}-tour-step-header {
147
+ display: flex;
148
+ justify-content: space-between;
149
+ align-items: center;
150
+ padding: 16px 16px 8px;
151
+ border-bottom: 1px solid #f0f0f0;
152
+ }
153
+
154
+ .${k}-tour-step-title {
155
+ font-weight: 500;
156
+ font-size: 16px;
157
+ color: #262626;
158
+ }
159
+
160
+ .${k}-tour-step-close {
161
+ cursor: pointer;
162
+ color: #999;
163
+ &:hover {
164
+ color: #666;
165
+ }
166
+ }
167
+
168
+ .${k}-tour-step-body {
169
+ font-size: ${tour.fontSize.content};
170
+ padding: 16px;
171
+ color: #595959;
172
+ }
173
+
174
+ .${k}-tour-step-footer {
175
+ display: flex;
176
+ justify-content: space-between;
177
+ align-items: center;
178
+ padding: 8px 16px 16px;
179
+ }
180
+
181
+ .${k}-tour-step-indicator {
182
+ color: #8c8c8c;
183
+ }
184
+
185
+ .${k}-tour-step-buttons {
186
+ display: flex;
187
+ gap: 8px;
188
+ }
189
+
190
+ /* 箭头样式 */
191
+ .${k}-tour-arrow {
192
+ pointer-events: none;
193
+ &:before, & {
194
+ position: absolute;
195
+ display: block;
196
+ border-style: solid;
197
+ border-color: transparent;
198
+ }
199
+ &:before {
200
+ content: ' ';
201
+ }
202
+ &.${k}-top,
203
+ &.${k}-bottom {
204
+ &:before, & {
205
+ border-width: ${arrowLong} ${arrowShort};
206
+ }
207
+ &:before {
208
+ left: calc(-1 * ${arrowShort});
209
+ }
210
+ }
211
+ &.${k}-top {
212
+ top: calc(-2 * ${arrowLong});
213
+ &:before {
214
+ top: calc(-${arrowLong} + 1px);
215
+ }
216
+ }
217
+ &.${k}-bottom {
218
+ bottom: calc(-2 * ${arrowLong});
219
+ &:before {
220
+ bottom: calc(-${arrowLong} + 1px);
221
+ }
222
+ }
223
+ &.${k}-left,
224
+ &.${k}-right {
225
+ &:before, & {
226
+ border-width: ${arrowShort} ${arrowLong};
227
+ }
228
+ &:before {
229
+ top: calc(-1 * ${arrowShort});
230
+ }
231
+ }
232
+ &.${k}-left {
233
+ left: calc(-2 * ${arrowLong});
234
+ &:before {
235
+ left: calc(-${arrowLong} + 1px);
236
+ }
237
+ }
238
+ &.${k}-right {
239
+ right: calc(-2 * ${arrowLong});
240
+ &:before {
241
+ right: calc(-${arrowLong} + 1px);
242
+ }
243
+ }
244
+ }
245
+
246
+ ${themes.map(theme => {
247
+ let borderColor: string;
248
+ let bgColor: string;
249
+ let color: string;
250
+ if (theme === 'dark') {
251
+ borderColor = tour.dark.arrowBorderColor;
252
+ bgColor = tour.dark.bgColor;
253
+ color = tour.dark.color;
254
+ } else {
255
+ borderColor = tour.arrow.borderColor;
256
+ bgColor = tour.bgColor;
257
+ color = tour.color;
258
+ }
259
+
260
+ return css`
261
+ &.${k}-${theme} {
262
+ background: ${bgColor};
263
+ color: ${color};
264
+ .${k}-tour-step-wrapper .${k}-tour-arrow {
265
+ ${Object.keys(directionMap).map(direction => {
266
+ const borderDirection = directionMap[direction as keyof typeof directionMap];
267
+ return css`
268
+ &.${k}-${direction} {
269
+ &:before {
270
+ border-${borderDirection}-color: ${bgColor};
271
+ }
272
+ }
273
+ `
274
+ })}
275
+ }
276
+ }
277
+ `
278
+ })}
279
+ `;
280
+ });
281
+
282
+ // 让样式能被导入
283
+ export default makeStyles;
@@ -0,0 +1,107 @@
1
+ import {
2
+ Component,
3
+ TypeDefs,
4
+ VNode,
5
+ createRef,
6
+ onMounted,
7
+ onUpdated,
8
+ nextTick
9
+ } from "intact";
10
+ import template from "./tour.vdt";
11
+ import { useConfigContext } from '../config';
12
+ import { TourStepProps } from './step';
13
+ import type {Events} from '../types';
14
+ import { createContext } from '../context';
15
+ import { usePosition } from './usePosition';
16
+ import { Feedback } from '../position';
17
+ import { useSteps } from './useSteps';
18
+ import { useArrow } from './useArrow';
19
+ import { useHighlight } from './useHighlight';
20
+ import { useNavigation } from './useNavigation';
21
+ import { useFixBody } from './useFixBody';
22
+ import { useMaskClosable } from './useMaskClosable';
23
+ import {Theme, themes} from './styles';
24
+
25
+ export interface TourProps {
26
+ value?: number;
27
+ theme?: Theme
28
+ data?: TourStepProps[];
29
+ beforeChange?: (current: number) => boolean | Promise<boolean>;
30
+ maskClosable?: boolean;
31
+ closable?: boolean;
32
+ doneText?: string;
33
+ showArrow?: boolean;
34
+ visible?: boolean;
35
+ }
36
+
37
+ export interface TourEvents {
38
+ finish: [];
39
+ prev: [number];
40
+ next: [number];
41
+ positioned: [Feedback];
42
+ }
43
+
44
+ export interface TourBlocks {
45
+ default: null;
46
+ }
47
+
48
+ export interface TourContextValue {
49
+ value: number;
50
+ total: number;
51
+ doneText: string;
52
+ closable: boolean;
53
+ onPrev: () => void;
54
+ onNext: () => void;
55
+ onFinish: () => void;
56
+ }
57
+
58
+ export const TourContext = createContext<TourContextValue>();
59
+
60
+ const typeDefs: Required<TypeDefs<TourProps>> = {
61
+ value: Number,
62
+ theme: themes,
63
+ data: Array,
64
+ beforeChange: Function,
65
+ maskClosable: Boolean,
66
+ closable: Boolean,
67
+ doneText: String,
68
+ showArrow: Boolean,
69
+ visible: Boolean,
70
+ };
71
+
72
+ const defaults = (): Partial<TourProps> => ({
73
+ value: 0,
74
+ theme: 'light',
75
+ data: [],
76
+ maskClosable: true,
77
+ closable: true,
78
+ doneText: '完成',
79
+ showArrow: true,
80
+ visible: true,
81
+ });
82
+
83
+ const events: Events<TourEvents> = {
84
+ finish: true,
85
+ prev: true,
86
+ next: true,
87
+ positioned: true,
88
+ };
89
+
90
+ export class Tour extends Component<TourProps, TourEvents, TourBlocks> {
91
+ static template = template;
92
+ static typeDefs = typeDefs;
93
+ static defaults = defaults;
94
+ static events = events;
95
+
96
+ public config = useConfigContext();
97
+ public tourRef = createRef<HTMLDivElement>();
98
+
99
+ public steps = useSteps();
100
+ public arrow = useArrow();
101
+ public highlight = useHighlight(this.steps.getTargetElement);
102
+ private position = usePosition(this.tourRef, this.steps.getTargetElement);
103
+ public navigation = useNavigation(this.steps.getTotalSteps);
104
+ private fixBody = useFixBody();
105
+ private useMaskClosable = useMaskClosable();
106
+
107
+ }
@@ -0,0 +1,83 @@
1
+ import {makeStyles} from './styles';
2
+ import {TourStep} from './step';
3
+ import {TourContext} from './tour';
4
+ import {getRestProps, stopPropagation} from '../utils';
5
+ import {mapChildren, isComponentVNode} from '../utils';
6
+
7
+ const { className, data, children, value, hoverable,
8
+ showArrow, theme, visible, maskClosable,
9
+ doneText, closable,
10
+ } = this.get();
11
+ const { k } = this.config;
12
+
13
+ const currentValue = value !== undefined ? value : 0;
14
+ const {arrowType, arrowRef} = this.arrow;
15
+ const {highlightRef} = this.highlight;
16
+ const {prev, next, finish} = this.navigation;
17
+ const {getTotalSteps} = this.steps;
18
+
19
+ const contextValue = {
20
+ value: value || 0,
21
+ total: getTotalSteps(),
22
+ doneText: doneText,
23
+ closable: closable,
24
+ onPrev: prev,
25
+ onNext: next,
26
+ onFinish: finish
27
+ }
28
+
29
+ const classNameObj = {
30
+ [`${k}-tour`]: true,
31
+ [`${k}-${theme}`]: true,
32
+ [className]: className,
33
+ [makeStyles(k)]: true,
34
+ };
35
+
36
+ <div class={classNameObj} {...getRestProps(this)} v-if={visible}>
37
+ <TourContext.Provider value={contextValue}>
38
+ {/* 高亮目标元素 */}
39
+ <div
40
+ class={{
41
+ [`${k}-tour-target-highlight`]: true,
42
+ [`${k}-hoverable`]: hoverable
43
+ }}
44
+ v-if={currentValue !== undefined}
45
+ ref={highlightRef}
46
+ ></div>
47
+
48
+ {/* 步骤内容 */}
49
+ <div
50
+ class={`${k}-tour-step-wrapper`}
51
+ ref={this.tourRef}
52
+ ev-click={stopPropagation}
53
+ >
54
+ <template v-if={!children}>
55
+ <TourStep
56
+ v-for={data}
57
+ v-if={$key === currentValue}
58
+ key={$key}
59
+ {...$value}
60
+ />
61
+ </template>
62
+ <template v-else>
63
+ {mapChildren(children, (vNode, index) => {
64
+ if (isComponentVNode(vNode, TourStep)) {
65
+ if (index === currentValue) {
66
+ return vNode;
67
+ }
68
+ }
69
+ return null;
70
+ })}
71
+ </template>
72
+
73
+ {/* 箭头 */}
74
+ <i v-if={showArrow && arrowType.value}
75
+ class={{
76
+ [`${k}-tour-arrow`]: true,
77
+ [`${k}-${arrowType.value}`]: arrowType.value,
78
+ }}
79
+ ref={arrowRef}
80
+ ></i>
81
+ </div>
82
+ </TourContext.Provider>
83
+ </div>
@@ -0,0 +1,46 @@
1
+ import {useInstance, createRef, nextTick} from 'intact';
2
+ import { Tour } from './tour';
3
+ import {Feedback} from '../position';
4
+ import {useState} from '../../hooks/useState';
5
+ import {clamp} from '../utils';
6
+
7
+ export function useArrow() {
8
+ const instance = useInstance() as Tour;
9
+ const arrowType = useState<string | null>(null);
10
+ const arrowRef = createRef<HTMLElement>();
11
+
12
+ // 监听positioned事件
13
+ instance.on('positioned', (feedback: Feedback) => {
14
+ updateArrow(feedback);
15
+ });
16
+
17
+ // update arrow position and type
18
+ function updateArrow(feedback: Feedback) {
19
+ if (!instance.get('showArrow')) return;
20
+
21
+ arrowType.set(feedback[feedback.important]);
22
+
23
+ nextTick(() => {
24
+ if (instance.$unmounted) return;
25
+
26
+ const arrow = arrowRef.value!;
27
+ const {target, element} = feedback;
28
+
29
+ if (feedback.important === 'vertical') {
30
+ // vertical important, adjust horizontal position
31
+ const arrowWidth = arrow.offsetWidth;
32
+ let left = target.left - element.left + (target.width - arrowWidth) / 2;
33
+ left = clamp(left, 1, element.width - 1 - arrowWidth);
34
+ arrow.setAttribute('style', `left: ${left}px`);
35
+ } else {
36
+ // horizontal important, adjust vertical position
37
+ const arrowHeight = arrow.offsetHeight;
38
+ let top = target.top - element.top + target.height / 2 - arrowHeight / 2;
39
+ top = clamp(top, 1, element.height - 1 - arrowHeight);
40
+ arrow.setAttribute('style', `top: ${top}px`);
41
+ }
42
+ });
43
+ }
44
+
45
+ return {arrowType, arrowRef};
46
+ }
@@ -0,0 +1,22 @@
1
+ import {useInstance} from 'intact';
2
+ import type {Tour} from './tour';
3
+ import {useFixBody as useFixBodyHook} from '../../hooks/useFixBody';
4
+
5
+ export function useFixBody() {
6
+ const instance = useInstance() as Tour;
7
+
8
+ const fixBodyHook = useFixBodyHook();
9
+
10
+ instance.watch('visible', (visible) => {
11
+ if (visible) {
12
+ fixBodyHook.onOpen();
13
+ } else {
14
+ fixBodyHook.onClose();
15
+ }
16
+ });
17
+
18
+ return {
19
+ onOpen: fixBodyHook.onOpen,
20
+ onClosed: fixBodyHook.onClose
21
+ };
22
+ }
@@ -0,0 +1,36 @@
1
+ import {useInstance, createRef, nextTick} from 'intact';
2
+ import { Tour } from './tour';
3
+
4
+ export function useHighlight(getTargetElement: (index?: number) => HTMLElement | null,) {
5
+ const instance = useInstance() as Tour;
6
+ const highlightRef = createRef<HTMLElement>();
7
+
8
+ instance.on('$updated' as any, updateHighlight);
9
+
10
+ instance.watch('visible', (visible) => {
11
+ if (visible) {
12
+ nextTick(() => {
13
+ updateHighlight();
14
+ });
15
+ }
16
+ });
17
+
18
+ // update highlight element position and size
19
+ function updateHighlight() {
20
+ const highlightElem = highlightRef.value;
21
+ const targetElem = getTargetElement();
22
+
23
+ if (highlightElem && targetElem) {
24
+ const rect = targetElem.getBoundingClientRect();
25
+ const padding = 8;
26
+
27
+ highlightElem.style.width = `${rect.width + padding * 2}px`;
28
+ highlightElem.style.height = `${rect.height + padding * 2}px`;
29
+ highlightElem.style.position = 'fixed';
30
+ highlightElem.style.left = `${rect.left - padding}px`;
31
+ highlightElem.style.top = `${rect.top - padding}px`;
32
+ }
33
+ }
34
+
35
+ return {highlightRef, updateHighlight};
36
+ }
@@ -0,0 +1,26 @@
1
+ import { useInstance } from "intact";
2
+ import { useDocumentClick } from "../../hooks/useDocumentClick";
3
+ import type {Tour} from './tour';
4
+
5
+ export function useMaskClosable() {
6
+ const tour = useInstance() as Tour;
7
+ const [addDocumentClick, removeDocumentClick] = useDocumentClick(tour.tourRef, (e) => {
8
+ const maskClosable = tour.get('maskClosable');
9
+ if (maskClosable) {
10
+ // 检查点击的是否是当前目标元素或其子元素
11
+ const targetElement = tour.steps.getTargetElement();
12
+ if (targetElement && (e.target === targetElement || targetElement.contains(e.target as Node))) {
13
+ return; // 点击的是目标元素,不关闭
14
+ }
15
+ tour.navigation.finish();
16
+ }
17
+ }, true);
18
+
19
+ tour.watch('visible', (visible: boolean | undefined) => {
20
+ if (visible) {
21
+ addDocumentClick();
22
+ } else {
23
+ removeDocumentClick();
24
+ }
25
+ });
26
+ }
@@ -0,0 +1,46 @@
1
+ import {useInstance, createRef, nextTick} from 'intact';
2
+ import { Tour } from './tour';
3
+
4
+ export function useNavigation(getTotalSteps: () => number) {
5
+ const instance = useInstance() as Tour;
6
+
7
+ async function prev() {
8
+ const { value, beforeChange } = instance.get();
9
+ if (value === undefined || value <= 0) return;
10
+
11
+ if (beforeChange) {
12
+ const canChange = await beforeChange(value - 1);
13
+ if (canChange === false) return;
14
+ }
15
+
16
+ instance.set('value', value - 1);
17
+ instance.trigger('prev', value - 1);
18
+ }
19
+
20
+ async function next() {
21
+ const { value, beforeChange } = instance.get();
22
+ if (value === undefined) return;
23
+
24
+ const steps = getTotalSteps();
25
+
26
+ if (value >= steps - 1) {
27
+ finish();
28
+ return;
29
+ }
30
+
31
+ if (beforeChange) {
32
+ const canChange = await beforeChange(value + 1);
33
+ if (canChange === false) return;
34
+ }
35
+
36
+ instance.set('value', value + 1);
37
+ instance.trigger('next', value + 1);
38
+ }
39
+
40
+ function finish() {
41
+ instance.trigger('finish');
42
+ instance.set('visible', false);
43
+ }
44
+
45
+ return {prev, next, finish};
46
+ }