-
Notifications
You must be signed in to change notification settings - Fork 131
Expand file tree
/
Copy pathcommon.js
More file actions
93 lines (83 loc) · 2.76 KB
/
Copy pathcommon.js
File metadata and controls
93 lines (83 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
* Toggle a boolean attribute on a HTML element
* @param {HTMLElement} element
* @param {string} attr
*/
export const toggleAttribute = (element, attr) => {
// Return without error if element or attr are missing
if (!element || !attr) return
// Toggle attribute value. Treat no existing attr same as when set to false
const value = element.getAttribute(attr) === 'true' ? 'false' : 'true'
element.setAttribute(attr, value)
}
/**
* Toggle a toggle a class on conditional content for an input based on checked state
* @param {HTMLElement} input input element
* @param {string} className class to toggle
*/
export const toggleConditionalInput = (input, className) => {
// Return without error if input or class are missing
if (!input || !className) return
// If the input has conditional content it had a data-aria-controls attribute
const conditionalId = input.getAttribute('aria-controls')
if (conditionalId) {
// Get the conditional element from the input data-aria-controls attribute
const conditionalElement = document.getElementById(conditionalId)
if (conditionalElement) {
if (input.checked) {
conditionalElement.classList.remove(className)
input.setAttribute('aria-expanded', true)
} else {
conditionalElement.classList.add(className)
input.setAttribute('aria-expanded', false)
}
}
}
}
/**
* Move focus to element
*
* Sets tabindex to -1 to make the element programmatically focusable,
* but removes it on blur as the element doesn't need to be focused again.
*
* Original code taken from GDS (Government Digital Service)
* {@link https://github.com/alphagov/govuk-frontend}
*
* @template {HTMLElement} FocusElement
* @param {FocusElement} $element - HTML element
* @param {object} [options] - Handler options
* @param {function(this: FocusElement): void} [options.onBeforeFocus] - Callback before focus
* @param {function(this: FocusElement): void} [options.onBlur] - Callback on blur
*/
export function setFocus($element, options = {}) {
const isFocusable = $element.getAttribute('tabindex')
if (!isFocusable) {
$element.setAttribute('tabindex', '-1')
}
/**
* Handle element focus
*/
function onFocus() {
$element.removeEventListener('focus', onFocus)
$element.addEventListener('blur', onBlur)
}
/**
* Handle element blur
*/
function onBlur() {
$element.removeEventListener('blur', onBlur)
if (options.onBlur) {
options.onBlur.call($element)
}
if (!isFocusable) {
$element.removeAttribute('tabindex')
}
}
// Add listener to reset element on blur, after focus
$element.addEventListener('focus', onFocus)
// Focus element
if (options.onBeforeFocus) {
options.onBeforeFocus.call($element)
}
$element.focus()
}