@mdui/shared 1.0.6 → 1.0.7
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/helpers/decorator.d.ts +3 -0
- package/helpers/decorator.js +4 -1
- package/mixin.less +6 -6
- package/mixins/scrollBehavior.d.ts +1 -1
- package/mixins/scrollBehavior.js +41 -20
- package/package.json +1 -1
package/helpers/decorator.d.ts
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
* 但在 vue 的服务端渲染(ssr)时,不存在 DOM 对象,所以会把 attribute 属性设置成 attr="true" 或 attr="false"
|
|
9
9
|
* 所以在 attribute 属性 attr="false" 时,需要把属性值转换为布尔值 false
|
|
10
10
|
*
|
|
11
|
+
* 在 CSS 中选择布尔属性时,必须排除掉属性值为 false 的情况。i 表示不区分大小写。仅 public 属性需要这样处理,private 和 protected 属性不需要
|
|
12
|
+
* 例如::host([hide]:not([hide="false" i])) { ... }
|
|
13
|
+
*
|
|
11
14
|
* 这段代码不能封装成函数,否则生成 custom-elements.json 会识别不了
|
|
12
15
|
* 这段注释仅在这里写一次,其他地方不再重复
|
|
13
16
|
*
|
package/helpers/decorator.js
CHANGED
|
@@ -8,11 +8,14 @@
|
|
|
8
8
|
* 但在 vue 的服务端渲染(ssr)时,不存在 DOM 对象,所以会把 attribute 属性设置成 attr="true" 或 attr="false"
|
|
9
9
|
* 所以在 attribute 属性 attr="false" 时,需要把属性值转换为布尔值 false
|
|
10
10
|
*
|
|
11
|
+
* 在 CSS 中选择布尔属性时,必须排除掉属性值为 false 的情况。i 表示不区分大小写。仅 public 属性需要这样处理,private 和 protected 属性不需要
|
|
12
|
+
* 例如::host([hide]:not([hide="false" i])) { ... }
|
|
13
|
+
*
|
|
11
14
|
* 这段代码不能封装成函数,否则生成 custom-elements.json 会识别不了
|
|
12
15
|
* 这段注释仅在这里写一次,其他地方不再重复
|
|
13
16
|
*
|
|
14
17
|
* @see https://v3-migration.vuejs.org/zh/breaking-changes/attribute-coercion.html
|
|
15
18
|
*/
|
|
16
19
|
export const booleanConverter = (value) => {
|
|
17
|
-
return value !== null && value !== 'false';
|
|
20
|
+
return value !== null && value.toLowerCase() !== 'false';
|
|
18
21
|
};
|
package/mixin.less
CHANGED
|
@@ -348,21 +348,21 @@
|
|
|
348
348
|
// @duration 为 short1、short2 等
|
|
349
349
|
// @timing-function 为 standard、standard-accelerate、emphasized 等
|
|
350
350
|
// @delay 可以为整数,表示毫秒;也可以为 short1、short2 等
|
|
351
|
-
.transition(@
|
|
351
|
+
.transition(@prop, @duration, @timing-function, @delay: 0) {
|
|
352
352
|
@durationVariable: "--mdui-motion-duration-@{duration}";
|
|
353
353
|
@timingFunctionVariable: "--mdui-motion-easing-@{timing-function}";
|
|
354
354
|
|
|
355
|
-
& when (@delay =0) {
|
|
356
|
-
transition: ~"@{
|
|
355
|
+
& when (@delay = 0) {
|
|
356
|
+
transition: ~"@{prop} var(@{durationVariable}) var(@{timingFunctionVariable})";
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
-
& when not (@delay =0) {
|
|
359
|
+
& when not (@delay = 0) {
|
|
360
360
|
& when (isnumber(@delay)) {
|
|
361
|
-
transition: ~"@{
|
|
361
|
+
transition: ~"@{prop} var(@{durationVariable}) var(@{timingFunctionVariable}) @{delay}ms";
|
|
362
362
|
}
|
|
363
363
|
|
|
364
364
|
& when not (isnumber(@delay)) {
|
|
365
|
-
transition: ~"@{
|
|
365
|
+
transition: ~"@{prop} var(@{durationVariable}) var(@{timingFunctionVariable}) var(--mdui-motion-duration-@{delay})";
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
368
|
}
|
|
@@ -10,7 +10,7 @@ export declare class ScrollBehaviorMixinInterface {
|
|
|
10
10
|
scrollBehavior?: ScrollBehavior;
|
|
11
11
|
scrollThreshold?: number;
|
|
12
12
|
protected scrollBehaviorDefinedController: DefinedController;
|
|
13
|
-
protected
|
|
13
|
+
protected setContainerPadding(action: 'add' | 'update' | 'remove', scrollTarget?: string | HTMLElement | JQ<HTMLElement>): void;
|
|
14
14
|
protected hasScrollBehavior(behavior: ScrollBehavior | ScrollBehavior[]): boolean;
|
|
15
15
|
}
|
|
16
16
|
/**
|
package/mixins/scrollBehavior.js
CHANGED
|
@@ -5,6 +5,11 @@ import '@mdui/jq/methods/css.js';
|
|
|
5
5
|
import { isNodeName } from '@mdui/jq/shared/helper.js';
|
|
6
6
|
import { DefinedController } from '../controllers/defined.js';
|
|
7
7
|
import { watch } from '../decorators/watch.js';
|
|
8
|
+
/**
|
|
9
|
+
* 如果同时有多个组件在同一个元素上设置了 padding-top 或 padding-bottom,则移除其中一个组件时,不移除 padding-top 或 padding-bottom
|
|
10
|
+
* 键为添加 padding 的目标元素,值为在分别在 top 和 bottom 上添加的组件数组
|
|
11
|
+
*/
|
|
12
|
+
const weakMap = new WeakMap();
|
|
8
13
|
/**
|
|
9
14
|
* 滚动行为
|
|
10
15
|
*
|
|
@@ -43,10 +48,12 @@ export const ScrollBehaviorMixin = (superclass) => {
|
|
|
43
48
|
throw new Error('Must implement scrollPaddingPosition getter');
|
|
44
49
|
}
|
|
45
50
|
async onScrollTargetChange(oldValue, newValue) {
|
|
51
|
+
const hasUpdated = this.hasUpdated;
|
|
46
52
|
await this.scrollBehaviorDefinedController.whenDefined();
|
|
47
|
-
//
|
|
48
|
-
if (
|
|
49
|
-
this.
|
|
53
|
+
// 旧元素移除 padding,新元素添加 padding
|
|
54
|
+
if (hasUpdated) {
|
|
55
|
+
this.setContainerPadding('remove', oldValue);
|
|
56
|
+
this.setContainerPadding('add', newValue);
|
|
50
57
|
}
|
|
51
58
|
if (!this.scrollBehavior) {
|
|
52
59
|
return;
|
|
@@ -61,12 +68,8 @@ export const ScrollBehaviorMixin = (superclass) => {
|
|
|
61
68
|
newListening.addEventListener('scroll', this.onListeningScroll);
|
|
62
69
|
}
|
|
63
70
|
}
|
|
64
|
-
async onScrollBehaviorChange(
|
|
71
|
+
async onScrollBehaviorChange() {
|
|
65
72
|
await this.scrollBehaviorDefinedController.whenDefined();
|
|
66
|
-
// 仅在有值切换到无值、或无值切换到有值时,更新
|
|
67
|
-
if ((oldValue && !newValue) || (!oldValue && newValue)) {
|
|
68
|
-
this.updateContainerPadding();
|
|
69
|
-
}
|
|
70
73
|
const listening = this.getListening(this.scrollTarget);
|
|
71
74
|
if (!listening) {
|
|
72
75
|
return;
|
|
@@ -83,13 +86,13 @@ export const ScrollBehaviorMixin = (superclass) => {
|
|
|
83
86
|
super.connectedCallback();
|
|
84
87
|
this.scrollBehaviorDefinedController.whenDefined().then(() => {
|
|
85
88
|
this.isParentLayout = isNodeName(this.parentElement, 'mdui-layout');
|
|
86
|
-
this.
|
|
89
|
+
this.setContainerPadding('add', this.scrollTarget);
|
|
87
90
|
});
|
|
88
91
|
}
|
|
89
92
|
disconnectedCallback() {
|
|
90
93
|
super.disconnectedCallback();
|
|
91
94
|
this.scrollBehaviorDefinedController.whenDefined().then(() => {
|
|
92
|
-
this.
|
|
95
|
+
this.setContainerPadding('remove', this.scrollTarget);
|
|
93
96
|
});
|
|
94
97
|
}
|
|
95
98
|
/**
|
|
@@ -128,24 +131,42 @@ export const ScrollBehaviorMixin = (superclass) => {
|
|
|
128
131
|
}
|
|
129
132
|
/**
|
|
130
133
|
* 更新滚动容器的 padding,避免内容被 navigation-bar 覆盖
|
|
131
|
-
*
|
|
132
|
-
* @param
|
|
134
|
+
* @param action 新增、更新、移除 padding
|
|
135
|
+
* @param scrollTarget 在该元素上添加、更新或移除 padding
|
|
133
136
|
*/
|
|
134
|
-
|
|
135
|
-
const container = this.getContainer(
|
|
137
|
+
setContainerPadding(action, scrollTarget) {
|
|
138
|
+
const container = this.getContainer(scrollTarget);
|
|
136
139
|
if (!container || this.isParentLayout) {
|
|
137
140
|
return;
|
|
138
141
|
}
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
142
|
+
const position = this.scrollPaddingPosition;
|
|
143
|
+
const propName = position === 'top' ? 'paddingTop' : 'paddingBottom';
|
|
144
|
+
if (action === 'add' || action === 'update') {
|
|
145
|
+
const propValue = ['fixed', 'absolute'].includes($(this).css('position'))
|
|
143
146
|
? this.offsetHeight
|
|
144
147
|
: null;
|
|
145
148
|
$(container).css({ [propName]: propValue });
|
|
149
|
+
// 添加 padding 时,weakMap 中添加指定元素
|
|
150
|
+
if (action === 'add' && propValue !== null) {
|
|
151
|
+
const options = weakMap.get(container) ?? { top: [], bottom: [] };
|
|
152
|
+
options[position].push(this);
|
|
153
|
+
weakMap.set(container, options);
|
|
154
|
+
}
|
|
146
155
|
}
|
|
147
|
-
|
|
148
|
-
|
|
156
|
+
// 如果 weakMap 中指定元素的计数为 0,则移除 padding
|
|
157
|
+
if (action === 'remove') {
|
|
158
|
+
const options = weakMap.get(container);
|
|
159
|
+
if (!options) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const index = options[position].indexOf(this);
|
|
163
|
+
if (index > -1) {
|
|
164
|
+
options[position].splice(index, 1);
|
|
165
|
+
weakMap.set(container, options);
|
|
166
|
+
}
|
|
167
|
+
if (!options[position].length) {
|
|
168
|
+
$(container).css({ [propName]: null });
|
|
169
|
+
}
|
|
149
170
|
}
|
|
150
171
|
}
|
|
151
172
|
onListeningScroll() {
|