oxy-uni-ui 2.1.0 → 2.1.2
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/attributes.json +1 -1
- package/components/common/abstracts/variable.scss +145 -100
- package/components/common/util.ts +25 -0
- package/components/composables/useDynamicVirtualScroll.ts +80 -0
- package/components/oxy-action-sheet/index.scss +6 -6
- package/components/oxy-backtop/index.scss +1 -1
- package/components/oxy-badge/index.scss +2 -2
- package/components/oxy-button/index.scss +3 -6
- package/components/oxy-calendar/index.scss +2 -2
- package/components/oxy-calendar/oxy-calendar.vue +3 -3
- package/components/oxy-calendar-view/monthPanel/month-panel.vue +72 -37
- package/components/oxy-calendar-view/monthPanel/types.ts +43 -1
- package/components/oxy-calendar-view/types.ts +1 -1
- package/components/oxy-calendar-view/utils.ts +12 -1
- package/components/oxy-calendar-view/yearPanel/types.ts +36 -2
- package/components/oxy-calendar-view/yearPanel/year-panel.vue +64 -45
- package/components/oxy-card/index.scss +4 -4
- package/components/oxy-cell/index.scss +1 -1
- package/components/oxy-cell-group/index.scss +2 -2
- package/components/oxy-checkbox/index.scss +87 -197
- package/components/oxy-collapse/index.scss +1 -1
- package/components/oxy-collapse-item/index.scss +2 -2
- package/components/oxy-corner/index.scss +3 -3
- package/components/oxy-count-to/oxy-count-to.vue +3 -3
- package/components/oxy-count-to/types.ts +1 -1
- package/components/oxy-date-strip-item/index.scss +4 -4
- package/components/oxy-datetime-picker/types.ts +1 -1
- package/components/oxy-datetime-picker-view/types.ts +2 -2
- package/components/oxy-fab/index.scss +1 -5
- package/components/oxy-file-list/index.scss +2 -2
- package/components/oxy-footer/index.scss +2 -2
- package/components/oxy-footer/oxy-footer.vue +2 -3
- package/components/oxy-form-item/index.scss +0 -5
- package/components/oxy-grid/oxy-grid.vue +1 -1
- package/components/oxy-grid-item/index.scss +1 -1
- package/components/oxy-guidance/index.scss +2 -2
- package/components/oxy-img/index.scss +2 -2
- package/components/oxy-img-cropper/index.scss +0 -2
- package/components/oxy-img-lazy/index.scss +0 -1
- package/components/oxy-index-anchor/index.scss +3 -3
- package/components/oxy-input/index.scss +2 -2
- package/components/oxy-input-number/index.scss +21 -3
- package/components/oxy-input-number/oxy-input-number.vue +9 -1
- package/components/oxy-keyboard/index.scss +1 -1
- package/components/oxy-link/index.scss +11 -10
- package/components/oxy-loading/index.scss +1 -1
- package/components/oxy-loadmore/index.scss +1 -1
- package/components/oxy-message-box/index.scss +7 -7
- package/components/oxy-navbar/index.scss +1 -1
- package/components/oxy-navbar/oxy-navbar.vue +2 -3
- package/components/oxy-password-input/index.scss +4 -4
- package/components/oxy-picker/types.ts +1 -1
- package/components/oxy-picker-view/oxy-picker-view.vue +8 -5
- package/components/oxy-picker-view/types.ts +2 -2
- package/components/oxy-progress/index.scss +2 -2
- package/components/oxy-radio/index.scss +8 -4
- package/components/oxy-radio-group/index.scss +0 -1
- package/components/oxy-rich-text/index.scss +2 -6
- package/components/oxy-rich-text/mp-html/mp-html.d.ts +2 -0
- package/components/oxy-rich-text/mp-html/mp-html.vue +2 -1
- package/components/oxy-rich-text/mp-html/node/node.vue +23 -0
- package/components/oxy-rich-text/mp-html/parser.js +6 -6
- package/components/oxy-rich-text/oxy-rich-text.vue +23 -0
- package/components/oxy-search/index.scss +1 -1
- package/components/oxy-segmented/index.scss +4 -8
- package/components/oxy-select/index.scss +6 -6
- package/components/oxy-sidebar-item/index.scss +20 -11
- package/components/oxy-slider/index.scss +4 -5
- package/components/oxy-sort-button/index.scss +6 -9
- package/components/oxy-splitter-panel/index.scss +8 -8
- package/components/oxy-step/index.scss +9 -9
- package/components/oxy-swiper-nav/index.scss +2 -2
- package/components/oxy-switch/index.scss +3 -3
- package/components/oxy-tab/index.scss +8 -2
- package/components/oxy-tabbar/index.scss +3 -3
- package/components/oxy-tabbar/oxy-tabbar.vue +3 -3
- package/components/oxy-table/index.scss +0 -1
- package/components/oxy-table-col/index.scss +1 -2
- package/components/oxy-tabs/index.scss +3 -3
- package/components/oxy-tag/index.scss +160 -20
- package/components/oxy-tag/oxy-tag.vue +14 -2
- package/components/oxy-tag/types.ts +9 -0
- package/components/oxy-text/index.scss +1 -1
- package/components/oxy-textarea/index.scss +2 -6
- package/components/oxy-toast/index.scss +1 -1
- package/components/oxy-tree/index.scss +31 -11
- package/components/oxy-tree/oxy-tree.vue +113 -2
- package/components/oxy-tree/types.ts +1 -0
- package/components/oxy-upload/index.scss +3 -3
- package/components/oxy-video-preview/index.scss +3 -3
- package/components/oxy-virtual-scroll/index.scss +1 -1
- package/components/oxy-voice-player/index.scss +36 -36
- package/components/oxy-watermark/index.scss +1 -1
- package/dev-tools.ts +2 -0
- package/devTools/components/DevToolsOverlay.vue +56 -0
- package/devTools/components/DevToolsUiHost.vue +589 -0
- package/devTools/config.js +55 -0
- package/devTools/core/components/mpDevBubble.vue +174 -0
- package/devTools/core/libs/createH5Bubble.js +156 -0
- package/devTools/core/libs/devCache.js +151 -0
- package/devTools/core/libs/devOptions.js +163 -0
- package/devTools/core/libs/devUi.js +219 -0
- package/devTools/core/libs/drawView.js +140 -0
- package/devTools/core/libs/errorReport.js +64 -0
- package/devTools/core/libs/jsonCompress.js +334 -0
- package/devTools/core/libs/logReport.js +59 -0
- package/devTools/core/libs/pageLinkList.js +125 -0
- package/devTools/core/libs/timeFormat.js +94 -0
- package/devTools/core/proxy/console.js +430 -0
- package/devTools/core/proxy/index.js +36 -0
- package/devTools/core/proxy/request.js +495 -0
- package/devTools/core/proxy/storage.js +113 -0
- package/devTools/core/proxy/uniBus.js +153 -0
- package/devTools/core/proxy/uniListen.js +192 -0
- package/devTools/core/proxy/vueMixin.js +120 -0
- package/devTools/index.js +168 -0
- package/devTools/page/components/bottomTools.vue +1046 -0
- package/devTools/page/components/dialog/addStorage.vue +204 -0
- package/devTools/page/components/dialog/createDir.vue +366 -0
- package/devTools/page/components/dialog/editDialog.vue +192 -0
- package/devTools/page/components/dialog/routeDialog.vue +184 -0
- package/devTools/page/components/dialog/sendRequest.vue +603 -0
- package/devTools/page/components/dialog/textFileEditDialog.vue +391 -0
- package/devTools/page/components/libs/appDelDir.js +86 -0
- package/devTools/page/components/libs/dirReader.js +248 -0
- package/devTools/page/components/libs/fileSize.js +15 -0
- package/devTools/page/components/libs/getRuntimeInfo.js +134 -0
- package/devTools/page/components/listItem/consoleItem.vue +314 -0
- package/devTools/page/components/listItem/errorItem.vue +292 -0
- package/devTools/page/components/listItem/fileSysItem.vue +533 -0
- package/devTools/page/components/listItem/infoList.vue +100 -0
- package/devTools/page/components/listItem/jsRunnerItem.vue +255 -0
- package/devTools/page/components/listItem/logItem.vue +193 -0
- package/devTools/page/components/listItem/networkItem.vue +398 -0
- package/devTools/page/components/listItem/objectAnalysis.vue +651 -0
- package/devTools/page/components/listItem/pages.vue +319 -0
- package/devTools/page/components/listItem/routeItem.vue +153 -0
- package/devTools/page/components/listItem/setting.vue +734 -0
- package/devTools/page/components/listItem/storageList.vue +681 -0
- package/devTools/page/components/listItem/tools.vue +315 -0
- package/devTools/page/components/listItem/vuexList.vue +599 -0
- package/devTools/page/components/main.vue +1867 -0
- package/devTools/page/components/mixins/animationControl.js +91 -0
- package/devTools/page/components/mixins/mp.js +83 -0
- package/devTools/page/components/ui/btnTabs.vue +90 -0
- package/devTools/page/components/ui/codeHisPicker.vue +172 -0
- package/devTools/page/components/ui/h5Cell.vue +13 -0
- package/devTools/page/components/ui/menuBtn.vue +94 -0
- package/devTools/page/components/ui/mobileSwiperScroll.vue +74 -0
- package/devTools/page/components/ui/requestSpeedLimit.vue +52 -0
- package/devTools/page/components/ui/requestTimeoutMock.vue +55 -0
- package/devTools/page/components/ui/subTitleBar.vue +101 -0
- package/devTools/page/static/copy.png +0 -0
- package/devTools/page/static/delete.png +0 -0
- package/devTools/page/static/fileSys/AI.png +0 -0
- package/devTools/page/static/fileSys/DWG.png +0 -0
- package/devTools/page/static/fileSys/EXE.png +0 -0
- package/devTools/page/static/fileSys/GIF.png +0 -0
- package/devTools/page/static/fileSys/HTML.png +0 -0
- package/devTools/page/static/fileSys/PSD.png +0 -0
- package/devTools/page/static/fileSys/RVT.png +0 -0
- package/devTools/page/static/fileSys/SKP.png +0 -0
- package/devTools/page/static/fileSys/SVG.png +0 -0
- package/devTools/page/static/fileSys/excel.png +0 -0
- package/devTools/page/static/fileSys/pdf.png +0 -0
- package/devTools/page/static/fileSys/pptl.png +0 -0
- package/devTools/page/static/fileSys/shipin.png +0 -0
- package/devTools/page/static/fileSys/tupian.png +0 -0
- package/devTools/page/static/fileSys/txt.png +0 -0
- package/devTools/page/static/fileSys/weizhiwenjian.png +0 -0
- package/devTools/page/static/fileSys/wenjianjia.png +0 -0
- package/devTools/page/static/fileSys/word.png +0 -0
- package/devTools/page/static/fileSys/yasuo.png +0 -0
- package/devTools/page/static/fileSys/yinpin.png +0 -0
- package/devTools/page/static/fold.png +0 -0
- package/devTools/page/static/menu.png +0 -0
- package/devTools/page/static/refresh.png +0 -0
- package/devTools/page/static/unfold.png +0 -0
- package/devTools/tools.vue +25 -0
- package/devTools/type/devTools.d.ts +406 -0
- package/oxy-dev-tools/components/DevToolsUiHost.vue +555 -0
- package/oxy-dev-tools/config.js +61 -0
- package/oxy-dev-tools/core/components/mpDevBubble.vue +176 -0
- package/oxy-dev-tools/core/libs/createH5Bubble.js +156 -0
- package/oxy-dev-tools/core/libs/devCache.js +149 -0
- package/oxy-dev-tools/core/libs/devOptions.js +160 -0
- package/oxy-dev-tools/core/libs/devUi.js +219 -0
- package/oxy-dev-tools/core/libs/drawView.js +144 -0
- package/oxy-dev-tools/core/libs/errorReport.js +60 -0
- package/oxy-dev-tools/core/libs/jsonCompress.js +328 -0
- package/oxy-dev-tools/core/libs/logReport.js +55 -0
- package/oxy-dev-tools/core/libs/pageLinkList.js +121 -0
- package/oxy-dev-tools/core/libs/timeFormat.js +93 -0
- package/oxy-dev-tools/core/proxy/console.js +398 -0
- package/oxy-dev-tools/core/proxy/index.js +33 -0
- package/oxy-dev-tools/core/proxy/request.js +473 -0
- package/oxy-dev-tools/core/proxy/storage.js +96 -0
- package/oxy-dev-tools/core/proxy/uniBus.js +148 -0
- package/oxy-dev-tools/core/proxy/uniListen.js +190 -0
- package/oxy-dev-tools/core/proxy/vueMixin.js +115 -0
- package/oxy-dev-tools/index.ts +183 -0
- package/oxy-dev-tools/oxy-dev-tools.vue +62 -0
- package/oxy-dev-tools/page/components/bottomTools.vue +933 -0
- package/oxy-dev-tools/page/components/dialog/addStorage.vue +184 -0
- package/oxy-dev-tools/page/components/dialog/createDir.vue +352 -0
- package/oxy-dev-tools/page/components/dialog/editDialog.vue +178 -0
- package/oxy-dev-tools/page/components/dialog/routeDialog.vue +170 -0
- package/oxy-dev-tools/page/components/dialog/sendRequest.vue +530 -0
- package/oxy-dev-tools/page/components/dialog/textFileEditDialog.vue +379 -0
- package/oxy-dev-tools/page/components/libs/appDelDir.js +77 -0
- package/oxy-dev-tools/page/components/libs/dirReader.js +239 -0
- package/oxy-dev-tools/page/components/libs/fileSize.js +15 -0
- package/oxy-dev-tools/page/components/libs/getRuntimeInfo.js +132 -0
- package/oxy-dev-tools/page/components/listItem/consoleItem.vue +292 -0
- package/oxy-dev-tools/page/components/listItem/errorItem.vue +268 -0
- package/oxy-dev-tools/page/components/listItem/fileSysItem.vue +511 -0
- package/oxy-dev-tools/page/components/listItem/infoList.vue +89 -0
- package/oxy-dev-tools/page/components/listItem/jsRunnerItem.vue +236 -0
- package/oxy-dev-tools/page/components/listItem/logItem.vue +185 -0
- package/oxy-dev-tools/page/components/listItem/networkItem.vue +362 -0
- package/oxy-dev-tools/page/components/listItem/objectAnalysis.vue +642 -0
- package/oxy-dev-tools/page/components/listItem/pages.vue +285 -0
- package/oxy-dev-tools/page/components/listItem/routeItem.vue +140 -0
- package/oxy-dev-tools/page/components/listItem/setting.vue +687 -0
- package/oxy-dev-tools/page/components/listItem/storageList.vue +623 -0
- package/oxy-dev-tools/page/components/listItem/tools.vue +273 -0
- package/oxy-dev-tools/page/components/listItem/vuexList.vue +559 -0
- package/oxy-dev-tools/page/components/main.vue +1824 -0
- package/oxy-dev-tools/page/components/mixins/animationControl.js +80 -0
- package/oxy-dev-tools/page/components/mixins/mp.js +76 -0
- package/oxy-dev-tools/page/components/ui/btnTabs.vue +77 -0
- package/oxy-dev-tools/page/components/ui/codeHisPicker.vue +161 -0
- package/oxy-dev-tools/page/components/ui/h5Cell.vue +13 -0
- package/oxy-dev-tools/page/components/ui/menuBtn.vue +87 -0
- package/oxy-dev-tools/page/components/ui/mobileSwiperScroll.vue +71 -0
- package/oxy-dev-tools/page/components/ui/requestSpeedLimit.vue +47 -0
- package/oxy-dev-tools/page/components/ui/requestTimeoutMock.vue +50 -0
- package/oxy-dev-tools/page/components/ui/subTitleBar.vue +87 -0
- package/oxy-dev-tools/page/static/copy.png +0 -0
- package/oxy-dev-tools/page/static/delete.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/AI.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/DWG.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/EXE.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/GIF.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/HTML.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/PSD.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/RVT.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/SKP.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/SVG.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/excel.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/pdf.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/pptl.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/shipin.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/tupian.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/txt.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/weizhiwenjian.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/wenjianjia.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/word.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/yasuo.png +0 -0
- package/oxy-dev-tools/page/static/fileSys/yinpin.png +0 -0
- package/oxy-dev-tools/page/static/fold.png +0 -0
- package/oxy-dev-tools/page/static/menu.png +0 -0
- package/oxy-dev-tools/page/static/refresh.png +0 -0
- package/oxy-dev-tools/page/static/unfold.png +0 -0
- package/oxy-dev-tools/tools.vue +22 -0
- package/oxy-dev-tools/type/devTools.d.ts +406 -0
- package/package.json +1 -1
- package/tags.json +1 -1
- package/web-types.json +1 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ref, computed, type Ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
export interface DynamicVirtualScrollItem {
|
|
4
|
+
top: number
|
|
5
|
+
height: number
|
|
6
|
+
[key: string]: any
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface UseDynamicVirtualScrollOptions<T extends DynamicVirtualScrollItem> {
|
|
10
|
+
data: Ref<T[]>
|
|
11
|
+
scrollTop: Ref<number>
|
|
12
|
+
viewportHeight: Ref<number>
|
|
13
|
+
buffer?: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function useDynamicVirtualScroll<T extends DynamicVirtualScrollItem>(options: UseDynamicVirtualScrollOptions<T>) {
|
|
17
|
+
const { data, scrollTop, viewportHeight, buffer = 0 } = options
|
|
18
|
+
|
|
19
|
+
const visibleData = computed(() => {
|
|
20
|
+
const st = scrollTop.value
|
|
21
|
+
const sh = viewportHeight.value
|
|
22
|
+
const buf = buffer || sh // 默认上下多预留一屏高度
|
|
23
|
+
|
|
24
|
+
const minTop = st - buf
|
|
25
|
+
const maxTop = st + sh + buf
|
|
26
|
+
|
|
27
|
+
// 二分查找第一个进入可视区的元素
|
|
28
|
+
let left = 0
|
|
29
|
+
let right = data.value.length - 1
|
|
30
|
+
let startIndex = 0
|
|
31
|
+
|
|
32
|
+
while (left <= right) {
|
|
33
|
+
const mid = Math.floor((left + right) / 2)
|
|
34
|
+
const item = data.value[mid]
|
|
35
|
+
if (item.top + item.height > minTop) {
|
|
36
|
+
startIndex = mid
|
|
37
|
+
right = mid - 1
|
|
38
|
+
} else {
|
|
39
|
+
left = mid + 1
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 从 startIndex 往后取,直到超出可视区
|
|
44
|
+
const result = []
|
|
45
|
+
for (let i = startIndex; i < data.value.length; i++) {
|
|
46
|
+
const item = data.value[i]
|
|
47
|
+
if (item.top < maxTop) {
|
|
48
|
+
result.push({ ...item, index: i })
|
|
49
|
+
} else {
|
|
50
|
+
break
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return result
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const getTargetIndex = (st: number) => {
|
|
58
|
+
let left = 0
|
|
59
|
+
let right = data.value.length - 1
|
|
60
|
+
let targetIndex = 0
|
|
61
|
+
|
|
62
|
+
while (left <= right) {
|
|
63
|
+
const mid = Math.floor((left + right) / 2)
|
|
64
|
+
const item = data.value[mid]
|
|
65
|
+
if (st < item.top + item.height) {
|
|
66
|
+
targetIndex = mid
|
|
67
|
+
right = mid - 1
|
|
68
|
+
} else {
|
|
69
|
+
left = mid + 1
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return targetIndex
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
visibleData,
|
|
78
|
+
getTargetIndex
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
@include b(action-sheet) {
|
|
60
|
-
background-color: $-
|
|
60
|
+
background-color: $-action-sheet-bg;
|
|
61
61
|
padding-bottom: 2rpx;
|
|
62
62
|
margin-bottom: var(--window-bottom);
|
|
63
63
|
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
line-height: initial;
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
|
|
115
115
|
@include edeep(action-loading){
|
|
116
116
|
width: $-action-sheet-loading-size;
|
|
117
117
|
height: $-action-sheet-loading-size;
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
color: $-action-sheet-close-color;
|
|
170
170
|
font-size: $-action-sheet-close-fs;
|
|
171
171
|
transform: rotate(-45deg);
|
|
172
|
-
line-height:
|
|
172
|
+
line-height: $-line-height-tight;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
@include e(panels) {
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
&:last-of-type {
|
|
184
|
-
margin-bottom:
|
|
184
|
+
margin-bottom: $-spacing-24;
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
|
|
@@ -203,13 +203,13 @@
|
|
|
203
203
|
width: $-action-sheet-panel-img-fs;
|
|
204
204
|
height: $-action-sheet-panel-img-fs;
|
|
205
205
|
margin: 0 auto;
|
|
206
|
-
margin-bottom:
|
|
206
|
+
margin-bottom: $-spacing-16;
|
|
207
207
|
border-radius: $-action-sheet-panel-img-radius;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
@include e(panel-title) {
|
|
211
211
|
font-size: $-action-sheet-subname-fs;
|
|
212
|
-
line-height:
|
|
212
|
+
line-height: $-line-height-base;
|
|
213
213
|
text-align: center;
|
|
214
214
|
color: $-action-sheet-color;
|
|
215
215
|
@include lineEllipsis;
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
text-align: center;
|
|
29
29
|
white-space: nowrap;
|
|
30
30
|
border: $-badge-border;
|
|
31
|
-
font-weight:
|
|
31
|
+
font-weight: $-fw-medium;
|
|
32
32
|
|
|
33
33
|
@include when(fixed) {
|
|
34
34
|
position: absolute;
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
height: $-badge-dot-size;
|
|
42
42
|
width: $-badge-dot-size;
|
|
43
43
|
padding: 0;
|
|
44
|
-
border-radius:
|
|
44
|
+
border-radius: $-radius-circle;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
@each $type in (primary, success, warning, info, danger) {
|
|
@@ -47,7 +47,6 @@
|
|
|
47
47
|
display: inline-block;
|
|
48
48
|
outline: none;
|
|
49
49
|
-webkit-appearance: none;
|
|
50
|
-
outline: none;
|
|
51
50
|
background: transparent;
|
|
52
51
|
box-sizing: border-box;
|
|
53
52
|
border: none;
|
|
@@ -109,8 +108,6 @@
|
|
|
109
108
|
background-repeat: no-repeat;
|
|
110
109
|
}
|
|
111
110
|
|
|
112
|
-
@include when(loading) {}
|
|
113
|
-
|
|
114
111
|
@include when(primary) {
|
|
115
112
|
background: $-button-primary-bg-color;
|
|
116
113
|
color: $-button-primary-color;
|
|
@@ -161,7 +158,7 @@
|
|
|
161
158
|
|
|
162
159
|
@include when(icon) {
|
|
163
160
|
min-width: 0;
|
|
164
|
-
border-radius:
|
|
161
|
+
border-radius: $-radius-circle;
|
|
165
162
|
}
|
|
166
163
|
|
|
167
164
|
@include when(text) {
|
|
@@ -223,7 +220,7 @@
|
|
|
223
220
|
|
|
224
221
|
@include when(plain) {
|
|
225
222
|
background: $-button-plain-bg-color;
|
|
226
|
-
border:
|
|
223
|
+
border: #{$-border-width-base} solid currentColor;
|
|
227
224
|
|
|
228
225
|
@include when(primary) {
|
|
229
226
|
color: $-button-primary-bg-color;
|
|
@@ -295,7 +292,7 @@
|
|
|
295
292
|
width: $-button-icon-size;
|
|
296
293
|
height: $-button-icon-size;
|
|
297
294
|
padding: 0;
|
|
298
|
-
border-radius:
|
|
295
|
+
border-radius: $-radius-circle;
|
|
299
296
|
color: $-button-icon-color;
|
|
300
297
|
|
|
301
298
|
&::after {
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
@include edeep(tag) {
|
|
74
|
-
margin-right:
|
|
74
|
+
margin-right: $-spacing-16;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
@include e(view) {
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
font-size: $-fs-content;
|
|
92
92
|
|
|
93
93
|
@include when(monthrange) {
|
|
94
|
-
padding-bottom:
|
|
94
|
+
padding-bottom: $-spacing-24;
|
|
95
95
|
box-shadow: $-calendar-panel-shadow-light;
|
|
96
96
|
}
|
|
97
97
|
}
|
|
@@ -238,7 +238,7 @@ const emit = defineEmits(['cancel', 'change', 'update:modelValue', 'confirm', 'o
|
|
|
238
238
|
const pickerShow = ref<boolean>(false)
|
|
239
239
|
const calendarValue = ref<null | number | number[]>(null)
|
|
240
240
|
const lastCalendarValue = ref<null | number | number[]>(null)
|
|
241
|
-
const panelHeight = ref<number>(
|
|
241
|
+
const panelHeight = ref<number>(676)
|
|
242
242
|
const confirmBtnDisabled = ref<boolean>(true)
|
|
243
243
|
const currentTab = ref<number>(0)
|
|
244
244
|
const lastTab = ref<number>(0)
|
|
@@ -294,7 +294,7 @@ watch(
|
|
|
294
294
|
const index = newValue.indexOf('range') > -1 ? rangeTabs.indexOf(newValue) || 0 : tabs.indexOf(newValue)
|
|
295
295
|
currentTab.value = index
|
|
296
296
|
}
|
|
297
|
-
panelHeight.value = props.showConfirm ?
|
|
297
|
+
panelHeight.value = props.showConfirm ? 676 : 800
|
|
298
298
|
currentType.value = deepClone(newValue)
|
|
299
299
|
},
|
|
300
300
|
{
|
|
@@ -306,7 +306,7 @@ watch(
|
|
|
306
306
|
watch(
|
|
307
307
|
() => props.showConfirm,
|
|
308
308
|
(val) => {
|
|
309
|
-
panelHeight.value = val ?
|
|
309
|
+
panelHeight.value = val ? 676 : 800
|
|
310
310
|
},
|
|
311
311
|
{
|
|
312
312
|
deep: true,
|
|
@@ -8,27 +8,34 @@
|
|
|
8
8
|
</view>
|
|
9
9
|
<scroll-view
|
|
10
10
|
:class="`oxy-month-panel__container ${!!timeType ? 'oxy-month-panel__container--time' : ''}`"
|
|
11
|
-
:style="`height: ${
|
|
11
|
+
:style="`height: ${scrollHeight}px`"
|
|
12
12
|
scroll-y
|
|
13
13
|
@scroll="monthScroll"
|
|
14
14
|
:scroll-top="scrollTop"
|
|
15
15
|
>
|
|
16
|
-
<view
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
:
|
|
20
|
-
:
|
|
21
|
-
:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
16
|
+
<view class="oxy-month-panel__list" :style="`height: ${totalHeight}px; position: relative;`">
|
|
17
|
+
<view
|
|
18
|
+
v-for="item in visibleMonths"
|
|
19
|
+
:key="item.date"
|
|
20
|
+
:id="`month${item.index}`"
|
|
21
|
+
:style="`position: absolute; top: ${item.top}px; width: 100%;`"
|
|
22
|
+
>
|
|
23
|
+
<month
|
|
24
|
+
:type="type"
|
|
25
|
+
:date="item.date"
|
|
26
|
+
:value="value"
|
|
27
|
+
:min-date="minDate"
|
|
28
|
+
:max-date="maxDate"
|
|
29
|
+
:first-day-of-week="firstDayOfWeek"
|
|
30
|
+
:formatter="formatter"
|
|
31
|
+
:max-range="maxRange"
|
|
32
|
+
:range-prompt="rangePrompt"
|
|
33
|
+
:allow-same-day="allowSameDay"
|
|
34
|
+
:default-time="defaultTime"
|
|
35
|
+
:showTitle="item.index !== 0"
|
|
36
|
+
@change="handleDateChange"
|
|
37
|
+
/>
|
|
38
|
+
</view>
|
|
32
39
|
</view>
|
|
33
40
|
</scroll-view>
|
|
34
41
|
<view v-if="timeType" class="oxy-month-panel__time">
|
|
@@ -65,10 +72,23 @@ export default {
|
|
|
65
72
|
import OxyPickerView from '../../oxy-picker-view/oxy-picker-view.vue'
|
|
66
73
|
import { computed, ref, watch, onMounted } from 'vue'
|
|
67
74
|
import { debounce, isArray, isEqual, isNumber, pause, unitConvert } from '../../common/util'
|
|
68
|
-
import {
|
|
75
|
+
import {
|
|
76
|
+
compareMonth,
|
|
77
|
+
formatMonthTitle,
|
|
78
|
+
getMonthEndDay,
|
|
79
|
+
getMonths,
|
|
80
|
+
getTimeData,
|
|
81
|
+
getWeekLabel,
|
|
82
|
+
designPxToRuntimePx,
|
|
83
|
+
MONTH_ROW_HEIGHT,
|
|
84
|
+
MONTH_ROW_GAP,
|
|
85
|
+
MONTH_TITLE_HEIGHT,
|
|
86
|
+
TIME_PICKER_HEIGHT
|
|
87
|
+
} from '../utils'
|
|
69
88
|
import Month from '../month/month.vue'
|
|
70
89
|
import { monthPanelProps, type MonthInfo, type MonthPanelTimeType, type MonthPanelExpose } from './types'
|
|
71
90
|
import { useTranslate } from '../../composables/useTranslate'
|
|
91
|
+
import { useDynamicVirtualScroll } from '../../composables/useDynamicVirtualScroll'
|
|
72
92
|
import type { CalendarItem } from '../types'
|
|
73
93
|
|
|
74
94
|
const props = defineProps(monthPanelProps)
|
|
@@ -77,18 +97,13 @@ const emit = defineEmits(['change', 'pickstart', 'pickend'])
|
|
|
77
97
|
const { translate } = useTranslate('calendar-view')
|
|
78
98
|
|
|
79
99
|
const scrollTop = ref<number>(0) // 滚动位置
|
|
100
|
+
const currentScrollTop = ref<number>(0) // 当前虚拟渲染滚动位置
|
|
80
101
|
const scrollIndex = ref<number>(0) // 当前显示的月份索引
|
|
81
102
|
const timeValue = ref<number[]>([]) // 当前选中的时分秒
|
|
82
103
|
|
|
83
104
|
const timeType = ref<MonthPanelTimeType>('') // 当前时间类型,是开始还是结束
|
|
84
105
|
const innerValue = ref<string | number | (number | null)[]>('') // 内部保存一个值,用于判断新老值,避免监听器触发
|
|
85
106
|
|
|
86
|
-
const designPxToRuntimePx = (designPx: number): number => unitConvert(`${designPx * 2}rpx`)
|
|
87
|
-
const MONTH_ROW_HEIGHT = designPxToRuntimePx(64)
|
|
88
|
-
const MONTH_ROW_GAP = designPxToRuntimePx(4)
|
|
89
|
-
const MONTH_TITLE_HEIGHT = designPxToRuntimePx(45)
|
|
90
|
-
const TIME_PICKER_HEIGHT = designPxToRuntimePx(125)
|
|
91
|
-
|
|
92
107
|
const handleChange = debounce((value) => {
|
|
93
108
|
emit('change', {
|
|
94
109
|
value
|
|
@@ -139,23 +154,44 @@ const weekLabel = computed(() => {
|
|
|
139
154
|
// 滚动区域的高度
|
|
140
155
|
const scrollHeight = computed(() => {
|
|
141
156
|
const panelHeight = designPxToRuntimePx(props.panelHeight)
|
|
142
|
-
const scrollHeight: number =
|
|
157
|
+
const scrollHeight: number = panelHeight - (props.showPanelTitle ? MONTH_TITLE_HEIGHT : 0) - (timeType.value ? TIME_PICKER_HEIGHT : 0)
|
|
143
158
|
return scrollHeight
|
|
144
159
|
})
|
|
145
160
|
|
|
146
161
|
// 月份日期和月份高度
|
|
147
162
|
const months = computed<MonthInfo[]>(() => {
|
|
163
|
+
let top = 0
|
|
148
164
|
return getMonths(props.minDate, props.maxDate).map((month, index) => {
|
|
149
165
|
const offset = (7 + new Date(month).getDay() - props.firstDayOfWeek) % 7
|
|
150
166
|
const totalDay = getMonthEndDay(new Date(month).getFullYear(), new Date(month).getMonth() + 1)
|
|
151
167
|
const rows = Math.ceil((offset + totalDay) / 7)
|
|
168
|
+
const height = rows * MONTH_ROW_HEIGHT + (rows - 1) * MONTH_ROW_GAP + (index === 0 ? 0 : MONTH_TITLE_HEIGHT)
|
|
169
|
+
const currentTop = top
|
|
170
|
+
top += height
|
|
152
171
|
return {
|
|
153
|
-
height
|
|
172
|
+
height,
|
|
173
|
+
top: currentTop,
|
|
154
174
|
date: month
|
|
155
175
|
}
|
|
156
176
|
})
|
|
157
177
|
})
|
|
158
178
|
|
|
179
|
+
const totalHeight = computed(() => {
|
|
180
|
+
if (months.value.length === 0) return 0
|
|
181
|
+
const last = months.value[months.value.length - 1]
|
|
182
|
+
return last.top + last.height
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
// 滚动区域的高度(用于计算可视区域)
|
|
186
|
+
const viewportHeight = computed(() => designPxToRuntimePx(props.panelHeight))
|
|
187
|
+
|
|
188
|
+
// 引入动态虚拟滚动 Hook
|
|
189
|
+
const { visibleData: visibleMonths, getTargetIndex } = useDynamicVirtualScroll<MonthInfo>({
|
|
190
|
+
data: months,
|
|
191
|
+
scrollTop: currentScrollTop,
|
|
192
|
+
viewportHeight
|
|
193
|
+
})
|
|
194
|
+
|
|
159
195
|
watch(
|
|
160
196
|
() => props.type,
|
|
161
197
|
(val) => {
|
|
@@ -229,8 +265,13 @@ async function scrollIntoView() {
|
|
|
229
265
|
}
|
|
230
266
|
scrollTop.value = 0
|
|
231
267
|
if (top > 0) {
|
|
268
|
+
const targetTop = top + (activeMonthIndex > 0 && compareMonth(months.value[0].date, activeDate) !== 0 ? MONTH_TITLE_HEIGHT : 0)
|
|
269
|
+
currentScrollTop.value = targetTop
|
|
270
|
+
// 在首次渲染前同步 currentScrollTop,避免闪烁
|
|
271
|
+
scrollTop.value = targetTop
|
|
232
272
|
await pause()
|
|
233
|
-
|
|
273
|
+
} else {
|
|
274
|
+
currentScrollTop.value = 0
|
|
234
275
|
}
|
|
235
276
|
}
|
|
236
277
|
/**
|
|
@@ -351,8 +392,9 @@ const monthScroll = (event: { detail: { scrollTop: number } }) => {
|
|
|
351
392
|
if (months.value.length <= 1) {
|
|
352
393
|
return
|
|
353
394
|
}
|
|
354
|
-
const
|
|
355
|
-
|
|
395
|
+
const st = Math.max(0, event.detail.scrollTop)
|
|
396
|
+
currentScrollTop.value = st
|
|
397
|
+
doSetSubtitle(st)
|
|
356
398
|
}
|
|
357
399
|
|
|
358
400
|
/**
|
|
@@ -360,14 +402,7 @@ const monthScroll = (event: { detail: { scrollTop: number } }) => {
|
|
|
360
402
|
* scrollTop 滚动条位置
|
|
361
403
|
*/
|
|
362
404
|
function doSetSubtitle(scrollTop: number) {
|
|
363
|
-
|
|
364
|
-
for (let index = 0; index < months.value.length; index++) {
|
|
365
|
-
height = height + months.value[index].height
|
|
366
|
-
if (scrollTop < height) {
|
|
367
|
-
scrollIndex.value = index
|
|
368
|
-
return
|
|
369
|
-
}
|
|
370
|
-
}
|
|
405
|
+
scrollIndex.value = getTargetIndex(scrollTop)
|
|
371
406
|
}
|
|
372
407
|
|
|
373
408
|
defineExpose<MonthPanelExpose>({
|
|
@@ -8,25 +8,67 @@ import type { CalendarFormatter, CalendarTimeFilter, CalendarType } from '../typ
|
|
|
8
8
|
export interface MonthInfo {
|
|
9
9
|
date: number
|
|
10
10
|
height: number
|
|
11
|
+
top: number
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export const monthPanelProps = {
|
|
15
|
+
/**
|
|
16
|
+
* 日期类型
|
|
17
|
+
*/
|
|
14
18
|
type: makeRequiredProp(String as PropType<CalendarType>),
|
|
19
|
+
/**
|
|
20
|
+
* 选中值
|
|
21
|
+
*/
|
|
15
22
|
value: makeRequiredProp([Number, Array, null] as PropType<number | (number | null)[] | null>),
|
|
23
|
+
/**
|
|
24
|
+
* 最小日期时间戳
|
|
25
|
+
*/
|
|
16
26
|
minDate: makeRequiredProp(Number),
|
|
27
|
+
/**
|
|
28
|
+
* 最大日期时间戳
|
|
29
|
+
*/
|
|
17
30
|
maxDate: makeRequiredProp(Number),
|
|
31
|
+
/**
|
|
32
|
+
* 一周的第一天
|
|
33
|
+
*/
|
|
18
34
|
firstDayOfWeek: makeRequiredProp(Number),
|
|
35
|
+
/**
|
|
36
|
+
* 格式化函数
|
|
37
|
+
*/
|
|
19
38
|
formatter: Function as PropType<CalendarFormatter>,
|
|
39
|
+
/**
|
|
40
|
+
* 最大范围限制
|
|
41
|
+
*/
|
|
20
42
|
maxRange: Number,
|
|
43
|
+
/**
|
|
44
|
+
* 超出范围提示
|
|
45
|
+
*/
|
|
21
46
|
rangePrompt: String,
|
|
47
|
+
/**
|
|
48
|
+
* 是否允许选择同一天
|
|
49
|
+
*/
|
|
22
50
|
allowSameDay: makeBooleanProp(false),
|
|
51
|
+
/**
|
|
52
|
+
* 是否展示面板标题
|
|
53
|
+
*/
|
|
23
54
|
showPanelTitle: makeBooleanProp(false),
|
|
55
|
+
/**
|
|
56
|
+
* 默认时间
|
|
57
|
+
*/
|
|
24
58
|
defaultTime: {
|
|
25
59
|
type: [Array] as PropType<Array<number[]>>
|
|
26
60
|
},
|
|
61
|
+
/**
|
|
62
|
+
* 面板高度
|
|
63
|
+
*/
|
|
27
64
|
panelHeight: makeRequiredProp(Number),
|
|
28
|
-
|
|
65
|
+
/**
|
|
66
|
+
* 用于过滤时间选择器的数据
|
|
67
|
+
*/
|
|
29
68
|
timeFilter: Function as PropType<CalendarTimeFilter>,
|
|
69
|
+
/**
|
|
70
|
+
* 是否隐藏秒
|
|
71
|
+
*/
|
|
30
72
|
hideSecond: makeBooleanProp(false),
|
|
31
73
|
/**
|
|
32
74
|
* 是否在手指松开时立即触发picker-view的 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import { computed } from 'vue'
|
|
2
2
|
import dayjs from '../../dayjs'
|
|
3
|
-
import { isArray, isFunction, padZero } from '../common/util'
|
|
3
|
+
import { isArray, isFunction, padZero, unitConvert } from '../common/util'
|
|
4
4
|
import { useTranslate } from '../composables/useTranslate'
|
|
5
5
|
import type { CalendarDayType, CalendarItem, CalendarTimeFilter, CalendarType } from './types'
|
|
6
6
|
const { translate } = useTranslate('calendar-view')
|
|
7
7
|
|
|
8
|
+
export const designPxToRuntimePx = (designPx: number): number => unitConvert(`${designPx}rpx`)
|
|
9
|
+
export const MONTH_ROW_HEIGHT = designPxToRuntimePx(128)
|
|
10
|
+
export const MONTH_ROW_GAP = designPxToRuntimePx(8)
|
|
11
|
+
export const MONTH_TITLE_HEIGHT = designPxToRuntimePx(90)
|
|
12
|
+
export const YEAR_TITLE_HEIGHT = designPxToRuntimePx(90)
|
|
13
|
+
export const TIME_PICKER_HEIGHT = designPxToRuntimePx(250)
|
|
14
|
+
export const PANEL_EXTRA_WITH_TITLE = designPxToRuntimePx(52)
|
|
15
|
+
export const PANEL_EXTRA_NO_TITLE = designPxToRuntimePx(32)
|
|
16
|
+
export const YEAR_HEIGHT_WITHOUT_TITLE = MONTH_ROW_HEIGHT * 3 + MONTH_ROW_GAP * 2
|
|
17
|
+
export const YEAR_HEIGHT_WITH_TITLE = YEAR_HEIGHT_WITHOUT_TITLE + YEAR_TITLE_HEIGHT
|
|
18
|
+
|
|
8
19
|
const weeks = computed(() => {
|
|
9
20
|
return [
|
|
10
21
|
translate('weeks.sun'),
|
|
@@ -3,26 +3,60 @@ import { makeBooleanProp, makeRequiredProp } from '../../common/props'
|
|
|
3
3
|
import type { CalendarFormatter, CalendarType } from '../types'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* 年份信息
|
|
7
7
|
*/
|
|
8
8
|
export interface YearInfo {
|
|
9
9
|
date: number
|
|
10
10
|
height: number
|
|
11
|
+
top: number
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export const yearPanelProps = {
|
|
15
|
+
/**
|
|
16
|
+
* 日期类型
|
|
17
|
+
*/
|
|
14
18
|
type: makeRequiredProp(String as PropType<CalendarType>),
|
|
15
|
-
|
|
19
|
+
/**
|
|
20
|
+
* 选中值
|
|
21
|
+
*/
|
|
22
|
+
value: makeRequiredProp([Number, Array, null] as PropType<number | (number | null)[] | null>),
|
|
23
|
+
/**
|
|
24
|
+
* 最小日期时间戳
|
|
25
|
+
*/
|
|
16
26
|
minDate: makeRequiredProp(Number),
|
|
27
|
+
/**
|
|
28
|
+
* 最大日期时间戳
|
|
29
|
+
*/
|
|
17
30
|
maxDate: makeRequiredProp(Number),
|
|
31
|
+
/**
|
|
32
|
+
* 格式化函数
|
|
33
|
+
*/
|
|
18
34
|
formatter: Function as PropType<CalendarFormatter>,
|
|
35
|
+
/**
|
|
36
|
+
* 最大范围限制
|
|
37
|
+
*/
|
|
19
38
|
maxRange: Number,
|
|
39
|
+
/**
|
|
40
|
+
* 超出范围提示
|
|
41
|
+
*/
|
|
20
42
|
rangePrompt: String,
|
|
43
|
+
/**
|
|
44
|
+
* 是否允许选择同一天
|
|
45
|
+
*/
|
|
21
46
|
allowSameDay: makeBooleanProp(false),
|
|
47
|
+
/**
|
|
48
|
+
* 是否展示标题
|
|
49
|
+
*/
|
|
22
50
|
showPanelTitle: makeBooleanProp(false),
|
|
51
|
+
/**
|
|
52
|
+
* 默认时间
|
|
53
|
+
*/
|
|
23
54
|
defaultTime: {
|
|
24
55
|
type: [Array] as PropType<Array<number[]>>
|
|
25
56
|
},
|
|
57
|
+
/**
|
|
58
|
+
* 面板高度
|
|
59
|
+
*/
|
|
26
60
|
panelHeight: makeRequiredProp(Number)
|
|
27
61
|
}
|
|
28
62
|
|