Skip to content

Commit eae2944

Browse files
committed
refactor: 更新 base-select 代码复用
1 parent 77bdd87 commit eae2944

File tree

2 files changed

+88
-157
lines changed

2 files changed

+88
-157
lines changed
Lines changed: 7 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,26 @@
1-
import { debounce, getHeight, getInnerHeight, getTransitionDelayDurationFromElement } from "../../modules/utility.js"
1+
import { getTransitionDelayDurationFromElement } from "../../modules/utility.js"
2+
import { registerSelect, unregisterSelect } from "../../modules/base-select.js"
23
import Data from "../../modules/data.js"
3-
import EventHandler from "../../modules/event-handler.js"
44
import Popover from "../../modules/base-popover.js"
5-
import Input from "../../modules/input.js"
65

76
export function init(id, invoke, options) {
87
const el = document.getElementById(id)
98
if (el === null) {
109
return
1110
}
1211

13-
const { confirmMethodCallback, searchMethodCallback } = options;
1412
const search = el.querySelector(".search-text")
1513
const popover = Popover.init(el)
16-
17-
const shown = () => {
18-
if (search) {
19-
search.focus();
20-
}
21-
const active = popover.toggleMenu.querySelector('.dropdown-item.active');
22-
if (active) {
23-
scrollIntoView(el, active);
24-
}
25-
}
26-
27-
const keydown = e => {
28-
const menu = popover.toggleMenu;
29-
const key = e.key;
30-
if (key === "Enter" || key === 'NumpadEnter') {
31-
if (popover.isPopover) {
32-
popover.hide();
33-
}
34-
else {
35-
menu.classList.remove('show');
36-
}
37-
const activeItem = menu.querySelector('.active');
38-
let index = indexOf(menu, activeItem)
39-
invoke.invokeMethodAsync(confirmMethodCallback, index)
40-
}
41-
else if (key === 'ArrowUp' || key === 'ArrowDown') {
42-
e.preventDefault();
43-
44-
if (menu.querySelector('.dropdown-virtual')) {
45-
return;
46-
}
47-
48-
const items = [...menu.querySelectorAll('.dropdown-item:not(.disabled)')];
49-
if (items.length > 0) {
50-
let current = menu.querySelector('.active');
51-
if (current !== null) {
52-
current.classList.remove('active');
53-
}
54-
55-
let index = current === null ? -1 : items.indexOf(current);
56-
index = key === 'ArrowUp' ? index - 1 : index + 1;
57-
if (index < 0) {
58-
index = items.length - 1;
59-
}
60-
else if (index > items.length - 1) {
61-
index = 0;
62-
}
63-
current = items[index];
64-
current.classList.add('active');
65-
scrollIntoView(el, current);
66-
}
67-
}
68-
}
69-
70-
if (popover.isPopover) {
71-
EventHandler.on(el, 'shown.bs.popover', shown);
72-
}
73-
else {
74-
EventHandler.on(el, 'shown.bs.dropdown', shown);
75-
}
76-
7714
const input = el.querySelector(`#${id}_input`);
78-
EventHandler.on(input, 'keydown', keydown)
79-
80-
const onSearch = debounce(async v => {
81-
search.parentElement.classList.add('l');
82-
await invoke.invokeMethodAsync(searchMethodCallback, v);
83-
search.parentElement.classList.remove('l');
84-
});
85-
if (search) {
86-
Input.composition(search, onSearch);
87-
EventHandler.on(search, 'keydown', keydown);
88-
}
89-
9015
const select = {
91-
el,
16+
el, invoke, options,
9217
search,
18+
keydownEl: [search, input],
9319
popover
9420
}
9521
Data.set(id, select);
22+
23+
registerSelect(select);
9624
}
9725

