Skip to content

Commit 2f1a2b9

Browse files
committed
added Btable filterEvent helper based on BSV2 logic
1 parent b49e5ac commit 2f1a2b9

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import {closest, getAttr, getById, matches, select} from '../../../utils/dom'
2+
3+
const TABLE_TAG_NAMES = ['TD', 'TH', 'TR']
4+
5+
// Filter CSS selector for click/dblclick/etc. events
6+
// If any of these selectors match the clicked element, we ignore the event
7+
export const EVENT_FILTER = [
8+
'a',
9+
'a *', // Include content inside links
10+
'button',
11+
'button *', // Include content inside buttons
12+
'input:not(.disabled):not([disabled])',
13+
'select:not(.disabled):not([disabled])',
14+
'textarea:not(.disabled):not([disabled])',
15+
'[role="link"]',
16+
'[role="link"] *',
17+
'[role="button"]',
18+
'[role="button"] *',
19+
'[tabindex]:not(.disabled):not([disabled])',
20+
].join(',')
21+
22+
// Returns `true` if we should ignore the click/double-click/keypress event
23+
// Avoids having the user need to use `@click.stop` on the form control
24+
export const filterEvent = (event: Event) => {
25+
// Exit early when we don't have a target element
26+
if (!event || !event.target) {
27+
/* istanbul ignore next */
28+
return false
29+
}
30+
const el = event.target as HTMLElement
31+
// Exit early when element is disabled or a table element
32+
if (('disabled' in el && (el as any).disabled) || TABLE_TAG_NAMES.indexOf(el.tagName) !== -1) {
33+
return false
34+
}
35+
// Ignore the click when it was inside a dropdown menu
36+
if (closest('.dropdown-menu', el)) {
37+
return true
38+
}
39+
const label = el.tagName === 'LABEL' ? el : closest('label', el)
40+
// If the label's form control is not disabled then we don't propagate event
41+
// Modern browsers have `label.control` that references the associated input, but IE 11
42+
// does not have this property on the label element, so we resort to DOM lookups
43+
if (label) {
44+
const labelFor = getAttr(label, 'for')
45+
const input = labelFor ? getById(labelFor) : select('input, select, textarea', label)
46+
if (input && !input.disabled) {
47+
return true
48+
}
49+
}
50+
// Otherwise check if the event target matches one of the selectors in the
51+
// event filter (i.e. anchors, non disabled inputs, etc.)
52+
// Return `true` if we should ignore the event
53+
return matches(el, EVENT_FILTER)
54+
}

0 commit comments

Comments
 (0)