@primer/components 0.0.0-2021109221452 → 0.0.0-2021109223232

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 (175) hide show
  1. package/CHANGELOG.md +5 -3
  2. package/dist/browser.esm.js +178 -178
  3. package/dist/browser.esm.js.map +1 -1
  4. package/dist/browser.umd.js +179 -179
  5. package/dist/browser.umd.js.map +1 -1
  6. package/lib/ActionList/index.js +23 -12
  7. package/lib/AnchoredOverlay/index.js +12 -4
  8. package/lib/Autocomplete/index.js +14 -7
  9. package/lib/Button/index.js +70 -21
  10. package/lib/DropdownMenu/index.js +20 -6
  11. package/lib/DropdownStyles.js +26 -18
  12. package/lib/FilteredActionList/index.js +12 -4
  13. package/lib/Overlay.js +3 -1
  14. package/lib/Pagination/index.js +12 -6
  15. package/lib/Portal/Portal.js +3 -2
  16. package/lib/Portal/index.js +16 -5
  17. package/lib/SelectMenu/hooks/useKeyboardNav.js +96 -80
  18. package/lib/SelectMenu/index.js +14 -7
  19. package/lib/SelectPanel/index.js +12 -4
  20. package/lib/Token/index.js +30 -11
  21. package/lib/behaviors/anchoredPosition.js +234 -205
  22. package/lib/behaviors/focusTrap.js +157 -121
  23. package/lib/behaviors/focusZone.js +509 -434
  24. package/lib/behaviors/scrollIntoViewingArea.js +35 -18
  25. package/lib/constants.js +43 -39
  26. package/lib/hooks/index.js +60 -16
  27. package/lib/hooks/useAnchoredPosition.js +40 -31
  28. package/lib/hooks/useCombinedRefs.d.ts +2 -2
  29. package/lib/hooks/useCombinedRefs.js +35 -46
  30. package/lib/hooks/useDialog.js +96 -72
  31. package/lib/hooks/useFocusTrap.js +60 -43
  32. package/lib/hooks/useFocusZone.js +50 -54
  33. package/lib/hooks/useOnEscapePress.js +36 -25
  34. package/lib/hooks/useOpenAndCloseFocus.js +34 -22
  35. package/lib/hooks/useProvidedRefOrCreate.js +14 -10
  36. package/lib/hooks/useProvidedStateOrCreate.js +16 -13
  37. package/lib/hooks/useRenderForcingRef.js +17 -13
  38. package/lib/hooks/useResizeObserver.js +18 -15
  39. package/lib/hooks/useSafeTimeout.js +30 -22
  40. package/lib/hooks/useScrollFlash.js +23 -16
  41. package/lib/index.js +636 -161
  42. package/lib/polyfills/eventListenerSignal.js +45 -37
  43. package/lib/sx.js +14 -7
  44. package/lib/theme-preval.js +2945 -64
  45. package/lib/theme.js +12 -3
  46. package/lib/utils/iterateFocusableElements.js +85 -63
  47. package/lib/utils/theme.js +47 -33
  48. package/lib/utils/types/AriaRole.js +1 -2
  49. package/lib/utils/types/ComponentProps.js +1 -2
  50. package/lib/utils/types/Flatten.js +1 -2
  51. package/lib/utils/types/KeyPaths.js +1 -2
  52. package/lib/utils/types/MandateProps.js +1 -16
  53. package/lib/utils/types/Merge.js +1 -2
  54. package/lib/utils/types/index.js +69 -16
  55. package/lib/utils/uniqueId.js +8 -5
  56. package/lib/utils/useIsomorphicLayoutEffect.d.ts +3 -0
  57. package/lib/utils/useIsomorphicLayoutEffect.js +12 -0
  58. package/lib/utils/userAgent.js +12 -8
  59. package/lib-esm/Overlay.js +2 -1
  60. package/lib-esm/Portal/Portal.js +2 -1
  61. package/lib-esm/hooks/useAnchoredPosition.js +2 -1
  62. package/lib-esm/hooks/useCombinedRefs.d.ts +2 -2
  63. package/lib-esm/hooks/useCombinedRefs.js +3 -2
  64. package/lib-esm/hooks/useResizeObserver.js +2 -2
  65. package/lib-esm/utils/useIsomorphicLayoutEffect.d.ts +3 -0
  66. package/lib-esm/utils/useIsomorphicLayoutEffect.js +3 -0
  67. package/package.json +2 -3
  68. package/lib/ActionList/Divider.jsx +0 -29
  69. package/lib/ActionList/Group.jsx +0 -23
  70. package/lib/ActionList/Header.jsx +0 -66
  71. package/lib/ActionList/Item.jsx +0 -301
  72. package/lib/ActionList/List.jsx +0 -138
  73. package/lib/ActionMenu.jsx +0 -73
  74. package/lib/AnchoredOverlay/AnchoredOverlay.jsx +0 -100
  75. package/lib/Autocomplete/Autocomplete.jsx +0 -100
  76. package/lib/Autocomplete/AutocompleteContext.jsx +0 -5
  77. package/lib/Autocomplete/AutocompleteInput.jsx +0 -113
  78. package/lib/Autocomplete/AutocompleteMenu.jsx +0 -190
  79. package/lib/Autocomplete/AutocompleteOverlay.jsx +0 -55
  80. package/lib/Avatar.jsx +0 -34
  81. package/lib/AvatarPair.jsx +0 -29
  82. package/lib/AvatarStack.jsx +0 -151
  83. package/lib/BaseStyles.jsx +0 -65
  84. package/lib/BorderBox.jsx +0 -18
  85. package/lib/Box.jsx +0 -10
  86. package/lib/BranchName.jsx +0 -20
  87. package/lib/Breadcrumbs.jsx +0 -74
  88. package/lib/Button/Button.jsx +0 -60
  89. package/lib/Button/ButtonBase.jsx +0 -36
  90. package/lib/Button/ButtonClose.jsx +0 -55
  91. package/lib/Button/ButtonDanger.jsx +0 -63
  92. package/lib/Button/ButtonGroup.jsx +0 -55
  93. package/lib/Button/ButtonInvisible.jsx +0 -52
  94. package/lib/Button/ButtonOutline.jsx +0 -63
  95. package/lib/Button/ButtonPrimary.jsx +0 -62
  96. package/lib/Button/ButtonStyles.jsx +0 -37
  97. package/lib/Button/ButtonTableList.jsx +0 -49
  98. package/lib/Caret.jsx +0 -93
  99. package/lib/CircleBadge.jsx +0 -43
  100. package/lib/CircleOcticon.jsx +0 -21
  101. package/lib/CounterLabel.jsx +0 -44
  102. package/lib/Details.jsx +0 -21
  103. package/lib/Dialog/ConfirmationDialog.jsx +0 -146
  104. package/lib/Dialog/Dialog.jsx +0 -273
  105. package/lib/Dialog.jsx +0 -131
  106. package/lib/Dropdown.jsx +0 -134
  107. package/lib/DropdownMenu/DropdownButton.jsx +0 -14
  108. package/lib/DropdownMenu/DropdownMenu.jsx +0 -70
  109. package/lib/FilterList.jsx +0 -63
  110. package/lib/FilteredActionList/FilteredActionList.jsx +0 -100
  111. package/lib/FilteredSearch.jsx +0 -29
  112. package/lib/Flash.jsx +0 -70
  113. package/lib/Flex.jsx +0 -15
  114. package/lib/FormGroup.jsx +0 -25
  115. package/lib/Grid.jsx +0 -15
  116. package/lib/Header.jsx +0 -90
  117. package/lib/Heading.jsx +0 -21
  118. package/lib/Label.jsx +0 -84
  119. package/lib/LabelGroup.jsx +0 -19
  120. package/lib/Link.jsx +0 -38
  121. package/lib/Overlay.jsx +0 -155
  122. package/lib/Pagehead.jsx +0 -18
  123. package/lib/Pagination/Pagination.jsx +0 -163
  124. package/lib/Pagination/model.jsx +0 -174
  125. package/lib/PointerBox.jsx +0 -25
  126. package/lib/Popover.jsx +0 -210
  127. package/lib/Portal/Portal.jsx +0 -78
  128. package/lib/Position.jsx +0 -46
  129. package/lib/ProgressBar.jsx +0 -39
  130. package/lib/SelectMenu/SelectMenu.jsx +0 -114
  131. package/lib/SelectMenu/SelectMenuContext.jsx +0 -5
  132. package/lib/SelectMenu/SelectMenuDivider.jsx +0 -43
  133. package/lib/SelectMenu/SelectMenuFilter.jsx +0 -59
  134. package/lib/SelectMenu/SelectMenuFooter.jsx +0 -46
  135. package/lib/SelectMenu/SelectMenuHeader.jsx +0 -44
  136. package/lib/SelectMenu/SelectMenuItem.jsx +0 -143
  137. package/lib/SelectMenu/SelectMenuList.jsx +0 -60
  138. package/lib/SelectMenu/SelectMenuLoadingAnimation.jsx +0 -21
  139. package/lib/SelectMenu/SelectMenuModal.jsx +0 -119
  140. package/lib/SelectMenu/SelectMenuTab.jsx +0 -93
  141. package/lib/SelectMenu/SelectMenuTabPanel.jsx +0 -43
  142. package/lib/SelectMenu/SelectMenuTabs.jsx +0 -58
  143. package/lib/SelectPanel/SelectPanel.jsx +0 -105
  144. package/lib/SideNav.jsx +0 -177
  145. package/lib/Spinner.jsx +0 -35
  146. package/lib/StateLabel.jsx +0 -89
  147. package/lib/StyledOcticon.jsx +0 -20
  148. package/lib/SubNav.jsx +0 -104
  149. package/lib/TabNav.jsx +0 -60
  150. package/lib/Text.jsx +0 -14
  151. package/lib/TextInput.jsx +0 -23
  152. package/lib/TextInputWithTokens.jsx +0 -218
  153. package/lib/ThemeProvider.jsx +0 -130
  154. package/lib/Timeline.jsx +0 -124
  155. package/lib/Token/AvatarToken.jsx +0 -54
  156. package/lib/Token/IssueLabelToken.jsx +0 -125
  157. package/lib/Token/Token.jsx +0 -103
  158. package/lib/Token/TokenBase.jsx +0 -88
  159. package/lib/Token/_RemoveTokenButton.jsx +0 -108
  160. package/lib/Token/_TokenTextContainer.jsx +0 -49
  161. package/lib/Tooltip.jsx +0 -246
  162. package/lib/Truncate.jsx +0 -27
  163. package/lib/UnderlineNav.jsx +0 -90
  164. package/lib/_TextInputWrapper.jsx +0 -114
  165. package/lib/_UnstyledTextInput.jsx +0 -22
  166. package/lib/hooks/useDetails.jsx +0 -39
  167. package/lib/hooks/useOnOutsideClick.jsx +0 -61
  168. package/lib/hooks/useOverlay.jsx +0 -15
  169. package/lib/utils/deprecate.jsx +0 -59
  170. package/lib/utils/isNumeric.jsx +0 -7
  171. package/lib/utils/ssr.jsx +0 -6
  172. package/lib/utils/test-deprecations.jsx +0 -20
  173. package/lib/utils/test-helpers.jsx +0 -8
  174. package/lib/utils/test-matchers.jsx +0 -100
  175. package/lib/utils/testing.jsx +0 -206
