hyperscript-rxjs 1.3.15 → 1.3.17
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/dist/hyperscript-rxjs.d.ts +1438 -0
- package/dist/hyperscript-rxjs.js +4157 -0
- package/package.json +21 -12
- package/src/array/advance.d.ts +0 -9
- package/src/array/advance.js +0 -13
- package/src/array/advance.test.js +0 -12
- package/src/array/arrayInsert.d.ts +0 -8
- package/src/array/arrayInsert.js +0 -13
- package/src/array/arrayInsert.test.js +0 -13
- package/src/array/arrayRemove.d.ts +0 -7
- package/src/array/arrayRemove.js +0 -15
- package/src/array/arrayRemove.test.js +0 -13
- package/src/array/findLastIndex.d.ts +0 -14
- package/src/array/findLastIndex.js +0 -20
- package/src/array/findLastIndex.test.js +0 -41
- package/src/array/index.d.ts +0 -9
- package/src/array/index.js +0 -9
- package/src/array/isRange.d.ts +0 -7
- package/src/array/isRange.js +0 -15
- package/src/array/isRange.test.js +0 -6
- package/src/array/rangeArray.d.ts +0 -7
- package/src/array/rangeArray.js +0 -10
- package/src/array/rangeArray.test.js +0 -11
- package/src/array/unwrapArgs.d.ts +0 -10
- package/src/array/unwrapArgs.js +0 -15
- package/src/array/unwrapArgs.test.js +0 -33
- package/src/array/zipArray.d.ts +0 -11
- package/src/array/zipArray.js +0 -24
- package/src/array/zipArray.test.js +0 -16
- package/src/comparers/Comparer.d.ts +0 -101
- package/src/comparers/Comparer.js +0 -149
- package/src/comparers/comparers.d.ts +0 -21
- package/src/comparers/comparers.js +0 -10
- package/src/comparers/differenceSet.d.ts +0 -20
- package/src/comparers/differenceSet.js +0 -35
- package/src/comparers/differenceSet.test.js +0 -11
- package/src/comparers/distinctArray.d.ts +0 -13
- package/src/comparers/distinctArray.js +0 -30
- package/src/comparers/distinctArray.test.js +0 -10
- package/src/comparers/findIndexInSet.d.ts +0 -20
- package/src/comparers/findIndexInSet.js +0 -27
- package/src/comparers/findIndexInSet.test.js +0 -8
- package/src/comparers/groupArrayBy.d.ts +0 -19
- package/src/comparers/groupArrayBy.js +0 -29
- package/src/comparers/groupArrayBy.test.js +0 -38
- package/src/comparers/groupSortedEntries.d.ts +0 -17
- package/src/comparers/groupSortedEntries.js +0 -38
- package/src/comparers/groupSortedEntries.test.js +0 -46
- package/src/comparers/index.d.ts +0 -14
- package/src/comparers/index.js +0 -14
- package/src/comparers/intersectSet.d.ts +0 -19
- package/src/comparers/intersectSet.js +0 -35
- package/src/comparers/intersectSet.test.js +0 -14
- package/src/comparers/isEqualset.d.ts +0 -22
- package/src/comparers/isEqualset.js +0 -33
- package/src/comparers/isEqualset.test.js +0 -22
- package/src/comparers/isSubset.d.ts +0 -21
- package/src/comparers/isSubset.js +0 -33
- package/src/comparers/isSubset.test.js +0 -21
- package/src/comparers/isSuperset.d.ts +0 -21
- package/src/comparers/isSuperset.js +0 -13
- package/src/comparers/isSuperset.test.js +0 -21
- package/src/comparers/sortedArrayToSet.d.ts +0 -20
- package/src/comparers/sortedArrayToSet.js +0 -35
- package/src/comparers/sortedArrayToSet.test.js +0 -11
- package/src/comparers/unionSet.d.ts +0 -21
- package/src/comparers/unionSet.js +0 -34
- package/src/comparers/unionSet.test.js +0 -11
- package/src/comparison/compareDate.d.ts +0 -8
- package/src/comparison/compareDate.js +0 -11
- package/src/comparison/compareEntries.d.ts +0 -13
- package/src/comparison/compareEntries.js +0 -13
- package/src/comparison/compareKey.d.ts +0 -11
- package/src/comparison/compareKey.js +0 -25
- package/src/comparison/compareKey.test.js +0 -21
- package/src/comparison/compareKeyPath.d.ts +0 -15
- package/src/comparison/compareKeyPath.js +0 -33
- package/src/comparison/compareKeyPath.test.js +0 -28
- package/src/comparison/compareNumber.d.ts +0 -11
- package/src/comparison/compareNumber.js +0 -27
- package/src/comparison/compareNumber.test.js +0 -21
- package/src/comparison/defaultCompare.d.ts +0 -8
- package/src/comparison/defaultCompare.js +0 -12
- package/src/comparison/defaultCompare.test.js +0 -24
- package/src/comparison/index.d.ts +0 -7
- package/src/comparison/index.js +0 -7
- package/src/comparison/infinity.test.js +0 -122
- package/src/comparison/typeof.test.js +0 -64
- package/src/comparison/types.d.ts +0 -5
- package/src/comparison/types.js +0 -11
- package/src/deep/Deep.d.ts +0 -58
- package/src/deep/Deep.js +0 -267
- package/src/deep/Deep.test.js +0 -130
- package/src/deep/deepCombineLatest.test.js +0 -36
- package/src/deep/deepMerge.test.js +0 -34
- package/src/deep/differenceDeep.test.js +0 -31
- package/src/deep/freshValueDeep.test.js +0 -17
- package/src/deep/index.d.ts +0 -1
- package/src/deep/index.js +0 -2
- package/src/deep/intersectDeep.test.js +0 -25
- package/src/deep/intersectEntries.d.ts +0 -13
- package/src/deep/intersectEntries.js +0 -37
- package/src/deep/intersectEntries.test.js +0 -20
- package/src/deep/objectToDeep.test.js +0 -31
- package/src/deep/replaceValueDeep.test.js +0 -21
- package/src/deep/unionDeep.test.js +0 -30
- package/src/deep/zipValueDeep.test.js +0 -21
- package/src/deep-rxjs/ObservableArray.d.ts +0 -55
- package/src/deep-rxjs/ObservableArray.js +0 -94
- package/src/deep-rxjs/ObservableArray.test.js +0 -117
- package/src/deep-rxjs/index.d.ts +0 -2
- package/src/deep-rxjs/index.js +0 -2
- package/src/deep-rxjs/isRxType.d.ts +0 -9
- package/src/deep-rxjs/isRxType.js +0 -15
- package/src/deep-rxjs/isRxType.test.js +0 -43
- package/src/hyperscript-rxjs/HyperscriptExtensions.d.ts +0 -20
- package/src/hyperscript-rxjs/checkbox.d.ts +0 -13
- package/src/hyperscript-rxjs/checkbox.js +0 -47
- package/src/hyperscript-rxjs/checkbox.test.js +0 -68
- package/src/hyperscript-rxjs/choice.d.ts +0 -13
- package/src/hyperscript-rxjs/choice.js +0 -24
- package/src/hyperscript-rxjs/choice.test.js +0 -108
- package/src/hyperscript-rxjs/collapse.d.ts +0 -14
- package/src/hyperscript-rxjs/collapse.js +0 -32
- package/src/hyperscript-rxjs/collapse.test.js +0 -67
- package/src/hyperscript-rxjs/displays/blockLevelFamily.d.ts +0 -5
- package/src/hyperscript-rxjs/displays/blockLevelFamily.js +0 -51
- package/src/hyperscript-rxjs/displays/getDisplay.d.ts +0 -7
- package/src/hyperscript-rxjs/displays/getDisplay.js +0 -51
- package/src/hyperscript-rxjs/displays/getDisplay.test.js +0 -56
- package/src/hyperscript-rxjs/displays/index.d.ts +0 -3
- package/src/hyperscript-rxjs/displays/index.js +0 -3
- package/src/hyperscript-rxjs/displays/inlineFamily.d.ts +0 -5
- package/src/hyperscript-rxjs/displays/inlineFamily.js +0 -73
- package/src/hyperscript-rxjs/flip.d.ts +0 -15
- package/src/hyperscript-rxjs/flip.js +0 -29
- package/src/hyperscript-rxjs/flip.test.js +0 -85
- package/src/hyperscript-rxjs/fragment.d.ts +0 -10
- package/src/hyperscript-rxjs/fragment.js +0 -22
- package/src/hyperscript-rxjs/fragment.test.js +0 -70
- package/src/hyperscript-rxjs/hyperscript.d.ts +0 -15
- package/src/hyperscript-rxjs/hyperscript.js +0 -170
- package/src/hyperscript-rxjs/hyperscript.test.js +0 -75
- package/src/hyperscript-rxjs/index.d.ts +0 -19
- package/src/hyperscript-rxjs/index.js +0 -19
- package/src/hyperscript-rxjs/multiselect.d.ts +0 -18
- package/src/hyperscript-rxjs/multiselect.js +0 -41
- package/src/hyperscript-rxjs/multiselect.test.js +0 -121
- package/src/hyperscript-rxjs/numberbox.d.ts +0 -14
- package/src/hyperscript-rxjs/numberbox.js +0 -73
- package/src/hyperscript-rxjs/numberbox.test.js +0 -84
- package/src/hyperscript-rxjs/radio.d.ts +0 -15
- package/src/hyperscript-rxjs/radio.js +0 -53
- package/src/hyperscript-rxjs/radio.test.js +0 -59
- package/src/hyperscript-rxjs/select.d.ts +0 -28
- package/src/hyperscript-rxjs/select.js +0 -88
- package/src/hyperscript-rxjs/select.test.js +0 -101
- package/src/hyperscript-rxjs/tabControls/bindTabIndex.d.ts +0 -12
- package/src/hyperscript-rxjs/tabControls/bindTabIndex.js +0 -59
- package/src/hyperscript-rxjs/tabControls/index.d.ts +0 -8
- package/src/hyperscript-rxjs/tabControls/index.js +0 -10
- package/src/hyperscript-rxjs/tabControls/tabControl.d.ts +0 -19
- package/src/hyperscript-rxjs/tabControls/tabControl.js +0 -40
- package/src/hyperscript-rxjs/tabControls/tabControl.test.js +0 -98
- package/src/hyperscript-rxjs/tabControls/tabNavItem.d.ts +0 -9
- package/src/hyperscript-rxjs/tabControls/tabNavItem.js +0 -30
- package/src/hyperscript-rxjs/tabControls/tabPanel.d.ts +0 -9
- package/src/hyperscript-rxjs/tabControls/tabPanel.js +0 -21
- package/src/hyperscript-rxjs/tabControls/tabRoot.d.ts +0 -7
- package/src/hyperscript-rxjs/tabControls/tabRoot.js +0 -26
- package/src/hyperscript-rxjs/tags.d.ts +0 -193
- package/src/hyperscript-rxjs/tags.js +0 -751
- package/src/hyperscript-rxjs/tags.test.js +0 -75
- package/src/hyperscript-rxjs/textNode.d.ts +0 -11
- package/src/hyperscript-rxjs/textNode.js +0 -51
- package/src/hyperscript-rxjs/textNode.test.js +0 -56
- package/src/hyperscript-rxjs/textarea.d.ts +0 -17
- package/src/hyperscript-rxjs/textarea.js +0 -45
- package/src/hyperscript-rxjs/textarea.test.js +0 -52
- package/src/hyperscript-rxjs/textbox.d.ts +0 -15
- package/src/hyperscript-rxjs/textbox.js +0 -42
- package/src/hyperscript-rxjs/textbox.test.js +0 -52
- package/src/index.d.ts +0 -19
- package/src/index.js +0 -19
- package/src/nodes/attachSubscriptionToNode.d.ts +0 -13
- package/src/nodes/attachSubscriptionToNode.js +0 -25
- package/src/nodes/attachSubscriptionToNode.test.js +0 -73
- package/src/nodes/index.d.ts +0 -6
- package/src/nodes/index.js +0 -6
- package/src/nodes/normalizeChildNodes.d.ts +0 -9
- package/src/nodes/normalizeChildNodes.js +0 -15
- package/src/nodes/normalizeChildNodes.test.js +0 -55
- package/src/nodes/parseHyperscriptArgs.d.ts +0 -10
- package/src/nodes/parseHyperscriptArgs.js +0 -57
- package/src/nodes/parseHyperscriptArgs.test.js +0 -85
- package/src/nodes/pipeEvent.d.ts +0 -15
- package/src/nodes/pipeEvent.js +0 -49
- package/src/nodes/pipeEvent.test.js +0 -97
- package/src/nodes/subscribeEvent.d.ts +0 -15
- package/src/nodes/subscribeEvent.js +0 -56
- package/src/nodes/subscribeEvent.test.js +0 -88
- package/src/object/index.d.ts +0 -10
- package/src/object/index.js +0 -11
- package/src/object/intersectObject.d.ts +0 -12
- package/src/object/intersectObject.js +0 -23
- package/src/object/intersectObject.test.js +0 -69
- package/src/object/isEmptyObject.d.ts +0 -7
- package/src/object/isEmptyObject.js +0 -13
- package/src/object/isEmptyObject.test.js +0 -33
- package/src/object/isPlainObject.d.ts +0 -11
- package/src/object/isPlainObject.js +0 -18
- package/src/object/nestedCombineLatest.d.ts +0 -11
- package/src/object/nestedCombineLatest.js +0 -18
- package/src/object/nestedCombineLatest.test.js +0 -25
- package/src/object/nestedMerge.d.ts +0 -11
- package/src/object/nestedMerge.js +0 -11
- package/src/object/nestedMerge.test.js +0 -61
- package/src/object/pickBehaviorSubject.d.ts +0 -13
- package/src/object/pickBehaviorSubject.js +0 -81
- package/src/object/pickBehaviorSubject.test.js +0 -88
- package/src/object/pluckProperty.d.ts +0 -13
- package/src/object/pluckProperty.js +0 -24
- package/src/object/pluckProperty.test.js +0 -37
- package/src/object/restore.d.ts +0 -12
- package/src/object/restore.js +0 -69
- package/src/object/restore.test.js +0 -124
- package/src/object/splitObjectByObservable.d.ts +0 -12
- package/src/object/splitObjectByObservable.js +0 -41
- package/src/object/splitObjectByObservable.test.js +0 -78
- package/src/props/getNestedProperty.d.ts +0 -12
- package/src/props/getNestedProperty.js +0 -31
- package/src/props/getNestedProperty.test.js +0 -72
- package/src/props/index.d.ts +0 -7
- package/src/props/index.js +0 -7
- package/src/props/parsePropName.d.ts +0 -13
- package/src/props/parsePropName.js +0 -45
- package/src/props/parsePropName.test.js +0 -67
- package/src/props/setProp.d.ts +0 -16
- package/src/props/setProp.js +0 -42
- package/src/props/setProp.test.js +0 -59
- package/src/props/setProps.d.ts +0 -14
- package/src/props/setProps.js +0 -47
- package/src/props/setProps.test.js +0 -97
- package/src/props/subscribeProp.d.ts +0 -16
- package/src/props/subscribeProp.js +0 -47
- package/src/props/subscribeProp.test.js +0 -81
- package/src/ramda/compose.d.ts +0 -10
- package/src/ramda/compose.js +0 -36
- package/src/ramda/compose.test.js +0 -73
- package/src/ramda/cond.d.ts +0 -12
- package/src/ramda/cond.js +0 -29
- package/src/ramda/cond.test.js +0 -88
- package/src/ramda/fold.d.ts +0 -13
- package/src/ramda/fold.js +0 -20
- package/src/ramda/fold.test.js +0 -51
- package/src/ramda/index.d.ts +0 -6
- package/src/ramda/index.js +0 -6
- package/src/ramda/pipe.d.ts +0 -13
- package/src/ramda/pipe.js +0 -27
- package/src/ramda/pipe.test.js +0 -77
- package/src/ramda/unfold.d.ts +0 -11
- package/src/ramda/unfold.js +0 -20
- package/src/ramda/unfold.test.js +0 -29
- package/src/unquoted-json/ajax.test.js +0 -1074
- package/src/unquoted-json/index.d.ts +0 -13
- package/src/unquoted-json/index.js +0 -12
- package/src/unquoted-json/queryStringify.d.ts +0 -8
- package/src/unquoted-json/queryStringify.js +0 -70
- package/src/unquoted-json/queryStringify.test.js +0 -110
- package/src/unquoted-json/stringifyKey.d.ts +0 -7
- package/src/unquoted-json/stringifyKey.js +0 -16
- package/src/unquoted-json/stringifyKey.test.js +0 -51
- package/src/unquoted-json/stringifyStringValue.d.ts +0 -7
- package/src/unquoted-json/stringifyStringValue.js +0 -17
- package/src/unquoted-json/stringifyStringValue.test.js +0 -52
- package/src/unquoted-json/unquotedJsonStringify.d.ts +0 -7
- package/src/unquoted-json/unquotedJsonStringify.js +0 -39
- package/src/unquoted-json/unquotedJsonStringify.test.js +0 -52
@@ -1,121 +0,0 @@
|
|
1
|
-
import { BehaviorSubject } from 'rxjs';
|
2
|
-
import { multiselect } from './multiselect';
|
3
|
-
import { option } from './tags';
|
4
|
-
|
5
|
-
describe('multiselect', () => {
|
6
|
-
test('should create a multi-select element with options', () => {
|
7
|
-
const a = new BehaviorSubject(false);
|
8
|
-
const b = new BehaviorSubject(false);
|
9
|
-
const c = new BehaviorSubject(false);
|
10
|
-
|
11
|
-
const elem = multiselect({
|
12
|
-
oninput: e => {
|
13
|
-
let aa = e.target[0].selected;
|
14
|
-
if (a.value !== aa) a.next(aa);
|
15
|
-
|
16
|
-
let bb = e.target[1].selected;
|
17
|
-
if (b.value !== bb) b.next(bb);
|
18
|
-
|
19
|
-
let cc = e.target[2].selected;
|
20
|
-
if (c.value !== cc) c.next(cc);
|
21
|
-
},
|
22
|
-
},
|
23
|
-
option({ selected: a }, "A"),
|
24
|
-
option({ selected: b }, "B"),
|
25
|
-
option({ selected: c }, "C")
|
26
|
-
);
|
27
|
-
|
28
|
-
// 初始状态
|
29
|
-
expect(elem.multiple).toBe(true);
|
30
|
-
expect(elem.options[0].selected).toBe(false);
|
31
|
-
expect(elem.options[1].selected).toBe(false);
|
32
|
-
expect(elem.options[2].selected).toBe(false);
|
33
|
-
|
34
|
-
// 更新 BehaviorSubject
|
35
|
-
a.next(true);
|
36
|
-
b.next(false);
|
37
|
-
c.next(true);
|
38
|
-
expect(elem.options[0].selected).toBe(true);
|
39
|
-
expect(elem.options[1].selected).toBe(false);
|
40
|
-
expect(elem.options[2].selected).toBe(true);
|
41
|
-
|
42
|
-
// 模拟用户选择
|
43
|
-
elem.options[0].selected = false;
|
44
|
-
elem.options[1].selected = true;
|
45
|
-
elem.options[2].selected = false;
|
46
|
-
elem.dispatchEvent(new Event('input'));
|
47
|
-
|
48
|
-
expect(a.getValue()).toBe(false);
|
49
|
-
expect(b.getValue()).toBe(true);
|
50
|
-
expect(c.getValue()).toBe(false);
|
51
|
-
});
|
52
|
-
|
53
|
-
test('should handle oninput and onchange callbacks', () => {
|
54
|
-
const oninputMock = jest.fn();
|
55
|
-
const onchangeMock = jest.fn();
|
56
|
-
|
57
|
-
const elem = multiselect(
|
58
|
-
{ oninput: oninputMock, onchange: onchangeMock },
|
59
|
-
option({ value: 'A' }, 'Option A'),
|
60
|
-
option({ value: 'B' }, 'Option B')
|
61
|
-
);
|
62
|
-
|
63
|
-
// 模拟用户交互
|
64
|
-
elem.options[0].selected = true;
|
65
|
-
elem.dispatchEvent(new Event('input'));
|
66
|
-
expect(oninputMock).toHaveBeenCalledWith(expect.any(Event));
|
67
|
-
|
68
|
-
elem.options[1].selected = true;
|
69
|
-
elem.dispatchEvent(new Event('change'));
|
70
|
-
expect(onchangeMock).toHaveBeenCalledWith(expect.any(Event));
|
71
|
-
});
|
72
|
-
|
73
|
-
test('should throw an error if props is not an object', () => {
|
74
|
-
expect(() => multiselect(null)).toThrow('`select` requires a `props` object.');
|
75
|
-
});
|
76
|
-
|
77
|
-
test('should synchronize selected state between BehaviorSubject and DOM', () => {
|
78
|
-
const a = new BehaviorSubject(false);
|
79
|
-
const b = new BehaviorSubject(true);
|
80
|
-
|
81
|
-
const elem = multiselect(
|
82
|
-
{
|
83
|
-
oninput: e => {
|
84
|
-
let aa = e.target[0].selected;
|
85
|
-
if (a.value !== aa) a.next(aa);
|
86
|
-
|
87
|
-
let bb = e.target[1].selected;
|
88
|
-
if (b.value !== bb) b.next(bb);
|
89
|
-
|
90
|
-
},
|
91
|
-
|
92
|
-
},
|
93
|
-
option({ selected: a }, 'Option A'),
|
94
|
-
option({ selected: b }, 'Option B')
|
95
|
-
);
|
96
|
-
|
97
|
-
// 初始状态
|
98
|
-
expect(elem.options[0].selected).toBe(false);
|
99
|
-
expect(elem.options[1].selected).toBe(true);
|
100
|
-
|
101
|
-
// 更新 BehaviorSubject
|
102
|
-
a.next(true);
|
103
|
-
b.next(false);
|
104
|
-
expect(elem.options[0].selected).toBe(true);
|
105
|
-
expect(elem.options[1].selected).toBe(false);
|
106
|
-
|
107
|
-
// 更新 DOM
|
108
|
-
elem.options[0].selected = false;
|
109
|
-
elem.options[1].selected = true;
|
110
|
-
elem.dispatchEvent(new Event('input'));
|
111
|
-
|
112
|
-
expect(a.getValue()).toBe(false);
|
113
|
-
expect(b.getValue()).toBe(true);
|
114
|
-
});
|
115
|
-
|
116
|
-
test('should handle empty options', () => {
|
117
|
-
const elem = multiselect({}, []);
|
118
|
-
expect(elem.multiple).toBe(true);
|
119
|
-
expect(elem.options.length).toBe(0);
|
120
|
-
});
|
121
|
-
});
|
@@ -1,14 +0,0 @@
|
|
1
|
-
import { BehaviorSubject } from 'rxjs';
|
2
|
-
import { HyperscriptExtensions } from './HyperscriptExtensions';
|
3
|
-
|
4
|
-
/**
|
5
|
-
* 创建一个支持双向绑定的数字输入框。
|
6
|
-
*
|
7
|
-
* @param props - 配置对象,必须包含 number(BehaviorSubject<number>),其余为 <input> 元素属性。
|
8
|
-
* @returns 创建的数字输入框元素。
|
9
|
-
* @throws 如果 props 不是对象,或者 number 不是 BehaviorSubject 会抛出错误。
|
10
|
-
*/
|
11
|
-
export function numberbox(props: {
|
12
|
-
number: BehaviorSubject<number>;
|
13
|
-
[key: string]: any;
|
14
|
-
}): HyperscriptExtensions<HTMLInputElement>;
|
@@ -1,73 +0,0 @@
|
|
1
|
-
import { BehaviorSubject, Observable } from 'rxjs';
|
2
|
-
import { map } from 'rxjs/operators';
|
3
|
-
import { input } from './tags';
|
4
|
-
import { subscribeProp } from '../props/subscribeProp';
|
5
|
-
// import { fromEvent } from 'rxjs';
|
6
|
-
// import { attachSubscriptionToNode } from '../../nodes/attachSubscriptionToNode';
|
7
|
-
|
8
|
-
/**
|
9
|
-
* @typedef {import("./HyperscriptExtensions").HyperscriptExtensions<HTMLInputElement>} HyperscriptInputElement
|
10
|
-
*/
|
11
|
-
|
12
|
-
/**
|
13
|
-
* 创建一个支持双向绑定的数字输入框。
|
14
|
-
*
|
15
|
-
* `numberbox` 是一个自定义的输入框组件,支持通过 RxJS 的 `BehaviorSubject` 实现数字值的双向绑定。
|
16
|
-
*
|
17
|
-
* @param {{ number: BehaviorSubject<number>; [key: string]: any;}} props - 配置对象,包含输入框的属性。
|
18
|
-
* @returns {HyperscriptInputElement} - 创建的数字输入框元素。
|
19
|
-
* @throws {Error} 如果 `props` 不是对象,或者 `number` 不是 `BehaviorSubject` 实例。
|
20
|
-
*
|
21
|
-
*/
|
22
|
-
export function numberbox(props) {
|
23
|
-
if (typeof props !== 'object' || props === null) {
|
24
|
-
throw new Error('`numberbox` requires a `props` object.');
|
25
|
-
}
|
26
|
-
let { number, ...rest } = props;
|
27
|
-
let elem =
|
28
|
-
/** @type {HyperscriptInputElement} */
|
29
|
-
(input({ ...rest, type: 'text' }));
|
30
|
-
|
31
|
-
if (number && number instanceof BehaviorSubject) {
|
32
|
-
let value = number.pipe(map(n => String(n)));
|
33
|
-
|
34
|
-
subscribeProp(elem, 'value', value);
|
35
|
-
|
36
|
-
let subscriber =
|
37
|
-
/**
|
38
|
-
*
|
39
|
-
* @param {Observable<Event>} blur$
|
40
|
-
* @returns
|
41
|
-
*/
|
42
|
-
blur$ =>
|
43
|
-
blur$.pipe(
|
44
|
-
map(e => Number(
|
45
|
-
/** @type {HTMLInputElement} */
|
46
|
-
(e.target).value)
|
47
|
-
)
|
48
|
-
).subscribe(newValue => {
|
49
|
-
if (Number.isNaN(newValue)) {
|
50
|
-
elem.select();
|
51
|
-
} else if (number.value !== newValue) {
|
52
|
-
number.next(newValue);
|
53
|
-
}
|
54
|
-
})
|
55
|
-
|
56
|
-
// 展开pipeEvent是为了正确生成测试代码
|
57
|
-
// let event$ = fromEvent(elem, 'blur')// 创建事件流 Observable
|
58
|
-
// let subscription = blurSubscriber(event$); // 订阅事件流并处理
|
59
|
-
// attachSubscriptionToNode(elem, subscription); // 将订阅附加到 DOM 元素,便于管理
|
60
|
-
|
61
|
-
elem.pipeEvent('blur', subscriber)
|
62
|
-
|
63
|
-
} else {
|
64
|
-
throw new Error(
|
65
|
-
'`numberbox` requires a `number` prop that is an instance of BehaviorSubject. '
|
66
|
-
);
|
67
|
-
}
|
68
|
-
|
69
|
-
// 数字右对齐,用 style 可以获得最高优先级
|
70
|
-
elem.style.textAlign = 'right';
|
71
|
-
|
72
|
-
return elem;
|
73
|
-
}
|
@@ -1,84 +0,0 @@
|
|
1
|
-
import { BehaviorSubject } from 'rxjs';
|
2
|
-
import { numberbox } from './numberbox';
|
3
|
-
import { subscribeProp } from '../props/subscribeProp';
|
4
|
-
import { attachSubscriptionToNode } from '../nodes/attachSubscriptionToNode';
|
5
|
-
|
6
|
-
jest.mock('../props/subscribeProp', () => ({
|
7
|
-
subscribeProp: jest.fn(),
|
8
|
-
}));
|
9
|
-
|
10
|
-
jest.mock('../nodes/attachSubscriptionToNode', () => ({
|
11
|
-
attachSubscriptionToNode: jest.fn(),
|
12
|
-
}));
|
13
|
-
|
14
|
-
describe('numberbox', () => {
|
15
|
-
beforeEach(() => {
|
16
|
-
jest.clearAllMocks();
|
17
|
-
});
|
18
|
-
|
19
|
-
test('should create a numberbox with a BehaviorSubject', () => {
|
20
|
-
const number = new BehaviorSubject(42);
|
21
|
-
const elem = numberbox({ number });
|
22
|
-
|
23
|
-
// 验证 input 元素的类型
|
24
|
-
expect(elem.tagName.toLowerCase()).toBe('input');
|
25
|
-
expect(elem.type).toBe('text');
|
26
|
-
|
27
|
-
// 验证 subscribeProp 被正确调用
|
28
|
-
expect(subscribeProp).toHaveBeenCalledWith(elem, 'value', expect.any(Object));
|
29
|
-
|
30
|
-
// 验证样式
|
31
|
-
expect(elem.style.textAlign).toBe('right');
|
32
|
-
});
|
33
|
-
|
34
|
-
test('should update BehaviorSubject when valid number is entered', () => {
|
35
|
-
const number = new BehaviorSubject(42);
|
36
|
-
const elem = numberbox({ number });
|
37
|
-
|
38
|
-
// 模拟 blur 事件
|
39
|
-
const blurEvent = new Event('blur');
|
40
|
-
elem.value = '100';
|
41
|
-
elem.dispatchEvent(blurEvent);
|
42
|
-
|
43
|
-
// 验证 BehaviorSubject 的值是否更新
|
44
|
-
expect(number.getValue()).toBe(100);
|
45
|
-
});
|
46
|
-
|
47
|
-
test('should select input when invalid number is entered', () => {
|
48
|
-
const number = new BehaviorSubject(42);
|
49
|
-
const elem = numberbox({ number });
|
50
|
-
|
51
|
-
// 模拟 select 方法
|
52
|
-
elem.select = jest.fn();
|
53
|
-
|
54
|
-
// 模拟 blur 事件
|
55
|
-
const blurEvent = new Event('blur');
|
56
|
-
elem.value = 'invalid';
|
57
|
-
elem.dispatchEvent(blurEvent);
|
58
|
-
|
59
|
-
// 验证 select 是否被调用
|
60
|
-
expect(elem.select).toHaveBeenCalled();
|
61
|
-
});
|
62
|
-
|
63
|
-
test('should attach subscription to the DOM element', () => {
|
64
|
-
const number = new BehaviorSubject(42);
|
65
|
-
const elem = numberbox({ number });
|
66
|
-
|
67
|
-
// 验证 attachSubscriptionToNode 被正确调用
|
68
|
-
expect(attachSubscriptionToNode).toHaveBeenCalledWith(elem, expect.any(Object));
|
69
|
-
});
|
70
|
-
|
71
|
-
test('should throw an error if number is not a BehaviorSubject', () => {
|
72
|
-
const invalidNumber = 42;
|
73
|
-
|
74
|
-
expect(() => numberbox({ number: invalidNumber })).toThrow(
|
75
|
-
'`numberbox` requires a `number` prop that is an instance of BehaviorSubject. '
|
76
|
-
);
|
77
|
-
});
|
78
|
-
|
79
|
-
test('should throw an error if number prop is missing', () => {
|
80
|
-
expect(() => numberbox({})).toThrow(
|
81
|
-
'`numberbox` requires a `number` prop that is an instance of BehaviorSubject. '
|
82
|
-
);
|
83
|
-
});
|
84
|
-
});
|
@@ -1,15 +0,0 @@
|
|
1
|
-
import { BehaviorSubject } from 'rxjs';
|
2
|
-
import { HyperscriptExtensions } from './HyperscriptExtensions';
|
3
|
-
|
4
|
-
/**
|
5
|
-
* 创建一个支持 RxJS 数据绑定的 <input type="radio"> 单选按钮。
|
6
|
-
*
|
7
|
-
* @param props - 配置对象,必须包含 checked(BehaviorSubject<boolean>)。
|
8
|
-
* @returns 创建的 <input type="radio"> 元素。
|
9
|
-
* @throws 如果 props 不是对象,或者 checked 不是 BehaviorSubject 会抛出错误。
|
10
|
-
*/
|
11
|
-
export function radio(props: {
|
12
|
-
checked: BehaviorSubject<boolean>,
|
13
|
-
[key: string]: any
|
14
|
-
}): HyperscriptExtensions<HTMLInputElement>;
|
15
|
-
|
@@ -1,53 +0,0 @@
|
|
1
|
-
import { map } from 'rxjs/operators'
|
2
|
-
import { input } from './tags'
|
3
|
-
import { BehaviorSubject, Observable } from 'rxjs';
|
4
|
-
// import { fromEvent } from 'rxjs';
|
5
|
-
// import { attachSubscriptionToNode } from '../../nodes/attachSubscriptionToNode';
|
6
|
-
|
7
|
-
/**
|
8
|
-
* @typedef {import("./HyperscriptExtensions").HyperscriptExtensions<HTMLInputElement>} HyperscriptInputElement
|
9
|
-
*/
|
10
|
-
|
11
|
-
/**
|
12
|
-
* 单选按钮
|
13
|
-
* @param {{checked: BehaviorSubject<boolean>; [key: string]: any}} props
|
14
|
-
* @returns {HyperscriptInputElement}
|
15
|
-
*/
|
16
|
-
export function radio(props) {
|
17
|
-
if (typeof props !== 'object' || props === null) {
|
18
|
-
throw new Error('`radio` requires a `props` object.');
|
19
|
-
}
|
20
|
-
|
21
|
-
const elem =
|
22
|
-
/** @type {HyperscriptInputElement} */
|
23
|
-
(input({ ...props, type: 'radio' }))
|
24
|
-
|
25
|
-
if (props.checked && props.checked instanceof BehaviorSubject) {
|
26
|
-
const subscriber =
|
27
|
-
/**
|
28
|
-
*
|
29
|
-
* @param {Observable<Event>} input$
|
30
|
-
* @returns
|
31
|
-
*/
|
32
|
-
input$ =>
|
33
|
-
input$.pipe(
|
34
|
-
map(e =>
|
35
|
-
/** @type {HTMLInputElement} */
|
36
|
-
(e.target).checked),
|
37
|
-
).subscribe(props.checked)
|
38
|
-
|
39
|
-
elem.pipeEvent('input', subscriber)
|
40
|
-
|
41
|
-
// 展开pipeEvent是为了正确生成测试代码
|
42
|
-
// let event$ = fromEvent(elem, 'input')// 创建事件流 Observable
|
43
|
-
// let subscription = subscriber(event$); // 订阅事件流并处理
|
44
|
-
// attachSubscriptionToNode(elem, subscription); // 将订阅附加到 DOM 元素,便于管理
|
45
|
-
|
46
|
-
} else {
|
47
|
-
throw new Error(
|
48
|
-
'`radio` requires a `checked` prop that is an instance of BehaviorSubject. '
|
49
|
-
);
|
50
|
-
}
|
51
|
-
|
52
|
-
return elem
|
53
|
-
}
|
@@ -1,59 +0,0 @@
|
|
1
|
-
import { BehaviorSubject } from 'rxjs';
|
2
|
-
import { radio } from './radio';
|
3
|
-
import { attachSubscriptionToNode } from '../nodes/attachSubscriptionToNode';
|
4
|
-
|
5
|
-
jest.mock('../nodes/attachSubscriptionToNode', () => ({
|
6
|
-
attachSubscriptionToNode: jest.fn(),
|
7
|
-
}));
|
8
|
-
|
9
|
-
describe('radio', () => {
|
10
|
-
beforeEach(() => {
|
11
|
-
jest.clearAllMocks();
|
12
|
-
});
|
13
|
-
|
14
|
-
test('should create a radio input element with BehaviorSubject', () => {
|
15
|
-
const checked = new BehaviorSubject(false);
|
16
|
-
const elem = radio({ checked, name: 'test', value: 'option1' });
|
17
|
-
|
18
|
-
// 验证返回的元素
|
19
|
-
expect(elem).toBeInstanceOf(HTMLInputElement);
|
20
|
-
expect(elem.type).toBe('radio');
|
21
|
-
expect(elem.name).toBe('test');
|
22
|
-
expect(elem.value).toBe('option1');
|
23
|
-
});
|
24
|
-
|
25
|
-
test('should bind checked state to BehaviorSubject', () => {
|
26
|
-
const checked = new BehaviorSubject(false);
|
27
|
-
const elem = radio({ checked });
|
28
|
-
|
29
|
-
// 模拟 input 事件
|
30
|
-
const event = new Event('input');
|
31
|
-
elem.checked = true;
|
32
|
-
elem.dispatchEvent(event);
|
33
|
-
|
34
|
-
// 验证 BehaviorSubject 的值是否更新
|
35
|
-
expect(checked.getValue()).toBe(true);
|
36
|
-
});
|
37
|
-
|
38
|
-
test('should attach subscription to the DOM element', () => {
|
39
|
-
const checked = new BehaviorSubject(false);
|
40
|
-
const elem = radio({ checked });
|
41
|
-
|
42
|
-
// 验证 attachSubscriptionToNode 被正确调用
|
43
|
-
expect(attachSubscriptionToNode).toHaveBeenCalledWith(elem, expect.any(Object));
|
44
|
-
});
|
45
|
-
|
46
|
-
test('should throw an error if props is not an object', () => {
|
47
|
-
let msg = '`radio` requires a `props` object.'
|
48
|
-
expect(() => radio(null)).toThrow(msg);
|
49
|
-
expect(() => radio(42)).toThrow(msg);
|
50
|
-
expect(() => radio(undefined)).toThrow(msg);
|
51
|
-
});
|
52
|
-
|
53
|
-
test('should throw an error if checked is not a BehaviorSubject', () => {
|
54
|
-
let msg = '`radio` requires a `checked` prop that is an instance of BehaviorSubject. ';
|
55
|
-
expect(() => radio({ checked: null })).toThrow(msg);
|
56
|
-
expect(() => radio({ checked: 42 })).toThrow(msg);
|
57
|
-
expect(() => radio({ checked: {} })).toThrow(msg);
|
58
|
-
});
|
59
|
-
});
|
@@ -1,28 +0,0 @@
|
|
1
|
-
import { BehaviorSubject } from 'rxjs';
|
2
|
-
import { HyperscriptExtensions } from './HyperscriptExtensions';
|
3
|
-
|
4
|
-
/**
|
5
|
-
* 创建一个支持 RxJS 数据绑定的 <select> 元素(仅单选)。
|
6
|
-
*
|
7
|
-
* @param props - 配置对象,包含 <select> 元素的属性,可选 selectedIndex/value(BehaviorSubject)。
|
8
|
-
* @param options - 一个或多个 <option> 元素。
|
9
|
-
* @returns 创建的 <select> 元素。
|
10
|
-
* @throws 如果 props 不是对象,或者 selectedIndex/value 不是 BehaviorSubject 会抛出错误。
|
11
|
-
*/
|
12
|
-
export function select(
|
13
|
-
props: {
|
14
|
-
selectedIndex?: BehaviorSubject<number>,
|
15
|
-
value?: BehaviorSubject<string>,
|
16
|
-
[key: string]: any
|
17
|
-
},
|
18
|
-
...options: HTMLOptionElement[]
|
19
|
-
): HyperscriptExtensions<HTMLSelectElement>;
|
20
|
-
|
21
|
-
export function select(
|
22
|
-
props: {
|
23
|
-
selectedIndex?: BehaviorSubject<number>,
|
24
|
-
value?: BehaviorSubject<string>,
|
25
|
-
[key: string]: any
|
26
|
-
},
|
27
|
-
options: HTMLOptionElement[]
|
28
|
-
): HyperscriptExtensions<HTMLSelectElement>;
|
@@ -1,88 +0,0 @@
|
|
1
|
-
import { BehaviorSubject, Observable } from 'rxjs';
|
2
|
-
import { map } from 'rxjs/operators'
|
3
|
-
import { hyperscript } from './hyperscript'
|
4
|
-
|
5
|
-
// import { fromEvent } from 'rxjs';
|
6
|
-
// import { attachSubscriptionToNode } from '../nodes/attachSubscriptionToNode';
|
7
|
-
|
8
|
-
/**
|
9
|
-
* @typedef {import("./HyperscriptExtensions").HyperscriptExtensions<HTMLSelectElement>} HyperscriptSelectElement
|
10
|
-
*/
|
11
|
-
|
12
|
-
/**
|
13
|
-
* 创建一个支持 RxJS 数据绑定的 <select> 元素。仅单选选择框。
|
14
|
-
*
|
15
|
-
* @param {{ selectedIndex?: BehaviorSubject<number>, value?: BehaviorSubject<string>, [key: string]: any }} props - 配置对象,包含 <select> 元素的属性。
|
16
|
-
* @param {...HTMLOptionElement} options - 一个或多个 <option> 元素,必须是 HTMLOptionElement 类型。
|
17
|
-
* @returns {HyperscriptSelectElement} - 创建的 <select> 元素。
|
18
|
-
* @throws {Error} 如果 `props` 不是对象,或者 `selectedIndex` 或 `value` 不是 BehaviorSubject。
|
19
|
-
*/
|
20
|
-
export function select(props, ...options) {
|
21
|
-
if (typeof props !== 'object' || props === null) {
|
22
|
-
throw new Error('`select` requires a `props` object.');
|
23
|
-
}
|
24
|
-
|
25
|
-
let elem =
|
26
|
-
/** @type {HyperscriptSelectElement} */
|
27
|
-
(hyperscript('select', { ...props, multiple: false }, ...options))
|
28
|
-
|
29
|
-
// todo: 显示判断属性是否传递了属性,('selectedIndex' in props)
|
30
|
-
let { selectedIndex, value } = props
|
31
|
-
|
32
|
-
// 确保至少有一个是 BehaviorSubject
|
33
|
-
if (elem.options.length > 0 &&
|
34
|
-
!(selectedIndex instanceof BehaviorSubject) &&
|
35
|
-
!(value instanceof BehaviorSubject)) {
|
36
|
-
throw new Error('`select` requires at least one of `selectedIndex` or `value` to be a BehaviorSubject.');
|
37
|
-
}
|
38
|
-
|
39
|
-
if (selectedIndex && selectedIndex instanceof BehaviorSubject) {
|
40
|
-
|
41
|
-
selectedIndex.subscribe(i => {
|
42
|
-
/** @type {HTMLOptionElement} */
|
43
|
-
(elem[i]).selected = true
|
44
|
-
})
|
45
|
-
let subscriber =
|
46
|
-
/**
|
47
|
-
* @param {Observable<Event>} input$
|
48
|
-
*/
|
49
|
-
input$ =>
|
50
|
-
input$.pipe(
|
51
|
-
map(e =>
|
52
|
-
/** @type {HTMLSelectElement} */
|
53
|
-
(e.target).selectedIndex)
|
54
|
-
).subscribe(selectedIndex)
|
55
|
-
|
56
|
-
elem.pipeEvent('input', subscriber)
|
57
|
-
// let event$ = fromEvent(elem, 'input');
|
58
|
-
// let subscription = subscriber(event$);
|
59
|
-
// attachSubscriptionToNode(elem, subscription);
|
60
|
-
}
|
61
|
-
|
62
|
-
if (value && value instanceof BehaviorSubject) {
|
63
|
-
|
64
|
-
value.subscribe(value => {
|
65
|
-
Array.from(elem.getElementsByTagName('option'))
|
66
|
-
.filter(opt => opt.value === value)
|
67
|
-
.forEach(opt => { opt.selected = true })
|
68
|
-
})
|
69
|
-
|
70
|
-
let subscriber =
|
71
|
-
/**
|
72
|
-
* @param {Observable<Event>} input$
|
73
|
-
*/
|
74
|
-
|
75
|
-
input$ =>
|
76
|
-
input$.pipe(map(e =>
|
77
|
-
/** @type {HTMLSelectElement} */
|
78
|
-
(e.target).value)
|
79
|
-
).subscribe(value)
|
80
|
-
elem.pipeEvent('input', subscriber)
|
81
|
-
// let event$ = fromEvent(elem, 'input');
|
82
|
-
// let subscription = subscriber(event$);
|
83
|
-
// attachSubscriptionToNode(elem, subscription);
|
84
|
-
}
|
85
|
-
|
86
|
-
return elem
|
87
|
-
}
|
88
|
-
|
@@ -1,101 +0,0 @@
|
|
1
|
-
import { BehaviorSubject } from 'rxjs';
|
2
|
-
import { select } from './select';
|
3
|
-
import { option } from './tags';
|
4
|
-
|
5
|
-
describe('select', () => {
|
6
|
-
test('should create a single-select element with options', () => {
|
7
|
-
const selectedIndex = new BehaviorSubject(0);
|
8
|
-
const value = new BehaviorSubject('A');
|
9
|
-
|
10
|
-
const elem = select(
|
11
|
-
{ selectedIndex, value },
|
12
|
-
option({ value: 'A' }, 'Option A'),
|
13
|
-
option({ value: 'B' }, 'Option B'),
|
14
|
-
option({ value: 'C' }, 'Option C')
|
15
|
-
);
|
16
|
-
|
17
|
-
// 验证初始状态
|
18
|
-
expect(elem.multiple).toBe(false);
|
19
|
-
expect(elem.options.length).toBe(3);
|
20
|
-
expect(elem.options[0].selected).toBe(true);
|
21
|
-
expect(elem.options[1].selected).toBe(false);
|
22
|
-
expect(elem.options[2].selected).toBe(false);
|
23
|
-
expect(value.getValue()).toBe('A');
|
24
|
-
expect(selectedIndex.getValue()).toBe(0);
|
25
|
-
});
|
26
|
-
|
27
|
-
test('should synchronize selectedIndex with DOM', () => {
|
28
|
-
const selectedIndex = new BehaviorSubject(1);
|
29
|
-
|
30
|
-
const elem = select(
|
31
|
-
{ selectedIndex },
|
32
|
-
option({ value: 'A' }, 'Option A'),
|
33
|
-
option({ value: 'B' }, 'Option B'),
|
34
|
-
option({ value: 'C' }, 'Option C')
|
35
|
-
);
|
36
|
-
|
37
|
-
// 验证初始状态
|
38
|
-
expect(elem.options[0].selected).toBe(false);
|
39
|
-
expect(elem.options[1].selected).toBe(true);
|
40
|
-
expect(elem.options[2].selected).toBe(false);
|
41
|
-
|
42
|
-
// 更新 BehaviorSubject
|
43
|
-
selectedIndex.next(2);
|
44
|
-
expect(elem.options[0].selected).toBe(false);
|
45
|
-
expect(elem.options[1].selected).toBe(false);
|
46
|
-
expect(elem.options[2].selected).toBe(true);
|
47
|
-
|
48
|
-
// 更新 DOM
|
49
|
-
elem.options[0].selected = true;
|
50
|
-
elem.dispatchEvent(new Event('input'));
|
51
|
-
expect(selectedIndex.getValue()).toBe(0);
|
52
|
-
});
|
53
|
-
|
54
|
-
test('should synchronize value with DOM', () => {
|
55
|
-
const value = new BehaviorSubject('B');
|
56
|
-
|
57
|
-
const elem = select(
|
58
|
-
{ value },
|
59
|
-
option({ value: 'A' }, 'Option A'),
|
60
|
-
option({ value: 'B' }, 'Option B'),
|
61
|
-
option({ value: 'C' }, 'Option C')
|
62
|
-
);
|
63
|
-
|
64
|
-
// 验证初始状态
|
65
|
-
expect(elem.options[0].selected).toBe(false);
|
66
|
-
expect(elem.options[1].selected).toBe(true);
|
67
|
-
expect(elem.options[2].selected).toBe(false);
|
68
|
-
|
69
|
-
// 更新 BehaviorSubject
|
70
|
-
value.next('C');
|
71
|
-
expect(elem.options[0].selected).toBe(false);
|
72
|
-
expect(elem.options[1].selected).toBe(false);
|
73
|
-
expect(elem.options[2].selected).toBe(true);
|
74
|
-
|
75
|
-
// 更新 DOM
|
76
|
-
elem.options[0].selected = true;
|
77
|
-
elem.dispatchEvent(new Event('input'));
|
78
|
-
expect(value.getValue()).toBe('A');
|
79
|
-
});
|
80
|
-
|
81
|
-
test('should throw an error if props is not an object', () => {
|
82
|
-
expect(() => select(null)).toThrow('`select` requires a `props` object.');
|
83
|
-
});
|
84
|
-
|
85
|
-
test('should throw an error if selectedIndex is not a BehaviorSubject', () => {
|
86
|
-
expect(() =>
|
87
|
-
select({ selectedIndex: 0 }, option({ value: 'A' }, 'Option A'))
|
88
|
-
).toThrow('`select` requires at least one of `selectedIndex` or `value` to be a BehaviorSubject.');
|
89
|
-
});
|
90
|
-
|
91
|
-
test('should throw an error if value is not a BehaviorSubject', () => {
|
92
|
-
expect(() =>
|
93
|
-
select({ value: 'A' }, option({ value: 'A' }, 'Option A'))
|
94
|
-
).toThrow('`select` requires at least one of `selectedIndex` or `value` to be a BehaviorSubject.');
|
95
|
-
});
|
96
|
-
|
97
|
-
test('should handle empty options', () => {
|
98
|
-
const elem = select({}, []);
|
99
|
-
expect(elem.options.length).toBe(0);
|
100
|
-
});
|
101
|
-
});
|
@@ -1,12 +0,0 @@
|
|
1
|
-
import { BehaviorSubject } from 'rxjs';
|
2
|
-
|
3
|
-
/**
|
4
|
-
* 绑定选项卡的激活状态到 tabIndex,实现动态切换选项卡的功能。
|
5
|
-
*
|
6
|
-
* @param tabRoot - 选项卡的根容器,包含导航栏和内容面板。
|
7
|
-
* @param tabIndex$ - 表示当前激活选项卡索引的 BehaviorSubject。
|
8
|
-
*/
|
9
|
-
export function bindTabIndex(
|
10
|
-
tabRoot: HTMLElement,
|
11
|
-
tabIndex$: BehaviorSubject<number>
|
12
|
-
): void;
|