cbvirtua 1.0.7 → 1.0.8

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/asy.js ADDED
@@ -0,0 +1,32 @@
1
+ async function asyncTaskWithCb(cb) {
2
+ let err, user, savedTask, notification;
3
+
4
+ [ err, user ] = await to(UserModel.findById(1));
5
+ if(!user) return cb('No user found');
6
+
7
+ [ err, savedTask ] = await to(TaskModel({userId: user.id, name: 'Demo Task'}));
8
+ if(err) return cb('Error occurred while saving task');
9
+
10
+ if(user.notificationsEnabled) {
11
+ [ err ] = await to(NotificationService.sendNotification(user.id, 'Task Created'));
12
+ if(err) return cb('Error while sending notification');
13
+ }
14
+
15
+ if(savedTask.assignedUser.id !== user.id) {
16
+ [ err, notification ] = await to(NotificationService.sendNotification(savedTask.assignedUser.id, 'Task was created for you'));
17
+ if(err) return cb('Error while sending notification');
18
+ }
19
+
20
+ cb(null, savedTask);
21
+ }
22
+
23
+ function to(promise, errorExt) {
24
+ return promise
25
+ .then(function (data) { return [null, data]; }) // 执行成功,返回数组第一项为 null。第二个是结果。
26
+ .catch(function (err) {
27
+ if (errorExt) {
28
+ Object.assign(err, errorExt);
29
+ }
30
+ return [err, undefined]; // 执行失败,返回数组第一项为错误信息,第二项为 undefined
31
+ });
32
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cbvirtua",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,69 @@
1
+ @sides: {
2
+ top: bottom;
3
+ bottom: top;
4
+ left: right;
5
+ right: left;
6
+ }
7
+ @N: .van-popper;
8
+ @{N} {
9
+ --van-arrow-size: 10px;
10
+ --van-popper-content-bg: #fff;
11
+ --van-popper-border: 1px solid #ebedf0;
12
+ border-radius: 4px;
13
+ color: #000;
14
+ background-color: var(--van-popper-content-bg);
15
+ padding: 10px 12px;
16
+ border: var(--van-popper-border);
17
+ position: absolute;
18
+ white-space: nowrap;
19
+ transition: opacity .3s;
20
+ font-size: 13px;
21
+ z-index: 1000;
22
+ width: max-content;
23
+
24
+ &__arrow {
25
+ position: absolute;
26
+ width: 10px;
27
+ height: 10px;
28
+ background: var(--van-popper-content-bg);
29
+ transform: rotate(45deg);
30
+ }
31
+
32
+ each(@sides, {
33
+ &[data-side^='@{value}'] {
34
+ @{N}__arrow {
35
+ @{key}: -5px;
36
+ }
37
+ @{N}__arrow {
38
+ border-@{key}: var(--van-popper-border);
39
+ }
40
+ @{N}__arrow when (@value =top) {
41
+ border-right: var(--van-popper-border);
42
+ }
43
+ @{N}__arrow when (@value =bottom) {
44
+ border-left: var(--van-popper-border);
45
+ }
46
+ @{N}__arrow when (@value =left) {
47
+ border-top: var(--van-popper-border);
48
+ }
49
+ @{N}__arrow when (@value =right) {
50
+ border-bottom: var(--van-popper-border);
51
+ }
52
+ }
53
+ });
54
+
55
+ &.is-dark {
56
+ --van-popper-content-bg: #000;
57
+ color: #fff;
58
+ border: none;
59
+
60
+ @{N}__arrow {
61
+ border-color: transparent;
62
+ }
63
+ }
64
+ }
65
+
66
+ .van-popper-fade-enter-from,
67
+ .van-popper-fade-leave-to {
68
+ opacity: 0;
69
+ }
@@ -0,0 +1,125 @@
1
+ @import '../../style/themes/index';
2
+ @import '../../style/mixins/index';
3
+ @import './mixin';
4
+
5
+ @row-prefix-cls: ~'@{ant-prefix}-row';
6
+ @col-prefix-cls: ~'@{ant-prefix}-col';
7
+
8
+ // Grid system
9
+ .@{row-prefix-cls} {
10
+ display: flex;
11
+ flex-flow: row wrap;
12
+
13
+ &::before,
14
+ &::after {
15
+ display: flex;
16
+ }
17
+
18
+ // No wrap of flex
19
+ &-no-wrap {
20
+ flex-wrap: nowrap;
21
+ }
22
+ }
23
+
24
+ // x轴原点
25
+ .@{row-prefix-cls}-start {
26
+ justify-content: flex-start;
27
+ }
28
+
29
+ // x轴居中
30
+ .@{row-prefix-cls}-center {
31
+ justify-content: center;
32
+ }
33
+
34
+ // x轴反方向
35
+ .@{row-prefix-cls}-end {
36
+ justify-content: flex-end;
37
+ }
38
+
39
+ // x轴平分
40
+ .@{row-prefix-cls}-space-between {
41
+ justify-content: space-between;
42
+ }
43
+
44
+ // x轴有间隔地平分
45
+ .@{row-prefix-cls}-space-around {
46
+ justify-content: space-around;
47
+ }
48
+
49
+ // 顶部对齐
50
+ .@{row-prefix-cls}-top {
51
+ align-items: flex-start;
52
+ }
53
+
54
+ // 居中对齐
55
+ .@{row-prefix-cls}-middle {
56
+ align-items: center;
57
+ }
58
+
59
+ // 底部对齐
60
+ .@{row-prefix-cls}-bottom {
61
+ align-items: flex-end;
62
+ }
63
+
64
+ .@{col-prefix-cls} {
65
+ position: relative;
66
+ max-width: 100%;
67
+ // Prevent columns from collapsing when empty
68
+ min-height: 1px;
69
+ }
70
+
71
+ .make-grid();
72
+
73
+ // Extra small grid
74
+ //
75
+ // Columns, offsets, pushes, and pulls for extra small devices like
76
+ // smartphones.
77
+
78
+ .make-grid(-xs);
79
+
80
+ // Small grid
81
+ //
82
+ // Columns, offsets, pushes, and pulls for the small device range, from phones
83
+ // to tablets.
84
+
85
+ @media (min-width: @screen-sm-min) {
86
+ .make-grid(-sm);
87
+ }
88
+
89
+ // Medium grid
90
+ //
91
+ // Columns, offsets, pushes, and pulls for the desktop device range.
92
+
93
+ @media (min-width: @screen-md-min) {
94
+ .make-grid(-md);
95
+ }
96
+
97
+ // Large grid
98
+ //
99
+ // Columns, offsets, pushes, and pulls for the large desktop device range.
100
+
101
+ @media (min-width: @screen-lg-min) {
102
+ .make-grid(-lg);
103
+ }
104
+
105
+ // Extra Large grid
106
+ //
107
+ // Columns, offsets, pushes, and pulls for the full hd device range.
108
+
109
+ @media (min-width: @screen-xl-min) {
110
+ .make-grid(-xl);
111
+ }
112
+
113
+ // Extra Extra Large grid
114
+ //
115
+ // Columns, offsets, pushes, and pulls for the full hd device range.
116
+
117
+ @media (min-width: @screen-xxl-min) {
118
+ .make-grid(-xxl);
119
+ }
120
+
121
+ @media (min-width: @screen-xxxl-min) {
122
+ .make-grid(-xxxl);
123
+ }
124
+
125
+ @import './rtl';
@@ -0,0 +1,2 @@
1
+ import '../../style/index.less';
2
+ import './index.less';
@@ -0,0 +1,53 @@
1
+ @import '../../style/mixins/index';
2
+
3
+ // mixins for grid system
4
+ // ------------------------
5
+
6
+ .loop-grid-columns(@index, @class) when (@index > 0) {
7
+ .@{ant-prefix}-col@{class}-@{index} {
8
+ display: block;
9
+ flex: 0 0 percentage((@index / @grid-columns));
10
+ max-width: percentage((@index / @grid-columns));
11
+ }
12
+ .@{ant-prefix}-col@{class}-push-@{index} {
13
+ left: percentage((@index / @grid-columns));
14
+ }
15
+ .@{ant-prefix}-col@{class}-pull-@{index} {
16
+ right: percentage((@index / @grid-columns));
17
+ }
18
+ .@{ant-prefix}-col@{class}-offset-@{index} {
19
+ margin-left: percentage((@index / @grid-columns));
20
+ }
21
+ .@{ant-prefix}-col@{class}-order-@{index} {
22
+ order: @index;
23
+ }
24
+ .loop-grid-columns((@index - 1), @class);
25
+ }
26
+
27
+ .loop-grid-columns(@index, @class) when (@index = 0) {
28
+ .@{ant-prefix}-col@{class}-@{index} {
29
+ display: none;
30
+ }
31
+ .@{ant-prefix}-col-push-@{index} {
32
+ left: auto;
33
+ }
34
+ .@{ant-prefix}-col-pull-@{index} {
35
+ right: auto;
36
+ }
37
+ .@{ant-prefix}-col@{class}-push-@{index} {
38
+ left: auto;
39
+ }
40
+ .@{ant-prefix}-col@{class}-pull-@{index} {
41
+ right: auto;
42
+ }
43
+ .@{ant-prefix}-col@{class}-offset-@{index} {
44
+ margin-left: 0;
45
+ }
46
+ .@{ant-prefix}-col@{class}-order-@{index} {
47
+ order: 0;
48
+ }
49
+ }
50
+
51
+ .make-grid(@class: ~'') {
52
+ .loop-grid-columns(@grid-columns, @class);
53
+ }
package/style/rtl.less ADDED
@@ -0,0 +1,68 @@
1
+ @import '../../style/themes/index';
2
+ @import '../../style/mixins/index';
3
+
4
+ .@{ant-prefix}-row {
5
+ &-rtl {
6
+ direction: rtl;
7
+ }
8
+ }
9
+
10
+ // mixin
11
+ .loop-grid-columns(@index, @class) when (@index > 0) {
12
+ .@{ant-prefix}-col@{class}-push-@{index} {
13
+ // reset property in RTL direction
14
+ &.@{ant-prefix}-col-rtl {
15
+ right: percentage((@index / @grid-columns));
16
+ left: auto;
17
+ }
18
+ }
19
+
20
+ .@{ant-prefix}-col@{class}-pull-@{index} {
21
+ // reset property in RTL direction
22
+ &.@{ant-prefix}-col-rtl {
23
+ right: auto;
24
+ left: percentage((@index / @grid-columns));
25
+ }
26
+ }
27
+
28
+ .@{ant-prefix}-col@{class}-offset-@{index} {
29
+ // reset property in RTL direction
30
+ &.@{ant-prefix}-col-rtl {
31
+ margin-right: percentage((@index / @grid-columns));
32
+ margin-left: 0;
33
+ }
34
+ }
35
+ }
36
+
37
+ .loop-grid-columns(@index, @class) when (@index = 0) {
38
+ .@{ant-prefix}-col-push-@{index} {
39
+ // reset property in RTL direction
40
+ &.@{ant-prefix}-col-rtl {
41
+ right: auto;
42
+ }
43
+ }
44
+
45
+ .@{ant-prefix}-col-pull-@{index} {
46
+ &.@{ant-prefix}-col-rtl {
47
+ left: auto;
48
+ }
49
+ }
50
+
51
+ .@{ant-prefix}-col@{class}-push-@{index} {
52
+ &.@{ant-prefix}-col-rtl {
53
+ right: auto;
54
+ }
55
+ }
56
+
57
+ .@{ant-prefix}-col@{class}-pull-@{index} {
58
+ &.@{ant-prefix}-col-rtl {
59
+ left: auto;
60
+ }
61
+ }
62
+
63
+ .@{ant-prefix}-col@{class}-offset-@{index} {
64
+ &.@{ant-prefix}-col-rtl {
65
+ margin-right: 0;
66
+ }
67
+ }
68
+ }
@@ -1,74 +0,0 @@
1
- <template>
2
- <li class="wzc_option" :style="styleVar" @click="currentSelect">
3
- <div class="wzc_option_dropdown_item">{{ label }}</div>
4
- </li>
5
- </template>
6
-
7
- <script>
8
- export default {
9
- name: "wzc_select",
10
- components: {},
11
- props: {
12
- width: {
13
- type: Number,
14
- default: -1,
15
- },
16
- height: {
17
- type: Number,
18
- default: 34,
19
- },
20
- label: {
21
- type: String,
22
- },
23
- optionid: {
24
- type: String,
25
- },
26
- },
27
- data() {
28
- return {};
29
- },
30
- created() {},
31
- mounted() {},
32
- watch: {},
33
- computed: {
34
- styleVar() {
35
- return {
36
- "--option-height": this.height + "px",
37
- "--option-width": this.width == -1? "100%" : this.width + "px",
38
- };
39
- },
40
- },
41
- methods: {
42
- currentSelect() {
43
- this.$parent.label = this.label;
44
- this.$parent.optionid = this.optionid;
45
- this.$parent.isListShow = !this.$parent.isListShow;
46
- // this.$emit('slot-content', {label: this.label, optionid: this.optionid} );
47
- }
48
- },
49
- };
50
- </script>
51
- <style scoped>
52
- .wzc_option {
53
- list-style: none;
54
- height: var(--option-height);
55
- width: var(--option-width);
56
-
57
- }
58
- .wzc_option:hover {
59
- color: #409eff;
60
- font-weight: 700;
61
- background-color: #f5f7fa;
62
- }
63
- .wzc_option_dropdown_item {
64
- height: 100%;
65
- width: calc(100% - 30px);
66
- line-height: var(--option-height);
67
- cursor: pointer;
68
- margin: 0 auto;
69
- overflow: hidden;
70
- text-overflow: ellipsis;
71
- white-space: nowrap;
72
- }
73
-
74
- </style>
@@ -1,209 +0,0 @@
1
- <template>
2
- <div class="wzc_select" :style="styleVar">
3
- <div class="divSelect" :class="{ 'drop_down': isListShow }" ref="divSelect">
4
- <div class="divSelectinput" @click="dropDownSelect">
5
- <!-- 选中后的内容 -->
6
- <div class="selectinfos" :title="label" :class="{ 'no_select': label == '请选择' }"> {{ label }} </div>
7
- <!-- 三角形图标 -->
8
- <i class="imgthree" :class="{ 'is-reverse': isListShow }">
9
- <svg t="1707138975702" class="icon" viewBox="0 0 1024 1024" version="1.1"
10
- xmlns="http://www.w3.org/2000/svg" p-id="1444" width="16" height="16">
11
- <path d="M512 187.24L699.501 512 887 836.76H137L324.5 512z" p-id="1445"></path>
12
- </svg>
13
- </i>
14
- </div>
15
- </div>
16
- <!-- 下拉框列表 -->
17
- <transition name="drop-down">
18
- <div class="Selectlist" v-show="isListShow" ref="dropDown">
19
- <div class="select_triangle"></div>
20
- <ul class="wzc_option_list">
21
- <slot name="wzc_option"></slot>
22
- </ul>
23
- </div>
24
- </transition>
25
- </div>
26
- </template>
27
-
28
- <script>
29
- export default {
30
- name: 'wzc_select',
31
- components: {},
32
- props: {
33
- placeholder: {
34
- type: String,
35
- default: '请选择'
36
- },
37
- width: {
38
- type: Number,
39
- default: 180
40
- },
41
- height: {
42
- type: Number,
43
- default: 40
44
- },
45
- },
46
- data() {
47
- return {
48
- label: '',
49
- isListShow: false,
50
- optionid: ''
51
- };
52
- },
53
- created() {
54
- this.label = this.placeholder;
55
- },
56
- mounted() {
57
- let _this = this;
58
- document.addEventListener("click", function (e) {
59
- if (_this.$refs.divSelect) {
60
- if (!!_this.$refs.divSelect.contains(e.target) || !!_this.$refs.dropDown.contains(e.target))
61
- return;
62
- else
63
- _this.isListShow = false;
64
- }
65
- })
66
- },
67
- computed: {
68
- styleVar() {
69
- return {
70
- '--select-height': this.height + 'px',
71
- '--select-width': this.width + 'px'
72
- }
73
- }
74
- },
75
- methods: {
76
- dropDownSelect() {
77
- this.isListShow = !this.isListShow;
78
- },
79
- },
80
- };
81
- </script>
82
- <style scoped>
83
- .wzc_select {
84
- border: 1px solid #E6E6E6;
85
- border-radius: 5px;
86
- height: var(--select-height);
87
- width: var(--select-width);
88
- line-height: var(--select-height);
89
- }
90
-
91
- .divSelect {
92
- width: 100%;
93
- height: 100%;
94
- border-radius: 5px;
95
- }
96
-
97
- .drop_down {
98
- box-shadow: 0px 0px 6px #709DF7;
99
- }
100
-
101
- .divSelectinput {
102
- width: calc(100% - 20px);
103
- height: 100%;
104
- margin: 0 5px 0 15px;
105
- display: flex;
106
- }
107
-
108
- .selectinfos {
109
- width: 87.5%;
110
- cursor: pointer;
111
- overflow: hidden;
112
- text-overflow: ellipsis;
113
- white-space: nowrap;
114
- }
115
-
116
- .no_select {
117
- color: #D3DCE6;
118
- }
119
-
120
- .imgthree {
121
- width: 12.5%;
122
- line-height: var(--select-height);
123
- text-align: center;
124
- transform: rotate(180deg);
125
- transition: all 0.3s;
126
- }
127
-
128
- .imgthree svg {
129
- width: 1em;
130
- height: 1em;
131
- }
132
-
133
- .imgthree:before {
134
- cursor: pointer;
135
- color: #D3DCE6;
136
- }
137
-
138
- .imgthree.is-reverse {
139
- transform: rotate(0deg);
140
- }
141
-
142
- .Selectlist {
143
- margin-top: 10px;
144
- z-index: 800;
145
- position: relative;
146
- background-color: #fff;
147
- }
148
-
149
- .wzc_option_list {
150
- border-radius: 5px;
151
- border: 1px solid #E4E7ED;
152
- width: 100%;
153
- padding: 3px 0px;
154
- box-shadow: 0px 0px 6px #709DF7;
155
- background-color: #fff;
156
- margin: 0;
157
- }
158
-
159
- .select_triangle {
160
- width: 14px;
161
- height: 7px;
162
- position: relative;
163
- left: 15px;
164
- }
165
-
166
- .select_triangle::before {
167
- position: absolute;
168
- content: "";
169
- left: 0px;
170
- width: 0;
171
- height: 0;
172
- border-top: 0px solid transparent;
173
- border-left: 9px solid transparent;
174
- border-right: 9px solid transparent;
175
- border-bottom: 8px solid #EBEEF5;
176
- }
177
-
178
- .select_triangle::after {
179
- position: absolute;
180
- left: 2px;
181
- top: 2px;
182
- content: "";
183
- width: 0;
184
- height: 0;
185
- border-top: 0px solid transparent;
186
- border-left: 7px solid transparent;
187
- border-right: 7px solid transparent;
188
- border-bottom: 8px solid #fff;
189
- }
190
-
191
- .drop-down-enter {
192
- opacity: 0;
193
- transform: translate(0px, -80px) scaleY(0.2);
194
- }
195
-
196
- .drop-down-leave-to {
197
- opacity: 0;
198
- transform: translate(0px, -80px) scaleY(0.2);
199
- }
200
-
201
- .drop-down-enter-active {
202
- transition: all 0.5s ease-in;
203
- }
204
-
205
- .drop-down-leave-active {
206
- transition: all 0.5s ease;
207
- }
208
- </style>
209
-
package/vue/ListItem.js DELETED
@@ -1,44 +0,0 @@
1
- import { jsx as _jsx } from "vue/jsx-runtime";
2
- /** @jsxImportSource vue */
3
- import { ref, defineComponent, watch } from "vue";
4
- import { isRTLDocument } from "../core/environment";
5
- /**
6
- * @internal
7
- */
8
- export const ListItem = /*#__PURE__*/ defineComponent({
9
- props: {
10
- _children: { type: Object, required: true },
11
- _resizer: { type: Object, required: true },
12
- _index: { type: Number, required: true },
13
- _offset: { type: Number, required: true },
14
- _hide: { type: Boolean },
15
- _isHorizontal: { type: Boolean },
16
- _element: { type: String, required: true },
17
- },
18
- setup(props) {
19
- const elementRef = ref();
20
- // The index may be changed if elements are inserted to or removed from the start of props.children
21
- watch(() => elementRef.value && props._index, (_, __, onCleanup) => {
22
- const cleanupObserver = props._resizer(elementRef.value, props._index);
23
- onCleanup(cleanupObserver);
24
- }, {
25
- flush: "post",
26
- });
27
- return () => {
28
- const { _children: children, _offset: offset, _hide: hide, _element: Element, _isHorizontal: isHorizontal, } = props;
29
- const style = {
30
- margin: 0,
31
- padding: 0,
32
- position: "absolute",
33
- [isHorizontal ? "height" : "width"]: "100%",
34
- [isHorizontal ? "top" : "left"]: "0px",
35
- [isHorizontal ? (isRTLDocument() ? "right" : "left") : "top"]: offset + "px",
36
- visibility: hide ? "hidden" : "visible",
37
- };
38
- if (isHorizontal) {
39
- style.display = "flex";
40
- }
41
- return (_jsx(Element, { ref: elementRef, style: style, children: children }));
42
- };
43
- },
44
- });
package/vue/ListItem.tsx DELETED
@@ -1,64 +0,0 @@
1
- /** @jsxImportSource vue */
2
- import { ref, defineComponent, watch, StyleValue, PropType, VNode } from "vue";
3
- import { ItemResizeObserver } from "../core/resizer";
4
- import { isRTLDocument } from "../core/environment";
5
-
6
- /**
7
- * @internal
8
- */
9
- export const ListItem = /*#__PURE__*/ defineComponent({
10
- props: {
11
- _children: { type: Object as PropType<VNode>, required: true },
12
- _resizer: { type: Object as PropType<ItemResizeObserver>, required: true },
13
- _index: { type: Number, required: true },
14
- _offset: { type: Number, required: true },
15
- _hide: { type: Boolean },
16
- _isHorizontal: { type: Boolean },
17
- _element: { type: String, required: true },
18
- },
19
- setup(props) {
20
- const elementRef = ref<HTMLDivElement>();
21
-
22
- // The index may be changed if elements are inserted to or removed from the start of props.children
23
- watch(
24
- () => elementRef.value && props._index,
25
- (_, __, onCleanup) => {
26
- const cleanupObserver = props._resizer(elementRef.value!, props._index);
27
- onCleanup(cleanupObserver);
28
- },
29
- {
30
- flush: "post",
31
- }
32
- );
33
-
34
- return () => {
35
- const {
36
- _children: children,
37
- _offset: offset,
38
- _hide: hide,
39
- _element: Element,
40
- _isHorizontal: isHorizontal,
41
- } = props as Omit<typeof props, "_element"> & { _element: "div" };
42
-
43
- const style: StyleValue = {
44
- margin: 0,
45
- padding: 0,
46
- position: "absolute",
47
- [isHorizontal ? "height" : "width"]: "100%",
48
- [isHorizontal ? "top" : "left"]: "0px",
49
- [isHorizontal ? (isRTLDocument() ? "right" : "left") : "top"]:
50
- offset + "px",
51
- visibility: hide ? "hidden" : "visible",
52
- };
53
- if (isHorizontal) {
54
- style.display = "flex";
55
- }
56
-
57
- return (
58
- <Element ref={elementRef} style={style}>
59
- {children}
60
- </Element>
61
- );
62
- };
63
- },
64
- });
package/vue/VList.js DELETED
@@ -1,133 +0,0 @@
1
- import { jsx as _jsx } from "vue/jsx-runtime";
2
- /** @jsxImportSource vue */
3
- import { ref, onMounted, defineComponent, onUnmounted, watch, } from "vue";
4
- import { SCROLL_IDLE, UPDATE_SCROLL_STATE, UPDATE_SCROLL_EVENT, UPDATE_SCROLL_END_EVENT, UPDATE_SIZE_STATE, overscanEndIndex, overscanStartIndex, createVirtualStore, ACTION_ITEMS_LENGTH_CHANGE, getScrollSize, getMinContainerSize, } from "../core/store";
5
- import { createResizer } from "../core/resizer";
6
- import { createScroller } from "../core/scroller";
7
- import { ListItem } from "./ListItem";
8
- import { exists } from "../core/utils";
9
- const props = {
10
- /**
11
- * The data items rendered by this component.
12
- */
13
- data: { type: Array, required: true },
14
- /**
15
- * Number of items to render above/below the visible bounds of the list. You can increase to avoid showing blank items in fast scrolling.
16
- * @defaultValue 4
17
- */
18
- overscan: { type: Number, default: 4 },
19
- /**
20
- * Item size hint for unmeasured items. It will help to reduce scroll jump when items are measured if used properly.
21
- *
22
- * - If not set, initial item sizes will be automatically estimated from measured sizes. This is recommended for most cases.
23
- * - If set, you can opt out estimation and use the value as initial item size.
24
- */
25
- itemSize: Number,
26
- /**
27
- * While true is set, scroll position will be maintained from the end not usual start when items are added to/removed from start. It's recommended to set false if you add to/remove from mid/end of the list because it can cause unexpected behavior. This prop is useful for reverse infinite scrolling.
28
- */
29
- shift: Boolean,
30
- /**
31
- * If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list.
32
- */
33
- horizontal: Boolean,
34
- };
35
- export const VList = /*#__PURE__*/ defineComponent({
36
- props: props,
37
- emits: ["scroll", "scrollEnd", "rangeChange"],
38
- setup(props, { emit, expose, slots }) {
39
- var _a;
40
- const isHorizontal = props.horizontal;
41
- const rootRef = ref();
42
- const store = createVirtualStore(props.data.length, (_a = props.itemSize) !== null && _a !== void 0 ? _a : 40, undefined, undefined, !props.itemSize);
43
- const resizer = createResizer(store, isHorizontal);
44
- const scroller = createScroller(store, isHorizontal);
45
- const rerender = ref(store._getStateVersion());
46
- const unsubscribeStore = store._subscribe(UPDATE_SCROLL_STATE + UPDATE_SIZE_STATE, () => {
47
- rerender.value = store._getStateVersion();
48
- });
49
- const unsubscribeOnScroll = store._subscribe(UPDATE_SCROLL_EVENT, () => {
50
- emit("scroll", store._getScrollOffset());
51
- });
52
- const unsubscribeOnScrollEnd = store._subscribe(UPDATE_SCROLL_END_EVENT, () => {
53
- emit("scrollEnd");
54
- });
55
- onMounted(() => {
56
- const root = rootRef.value;
57
- if (!root)
58
- return;
59
- resizer._observeRoot(root);
60
- scroller._observe(root);
61
- });
62
- onUnmounted(() => {
63
- unsubscribeStore();
64
- unsubscribeOnScroll();
65
- unsubscribeOnScrollEnd();
66
- resizer._dispose();
67
- scroller._dispose();
68
- });
69
- watch(() => props.data.length, (count) => {
70
- store._update(ACTION_ITEMS_LENGTH_CHANGE, [count, props.shift]);
71
- });
72
- watch([rerender, store._getJumpCount], ([, count], [, prevCount]) => {
73
- if (count === prevCount)
74
- return;
75
- const jump = store._flushJump();
76
- if (!jump)
77
- return;
78
- scroller._fixScrollJump(jump);
79
- }, { flush: "post" });
80
- watch([rerender, store._getRange], ([, [start, end]], [, [prevStart, prevEnd]]) => {
81
- if (prevStart === start && prevEnd === end)
82
- return;
83
- emit("rangeChange", start, end);
84
- }, { flush: "post" });
85
- expose({
86
- get scrollOffset() {
87
- return store._getScrollOffset();
88
- },
89
- get scrollSize() {
90
- return getScrollSize(store);
91
- },
92
- get viewportSize() {
93
- return store._getViewportSize();
94
- },
95
- scrollToIndex: scroller._scrollToIndex,
96
- scrollTo: scroller._scrollTo,
97
- scrollBy: scroller._scrollBy,
98
- });
99
- return () => {
100
- rerender.value;
101
- const count = props.data.length;
102
- const [startIndex, endIndex] = store._getRange();
103
- const scrollDirection = store._getScrollDirection();
104
- const totalSize = store._getTotalSize();
105
- // https://github.com/inokawa/virtua/issues/252#issuecomment-1822861368
106
- const minSize = getMinContainerSize(store);
107
- const items = [];
108
- for (let i = overscanStartIndex(startIndex, props.overscan, scrollDirection), j = overscanEndIndex(endIndex, props.overscan, scrollDirection, count); i <= j; i++) {
109
- const e = slots.default(props.data[i])[0];
110
- const key = e.key;
111
- items.push(_jsx(ListItem, { _resizer: resizer._observeItem, _index: i, _offset: store._getItemOffset(i), _hide: store._isUnmeasuredItem(i), _element: "div", _children: e, _isHorizontal: isHorizontal }, exists(key) ? key : "_" + i));
112
- }
113
- return (_jsx("div", { ref: rootRef, style: {
114
- display: isHorizontal ? "inline-block" : "block",
115
- [isHorizontal ? "overflowX" : "overflowY"]: "auto",
116
- overflowAnchor: "none",
117
- contain: "strict",
118
- width: "100%",
119
- height: "100%",
120
- }, children: _jsx("div", { style: {
121
- // contain: "content",
122
- overflowAnchor: "none", // opt out browser's scroll anchoring because it will conflict to scroll anchoring of virtualizer
123
- flex: "none", // flex style on parent can break layout
124
- position: "relative",
125
- visibility: "hidden",
126
- width: isHorizontal ? totalSize + "px" : "100%",
127
- height: isHorizontal ? "100%" : totalSize + "px",
128
- [isHorizontal ? "minWidth" : "minHeight"]: minSize + "px",
129
- pointerEvents: scrollDirection !== SCROLL_IDLE ? "none" : "auto",
130
- }, children: items }) }));
131
- };
132
- },
133
- });
package/vue/VList.tsx DELETED
@@ -1,291 +0,0 @@
1
- /** @jsxImportSource vue */
2
- import {
3
- ref,
4
- onMounted,
5
- defineComponent,
6
- onUnmounted,
7
- VNode,
8
- watch,
9
- ComponentOptionsMixin,
10
- SlotsType,
11
- ComponentOptionsWithObjectProps,
12
- ComponentObjectPropsOptions,
13
- } from "vue";
14
- import {
15
- SCROLL_IDLE,
16
- UPDATE_SCROLL_STATE,
17
- UPDATE_SCROLL_EVENT,
18
- UPDATE_SCROLL_END_EVENT,
19
- UPDATE_SIZE_STATE,
20
- overscanEndIndex,
21
- overscanStartIndex,
22
- createVirtualStore,
23
- ACTION_ITEMS_LENGTH_CHANGE,
24
- getScrollSize,
25
- getMinContainerSize,
26
- } from "../core/store";
27
- import { createResizer } from "../core/resizer";
28
- import { createScroller } from "../core/scroller";
29
- import { ScrollToIndexOpts } from "../core/types";
30
- import { ListItem } from "./ListItem";
31
- import { exists } from "../core/utils";
32
-
33
- interface VListHandle {
34
- /**
35
- * Get current scrollTop or scrollLeft.
36
- */
37
- readonly scrollOffset: number;
38
- /**
39
- * Get current scrollHeight or scrollWidth.
40
- */
41
- readonly scrollSize: number;
42
- /**
43
- * Get current offsetHeight or offsetWidth.
44
- */
45
- readonly viewportSize: number;
46
- /**
47
- * Scroll to the item specified by index.
48
- * @param index index of item
49
- * @param opts options
50
- */
51
- scrollToIndex(index: number, opts?: ScrollToIndexOpts): void;
52
- /**
53
- * Scroll to the given offset.
54
- * @param offset offset from start
55
- */
56
- scrollTo(offset: number): void;
57
- /**
58
- * Scroll by the given offset.
59
- * @param offset offset from current position
60
- */
61
- scrollBy(offset: number): void;
62
- }
63
-
64
- const props = {
65
- /**
66
- * The data items rendered by this component.
67
- */
68
- data: { type: Array, required: true },
69
- /**
70
- * Number of items to render above/below the visible bounds of the list. You can increase to avoid showing blank items in fast scrolling.
71
- * @defaultValue 4
72
- */
73
- overscan: { type: Number, default: 4 },
74
- /**
75
- * Item size hint for unmeasured items. It will help to reduce scroll jump when items are measured if used properly.
76
- *
77
- * - If not set, initial item sizes will be automatically estimated from measured sizes. This is recommended for most cases.
78
- * - If set, you can opt out estimation and use the value as initial item size.
79
- */
80
- itemSize: Number,
81
- /**
82
- * While true is set, scroll position will be maintained from the end not usual start when items are added to/removed from start. It's recommended to set false if you add to/remove from mid/end of the list because it can cause unexpected behavior. This prop is useful for reverse infinite scrolling.
83
- */
84
- shift: Boolean,
85
- /**
86
- * If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list.
87
- */
88
- horizontal: Boolean,
89
- } satisfies ComponentObjectPropsOptions;
90
-
91
- export const VList = /*#__PURE__*/ defineComponent({
92
- props: props,
93
- emits: ["scroll", "scrollEnd", "rangeChange"],
94
- setup(props, { emit, expose, slots }) {
95
- const isHorizontal = props.horizontal;
96
- const rootRef = ref<HTMLDivElement>();
97
- const store = createVirtualStore(
98
- props.data.length,
99
- props.itemSize ?? 40,
100
- undefined,
101
- undefined,
102
- !props.itemSize
103
- );
104
- const resizer = createResizer(store, isHorizontal);
105
- const scroller = createScroller(store, isHorizontal);
106
-
107
- const rerender = ref(store._getStateVersion());
108
- const unsubscribeStore = store._subscribe(
109
- UPDATE_SCROLL_STATE + UPDATE_SIZE_STATE,
110
- () => {
111
- rerender.value = store._getStateVersion();
112
- }
113
- );
114
-
115
- const unsubscribeOnScroll = store._subscribe(UPDATE_SCROLL_EVENT, () => {
116
- emit("scroll", store._getScrollOffset());
117
- });
118
- const unsubscribeOnScrollEnd = store._subscribe(
119
- UPDATE_SCROLL_END_EVENT,
120
- () => {
121
- emit("scrollEnd");
122
- }
123
- );
124
-
125
- onMounted(() => {
126
- const root = rootRef.value;
127
- if (!root) return;
128
- resizer._observeRoot(root);
129
- scroller._observe(root);
130
- });
131
- onUnmounted(() => {
132
- unsubscribeStore();
133
- unsubscribeOnScroll();
134
- unsubscribeOnScrollEnd();
135
- resizer._dispose();
136
- scroller._dispose();
137
- });
138
-
139
- watch(
140
- () => props.data.length,
141
- (count) => {
142
- store._update(ACTION_ITEMS_LENGTH_CHANGE, [count, props.shift]);
143
- }
144
- );
145
-
146
- watch(
147
- [rerender, store._getJumpCount],
148
- ([, count], [, prevCount]) => {
149
- if (count === prevCount) return;
150
-
151
- const jump = store._flushJump();
152
- if (!jump) return;
153
-
154
- scroller._fixScrollJump(jump);
155
- },
156
- { flush: "post" }
157
- );
158
-
159
- watch(
160
- [rerender, store._getRange],
161
- ([, [start, end]], [, [prevStart, prevEnd]]) => {
162
- if (prevStart === start && prevEnd === end) return;
163
-
164
- emit("rangeChange", start, end);
165
- },
166
- { flush: "post" }
167
- );
168
-
169
- expose({
170
- get scrollOffset() {
171
- return store._getScrollOffset();
172
- },
173
- get scrollSize() {
174
- return getScrollSize(store);
175
- },
176
- get viewportSize() {
177
- return store._getViewportSize();
178
- },
179
- scrollToIndex: scroller._scrollToIndex,
180
- scrollTo: scroller._scrollTo,
181
- scrollBy: scroller._scrollBy,
182
- } satisfies VListHandle);
183
-
184
- return () => {
185
- rerender.value;
186
-
187
- const count = props.data.length;
188
-
189
- const [startIndex, endIndex] = store._getRange();
190
- const scrollDirection = store._getScrollDirection();
191
- const totalSize = store._getTotalSize();
192
-
193
- // https://github.com/inokawa/virtua/issues/252#issuecomment-1822861368
194
- const minSize = getMinContainerSize(store);
195
-
196
- const items: VNode[] = [];
197
- for (
198
- let i = overscanStartIndex(startIndex, props.overscan, scrollDirection),
199
- j = overscanEndIndex(
200
- endIndex,
201
- props.overscan,
202
- scrollDirection,
203
- count
204
- );
205
- i <= j;
206
- i++
207
- ) {
208
- const e = slots.default(props.data![i]!)[0]! as VNode;
209
- const key = e.key;
210
- items.push(
211
- <ListItem
212
- key={exists(key) ? key : "_" + i}
213
- _resizer={resizer._observeItem}
214
- _index={i}
215
- _offset={store._getItemOffset(i)}
216
- _hide={store._isUnmeasuredItem(i)}
217
- _element="div"
218
- _children={e}
219
- _isHorizontal={isHorizontal}
220
- />
221
- );
222
- }
223
-
224
- return (
225
- <div
226
- ref={rootRef}
227
- style={{
228
- display: isHorizontal ? "inline-block" : "block",
229
- [isHorizontal ? "overflowX" : "overflowY"]: "auto",
230
- overflowAnchor: "none",
231
- contain: "strict",
232
- width: "100%",
233
- height: "100%",
234
- }}
235
- >
236
- <div
237
- style={{
238
- // contain: "content",
239
- overflowAnchor: "none", // opt out browser's scroll anchoring because it will conflict to scroll anchoring of virtualizer
240
- flex: "none", // flex style on parent can break layout
241
- position: "relative",
242
- visibility: "hidden",
243
- width: isHorizontal ? totalSize + "px" : "100%",
244
- height: isHorizontal ? "100%" : totalSize + "px",
245
- [isHorizontal ? "minWidth" : "minHeight"]: minSize + "px",
246
- pointerEvents: scrollDirection !== SCROLL_IDLE ? "none" : "auto",
247
- }}
248
- >
249
- {items}
250
- </div>
251
- </div>
252
- );
253
- };
254
- },
255
- } as ComponentOptionsWithObjectProps<
256
- typeof props,
257
- VListHandle,
258
- {},
259
- {},
260
- {},
261
- ComponentOptionsMixin,
262
- ComponentOptionsMixin,
263
- {
264
- /**
265
- * Callback invoked whenever scroll offset changes.
266
- * @param offset Current scrollTop or scrollLeft.
267
- */
268
- scroll: (offset: number) => void;
269
- /**
270
- * Callback invoked when scrolling stops.
271
- */
272
- scrollEnd: () => void;
273
- /**
274
- * Callback invoked when visible items range changes.
275
- */
276
- rangeChange: (
277
- /**
278
- * The start index of viewable items.
279
- */
280
- startIndex: number,
281
- /**
282
- * The end index of viewable items.
283
- */
284
- endIndex: number
285
- ) => void;
286
- },
287
- string,
288
- {},
289
- string,
290
- SlotsType<{ default: any }>
291
- >);
package/vue/ec.css DELETED
@@ -1,48 +0,0 @@
1
- .ellipsis-tooltip {
2
- z-index: 10;
3
- display: inline-block;
4
- background: #333333;
5
- color: #ffffff;
6
- padding: 5px 10px;
7
- font-size: 13px;
8
- border-radius: 4px;
9
- }
10
-
11
- .ellipsis-tooltip-arrow,
12
- .ellipsis-tooltip-arrow::before {
13
- position: absolute;
14
- width: 6px;
15
- height: 6px;
16
- background: inherit;
17
- }
18
-
19
- .ellipsis-tooltip-arrow {
20
- visibility: hidden;
21
- }
22
-
23
- .ellipsis-tooltip-arrow::before {
24
- visibility: visible;
25
- content: '';
26
- transform: rotate(45deg);
27
- }
28
-
29
- .ellipsis-tooltip[data-popper-placement^='top'] > .ellipsis-tooltip-arrow {
30
- bottom: -3px;
31
- }
32
-
33
- .ellipsis-tooltip[data-popper-placement^='bottom'] > .ellipsis-tooltip-arrow {
34
- top: -3px;
35
- }
36
-
37
- .ellipsis-tooltip[data-popper-placement^='left'] > .ellipsis-tooltip-arrow {
38
- right: -3px;
39
- }
40
-
41
- .ellipsis-tooltip[data-popper-placement^='right'] > .ellipsis-tooltip-arrow {
42
- left: -3px;
43
- }
44
-
45
- 作者:JasonSubmara
46
- 链接:https://juejin.cn/post/7278301902659190821
47
- 来源:稀土掘金
48
- 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
package/vue/ec.js DELETED
@@ -1,78 +0,0 @@
1
- import { createPopper } from '@popperjs/core';
2
-
3
- const getPadding = el => {
4
- const style = window.getComputedStyle(el, null);
5
- const paddingLeft = Number.parseInt(style.paddingLeft, 10) || 0;
6
- const paddingRight = Number.parseInt(style.paddingRight, 10) || 0;
7
- const paddingTop = Number.parseInt(style.paddingTop, 10) || 0;
8
- const paddingBottom = Number.parseInt(style.paddingBottom, 10) || 0;
9
- return {
10
- left: paddingLeft,
11
- right: paddingRight,
12
- top: paddingTop,
13
- bottom: paddingBottom,
14
- };
15
- };
16
-
17
- const renderContent = (target, parent) => {
18
- const tooltipContent = document.createElement('div');
19
- const arrowContent = document.createElement('div');
20
- arrowContent.className = ['ellipsis-tooltip-arrow'].join(' ');
21
- arrowContent.setAttribute('data-popper-arrow', 'true');
22
- tooltipContent.innerText = target.dataset.title;
23
- tooltipContent.setAttribute('role', 'tooltip');
24
- tooltipContent.appendChild(arrowContent);
25
- tooltipContent.className = ['ellipsis-tooltip'].join(' ');
26
- parent.setAttribute('aria-describedby', 'tooltip');
27
- parent.appendChild(tooltipContent);
28
- return {
29
- tooltipContent,
30
- };
31
- };
32
-
33
- export function useEllipsisPopper(options = {}) {
34
- const handleCellMouseEnter = event => {
35
- const target = event.target;
36
- const parent = target.parentNode;
37
- let range = document.createRange();
38
- range.setStart(target, 0);
39
- range.setEnd(target, target.childNodes.length);
40
- const rangeWidth = range.getBoundingClientRect().width;
41
- range.detach();
42
- const { left, right } = getPadding(target);
43
- const horizontalPadding = left + right;
44
- if (Math.floor(rangeWidth + horizontalPadding) > target.clientWidth) {
45
- const { tooltipContent } = renderContent(target, parent);
46
- const popperInstance = createPopper(parent, tooltipContent, {
47
- placement: options.placement ?? 'top',
48
- modifiers: [
49
- {
50
- name: 'offset',
51
- options: {
52
- offset: [0, 8],
53
- },
54
- },
55
- ],
56
- });
57
-
58
- const removePopper = () => {
59
- popperInstance.destroy();
60
- parent.removeChild(tooltipContent);
61
- parent.removeAttribute('aria-describedby');
62
- target.removeListener('mouseleave', removePopper);
63
- };
64
-
65
- target.addEventListener('mouseleave', removePopper);
66
- }
67
- };
68
-
69
- return {
70
- handleCellMouseEnter,
71
- };
72
- }
73
-
74
-
75
- 作者:JasonSubmara
76
- 链接:https://juejin.cn/post/7278301902659190821
77
- 来源:稀土掘金
78
- 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
package/vue/index.js DELETED
@@ -1,4 +0,0 @@
1
- /**
2
- * @module vue
3
- */
4
- export { VList } from "./VList";
package/vue/l.less DELETED
@@ -1,69 +0,0 @@
1
- #devices() {
2
- .lenovo-1() {
3
- @a: 1000px;
4
- @b: 200px;
5
- }
6
- }
7
-
8
- .rule(@content) {
9
- @returns: #devices.lenovo-1();
10
- @prop-1: @returns[@a];
11
- @prop-2: @returns[@b];
12
-
13
- @media (min-width: @prop-1) and (min-height: @prop-2) {
14
- @content()
15
- }
16
- }
17
-
18
- .a {
19
-
20
- .rule({
21
- color:#000
22
- })
23
- }
24
-
25
- @devices: {
26
- @lenovo: {
27
- width: 1000px;
28
- height: 800px;
29
- }
30
-
31
- @huawei: {
32
- width: 1200px;
33
- height: 800px;
34
- }
35
- }
36
-
37
- .adapt(@deviceName, @content) {
38
- @width: @devices[@@deviceName][width];
39
- @height: @devices[@@deviceName][width];
40
-
41
- @media (min-width: width) and (min-height: @height) {
42
- @content()
43
- }
44
- }
45
-
46
- .v {
47
- .adapt(lenovo, {
48
- .c {
49
- color:#000;
50
- }
51
- })
52
- }
53
-
54
- // const { defineConfig } = require('@vue/cli-service')
55
- // const path = require('node:path')
56
-
57
- // module.exports = defineConfig({
58
- //   // 全局配置使用less变量
59
- //   pluginOptions: {
60
- //     'style-resources-loader': {
61
- //       preProcessor: 'less',
62
- //       patterns: [
63
- //           // 这个是加上自己的路径,注意此处不能使用别名路径
64
- //           path.resolve(__dirname, "./src/assets/css/lessGlobalVars.less")
65
- //       ]
66
- //     }
67
- //   }
68
- // })
69
-