@@ -1,25 +1,34 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.focusTrap = void 0;
4
- const iterateFocusableElements_1 = require("../utils/iterateFocusableElements");
5
- const eventListenerSignal_1 = require("../polyfills/eventListenerSignal");
6
- eventListenerSignal_1.polyfill();
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.focusTrap = focusTrap;
7
+
8
+ var _iterateFocusableElements = require("../utils/iterateFocusableElements");
9
+
10
+ var _eventListenerSignal = require("../polyfills/eventListenerSignal");
11
+
12
+ (0, _eventListenerSignal.polyfill)();
7
13
  const suspendedTrapStack = [];
8
14
  let activeTrap = undefined;
15
+
9
16
  function tryReactivate() {
10
- const trapToReactivate = suspendedTrapStack.pop();
11
- if (trapToReactivate) {
12
- focusTrap(trapToReactivate.container, trapToReactivate.initialFocus, trapToReactivate.originalSignal);
13
- }
14
- }
15
- // @todo If AbortController.prototype.follow is ever implemented, that
17
+ const trapToReactivate = suspendedTrapStack.pop();
18
+
19
+ if (trapToReactivate) {
20
+ focusTrap(trapToReactivate.container, trapToReactivate.initialFocus, trapToReactivate.originalSignal);
21
+ }
22
+ } // @todo If AbortController.prototype.follow is ever implemented, that
16
23
  // could replace this function. @see https://github.com/whatwg/dom/issues/920
