@primer/behaviors 1.8.1 → 1.8.2-rc.0fdf228
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/cjs/focus-zone.js +14 -14
- package/dist/cjs/utils/is-editable-element.d.ts +1 -0
- package/dist/cjs/utils/is-editable-element.js +31 -0
- package/dist/esm/focus-zone.mjs +14 -14
- package/dist/esm/utils/is-editable-element.d.ts +1 -0
- package/dist/esm/utils/is-editable-element.mjs +29 -0
- package/package.json +7 -6
package/dist/cjs/focus-zone.js
CHANGED
|
@@ -4,6 +4,7 @@ var eventListenerSignal = require('./polyfills/event-listener-signal.js');
|
|
|
4
4
|
var userAgent = require('./utils/user-agent.js');
|
|
5
5
|
var iterateFocusableElements = require('./utils/iterate-focusable-elements.js');
|
|
6
6
|
var uniqueId = require('./utils/unique-id.js');
|
|
7
|
+
var isEditableElement = require('./utils/is-editable-element.js');
|
|
7
8
|
|
|
8
9
|
eventListenerSignal.polyfill();
|
|
9
10
|
exports.FocusKeys = void 0;
|
|
@@ -82,15 +83,11 @@ function getDirection(keyboardEvent) {
|
|
|
82
83
|
function shouldIgnoreFocusHandling(keyboardEvent, activeElement) {
|
|
83
84
|
const key = keyboardEvent.key;
|
|
84
85
|
const keyLength = [...key].length;
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
if (isTextInput && (keyLength === 1 || key === 'Home' || key === 'End')) {
|
|
86
|
+
const isEditable = isEditableElement.isEditableElement(activeElement);
|
|
87
|
+
if (isEditable && (keyLength === 1 || key === 'Home' || key === 'End')) {
|
|
88
88
|
return true;
|
|
89
89
|
}
|
|
90
90
|
if (activeElement instanceof HTMLSelectElement) {
|
|
91
|
-
if (keyLength === 1) {
|
|
92
|
-
return true;
|
|
93
|
-
}
|
|
94
91
|
if (key === 'ArrowDown' && userAgent.isMacOS() && !keyboardEvent.metaKey) {
|
|
95
92
|
return true;
|
|
96
93
|
}
|
|
@@ -98,20 +95,23 @@ function shouldIgnoreFocusHandling(keyboardEvent, activeElement) {
|
|
|
98
95
|
return true;
|
|
99
96
|
}
|
|
100
97
|
}
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const cursorAtEnd = textInput.selectionStart === textInput.value.length && textInput.selectionEnd === textInput.value.length;
|
|
98
|
+
if (isEditable) {
|
|
99
|
+
const isInputElement = activeElement instanceof HTMLTextAreaElement || activeElement instanceof HTMLInputElement;
|
|
100
|
+
const cursorAtStart = isInputElement && activeElement.selectionStart === 0 && activeElement.selectionEnd === 0;
|
|
101
|
+
const cursorAtEnd = isInputElement &&
|
|
102
|
+
activeElement.selectionStart === activeElement.value.length &&
|
|
103
|
+
activeElement.selectionEnd === activeElement.value.length;
|
|
108
104
|
if (key === 'ArrowLeft' && !cursorAtStart) {
|
|
109
105
|
return true;
|
|
110
106
|
}
|
|
111
107
|
if (key === 'ArrowRight' && !cursorAtEnd) {
|
|
112
108
|
return true;
|
|
113
109
|
}
|
|
114
|
-
|
|
110
|
+
const isContentEditable = activeElement instanceof HTMLElement && activeElement.isContentEditable;
|
|
111
|
+
if (activeElement instanceof HTMLTextAreaElement || isContentEditable) {
|
|
112
|
+
if (key === 'PageUp' || key === 'PageDown') {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
115
|
if (key === 'ArrowUp' && !cursorAtStart) {
|
|
116
116
|
return true;
|
|
117
117
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isEditableElement(target: EventTarget | null): boolean;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const nonEditableInputTypes = new Set([
|
|
4
|
+
'button',
|
|
5
|
+
'checkbox',
|
|
6
|
+
'color',
|
|
7
|
+
'file',
|
|
8
|
+
'hidden',
|
|
9
|
+
'image',
|
|
10
|
+
'radio',
|
|
11
|
+
'range',
|
|
12
|
+
'reset',
|
|
13
|
+
'submit',
|
|
14
|
+
]);
|
|
15
|
+
function isEditableElement(target) {
|
|
16
|
+
var _a, _b;
|
|
17
|
+
if (!(target instanceof HTMLElement))
|
|
18
|
+
return false;
|
|
19
|
+
const name = target.nodeName.toLowerCase();
|
|
20
|
+
const type = (_b = (_a = target.getAttribute('type')) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : 'text';
|
|
21
|
+
const isReadonly = target.ariaReadOnly === 'true' ||
|
|
22
|
+
target.getAttribute('aria-readonly') === 'true' ||
|
|
23
|
+
target.getAttribute('readonly') !== null;
|
|
24
|
+
return ((name === 'select' ||
|
|
25
|
+
name === 'textarea' ||
|
|
26
|
+
(name === 'input' && !nonEditableInputTypes.has(type)) ||
|
|
27
|
+
target.isContentEditable) &&
|
|
28
|
+
!isReadonly);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
exports.isEditableElement = isEditableElement;
|
package/dist/esm/focus-zone.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { polyfill } from './polyfills/event-listener-signal.mjs';
|
|
|
2
2
|
import { isMacOS } from './utils/user-agent.mjs';
|
|
3
3
|
import { iterateFocusableElements } from './utils/iterate-focusable-elements.mjs';
|
|
4
4
|
import { uniqueId } from './utils/unique-id.mjs';
|
|
5
|
+
import { isEditableElement } from './utils/is-editable-element.mjs';
|
|
5
6
|
|
|
6
7
|
polyfill();
|
|
7
8
|
var FocusKeys;
|
|
@@ -80,15 +81,11 @@ function getDirection(keyboardEvent) {
|
|
|
80
81
|
function shouldIgnoreFocusHandling(keyboardEvent, activeElement) {
|
|
81
82
|
const key = keyboardEvent.key;
|
|
82
83
|
const keyLength = [...key].length;
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
if (isTextInput && (keyLength === 1 || key === 'Home' || key === 'End')) {
|
|
84
|
+
const isEditable = isEditableElement(activeElement);
|
|
85
|
+
if (isEditable && (keyLength === 1 || key === 'Home' || key === 'End')) {
|
|
86
86
|
return true;
|
|
87
87
|
}
|
|
88
88
|
if (activeElement instanceof HTMLSelectElement) {
|
|
89
|
-
if (keyLength === 1) {
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
89
|
if (key === 'ArrowDown' && isMacOS() && !keyboardEvent.metaKey) {
|
|
93
90
|
return true;
|
|
94
91
|
}
|
|
@@ -96,20 +93,23 @@ function shouldIgnoreFocusHandling(keyboardEvent, activeElement) {
|
|
|
96
93
|
return true;
|
|
97
94
|
}
|
|
98
95
|
}
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const cursorAtEnd = textInput.selectionStart === textInput.value.length && textInput.selectionEnd === textInput.value.length;
|
|
96
|
+
if (isEditable) {
|
|
97
|
+
const isInputElement = activeElement instanceof HTMLTextAreaElement || activeElement instanceof HTMLInputElement;
|
|
98
|
+
const cursorAtStart = isInputElement && activeElement.selectionStart === 0 && activeElement.selectionEnd === 0;
|
|
99
|
+
const cursorAtEnd = isInputElement &&
|
|
100
|
+
activeElement.selectionStart === activeElement.value.length &&
|
|
101
|
+
activeElement.selectionEnd === activeElement.value.length;
|
|
106
102
|
if (key === 'ArrowLeft' && !cursorAtStart) {
|
|
107
103
|
return true;
|
|
108
104
|
}
|
|
109
105
|
if (key === 'ArrowRight' && !cursorAtEnd) {
|
|
110
106
|
return true;
|
|
111
107
|
}
|
|
112
|
-
|
|
108
|
+
const isContentEditable = activeElement instanceof HTMLElement && activeElement.isContentEditable;
|
|
109
|
+
if (activeElement instanceof HTMLTextAreaElement || isContentEditable) {
|
|
110
|
+
if (key === 'PageUp' || key === 'PageDown') {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
113
|
if (key === 'ArrowUp' && !cursorAtStart) {
|
|
114
114
|
return true;
|
|
115
115
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isEditableElement(target: EventTarget | null): boolean;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const nonEditableInputTypes = new Set([
|
|
2
|
+
'button',
|
|
3
|
+
'checkbox',
|
|
4
|
+
'color',
|
|
5
|
+
'file',
|
|
6
|
+
'hidden',
|
|
7
|
+
'image',
|
|
8
|
+
'radio',
|
|
9
|
+
'range',
|
|
10
|
+
'reset',
|
|
11
|
+
'submit',
|
|
12
|
+
]);
|
|
13
|
+
function isEditableElement(target) {
|
|
14
|
+
var _a, _b;
|
|
15
|
+
if (!(target instanceof HTMLElement))
|
|
16
|
+
return false;
|
|
17
|
+
const name = target.nodeName.toLowerCase();
|
|
18
|
+
const type = (_b = (_a = target.getAttribute('type')) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : 'text';
|
|
19
|
+
const isReadonly = target.ariaReadOnly === 'true' ||
|
|
20
|
+
target.getAttribute('aria-readonly') === 'true' ||
|
|
21
|
+
target.getAttribute('readonly') !== null;
|
|
22
|
+
return ((name === 'select' ||
|
|
23
|
+
name === 'textarea' ||
|
|
24
|
+
(name === 'input' && !nonEditableInputTypes.has(type)) ||
|
|
25
|
+
target.isContentEditable) &&
|
|
26
|
+
!isReadonly);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { isEditableElement };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primer/behaviors",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.2-rc.0fdf228",
|
|
4
4
|
"description": "Shared behaviors for JavaScript components",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/cjs/index.js",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
}
|
|
70
70
|
],
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@arethetypeswrong/cli": "^0.
|
|
72
|
+
"@arethetypeswrong/cli": "^0.18.0",
|
|
73
73
|
"@changesets/changelog-github": "^0.5.0",
|
|
74
74
|
"@changesets/cli": "^2.18.1",
|
|
75
75
|
"@github/prettier-config": "^0.0.6",
|
|
@@ -78,22 +78,23 @@
|
|
|
78
78
|
"@size-limit/preset-small-lib": "^11.1.4",
|
|
79
79
|
"@testing-library/react": "^16.0.0",
|
|
80
80
|
"@testing-library/user-event": "^14.5.1",
|
|
81
|
-
"@types/jest": "^
|
|
82
|
-
"@types/node": "^
|
|
81
|
+
"@types/jest": "^30.0.0",
|
|
82
|
+
"@types/node": "^24.0.10",
|
|
83
83
|
"@types/react": "^19.0.1",
|
|
84
84
|
"esbuild": "^0.25.0",
|
|
85
85
|
"esbuild-jest": "^0.5.0",
|
|
86
86
|
"eslint": "^8.50.0",
|
|
87
87
|
"eslint-plugin-github": "^5.0.0",
|
|
88
88
|
"eslint-plugin-prettier": "^5.0.0",
|
|
89
|
-
"jest": "^
|
|
90
|
-
"jest-environment-jsdom": "^
|
|
89
|
+
"jest": "^30.0.4",
|
|
90
|
+
"jest-environment-jsdom": "^30.0.4",
|
|
91
91
|
"prettier": "^3.0.3",
|
|
92
92
|
"react": "^19.0.0",
|
|
93
93
|
"react-dom": "^19.0.0",
|
|
94
94
|
"rimraf": "^6.0.1",
|
|
95
95
|
"rollup": "^4.18.0",
|
|
96
96
|
"size-limit": "^11.1.4",
|
|
97
|
+
"tslib": "^2.8.1",
|
|
97
98
|
"typescript": "^5.2.2"
|
|
98
99
|
}
|
|
99
100
|
}
|