@primer/behaviors 0.0.0-20220188453 → 0.0.0-2022019163715

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.
Files changed (78) hide show
  1. package/dist/cjs/anchored-position.d.ts +15 -0
  2. package/dist/cjs/anchored-position.js +210 -0
  3. package/dist/cjs/focus-trap.d.ts +2 -0
  4. package/dist/cjs/focus-trap.js +111 -0
  5. package/dist/cjs/focus-zone.d.ts +32 -0
  6. package/dist/cjs/focus-zone.js +410 -0
  7. package/{lib-esm → dist/cjs}/index.d.ts +0 -0
  8. package/dist/cjs/index.js +16 -0
  9. package/{lib-esm → dist/cjs}/polyfills/event-listener-signal.d.ts +0 -0
  10. package/dist/cjs/polyfills/event-listener-signal.js +44 -0
  11. package/{lib-esm → dist/cjs}/scroll-into-view.d.ts +0 -0
  12. package/dist/cjs/scroll-into-view.js +21 -0
  13. package/{lib-esm → dist/cjs}/utils/index.d.ts +0 -0
  14. package/dist/cjs/utils/index.js +15 -0
  15. package/dist/cjs/utils/iterate-focusable-elements.d.ts +8 -0
  16. package/dist/cjs/utils/iterate-focusable-elements.js +63 -0
  17. package/{lib-esm → dist/cjs}/utils/unique-id.d.ts +0 -0
  18. package/dist/cjs/utils/unique-id.js +8 -0
  19. package/{lib-esm → dist/cjs}/utils/user-agent.d.ts +0 -0
  20. package/dist/cjs/utils/user-agent.js +11 -0
  21. package/dist/esm/anchored-position.d.ts +15 -0
  22. package/dist/esm/anchored-position.js +206 -0
  23. package/dist/esm/focus-trap.d.ts +2 -0
  24. package/dist/esm/focus-trap.js +107 -0
  25. package/dist/esm/focus-zone.d.ts +32 -0
  26. package/dist/esm/focus-zone.js +406 -0
  27. package/{lib → dist/esm}/index.d.ts +0 -0
  28. package/{lib-esm → dist/esm}/index.js +1 -1
  29. package/{lib → dist/esm}/polyfills/event-listener-signal.d.ts +0 -0
  30. package/dist/esm/polyfills/event-listener-signal.js +40 -0
  31. package/{lib → dist/esm}/scroll-into-view.d.ts +0 -0
  32. package/dist/esm/scroll-into-view.js +17 -0
  33. package/{lib → dist/esm}/utils/index.d.ts +0 -0
  34. package/{lib-esm → dist/esm}/utils/index.js +1 -1
  35. package/dist/esm/utils/iterate-focusable-elements.d.ts +8 -0
  36. package/dist/esm/utils/iterate-focusable-elements.js +57 -0
  37. package/{lib → dist/esm}/utils/unique-id.d.ts +0 -0
  38. package/dist/esm/utils/unique-id.js +4 -0
  39. package/{lib → dist/esm}/utils/user-agent.d.ts +0 -0
  40. package/dist/esm/utils/user-agent.js +7 -0
  41. package/package.json +18 -35
  42. package/utils/package.json +7 -0
  43. package/lib/__tests__/anchored-position.test.js +0 -388
  44. package/lib/__tests__/focus-trap.test.js +0 -234
  45. package/lib/__tests__/focus-zone.test.js +0 -570
  46. package/lib/__tests__/iterate-focusable-elements.test.js +0 -55
  47. package/lib/__tests__/scroll-into-view.test.js +0 -245
  48. package/lib/anchored-position.d.ts +0 -89
  49. package/lib/anchored-position.js +0 -316
  50. package/lib/focus-trap.d.ts +0 -12
  51. package/lib/focus-trap.js +0 -179
  52. package/lib/focus-zone.d.ts +0 -137
  53. package/lib/focus-zone.js +0 -578
  54. package/lib/index.js +0 -57
  55. package/lib/polyfills/event-listener-signal.js +0 -64
  56. package/lib/scroll-into-view.js +0 -42
  57. package/lib/utils/index.js +0 -44
  58. package/lib/utils/iterate-focusable-elements.d.ts +0 -42
  59. package/lib/utils/iterate-focusable-elements.js +0 -113
  60. package/lib/utils/unique-id.js +0 -12
  61. package/lib/utils/user-agent.js +0 -15
  62. package/lib-esm/__tests__/anchored-position.test.js +0 -386
  63. package/lib-esm/__tests__/focus-trap.test.js +0 -227
  64. package/lib-esm/__tests__/focus-zone.test.js +0 -487
  65. package/lib-esm/__tests__/iterate-focusable-elements.test.js +0 -48
  66. package/lib-esm/__tests__/scroll-into-view.test.js +0 -243
  67. package/lib-esm/anchored-position.d.ts +0 -89
  68. package/lib-esm/anchored-position.js +0 -309
  69. package/lib-esm/focus-trap.d.ts +0 -12
  70. package/lib-esm/focus-trap.js +0 -170
  71. package/lib-esm/focus-zone.d.ts +0 -137
  72. package/lib-esm/focus-zone.js +0 -559
  73. package/lib-esm/polyfills/event-listener-signal.js +0 -57
  74. package/lib-esm/scroll-into-view.js +0 -35
  75. package/lib-esm/utils/iterate-focusable-elements.d.ts +0 -42
  76. package/lib-esm/utils/iterate-focusable-elements.js +0 -102
  77. package/lib-esm/utils/unique-id.js +0 -5
  78. package/lib-esm/utils/user-agent.js +0 -8