24
+
25
+
17
26
  function followSignal(signal) {
18
- const controller = new AbortController();
19
- signal.addEventListener('abort', () => {
20
- controller.abort();
21
- });
22
- return controller;
27
+ const controller = new AbortController();
28
+ signal.addEventListener('abort', () => {
29
+ controller.abort();
30
+ });
31
+ return controller;
23
32
  }
24
33
  /**
25
34
  * Returns the first focusable child of `container`. If `lastChild` is true,
@@ -27,117 +36,144 @@ function followSignal(signal) {
27
36
  * @param container
28
37
  * @param lastChild
29
38
  */
39
+
40
+
30
41
  function getFocusableChild(container, lastChild = false) {
31
- return iterateFocusableElements_1.iterateFocusableElements(container, { reverse: lastChild, strict: true, onlyTabbable: true }).next().value;
42
+ return (0, _iterateFocusableElements.iterateFocusableElements)(container, {
43
+ reverse: lastChild,
44
+ strict: true,
45
+ onlyTabbable: true
46
+ }).next().value;
32
47
  }
48
+ /**
49
+ * Traps focus within the given container.
50
+ * @param container The container in which to trap focus
51
+ * @returns AbortController - call `.abort()` to disable the focus trap
52
+ */
53
+
54
+
33
55
  function focusTrap(container, initialFocus, abortSignal) {
34
- // Set up an abort controller if a signal was not passed in
35
- const controller = new AbortController();
36
- const signal = abortSignal ?? controller.signal;
37
- container.setAttribute('data-focus-trap', 'active');
38
- let lastFocusedChild = undefined;
39
- // Ensure focus remains in the trap zone by checking that a given recently-focused
40
- // element is inside the trap zone. If it isn't, redirect focus to a suitable
41
- // element within the trap zone. If need to redirect focus and a suitable element
42
- // is not found, focus the container.
43
- function ensureTrapZoneHasFocus(focusedElement) {
44
- if (focusedElement instanceof HTMLElement && document.contains(container)) {
45
- if (container.contains(focusedElement)) {
46
- // If a child of the trap zone was focused, remember it
47
- lastFocusedChild = focusedElement;
48
- return;
49
- }
50
- else {
51
- if (lastFocusedChild && iterateFocusableElements_1.isTabbable(lastFocusedChild) && container.contains(lastFocusedChild)) {
52
- lastFocusedChild.focus();
53
- return;
54
- }
55
- else if (initialFocus && container.contains(initialFocus)) {
56
- initialFocus.focus();
57
- return;
58
- }
59
- else {
60
- // Ensure the container is focusable:
61
- // - Either the container already has a `tabIndex`
62
- // - Or provide a temporary `tabIndex`
63
- const containerNeedsTemporaryTabIndex = container.getAttribute('tabindex') === null;
64
- if (containerNeedsTemporaryTabIndex) {
65
- container.setAttribute('tabindex', '-1');
66
- }
67
- // Focus the container.
68
- container.focus();
69
- // If a temporary `tabIndex` was provided, remove it.
70
- if (containerNeedsTemporaryTabIndex) {
71
- // Once focus has moved from the container to a child within the FocusTrap,
72
- // the container can be made un-refocusable by removing `tabIndex`.
73
- container.addEventListener('blur', () => container.removeAttribute('tabindex'), { once: true });
74
- // NB: If `tabIndex` was removed *before* `blur`, then certain browsers (e.g. Chrome)
75
- // would consider `body` the `activeElement`, and as a result, keyboard navigation
76
- // between children would break, since `body` is outside the `FocusTrap`.
77
- }
78
- return;
79
- }
80
- }
56
+ // Set up an abort controller if a signal was not passed in
57
+ const controller = new AbortController();
58
+ const signal = abortSignal !== null && abortSignal !== void 0 ? abortSignal : controller.signal;
59
+ container.setAttribute('data-focus-trap', 'active');
60
+ let lastFocusedChild = undefined; // Ensure focus remains in the trap zone by checking that a given recently-focused
61
+ // element is inside the trap zone. If it isn't, redirect focus to a suitable
62
+ // element within the trap zone. If need to redirect focus and a suitable element
63
+ // is not found, focus the container.
64
+
65
+ function ensureTrapZoneHasFocus(focusedElement) {
66
+ if (focusedElement instanceof HTMLElement && document.contains(container)) {
67
+ if (container.contains(focusedElement)) {
68
+ // If a child of the trap zone was focused, remember it
69
+ lastFocusedChild = focusedElement;
70
+ return;
71
+ } else {
72
+ if (lastFocusedChild && (0, _iterateFocusableElements.isTabbable)(lastFocusedChild) && container.contains(lastFocusedChild)) {
73
+ lastFocusedChild.focus();
74
+ return;
75
+ } else if (initialFocus && container.contains(initialFocus)) {
76
+ initialFocus.focus();
77
+ return;
78
+ } else {
79
+ // Ensure the container is focusable:
80
+ // - Either the container already has a `tabIndex`
81
+ // - Or provide a temporary `tabIndex`
82
+ const containerNeedsTemporaryTabIndex = container.getAttribute('tabindex') === null;
83
+
84
+ if (containerNeedsTemporaryTabIndex) {
85
+ container.setAttribute('tabindex', '-1');
86
+ } // Focus the container.
87
+
88
+
89
+ container.focus(); // If a temporary `tabIndex` was provided, remove it.
90
+
91
+ if (containerNeedsTemporaryTabIndex) {
92
+ // Once focus has moved from the container to a child within the FocusTrap,
93
+ // the container can be made un-refocusable by removing `tabIndex`.
94
+ container.addEventListener('blur', () => container.removeAttribute('tabindex'), {
95
+ once: true
96
+ }); // NB: If `tabIndex` was removed *before* `blur`, then certain browsers (e.g. Chrome)
97
+ // would consider `body` the `activeElement`, and as a result, keyboard navigation
98
+ // between children would break, since `body` is outside the `FocusTrap`.
99
+ }
100
+
101
+ return;
81
102
  }
103
+ }
82
104
  }
83
- const wrappingController = followSignal(signal);
84
- container.addEventListener('keydown', event => {
85
- if (event.key !== 'Tab' || event.defaultPrevented) {
86
- return;
87
- }
88
- const { target } = event;
89
- const firstFocusableChild = getFocusableChild(container);
90
- const lastFocusableChild = getFocusableChild(container, true);
91
- if (target === firstFocusableChild && event.shiftKey) {
92
- event.preventDefault();
93
- lastFocusableChild?.focus();
94
- }
95
- else if (target === lastFocusableChild && !event.shiftKey) {
96
- event.preventDefault();
97
- firstFocusableChild?.focus();
98
- }
99
- }, { signal: wrappingController.signal });
100
- if (activeTrap) {
101
- const suspendedTrap = activeTrap;
102
- activeTrap.container.setAttribute('data-focus-trap', 'suspended');
103
- activeTrap.controller.abort();
104
- suspendedTrapStack.push(suspendedTrap);
105
+ }
106
+
107
+ const wrappingController = followSignal(signal);
108
+ container.addEventListener('keydown', event => {
109
+ if (event.key !== 'Tab' || event.defaultPrevented) {
110
+ return;
105
111
  }
106
- // When this trap is canceled, either by the user or by us for suspension
107
- wrappingController.signal.addEventListener('abort', () => {
108
- activeTrap = undefined;
109
- });
110
- // Only when user-canceled
111
- signal.addEventListener('abort', () => {
112
- container.removeAttribute('data-focus-trap');
113
- const suspendedTrapIndex = suspendedTrapStack.findIndex(t => t.container === container);
114
- if (suspendedTrapIndex >= 0) {
115
- suspendedTrapStack.splice(suspendedTrapIndex, 1);
116
- }
117
- tryReactivate();
118
- });
119
- // Prevent focus leaving the trap container
120
- document.addEventListener('focus', event => {
121
- ensureTrapZoneHasFocus(event.target);
122
- },
123
- // use capture to ensure we get all events. focus events do not bubble
124
- { signal: wrappingController.signal, capture: true });
125
- // focus the first element
126
- ensureTrapZoneHasFocus(document.activeElement);
127
- activeTrap = {
128
- container,
129
- controller: wrappingController,
130
- initialFocus,
131
- originalSignal: signal
132
- };
133
- // If we are activating a focus trap for a container that was previously
134
- // suspended, just remove it from the suspended list.
112
+
113
+ const {
114
+ target
115
+ } = event;
116
+ const firstFocusableChild = getFocusableChild(container);
117
+ const lastFocusableChild = getFocusableChild(container, true);
118
+
119
+ if (target === firstFocusableChild && event.shiftKey) {
120
+ event.preventDefault();
121
+ lastFocusableChild === null || lastFocusableChild === void 0 ? void 0 : lastFocusableChild.focus();
122
+ } else if (target === lastFocusableChild && !event.shiftKey) {
123
+ event.preventDefault();
124
+ firstFocusableChild === null || firstFocusableChild === void 0 ? void 0 : firstFocusableChild.focus();
125
+ }
126
+ }, {
127
+ signal: wrappingController.signal
128
+ });
129
+
130
+ if (activeTrap) {
131
+ const suspendedTrap = activeTrap;
132
+ activeTrap.container.setAttribute('data-focus-trap', 'suspended');
133
+ activeTrap.controller.abort();
134
+ suspendedTrapStack.push(suspendedTrap);
135
+ } // When this trap is canceled, either by the user or by us for suspension
136
+
137
+
138
+ wrappingController.signal.addEventListener('abort', () => {
139
+ activeTrap = undefined;
140
+ }); // Only when user-canceled
141
+
142
+ signal.addEventListener('abort', () => {
143
+ container.removeAttribute('data-focus-trap');
135
144
  const suspendedTrapIndex = suspendedTrapStack.findIndex(t => t.container === container);
145
+
136
146
  if (suspendedTrapIndex >= 0) {
137
- suspendedTrapStack.splice(suspendedTrapIndex, 1);
138
- }
139
- if (!abortSignal) {
140
- return controller;
147
+ suspendedTrapStack.splice(suspendedTrapIndex, 1);
141
148
  }
142
- }
143
- exports.focusTrap = focusTrap;
149
+
150
+ tryReactivate();
151
+ }); // Prevent focus leaving the trap container
152
+
153
+ document.addEventListener('focus', event => {
154
+ ensureTrapZoneHasFocus(event.target);
155
+ }, // use capture to ensure we get all events. focus events do not bubble
156
+ {
157
+ signal: wrappingController.signal,
158
+ capture: true
159
+ }); // focus the first element
160
+
161
+ ensureTrapZoneHasFocus(document.activeElement);
162
+ activeTrap = {
163
+ container,
164
+ controller: wrappingController,
165
+ initialFocus,
166
+ originalSignal: signal
167
+ }; // If we are activating a focus trap for a container that was previously
168
+ // suspended, just remove it from the suspended list.
169
+
170
+ const suspendedTrapIndex = suspendedTrapStack.findIndex(t => t.container === container);
171
+
172
+ if (suspendedTrapIndex >= 0) {
173
+ suspendedTrapStack.splice(suspendedTrapIndex, 1);
174
+ }
175
+
176
+ if (!abortSignal) {
177
+ return controller;
178
+ }
179
+ }