@mdui/shared 1.0.2 → 1.0.4
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/base/mdui-element.d.ts +16 -0
- package/base/mdui-element.js +18 -0
- package/helpers/observeResize.js +15 -10
- package/helpers/scroll.d.ts +6 -2
- package/helpers/scroll.js +15 -7
- package/mixins/anchor.d.ts +1 -1
- package/mixins/anchor.js +0 -1
- package/mixins/focusable.d.ts +1 -1
- package/mixins/focusable.js +7 -8
- package/mixins/scrollBehavior.d.ts +1 -1
- package/mixins/scrollBehavior.js +3 -4
- package/package.json +2 -1
- package/helpers/event.d.ts +0 -7
- package/helpers/event.js +0 -17
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
export type UnpackCustomEvent<T> = T extends CustomEvent<infer U> ? U : never;
|
|
3
|
+
export declare class MduiElement<E> extends LitElement {
|
|
4
|
+
/**
|
|
5
|
+
* 触发自定义事件。若返回 false,表示事件被取消
|
|
6
|
+
* @param type
|
|
7
|
+
* @param options 通常只用到 cancelable 和 detail;bubbles、composed 统一不用
|
|
8
|
+
*/
|
|
9
|
+
protected emit<K extends keyof E, D extends UnpackCustomEvent<E[K]>>(type: K, options?: CustomEventInit<D>): boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface MduiElement<E> {
|
|
12
|
+
addEventListener<K extends keyof M, M extends E & HTMLElementEventMap>(type: K, listener: (this: this, ev: M[K]) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
13
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
14
|
+
removeEventListener<K extends keyof M, M extends E & HTMLElementEventMap>(type: K, listener: (this: this, ev: M[K]) => unknown, options?: boolean | EventListenerOptions): void;
|
|
15
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
3
|
+
export class MduiElement extends LitElement {
|
|
4
|
+
/**
|
|
5
|
+
* 触发自定义事件。若返回 false,表示事件被取消
|
|
6
|
+
* @param type
|
|
7
|
+
* @param options 通常只用到 cancelable 和 detail;bubbles、composed 统一不用
|
|
8
|
+
*/
|
|
9
|
+
emit(type, options) {
|
|
10
|
+
const event = new CustomEvent(type, Object.assign({
|
|
11
|
+
bubbles: true,
|
|
12
|
+
cancelable: false,
|
|
13
|
+
composed: true,
|
|
14
|
+
detail: {},
|
|
15
|
+
}, options));
|
|
16
|
+
return this.dispatchEvent(event);
|
|
17
|
+
}
|
|
18
|
+
}
|
package/helpers/observeResize.js
CHANGED
|
@@ -16,17 +16,17 @@ export const observeResize = (target, callback) => {
|
|
|
16
16
|
const result = {
|
|
17
17
|
unobserve: () => {
|
|
18
18
|
$target.each((_, target) => {
|
|
19
|
-
const
|
|
20
|
-
const index = coArr.findIndex((co) => co.key === key);
|
|
19
|
+
const options = weakMap.get(target);
|
|
20
|
+
const index = options.coArr.findIndex((co) => co.key === key);
|
|
21
21
|
if (index !== -1) {
|
|
22
|
-
coArr.splice(index, 1);
|
|
22
|
+
options.coArr.splice(index, 1);
|
|
23
23
|
}
|
|
24
|
-
if (!coArr.length) {
|
|
24
|
+
if (!options.coArr.length) {
|
|
25
25
|
observer.unobserve(target);
|
|
26
26
|
weakMap.delete(target);
|
|
27
27
|
}
|
|
28
28
|
else {
|
|
29
|
-
weakMap.set(target,
|
|
29
|
+
weakMap.set(target, options);
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
32
|
},
|
|
@@ -37,8 +37,9 @@ export const observeResize = (target, callback) => {
|
|
|
37
37
|
observer = new ResizeObserver((entries) => {
|
|
38
38
|
entries.forEach((entry) => {
|
|
39
39
|
const target = entry.target;
|
|
40
|
-
const
|
|
41
|
-
|
|
40
|
+
const options = weakMap.get(target);
|
|
41
|
+
options.entry = entry;
|
|
42
|
+
options.coArr.forEach((co) => {
|
|
42
43
|
co.callback.call(result, entry, result);
|
|
43
44
|
});
|
|
44
45
|
});
|
|
@@ -46,10 +47,14 @@ export const observeResize = (target, callback) => {
|
|
|
46
47
|
}
|
|
47
48
|
// 添加监听
|
|
48
49
|
$target.each((_, target) => {
|
|
50
|
+
const options = weakMap.get(target) ?? { coArr: [] };
|
|
51
|
+
// 同一个元素已添加过监听后,再次添加新的监听时,不会立即执行回调函数,所以这里手动调用一次回调函数
|
|
52
|
+
if (options.coArr.length && options.entry) {
|
|
53
|
+
callback.call(result, options.entry, result);
|
|
54
|
+
}
|
|
55
|
+
options.coArr.push({ callback, key });
|
|
56
|
+
weakMap.set(target, options);
|
|
49
57
|
observer.observe(target);
|
|
50
|
-
const coArr = weakMap.get(target) ?? [];
|
|
51
|
-
coArr.push({ callback, key });
|
|
52
|
-
weakMap.set(target, coArr);
|
|
53
58
|
});
|
|
54
59
|
return result;
|
|
55
60
|
};
|
package/helpers/scroll.d.ts
CHANGED
|
@@ -10,15 +10,19 @@ import '@mdui/jq/methods/width.js';
|
|
|
10
10
|
* @param fresh 是否重新计算
|
|
11
11
|
*/
|
|
12
12
|
export declare const getScrollBarSize: (fresh?: boolean) => number;
|
|
13
|
+
/**
|
|
14
|
+
* 判断指定元素当前是否有滚动条
|
|
15
|
+
*/
|
|
16
|
+
export declare const hasScrollbar: (target: HTMLElement) => boolean;
|
|
13
17
|
/**
|
|
14
18
|
* 锁定指定元素,禁止滚动。对同一个元素多次调用此方法,只会锁定一次
|
|
15
19
|
* @param source 由该元素触发锁定
|
|
16
|
-
* @param target 锁定该元素的滚动状态,默认为
|
|
20
|
+
* @param target 锁定该元素的滚动状态,默认为 html
|
|
17
21
|
*/
|
|
18
22
|
export declare const lockScreen: (source: HTMLElement, target?: HTMLElement) => void;
|
|
19
23
|
/**
|
|
20
24
|
* 解除指定元素的滚动状态锁定。
|
|
21
25
|
* @param source 由该元素触发锁定
|
|
22
|
-
* @param target 锁定该元素的滚动状态,默认为
|
|
26
|
+
* @param target 锁定该元素的滚动状态,默认为 html
|
|
23
27
|
*/
|
|
24
28
|
export declare const unlockScreen: (source: HTMLElement, target?: HTMLElement) => void;
|
package/helpers/scroll.js
CHANGED
|
@@ -47,33 +47,41 @@ export const getScrollBarSize = (fresh) => {
|
|
|
47
47
|
}
|
|
48
48
|
return scrollBarSizeCached;
|
|
49
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* 判断指定元素当前是否有滚动条
|
|
52
|
+
*/
|
|
53
|
+
export const hasScrollbar = (target) => {
|
|
54
|
+
return target.scrollHeight > target.clientHeight;
|
|
55
|
+
};
|
|
50
56
|
const lockMap = new WeakMap();
|
|
51
57
|
const className = 'mdui-lock-screen';
|
|
52
58
|
/**
|
|
53
59
|
* 锁定指定元素,禁止滚动。对同一个元素多次调用此方法,只会锁定一次
|
|
54
60
|
* @param source 由该元素触发锁定
|
|
55
|
-
* @param target 锁定该元素的滚动状态,默认为
|
|
61
|
+
* @param target 锁定该元素的滚动状态,默认为 html
|
|
56
62
|
*/
|
|
57
63
|
export const lockScreen = (source, target) => {
|
|
58
64
|
const document = getDocument();
|
|
59
|
-
target ??= document.
|
|
65
|
+
target ??= document.documentElement;
|
|
60
66
|
if (!lockMap.has(target)) {
|
|
61
67
|
lockMap.set(target, new Set());
|
|
62
68
|
}
|
|
63
69
|
const lock = lockMap.get(target);
|
|
64
70
|
lock.add(source);
|
|
65
|
-
$(target)
|
|
66
|
-
|
|
67
|
-
.css('width', `calc(100% - ${getScrollBarSize()}px)`);
|
|
71
|
+
const $target = $(target);
|
|
72
|
+
if (hasScrollbar(target)) {
|
|
73
|
+
$target.css('width', `calc(100% - ${getScrollBarSize()}px)`);
|
|
74
|
+
}
|
|
75
|
+
$target.addClass(className);
|
|
68
76
|
};
|
|
69
77
|
/**
|
|
70
78
|
* 解除指定元素的滚动状态锁定。
|
|
71
79
|
* @param source 由该元素触发锁定
|
|
72
|
-
* @param target 锁定该元素的滚动状态,默认为
|
|
80
|
+
* @param target 锁定该元素的滚动状态,默认为 html
|
|
73
81
|
*/
|
|
74
82
|
export const unlockScreen = (source, target) => {
|
|
75
83
|
const document = getDocument();
|
|
76
|
-
target ??= document.
|
|
84
|
+
target ??= document.documentElement;
|
|
77
85
|
const lock = lockMap.get(target);
|
|
78
86
|
if (!lock) {
|
|
79
87
|
return;
|
package/mixins/anchor.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ type RenderAnchorOptions = {
|
|
|
11
11
|
tabIndex?: number;
|
|
12
12
|
refDirective?: DirectiveResult<typeof RefDirective>;
|
|
13
13
|
};
|
|
14
|
-
export declare class AnchorMixinInterface
|
|
14
|
+
export declare class AnchorMixinInterface {
|
|
15
15
|
href?: string;
|
|
16
16
|
download?: string;
|
|
17
17
|
target?: '_blank' | '_parent' | '_self' | '_top';
|
package/mixins/anchor.js
CHANGED
package/mixins/focusable.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import '@mdui/jq/methods/each.js';
|
|
|
4
4
|
import '@mdui/jq/methods/removeAttr.js';
|
|
5
5
|
import type { Constructor } from '@open-wc/dedupe-mixin';
|
|
6
6
|
import type { LitElement } from 'lit';
|
|
7
|
-
export declare class FocusableMixinInterface
|
|
7
|
+
export declare class FocusableMixinInterface {
|
|
8
8
|
autofocus: boolean;
|
|
9
9
|
tabIndex: number;
|
|
10
10
|
protected get focusDisabled(): boolean;
|
package/mixins/focusable.js
CHANGED
|
@@ -24,7 +24,7 @@ export const FocusableMixin = (superclass) => {
|
|
|
24
24
|
constructor() {
|
|
25
25
|
super(...arguments);
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* 是否在页面加载完成后自动获取焦点
|
|
28
28
|
*/
|
|
29
29
|
this.autofocus = false;
|
|
30
30
|
/**
|
|
@@ -42,7 +42,7 @@ export const FocusableMixin = (superclass) => {
|
|
|
42
42
|
this._tabIndex = 0;
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
|
-
*
|
|
45
|
+
* 元素在使用 Tab 键切换焦点时的顺序
|
|
46
46
|
*/
|
|
47
47
|
get tabIndex() {
|
|
48
48
|
const $this = $(this);
|
|
@@ -131,11 +131,11 @@ export const FocusableMixin = (superclass) => {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
/**
|
|
134
|
-
*
|
|
134
|
+
* 将焦点设置到当前元素。
|
|
135
135
|
*
|
|
136
|
-
*
|
|
136
|
+
* 可以传入一个对象作为参数,该对象的属性包括:
|
|
137
137
|
*
|
|
138
|
-
* * `preventScroll
|
|
138
|
+
* * `preventScroll`:默认情况下,元素获取焦点后,页面会滚动以将该元素滚动到视图中。如果不希望页面滚动,可以将此属性设置为 `true`。
|
|
139
139
|
*/
|
|
140
140
|
focus(options) {
|
|
141
141
|
if (this.focusDisabled || !this.focusElement) {
|
|
@@ -149,7 +149,7 @@ export const FocusableMixin = (superclass) => {
|
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
/**
|
|
152
|
-
*
|
|
152
|
+
* 移除当前元素的焦点
|
|
153
153
|
*/
|
|
154
154
|
blur() {
|
|
155
155
|
if (this.focusElement !== this) {
|
|
@@ -246,8 +246,7 @@ export const FocusableMixin = (superclass) => {
|
|
|
246
246
|
})
|
|
247
247
|
], FocusableMixinClass.prototype, "focusVisible", void 0);
|
|
248
248
|
__decorate([
|
|
249
|
-
property({ type: Number })
|
|
249
|
+
property({ type: Number, attribute: 'tabindex' })
|
|
250
250
|
], FocusableMixinClass.prototype, "tabIndex", null);
|
|
251
|
-
// @ts-ignore
|
|
252
251
|
return FocusableMixinClass;
|
|
253
252
|
};
|
|
@@ -5,7 +5,7 @@ import type { Constructor } from '@open-wc/dedupe-mixin';
|
|
|
5
5
|
import type { LitElement } from 'lit';
|
|
6
6
|
type ScrollBehavior = 'hide' | 'shrink' | 'elevate';
|
|
7
7
|
export type ScrollPaddingPosition = 'top' | 'bottom';
|
|
8
|
-
export declare class ScrollBehaviorMixinInterface
|
|
8
|
+
export declare class ScrollBehaviorMixinInterface {
|
|
9
9
|
scrollTarget?: string | HTMLElement | JQ<HTMLElement>;
|
|
10
10
|
scrollBehavior?: ScrollBehavior;
|
|
11
11
|
scrollThreshold?: number;
|
package/mixins/scrollBehavior.js
CHANGED
|
@@ -48,6 +48,7 @@ export const ScrollBehaviorMixin = (superclass) => {
|
|
|
48
48
|
if ((oldValue && !newValue) || (!oldValue && newValue)) {
|
|
49
49
|
this.updateContainerPadding();
|
|
50
50
|
}
|
|
51
|
+
// @ts-ignore
|
|
51
52
|
if (!this.scrollBehavior) {
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
@@ -71,6 +72,7 @@ export const ScrollBehaviorMixin = (superclass) => {
|
|
|
71
72
|
if (!listening) {
|
|
72
73
|
return;
|
|
73
74
|
}
|
|
75
|
+
// @ts-ignore
|
|
74
76
|
if (this.scrollBehavior) {
|
|
75
77
|
this.updateScrollTop(listening);
|
|
76
78
|
listening.addEventListener('scroll', this.onListeningScroll);
|
|
@@ -98,6 +100,7 @@ export const ScrollBehaviorMixin = (superclass) => {
|
|
|
98
100
|
* @param behavior 为数组时,只要其中一个行为在 scrollBehavior 中,即返回 `true`
|
|
99
101
|
*/
|
|
100
102
|
hasScrollBehavior(behavior) {
|
|
103
|
+
// @ts-ignore
|
|
101
104
|
const behaviors = (this.scrollBehavior?.split(' ') ??
|
|
102
105
|
[]);
|
|
103
106
|
if (Array.isArray(behavior)) {
|
|
@@ -193,9 +196,6 @@ export const ScrollBehaviorMixin = (superclass) => {
|
|
|
193
196
|
__decorate([
|
|
194
197
|
property({ attribute: 'scroll-target' })
|
|
195
198
|
], ScrollBehaviorMixinClass.prototype, "scrollTarget", void 0);
|
|
196
|
-
__decorate([
|
|
197
|
-
property({ reflect: true, attribute: 'scroll-behavior' })
|
|
198
|
-
], ScrollBehaviorMixinClass.prototype, "scrollBehavior", void 0);
|
|
199
199
|
__decorate([
|
|
200
200
|
property({ type: Number, reflect: true, attribute: 'scroll-threshold' })
|
|
201
201
|
], ScrollBehaviorMixinClass.prototype, "scrollThreshold", void 0);
|
|
@@ -205,6 +205,5 @@ export const ScrollBehaviorMixin = (superclass) => {
|
|
|
205
205
|
__decorate([
|
|
206
206
|
watch('scrollBehavior')
|
|
207
207
|
], ScrollBehaviorMixinClass.prototype, "onScrollBehaviorChange", null);
|
|
208
|
-
// @ts-ignore
|
|
209
208
|
return ScrollBehaviorMixinClass;
|
|
210
209
|
};
|
package/package.json
CHANGED
package/helpers/event.d.ts
DELETED
package/helpers/event.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 触发自定义事件
|
|
3
|
-
* @param element
|
|
4
|
-
* @param type
|
|
5
|
-
* @param options 通常只用到 cancelable 和 detail;bubbles、composed 统一不用
|
|
6
|
-
*/
|
|
7
|
-
export const emit = (element, type, options) => {
|
|
8
|
-
const event = new CustomEvent(type, {
|
|
9
|
-
bubbles: true,
|
|
10
|
-
cancelable: false,
|
|
11
|
-
composed: true,
|
|
12
|
-
detail: {},
|
|
13
|
-
...options,
|
|
14
|
-
});
|
|
15
|
-
element.dispatchEvent(event);
|
|
16
|
-
return event;
|
|
17
|
-
};
|