@@ -1,227 +0,0 @@
1
- import { fireEvent, render } from '@testing-library/react';
2
- import React from 'react';
3
- import { focusTrap } from '../focus-trap.js'; // Since we use strict `isTabbable` checks within focus trap, we need to mock these
4
- // properties that Jest does not populate.
5
-
6
- beforeAll(() => {
7
- try {
8
- Object.defineProperties(HTMLElement.prototype, {
9
- offsetHeight: {
10
- get: () => 42
11
- },
12
- offsetWidth: {
13
- get: () => 42
14
- },
15
- getClientRects: {
16
- get: () => () => [42]
17
- }
18
- });
19
- } catch {// ignore
20
- }
21
- });
22
- it('Should initially focus the container when activated', () => {
23
- const {
24
- container
25
- } = render( /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("button", {
26
- tabIndex: 0
27
- }, "Bad Apple"), /*#__PURE__*/React.createElement("div", {
28
- id: "trapContainer"
29
- }, /*#__PURE__*/React.createElement("button", {
30
- tabIndex: 0
31
- }, "Apple"), /*#__PURE__*/React.createElement("button", {
32
- tabIndex: 0
33
- }, "Banana"), /*#__PURE__*/React.createElement("button", {
34
- tabIndex: 0
35
- }, "Cantaloupe"))));
36
- const trapContainer = container.querySelector('#trapContainer');
37
- const controller = focusTrap(trapContainer);
38
- expect(document.activeElement).toEqual(trapContainer);
39
- controller.abort();
40
- });
41
- it('Should initially focus the initialFocus element when specified', () => {
42
- const {
43
- container
44
- } = render( /*#__PURE__*/React.createElement("div", {
45
- id: "trapContainer"
46
- }, /*#__PURE__*/React.createElement("button", {
47
- tabIndex: 0
48
- }, "Apple"), /*#__PURE__*/React.createElement("button", {
49
- tabIndex: 0
50
- }, "Banana"), /*#__PURE__*/React.createElement("button", {
51
- tabIndex: 0
52
- }, "Cantaloupe")));
53
- const trapContainer = container.querySelector('#trapContainer');
54
- const secondButton = trapContainer.querySelectorAll('button')[1];
55
- const controller = focusTrap(trapContainer, secondButton);
56
- expect(document.activeElement).toEqual(secondButton);
57
- controller.abort();
58
- });
59
- it('Should prevent focus from exiting the trap, returns focus to previously-focused element', async () => {
60
- const {
61
- container
62
- } = render( /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
63
- id: "trapContainer"
64
- }, /*#__PURE__*/React.createElement("button", {
65
- tabIndex: 0
66
- }, "Apple"), /*#__PURE__*/React.createElement("button", {
67
- tabIndex: 0
68
- }, "Banana"), /*#__PURE__*/React.createElement("button", {
69
- tabIndex: 0
70
- }, "Cantaloupe")), /*#__PURE__*/React.createElement("button", {
71
- id: "durian",
72
- tabIndex: 0
73
- }, "Durian")));
74
- const trapContainer = container.querySelector('#trapContainer');
75
- const secondButton = trapContainer.querySelectorAll('button')[1];
76
- const durianButton = container.querySelector('#durian');
77
- const controller = focusTrap(trapContainer);
78
- focus(durianButton);
79
- expect(document.activeElement).toEqual(trapContainer);
80
- focus(secondButton);
81
- expect(document.activeElement).toEqual(secondButton);
82
- focus(durianButton);
83
- expect(document.activeElement).toEqual(secondButton);
84
- controller.abort();
85
- });
86
- it('Should prevent focus from exiting the trap if there are no focusable children', async () => {
87
- const {
88
- container
89
- } = render( /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
90
- id: "trapContainer"
91
- }), /*#__PURE__*/React.createElement("button", {
92
- id: "durian",
93
- tabIndex: 0
94
- }, "Durian")));
95
- const trapContainer = container.querySelector('#trapContainer');
96
- const durianButton = container.querySelector('#durian');
97
- const controller = focusTrap(trapContainer);
98
- focus(durianButton);
99
- expect(document.activeElement === durianButton).toEqual(false);
100
- controller.abort();
101
- });
102
- it('Should cycle focus from last element to first element and vice-versa', async () => {
103
- const {
104
- container
105
- } = render( /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
106
- id: "trapContainer"
107
- }, /*#__PURE__*/React.createElement("button", {
108
- tabIndex: 0
109
- }, "Apple"), /*#__PURE__*/React.createElement("button", {
110
- tabIndex: 0
111
- }, "Banana"), /*#__PURE__*/React.createElement("button", {
112
- tabIndex: 0
113
- }, "Cantaloupe")), /*#__PURE__*/React.createElement("button", {
114
- id: "durian",
115
- tabIndex: 0
116
- }, "Durian")));
117
- const trapContainer = container.querySelector('#trapContainer');
118
- const firstButton = trapContainer.querySelector('button');
119
- const lastButton = trapContainer.querySelectorAll('button')[2];
120
- const controller = focusTrap(trapContainer);
121
- lastButton.focus();
122
- fireEvent(lastButton, new KeyboardEvent('keydown', {
123
- bubbles: true,
124
- key: 'Tab'
125
- }));
126
- expect(document.activeElement).toEqual(firstButton);
127
- fireEvent(firstButton, new KeyboardEvent('keydown', {
128
- bubbles: true,
129
- key: 'Tab',
130
- shiftKey: true
131
- }));
132
- expect(document.activeElement).toEqual(lastButton);
133
- controller.abort();
134
- });
135
- it('Should should release the trap when the signal is aborted', async () => {
136
- const {
137
- container
138
- } = render( /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
139
- id: "trapContainer"
140
- }, /*#__PURE__*/React.createElement("button", {
141
- tabIndex: 0
142
- }, "Apple"), /*#__PURE__*/React.createElement("button", {
143
- tabIndex: 0
144
- }, "Banana"), /*#__PURE__*/React.createElement("button", {
145
- tabIndex: 0
146
- }, "Cantaloupe")), /*#__PURE__*/React.createElement("button", {
147
- id: "durian",
148
- tabIndex: 0
149
- }, "Durian")));
150
- const trapContainer = container.querySelector('#trapContainer');
151
- const durianButton = container.querySelector('#durian');
152
- const controller = focusTrap(trapContainer);
153
- focus(durianButton);
154
- expect(document.activeElement).toEqual(trapContainer);
155
- controller.abort();
156
- focus(durianButton);
157
- expect(document.activeElement).toEqual(durianButton);
158
- });
159
- it('Should should release the trap when the container is removed from the DOM', async () => {
160
- var _trapContainer$parent;
161
-
162
- const {
163
- container
164
- } = render( /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
165
- id: "trapContainer"
166
- }, /*#__PURE__*/React.createElement("button", {
167
- tabIndex: 0
168
- }, "Apple")), /*#__PURE__*/React.createElement("button", {
169
- id: "durian",
170
- tabIndex: 0
171
- }, "Durian")));
172
- const trapContainer = container.querySelector('#trapContainer');
173
- const durianButton = container.querySelector('#durian');
174
- const firstButton = trapContainer.querySelector('button');
175
- focusTrap(trapContainer);
176
- focus(durianButton);
177
- expect(document.activeElement).toEqual(trapContainer); // empty trap and remove it from the DOM
178
-
179
- trapContainer.removeChild(firstButton);
180
- (_trapContainer$parent = trapContainer.parentElement) === null || _trapContainer$parent === void 0 ? void 0 : _trapContainer$parent.removeChild(trapContainer);
181
- focus(durianButton);
182
- expect(document.activeElement).toEqual(durianButton);
183
- });
184
- it('Should handle dynamic content', async () => {
185
- const {
186
- container
187
- } = render( /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
188
- id: "trapContainer"
189
- }, /*#__PURE__*/React.createElement("button", {
190
- tabIndex: 0
191
- }, "Apple"), /*#__PURE__*/React.createElement("button", {
192
- tabIndex: 0
193
- }, "Banana"), /*#__PURE__*/React.createElement("button", {
194
- tabIndex: 0
195
- }, "Cantaloupe")), /*#__PURE__*/React.createElement("button", {
196
- id: "durian",
197
- tabIndex: 0
198
- }, "Durian")));
199
- const trapContainer = container.querySelector('#trapContainer');
200
- const [firstButton, secondButton, thirdButton] = trapContainer.querySelectorAll('button');
201
- const controller = focusTrap(trapContainer);
202
- secondButton.focus();
203
- trapContainer.removeChild(thirdButton);
204
- fireEvent(secondButton, new KeyboardEvent('keydown', {
205
- bubbles: true,
206
- key: 'Tab'
207
- }));
208
- expect(document.activeElement).toEqual(firstButton);
209
- fireEvent(firstButton, new KeyboardEvent('keydown', {
210
- bubbles: true,
211
- key: 'Tab',
212
- shiftKey: true
213
- }));
214
- expect(document.activeElement).toEqual(secondButton);
215
- controller.abort();
216
- });
217
- /**
218
- * Helper to handle firing the focusin event, which jest/JSDOM does not do for us.
219
- * @param element
220
- */
221
-
222
- function focus(element) {
223
- element.focus();
224
- fireEvent(element, new FocusEvent('focusin', {
225
- bubbles: true
226
- }));
227
- }