9826
export function show(id) {
@@ -122,24 +50,6 @@ export function dispose(id) {
12250
Data.remove(id)
12351

12452
if (select) {
125-
const { el, popover, search } = select
126-
EventHandler.off(el, 'shown.bs.dropdown')
127-
EventHandler.off(el, 'keydown');
128-
Popover.dispose(popover);
129-
130-
if (search) {
131-
Input.dispose(search);
132-
EventHandler.off(search, 'keydown');
133-
}
53+
unregisterSelect(select);
13454
}
13555
}
136-
137-
const indexOf = (el, element) => {
138-
const items = el.querySelectorAll('.dropdown-item')
139-
return Array.prototype.indexOf.call(items, element)
140-
}
141-
142-
const scrollIntoView = (el, item) => {
143-
const behavior = el.getAttribute('data-bb-scroll-behavior') ?? 'smooth';
144-
item.scrollIntoView({ behavior: behavior, block: "nearest", inline: "start" });
145-
}

src/BootstrapBlazor/wwwroot/modules/base-select.js

Lines changed: 81 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,19 @@
22
import Input from "./input.js"
33
import EventHandler from "./event-handler.js"
44

5-
export function registerSearch(el, options) {
6-
Input.composition(search, onSearch);
7-
EventHandler.on(search, 'keydown', keydown);
8-
9-
if (popover.isPopover) {
10-
EventHandler.on(el, 'shown.bs.popover', shown);
11-
}
12-
else {
13-
EventHandler.on(el, 'shown.bs.dropdown', shown);
14-
}
5+
export function registerSelect(select) {
6+
initSearchHandler(select);
7+
initKeydownHandler(select);
8+
initShownHandler(select);
159
}
1610

17-
export function unregisterSearch(el) {
11+
export function unregisterSelect(select) {
12+
const { el, search, keydownEl, popover } = select;
1813
Input.dispose(search);
19-
EventHandler.off(search, 'keydown');
2014

15+
keydownEl.forEach(ele => {
16+
EventHandler.off(ele, 'keydown');
17+
})
2118
if (popover.isPopover) {
2219
EventHandler.off(el, 'shown.bs.popover');
2320
}
@@ -26,62 +23,86 @@ export function unregisterSearch(el) {
2623
}
2724
}
2825

29-
const onSearch = debounce(async v => {
30-
search.parentElement.classList.add('l');
31-
await invoke.invokeMethodAsync('TriggerOnSearch', v);
32-
search.parentElement.classList.remove('l');
33-
});
26+
const initKeydownHandler = select => {
27+
const { el, invoke, options, keydownEl, popover } = select;
28+
const { confirmMethodCallback } = options;
29+
const keydown = e => {
30+
const menu = popover.toggleMenu;
31+
const key = e.key;
32+
if (key === "Enter" || key === 'NumpadEnter') {
33+
if (popover.isPopover) {
34+
popover.hide();
35+
}
36+
else {
37+
menu.classList.remove('show');
38+
}
39+
const activeItem = menu.querySelector('.active');
40+
let index = indexOf(menu, activeItem)
41+
invoke.invokeMethodAsync(confirmMethodCallback, index)
42+
}
43+
else if (key === 'ArrowUp' || key === 'ArrowDown') {
44+
e.preventDefault();
3445

35-
const shown = () => {
36-
if (search) {
37-
search.focus();
38-
}
39-
const active = popover.toggleMenu.querySelector('.dropdown-item.active');
40-
if (active) {
41-
scrollIntoView(el, active);
42-
}
43-
}
46+
if (menu.querySelector('.dropdown-virtual')) {
47+
return;
48+
}
4449

45-
const keydown = e => {
46-
const menu = popover.toggleMenu;
47-
const key = e.key;
48-
if (key === "Enter" || key === 'NumpadEnter') {
49-
if (popover.isPopover) {
50-
popover.hide();
51-
}
52-
else {
53-
menu.classList.remove('show');
50+
const items = [...menu.querySelectorAll('.dropdown-item:not(.disabled)')];
51+
if (items.length > 0) {
52+
let current = menu.querySelector('.active');
53+
if (current !== null) {
54+
current.classList.remove('active');
55+
}
56+
57+
let index = current === null ? -1 : items.indexOf(current);
58+
index = key === 'ArrowUp' ? index - 1 : index + 1;
59+
if (index < 0) {
60+
index = items.length - 1;
61+
}
62+
else if (index > items.length - 1) {
63+
index = 0;
64+
}
65+
current = items[index];
66+
current.classList.add('active');
67+
scrollIntoView(el, current);
68+
}
5469
}
55-
const activeItem = menu.querySelector('.active');
56-
let index = indexOf(menu, activeItem)
57-
invoke.invokeMethodAsync(confirmMethodCallback, index)
5870
}
59-
else if (key === 'ArrowUp' || key === 'ArrowDown') {
60-
e.preventDefault();
6171

62-
if (menu.querySelector('.dropdown-virtual')) {
63-
return;
64-
}
72+
keydownEl.forEach(ele => {
73+
EventHandler.on(ele, 'keydown', keydown);
74+
});
75+
}
6576

66-
const items = [...menu.querySelectorAll('.dropdown-item:not(.disabled)')];
67-
if (items.length > 0) {
68-
let current = menu.querySelector('.active');
69-
if (current !== null) {
70-
current.classList.remove('active');
71-
}
77+
const initSearchHandler = select => {
78+
const { search, invoke, options } = select;
79+
const { searchMethodCallback } = options;
80+
const onSearch = debounce(async v => {
81+
search.parentElement.classList.add('l');
82+
await invoke.invokeMethodAsync(searchMethodCallback, v);
83+
search.parentElement.classList.remove('l');
84+
});
7285

73-
let index = current === null ? -1 : items.indexOf(current);
74-
index = key === 'ArrowUp' ? index - 1 : index + 1;
75-
if (index < 0) {
76-
index = items.length - 1;
77-
}
78-
else if (index > items.length - 1) {
79-
index = 0;
80-
}
81-
current = items[index];
82-
current.classList.add('active');
83-
scrollIntoView(el, current);
86+
Input.composition(search, onSearch);
87+
}
88+
89+
const initShownHandler = select => {
90+
const { el, search, popover } = select;
91+
const shown = () => {
92+
if (search) {
93+
search.focus();
8494
}
95+
const active = popover.toggleMenu.querySelector('.dropdown-item.active');
96+
if (active) {
97+
scrollIntoView(el, active);
98+
}
99+
}
100+
101+
if (popover.isPopover) {
102+
EventHandler.on(el, 'shown.bs.popover', shown);
103+
}
104+
else {
105+
EventHandler.on(el, 'shown.bs.dropdown', shown);
85106
}
86107
}
87108

0 commit comments

Comments
 (0)