@primer/components 30.3.0-rc.2010c7d4 → 31.0.0-rc.15aa0a10

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 (180) hide show
  1. package/.eslintrc.json +2 -1
  2. package/.storybook/preview.js +4 -4
  3. package/CHANGELOG.md +12 -2
  4. package/codemods/deprecateUtilityComponents.js +1 -1
  5. package/contributor-docs/adrs/adr-003-prop-norms.md +72 -0
  6. package/dist/browser.esm.js +798 -794
  7. package/dist/browser.esm.js.map +1 -1
  8. package/dist/browser.umd.js +801 -797
  9. package/dist/browser.umd.js.map +1 -1
  10. package/docs/content/Autocomplete.mdx +627 -0
  11. package/docs/content/TextInputTokens.mdx +89 -0
  12. package/docs/content/getting-started.md +1 -1
  13. package/docs/content/overriding-styles.mdx +7 -6
  14. package/docs/content/theming.md +5 -5
  15. package/docs/package-lock.json +288 -511
  16. package/docs/package.json +1 -1
  17. package/docs/src/@primer/gatsby-theme-doctocat/components/hero.js +14 -12
  18. package/docs/src/@primer/gatsby-theme-doctocat/nav.yml +2 -0
  19. package/docs/src/@primer/gatsby-theme-doctocat/primer-components-hero.svg +7 -7
  20. package/lib/ActionList/Item.js +1 -1
  21. package/lib/AnchoredOverlay/AnchoredOverlay.d.ts +2 -1
  22. package/lib/AnchoredOverlay/AnchoredOverlay.js +11 -3
  23. package/lib/Autocomplete/Autocomplete.d.ts +304 -0
  24. package/lib/Autocomplete/Autocomplete.js +145 -0
  25. package/lib/Autocomplete/AutocompleteContext.d.ts +17 -0
  26. package/lib/Autocomplete/AutocompleteContext.js +11 -0
  27. package/lib/Autocomplete/AutocompleteInput.d.ts +292 -0
  28. package/lib/Autocomplete/AutocompleteInput.js +157 -0
  29. package/lib/Autocomplete/AutocompleteMenu.d.ts +72 -0
  30. package/lib/Autocomplete/AutocompleteMenu.js +224 -0
  31. package/lib/Autocomplete/AutocompleteOverlay.d.ts +20 -0
  32. package/lib/Autocomplete/AutocompleteOverlay.js +80 -0
  33. package/lib/Autocomplete/index.d.ts +2 -0
  34. package/lib/Autocomplete/index.js +15 -0
  35. package/lib/BaseStyles.js +1 -1
  36. package/lib/BorderBox.js +1 -1
  37. package/lib/Button/ButtonInvisible.js +1 -1
  38. package/lib/Caret.js +2 -2
  39. package/lib/Dialog.js +1 -1
  40. package/lib/FilteredActionList/FilteredActionList.js +5 -31
  41. package/lib/Flash.js +16 -16
  42. package/lib/Label.js +1 -1
  43. package/lib/Overlay.d.ts +1 -0
  44. package/lib/Overlay.js +3 -1
  45. package/lib/ProgressBar.js +1 -1
  46. package/lib/StateLabel.js +13 -19
  47. package/lib/Token/_RemoveTokenButton.js +1 -1
  48. package/lib/__tests__/Autocomplete.test.d.ts +1 -0
  49. package/lib/__tests__/Autocomplete.test.js +528 -0
  50. package/lib/__tests__/BorderBox.test.js +1 -1
  51. package/lib/__tests__/CircleOcticon.test.js +1 -1
  52. package/lib/__tests__/CounterLabel.test.js +4 -4
  53. package/lib/__tests__/Flash.test.js +4 -4
  54. package/lib/__tests__/Link.test.js +1 -1
  55. package/lib/__tests__/behaviors/scrollIntoViewingArea.test.d.ts +1 -0
  56. package/lib/__tests__/behaviors/scrollIntoViewingArea.test.js +226 -0
  57. package/lib/behaviors/scrollIntoViewingArea.d.ts +1 -0
  58. package/lib/behaviors/scrollIntoViewingArea.js +39 -0
  59. package/lib/hooks/useOpenAndCloseFocus.d.ts +2 -1
  60. package/lib/hooks/useOpenAndCloseFocus.js +7 -2
  61. package/lib/hooks/useOverlay.d.ts +2 -1
  62. package/lib/hooks/useOverlay.js +4 -2
  63. package/lib/index.d.ts +2 -0
  64. package/lib/index.js +8 -0
  65. package/lib/stories/Autocomplete.stories.js +608 -0
  66. package/lib/stories/Dialog.stories.js +3 -3
  67. package/lib/stories/IssueLabelToken.stories.js +1 -1
  68. package/lib/stories/ProfileToken.stories.js +1 -1
  69. package/lib/theme-preval.js +370 -3100
  70. package/lib/utils/testing.d.ts +50 -493
  71. package/lib/utils/types/MandateProps.d.ts +3 -0
  72. package/lib/utils/types/MandateProps.js +1 -0
  73. package/lib/utils/types/index.d.ts +1 -0
  74. package/lib/utils/types/index.js +13 -0
  75. package/lib-esm/ActionList/Item.js +1 -1
  76. package/lib-esm/AnchoredOverlay/AnchoredOverlay.d.ts +2 -1
  77. package/lib-esm/AnchoredOverlay/AnchoredOverlay.js +11 -3
  78. package/lib-esm/Autocomplete/Autocomplete.d.ts +304 -0
  79. package/lib-esm/Autocomplete/Autocomplete.js +123 -0
  80. package/lib-esm/Autocomplete/AutocompleteContext.d.ts +17 -0
  81. package/lib-esm/Autocomplete/AutocompleteContext.js +2 -0
  82. package/lib-esm/Autocomplete/AutocompleteInput.d.ts +292 -0
  83. package/lib-esm/Autocomplete/AutocompleteInput.js +138 -0
  84. package/lib-esm/Autocomplete/AutocompleteMenu.d.ts +72 -0
  85. package/lib-esm/Autocomplete/AutocompleteMenu.js +205 -0
  86. package/lib-esm/Autocomplete/AutocompleteOverlay.d.ts +20 -0
  87. package/lib-esm/Autocomplete/AutocompleteOverlay.js +62 -0
  88. package/lib-esm/Autocomplete/index.d.ts +2 -0
  89. package/lib-esm/Autocomplete/index.js +1 -0
  90. package/lib-esm/BaseStyles.js +1 -1
  91. package/lib-esm/BorderBox.js +1 -1
  92. package/lib-esm/Button/ButtonInvisible.js +1 -1
  93. package/lib-esm/Caret.js +2 -2
  94. package/lib-esm/Dialog.js +1 -1
  95. package/lib-esm/FilteredActionList/FilteredActionList.js +3 -31
  96. package/lib-esm/Flash.js +16 -16
  97. package/lib-esm/Label.js +1 -1
  98. package/lib-esm/Overlay.d.ts +1 -0
  99. package/lib-esm/Overlay.js +3 -1
  100. package/lib-esm/ProgressBar.js +1 -1
  101. package/lib-esm/StateLabel.js +13 -19
  102. package/lib-esm/Token/_RemoveTokenButton.js +1 -1
  103. package/lib-esm/__tests__/Autocomplete.test.d.ts +1 -0
  104. package/lib-esm/__tests__/Autocomplete.test.js +494 -0
  105. package/lib-esm/__tests__/BorderBox.test.js +1 -1
  106. package/lib-esm/__tests__/CircleOcticon.test.js +1 -1
  107. package/lib-esm/__tests__/CounterLabel.test.js +4 -4
  108. package/lib-esm/__tests__/Flash.test.js +4 -4
  109. package/lib-esm/__tests__/Link.test.js +1 -1
  110. package/lib-esm/__tests__/behaviors/scrollIntoViewingArea.test.d.ts +1 -0
  111. package/lib-esm/__tests__/behaviors/scrollIntoViewingArea.test.js +224 -0
  112. package/lib-esm/behaviors/scrollIntoViewingArea.d.ts +1 -0
  113. package/lib-esm/behaviors/scrollIntoViewingArea.js +30 -0
  114. package/lib-esm/hooks/useOpenAndCloseFocus.d.ts +2 -1
  115. package/lib-esm/hooks/useOpenAndCloseFocus.js +7 -2
  116. package/lib-esm/hooks/useOverlay.d.ts +2 -1
  117. package/lib-esm/hooks/useOverlay.js +4 -2
  118. package/lib-esm/index.d.ts +2 -0
  119. package/lib-esm/index.js +1 -0
  120. package/lib-esm/stories/Autocomplete.stories.js +549 -0
  121. package/lib-esm/stories/Dialog.stories.js +3 -3
  122. package/lib-esm/stories/IssueLabelToken.stories.js +1 -1
  123. package/lib-esm/stories/ProfileToken.stories.js +1 -1
  124. package/lib-esm/theme-preval.js +370 -3100
  125. package/lib-esm/utils/testing.d.ts +50 -493
  126. package/lib-esm/utils/types/MandateProps.d.ts +3 -0
  127. package/lib-esm/utils/types/MandateProps.js +1 -0
  128. package/lib-esm/utils/types/index.d.ts +1 -0
  129. package/lib-esm/utils/types/index.js +2 -1
  130. package/package-lock.json +11 -8
  131. package/package.json +3 -3
  132. package/src/ActionList/Item.tsx +1 -1
  133. package/src/AnchoredOverlay/AnchoredOverlay.tsx +14 -3
  134. package/src/Autocomplete/Autocomplete.tsx +103 -0
  135. package/src/Autocomplete/AutocompleteContext.tsx +19 -0
  136. package/src/Autocomplete/AutocompleteInput.tsx +179 -0
  137. package/src/Autocomplete/AutocompleteMenu.tsx +341 -0
  138. package/src/Autocomplete/AutocompleteOverlay.tsx +68 -0
  139. package/src/Autocomplete/index.ts +2 -0
  140. package/src/BaseStyles.tsx +1 -1
  141. package/src/BorderBox.tsx +1 -1
  142. package/src/Button/ButtonInvisible.tsx +7 -2
  143. package/src/Caret.tsx +2 -2
  144. package/src/Dialog.tsx +1 -1
  145. package/src/FilteredActionList/FilteredActionList.tsx +10 -25
  146. package/src/Flash.tsx +16 -16
  147. package/src/Label.tsx +1 -1
  148. package/src/Overlay.tsx +4 -1
  149. package/src/ProgressBar.tsx +1 -1
  150. package/src/StateLabel.tsx +12 -20
  151. package/src/Token/_RemoveTokenButton.tsx +4 -2
  152. package/src/__tests__/Autocomplete.test.tsx +444 -0
  153. package/src/__tests__/BorderBox.test.tsx +1 -1
  154. package/src/__tests__/CircleOcticon.test.tsx +1 -1
  155. package/src/__tests__/CounterLabel.test.tsx +4 -4
  156. package/src/__tests__/Flash.test.tsx +4 -4
  157. package/src/__tests__/Link.test.tsx +1 -1
  158. package/src/__tests__/__snapshots__/AnchoredOverlay.test.tsx.snap +3 -3
  159. package/src/__tests__/__snapshots__/Autocomplete.test.tsx.snap +3414 -0
  160. package/src/__tests__/__snapshots__/Button.test.tsx.snap +9 -1
  161. package/src/__tests__/__snapshots__/ConfirmationDialog.test.tsx.snap +1 -1
  162. package/src/__tests__/__snapshots__/SelectPanel.test.tsx.snap +1 -1
  163. package/src/__tests__/__snapshots__/StateLabel.test.tsx.snap +0 -21
  164. package/src/__tests__/__snapshots__/TextInputWithTokens.test.tsx.snap +16 -16
  165. package/src/__tests__/__snapshots__/Token.test.tsx.snap +34 -34
  166. package/src/__tests__/behaviors/scrollIntoViewingArea.test.ts +195 -0
  167. package/src/behaviors/scrollIntoViewingArea.ts +27 -0
  168. package/src/hooks/useOpenAndCloseFocus.ts +7 -2
  169. package/src/hooks/useOverlay.tsx +4 -2
  170. package/src/index.ts +2 -0
  171. package/src/stories/Autocomplete.stories.tsx +572 -0
  172. package/src/stories/Dialog.stories.tsx +3 -3
  173. package/src/stories/IssueLabelToken.stories.tsx +1 -1
  174. package/src/stories/ProfileToken.stories.tsx +1 -1
  175. package/src/utils/types/MandateProps.ts +19 -0
  176. package/src/utils/types/index.ts +1 -0
  177. package/stats.html +1 -1
  178. package/docs/src/@primer/gatsby-theme-doctocat/components/live-code.js +0 -84
  179. package/docs/src/@primer/gatsby-theme-doctocat/components/nav-dropdown.js +0 -48
  180. package/docs/src/@primer/gatsby-theme-doctocat/components/wrap-page-element.js +0 -25
@@ -0,0 +1,205 @@
1
+ import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
2
+ import { ActionList } from '../ActionList';
3
+ import { useFocusZone } from '../hooks/useFocusZone';
4
+ import { Box, Spinner } from '../';
5
+ import { AutocompleteContext } from './AutocompleteContext';
6
+ import { PlusIcon } from '@primer/octicons-react';
7
+ import { uniqueId } from '../utils/uniqueId';
8
+ import { scrollIntoViewingArea } from '../behaviors/scrollIntoViewingArea';
9
+
10
+ const getDefaultSortFn = isItemSelectedFn => (itemIdA, itemIdB) => isItemSelectedFn(itemIdA) === isItemSelectedFn(itemIdB) ? 0 : isItemSelectedFn(itemIdA) ? -1 : 1;
11
+
12
+ function getDefaultItemFilter(filterValue) {
13
+ return function (item, _i) {
14
+ var _item$text;
15
+
16
+ return Boolean((_item$text = item.text) === null || _item$text === void 0 ? void 0 : _item$text.toLowerCase().startsWith(filterValue.toLowerCase()));
17
+ };
18
+ }
19
+
20
+ function getDefaultOnSelectionChange(setInputValueFn) {
21
+ return function (itemOrItems) {
22
+ const {
23
+ text = ''
24
+ } = Array.isArray(itemOrItems) ? itemOrItems.slice(-1)[0] : itemOrItems;
25
+ setInputValueFn(text);
26
+ };
27
+ }
28
+
29
+ const isItemSelected = (itemId, selectedItemIds) => selectedItemIds.includes(itemId);
30
+
31
+ function getItemById(itemId, items) {
32
+ return items.find(item => item.id === itemId);
33
+ } // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+
35
+
36
+ function AutocompleteMenu(props) {
37
+ const autocompleteContext = useContext(AutocompleteContext);
38
+
39
+ if (autocompleteContext === null) {
40
+ throw new Error('AutocompleteContext returned null values');
41
+ }
42
+
43
+ const {
44
+ activeDescendantRef,
45
+ id,
46
+ inputRef,
47
+ inputValue = '',
48
+ scrollContainerRef,
49
+ setAutocompleteSuggestion,
50
+ setShowMenu,
51
+ setInputValue,
52
+ setIsMenuDirectlyActivated,
53
+ setSelectedItemLength,
54
+ showMenu
55
+ } = autocompleteContext;
56
+ const {
57
+ items,
58
+ selectedItemIds,
59
+ sortOnCloseFn,
60
+ emptyStateText,
61
+ addNewItem,
62
+ loading,
63
+ selectionVariant,
64
+ filterFn,
65
+ 'aria-labelledby': ariaLabelledBy,
66
+ onOpenChange,
67
+ onSelectedChange,
68
+ customScrollContainerRef
69
+ } = props;
70
+ const listContainerRef = useRef(null);
71
+ const [highlightedItem, setHighlightedItem] = useState();
72
+ const [sortedItemIds, setSortedItemIds] = useState(items.map(({
73
+ id: itemId
74
+ }) => itemId));
75
+ const selectableItems = useMemo(() => items.map(selectableItem => {
76
+ return { ...selectableItem,
77
+ role: 'option',
78
+ id: selectableItem.id,
79
+ selected: selectionVariant === 'multiple' ? selectedItemIds.includes(selectableItem.id) : undefined,
80
+ onAction: item => {
81
+ const otherSelectedItemIds = selectedItemIds.filter(selectedItemId => selectedItemId !== item.id);
82
+ const newSelectedItemIds = selectedItemIds.includes(item.id) ? otherSelectedItemIds : [...otherSelectedItemIds, item.id];
83
+ const onSelectedChangeFn = onSelectedChange ? onSelectedChange : getDefaultOnSelectionChange(setInputValue);
84
+ onSelectedChangeFn(newSelectedItemIds.map(newSelectedItemId => getItemById(newSelectedItemId, items)));
85
+
86
+ if (selectionVariant === 'multiple') {
87
+ setInputValue('');
88
+ setAutocompleteSuggestion('');
89
+ } else {
90
+ var _inputRef$current;
91
+
92
+ setShowMenu(false);
93
+ (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.setSelectionRange(inputRef.current.value.length, inputRef.current.value.length);
94
+ }
95
+ }
96
+ };
97
+ }), [items, selectedItemIds, inputRef, onSelectedChange, selectionVariant, setAutocompleteSuggestion, setInputValue, setShowMenu]);
98
+ const itemSortOrderData = useMemo(() => sortedItemIds.reduce((acc, curr, i) => {
99
+ acc[curr] = i;
100
+ return acc;
101
+ }, {}), [sortedItemIds]);
102
+ const sortedAndFilteredItemsToRender = useMemo(() => selectableItems.filter(filterFn ? filterFn : getDefaultItemFilter(inputValue)).sort((a, b) => itemSortOrderData[a.id] - itemSortOrderData[b.id]), [selectableItems, itemSortOrderData, filterFn, inputValue]);
103
+ const allItemsToRender = useMemo(() => [// sorted and filtered selectable items
104
+ ...sortedAndFilteredItemsToRender, // menu item used for creating a token from whatever is in the text input
105
+ ...(addNewItem ? [{ ...addNewItem,
106
+ leadingVisual: () => /*#__PURE__*/React.createElement(PlusIcon, null),
107
+ onAction: item => {
108
+ // TODO: make it possible to pass a leadingVisual when using `addNewItem`
109
+ addNewItem.handleAddItem({ ...item,
110
+ id: item.id || uniqueId(),
111
+ leadingVisual: undefined
112
+ });
113
+
114
+ if (selectionVariant === 'multiple') {
115
+ setInputValue('');
116
+ setAutocompleteSuggestion('');
117
+ }
118
+ }
119
+ }] : [])], [sortedAndFilteredItemsToRender, addNewItem, setAutocompleteSuggestion, selectionVariant, setInputValue]);
120
+ useFocusZone({
121
+ containerRef: listContainerRef,
122
+ focusOutBehavior: 'wrap',
123
+ focusableElementFilter: element => {
124
+ return !(element instanceof HTMLInputElement);
125
+ },
126
+ activeDescendantFocus: inputRef,
127
+ onActiveDescendantChanged: (current, _previous, directlyActivated) => {
128
+ activeDescendantRef.current = current || null;
129
+
130
+ if (current) {
131
+ const selectedItem = selectableItems.find(item => item.id.toString() === current.getAttribute('data-id'));
132
+ setHighlightedItem(selectedItem);
133
+ setIsMenuDirectlyActivated(directlyActivated);
134
+ }
135
+
136
+ if (current && customScrollContainerRef && customScrollContainerRef.current && directlyActivated) {
137
+ scrollIntoViewingArea(current, customScrollContainerRef.current);
138
+ } else if (current && scrollContainerRef.current && directlyActivated) {
139
+ scrollIntoViewingArea(current, scrollContainerRef.current);
140
+ }
141
+ }
142
+ }, [loading]);
143
+ useEffect(() => {
144
+ var _highlightedItem$text;
145
+
146
+ if (highlightedItem !== null && highlightedItem !== void 0 && (_highlightedItem$text = highlightedItem.text) !== null && _highlightedItem$text !== void 0 && _highlightedItem$text.startsWith(inputValue) && !selectedItemIds.includes(highlightedItem.id)) {
147
+ setAutocompleteSuggestion(highlightedItem.text);
148
+ } else {
149
+ setAutocompleteSuggestion('');
150
+ }
151
+ }, [highlightedItem, inputValue, selectedItemIds, setAutocompleteSuggestion]);
152
+ useEffect(() => {
153
+ const itemIdSortResult = [...sortedItemIds].sort(sortOnCloseFn ? sortOnCloseFn : getDefaultSortFn(itemId => isItemSelected(itemId, selectedItemIds)));
154
+ const sortResultMatchesState = itemIdSortResult.length === sortedItemIds.length && itemIdSortResult.every((element, index) => element === sortedItemIds[index]);
155
+
156
+ if (showMenu === false && !sortResultMatchesState) {
157
+ setSortedItemIds(itemIdSortResult);
158
+ }
159
+
160
+ onOpenChange && onOpenChange(Boolean(showMenu));
161
+ }, [showMenu, onOpenChange, selectedItemIds, sortOnCloseFn, sortedItemIds]);
162
+ useEffect(() => {
163
+ if (selectedItemIds.length) {
164
+ setSelectedItemLength(selectedItemIds.length);
165
+ }
166
+ }, [selectedItemIds, setSelectedItemLength]);
167
+ return /*#__PURE__*/React.createElement(Box, {
168
+ sx: !showMenu ? {
169
+ // visually hides this label for sighted users
170
+ position: 'absolute',
171
+ width: '1px',
172
+ height: '1px',
173
+ padding: '0',
174
+ margin: '-1px',
175
+ overflow: 'hidden',
176
+ clip: 'rect(0, 0, 0, 0)',
177
+ whiteSpace: 'nowrap',
178
+ borderWidth: '0'
179
+ } : {}
180
+ }, loading ? /*#__PURE__*/React.createElement(Box, {
181
+ p: 3,
182
+ display: "flex",
183
+ justifyContent: "center"
184
+ }, /*#__PURE__*/React.createElement(Spinner, null)) : /*#__PURE__*/React.createElement("div", {
185
+ ref: listContainerRef
186
+ }, allItemsToRender.length ? /*#__PURE__*/React.createElement(ActionList, {
187
+ selectionVariant: "multiple" // have to typecast to `ItemProps` because we have an extra property
188
+ // on `items` for Autocomplete: `metadata`
189
+ ,
190
+ items: allItemsToRender,
191
+ role: "listbox",
192
+ id: `${id}-listbox`,
193
+ "aria-labelledby": ariaLabelledBy
194
+ }) : /*#__PURE__*/React.createElement(Box, {
195
+ p: 3
196
+ }, emptyStateText)));
197
+ }
198
+
199
+ AutocompleteMenu.displayName = "AutocompleteMenu";
200
+ AutocompleteMenu.defaultProps = {
201
+ emptyStateText: 'No selectable options',
202
+ selectionVariant: 'single'
203
+ };
204
+ AutocompleteMenu.displayName = 'AutocompleteMenu';
205
+ export default AutocompleteMenu;
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { OverlayProps } from '../Overlay';
3
+ import { ComponentProps } from '../utils/types';
4
+ declare type AutocompleteOverlayInternalProps = {
5
+ /**
6
+ * The ref of the element that the position of the menu is based on. By default, the menu is positioned based on the text input
7
+ */
8
+ menuAnchorRef?: React.RefObject<HTMLElement>;
9
+ /**
10
+ * Props to be spread on the internal `Overlay` component.
11
+ */
12
+ overlayProps?: Partial<OverlayProps>;
13
+ children?: React.ReactNode;
14
+ } & Pick<React.AriaAttributes, 'aria-labelledby'>;
15
+ declare function AutocompleteOverlay({ menuAnchorRef, overlayProps, children }: AutocompleteOverlayInternalProps): JSX.Element | null;
16
+ declare namespace AutocompleteOverlay {
17
+ var displayName: string;
18
+ }
19
+ export declare type AutocompleteOverlayProps = ComponentProps<typeof AutocompleteOverlay>;
20
+ export default AutocompleteOverlay;
@@ -0,0 +1,62 @@
1
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+
3
+ import React, { useCallback, useContext } from 'react';
4
+ import { useAnchoredPosition } from '../hooks';
5
+ import Overlay from '../Overlay';
6
+ import { AutocompleteContext } from './AutocompleteContext';
7
+ import { useCombinedRefs } from '../hooks/useCombinedRefs';
8
+
9
+ // TODO: consider making 'aria-labelledby' required
10
+ function AutocompleteOverlay({
11
+ menuAnchorRef,
12
+ overlayProps,
13
+ children
14
+ }) {
15
+ const autocompleteContext = useContext(AutocompleteContext);
16
+
17
+ if (autocompleteContext === null) {
18
+ throw new Error('AutocompleteContext returned null values');
19
+ }
20
+
21
+ const {
22
+ inputRef,
23
+ scrollContainerRef,
24
+ selectedItemLength,
25
+ setShowMenu,
26
+ showMenu = false
27
+ } = autocompleteContext;
28
+ const {
29
+ floatingElementRef,
30
+ position
31
+ } = useAnchoredPosition({
32
+ side: 'outside-bottom',
33
+ align: 'start',
34
+ anchorElementRef: menuAnchorRef ? menuAnchorRef : inputRef
35
+ }, [showMenu, selectedItemLength]);
36
+ const combinedOverlayRef = useCombinedRefs(scrollContainerRef, floatingElementRef);
37
+ const closeOptionList = useCallback(() => {
38
+ setShowMenu(false);
39
+ }, [setShowMenu]);
40
+
41
+ if (typeof window === 'undefined') {
42
+ return null;
43
+ }
44
+
45
+ return /*#__PURE__*/React.createElement(Overlay, _extends({
46
+ returnFocusRef: inputRef,
47
+ preventFocusOnOpen: true,
48
+ onClickOutside: closeOptionList,
49
+ onEscape: closeOptionList,
50
+ ref: combinedOverlayRef,
51
+ top: position === null || position === void 0 ? void 0 : position.top,
52
+ left: position === null || position === void 0 ? void 0 : position.left,
53
+ visibility: showMenu ? 'visible' : 'hidden',
54
+ sx: {
55
+ overflow: 'auto'
56
+ }
57
+ }, overlayProps), children);
58
+ }
59
+
60
+ AutocompleteOverlay.displayName = "AutocompleteOverlay";
61
+ AutocompleteOverlay.displayName = 'AutocompleteOverlay';
62
+ export default AutocompleteOverlay;
@@ -0,0 +1,2 @@
1
+ export { default } from './Autocomplete';
2
+ export type { AutocompleteMenuProps, AutocompleteInputProps, AutocompleteOverlayProps } from './Autocomplete';
@@ -0,0 +1 @@
1
+ export { default } from './Autocomplete';
@@ -42,7 +42,7 @@ function BaseStyles(props) {
42
42
 
43
43
  BaseStyles.displayName = "BaseStyles";
44
44
  BaseStyles.defaultProps = {
45
- color: 'text.primary',
45
+ color: 'fg.default',
46
46
  fontFamily: 'normal',
47
47
  lineHeight: 'default'
48
48
  };
@@ -11,7 +11,7 @@ const BorderBox = styled(Box).withConfig({
11
11
  BorderBox.defaultProps = {
12
12
  borderWidth: '1px',
13
13
  borderStyle: 'solid',
14
- borderColor: 'border.primary',
14
+ borderColor: 'border.default',
15
15
  borderRadius: 2
16
16
  };
17
17
  export default BorderBox;
@@ -5,5 +5,5 @@ import ButtonBase, { buttonSystemProps } from './ButtonBase';
5
5
  const ButtonInvisible = styled(ButtonBase).withConfig({
6
6
  displayName: "ButtonInvisible",
7
7
  componentId: "sc-1195tpn-0"
8
- })(["color:", ";background-color:transparent;border:0;border-radius:", ";box-shadow:none;&:disabled{color:", ";}&:focus{box-shadow:", ";}", ";", ""], get('colors.accent.fg'), get('radii.2'), get('colors.fg.muted'), get('shadows.btn.focusShadow'), buttonSystemProps, sx);
8
+ })(["color:", ";background-color:transparent;border:0;border-radius:", ";box-shadow:none;&:disabled{color:", ";}&:focus{box-shadow:", ";}&:hover{background-color:", ";}&:active{background-color:", ";}", ";", ""], get('colors.accent.fg'), get('radii.2'), get('colors.primer.fg.disabled'), get('shadows.btn.focusShadow'), get('colors.btn.hoverBg'), get('colors.btn.selectedBg'), buttonSystemProps, sx);
9
9
  export default ButtonInvisible;
package/lib-esm/Caret.js CHANGED
@@ -106,8 +106,8 @@ function Caret(props) {
106
106
  Caret.displayName = "Caret";
107
107
  Caret.locations = ['top', 'top-left', 'top-right', 'right', 'right-top', 'right-bottom', 'bottom', 'bottom-left', 'bottom-right', 'left', 'left-top', 'left-bottom'];
108
108
  Caret.defaultProps = {
109
- bg: 'bg.canvas',
110
- borderColor: 'border.primary',
109
+ bg: 'canvas.default',
110
+ borderColor: 'border.default',
111
111
  borderWidth: 1
112
112
  };
113
113
  export default Caret;
package/lib-esm/Dialog.js CHANGED
@@ -98,7 +98,7 @@ const Dialog = /*#__PURE__*/forwardRef(({
98
98
  }), children)) : null;
99
99
  });
100
100
  DialogHeader.defaultProps = {
101
- backgroundColor: 'bg.tertiary'
101
+ backgroundColor: 'canvas.subtle'
102
102
  };
103
103
  DialogHeader.propTypes = { ...Box.propTypes
104
104
  };
@@ -1,6 +1,7 @@
1
1
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
2
 
3
3
  import React, { useCallback, useEffect, useRef } from 'react';
4
+ import { useSSRSafeId } from '@react-aria/ssr';
4
5
  import TextInput from '../TextInput';
5
6
  import Box from '../Box';
6
7
  import { ActionList } from '../ActionList';
@@ -11,36 +12,7 @@ import styled from 'styled-components';
11
12
  import { get } from '../constants';
12
13
  import { useProvidedRefOrCreate } from '../hooks/useProvidedRefOrCreate';
13
14
  import useScrollFlash from '../hooks/useScrollFlash';
14
- import { useSSRSafeId } from '@react-aria/ssr';
15
-
16
- function scrollIntoViewingArea(child, container, margin = 8, behavior = 'smooth') {
17
- const {
18
- top: childTop,
19
- bottom: childBottom
20
- } = child.getBoundingClientRect();
21
- const {
22
- top: containerTop,
23
- bottom: containerBottom
24
- } = container.getBoundingClientRect();
25
- const isChildTopAboveViewingArea = childTop < containerTop + margin;
26
- const isChildBottomBelowViewingArea = childBottom > containerBottom - margin;
27
-
28
- if (isChildTopAboveViewingArea) {
29
- const scrollHeightToChildTop = childTop - containerTop + container.scrollTop;
30
- container.scrollTo({
31
- behavior,
32
- top: scrollHeightToChildTop - margin
33
- });
34
- } else if (isChildBottomBelowViewingArea) {
35
- const scrollHeightToChildBottom = childBottom - containerBottom + container.scrollTop;
36
- container.scrollTo({
37
- behavior,
38
- top: scrollHeightToChildBottom + margin
39
- });
40
- } // either completely in view or outside viewing area on both ends, don't scroll
41
-
42
- }
43
-
15
+ import { scrollIntoViewingArea } from '../behaviors/scrollIntoViewingArea';
44
16
  const StyledHeader = styled.div.withConfig({
45
17
  displayName: "FilteredActionList__StyledHeader",
46
18
  componentId: "yg3jkv-0"
@@ -95,7 +67,7 @@ export function FilteredActionList({
95
67
  useEffect(() => {
96
68
  // if items changed, we want to instantly move active descendant into view
97
69
  if (activeDescendantRef.current && scrollContainerRef.current) {
98
- scrollIntoViewingArea(activeDescendantRef.current, scrollContainerRef.current, undefined, 'auto');
70
+ scrollIntoViewingArea(activeDescendantRef.current, scrollContainerRef.current, 'vertical', undefined, undefined, 'auto');
99
71
  }
100
72
  }, [items]);
101
73
  useScrollFlash(scrollContainerRef);
package/lib-esm/Flash.js CHANGED
@@ -5,35 +5,35 @@ import sx from './sx';
5
5
  const variants = variant({
6
6
  variants: {
7
7
  default: {
8
- color: 'alert.info.text',
9
- backgroundColor: 'alert.info.bg',
10
- borderColor: 'alert.info.border',
8
+ color: 'fg.default',
9
+ backgroundColor: 'accent.subtle',
10
+ borderColor: 'accent.muted',
11
11
  svg: {
12
- color: 'alert.info.icon'
12
+ color: 'accent.fg'
13
13
  }
14
14
  },
15
15
  success: {
16
- color: 'alert.success.text',
17
- backgroundColor: 'alert.success.bg',
18
- borderColor: 'alert.success.border',
16
+ color: 'fg.default',
17
+ backgroundColor: 'success.subtle',
18
+ borderColor: 'success.muted',
19
19
  svg: {
20
- color: 'alert.success.icon'
20
+ color: 'success.fg'
21
21
  }
22
22
  },
23
23
  danger: {
24
- color: 'alert.error.text',
25
- backgroundColor: 'alert.error.bg',
26
- borderColor: 'alert.error.border',
24
+ color: 'fg.default',
25
+ backgroundColor: 'danger.subtle',
26
+ borderColor: 'danger.muted',
27
27
  svg: {
28
- color: 'alert.error.icon'
28
+ color: 'danger.fg'
29
29
  }
30
30
  },
31
31
  warning: {
32
- color: 'alert.warn.text',
33
- backgroundColor: 'alert.warn.bg',
34
- borderColor: 'alert.warn.border',
32
+ color: 'fg.default',
33
+ backgroundColor: 'attention.subtle',
34
+ borderColor: 'attention.muted',
35
35
  svg: {
36
- color: 'alert.warn.icon'
36
+ color: 'attention.fg'
37
37
  }
38
38
  }
39
39
  }
package/lib-esm/Label.js CHANGED
@@ -33,7 +33,7 @@ const Label = styled.span.withConfig({
33
33
  componentId: "sc-1t3ykp0-0"
34
34
  })(["display:inline-block;font-weight:", ";color:", ";border-radius:", ";&:hover{text-decoration:none;}", " ", " ", " ", " ", ""], get('fontWeights.semibold'), get('colors.fg.onEmphasis'), get('radii.3'), sizeVariant, COMMON, props => props.dropshadow ? 'box-shadow: inset 0 -1px 0 rgba(27, 31, 35, 0.12)' : '', props => props.outline ? outlineStyles : '', sx);
35
35
  Label.defaultProps = {
36
- bg: 'label.primary.border',
36
+ bg: 'neutral.emphasis',
37
37
  variant: 'medium'
38
38
  };
39
39
  export default Label;
@@ -40,6 +40,7 @@ export declare type OverlayProps = {
40
40
  top: number;
41
41
  left: number;
42
42
  portalContainerName?: string;
43
+ preventFocusOnOpen?: boolean;
43
44
  } & Omit<ComponentProps<typeof StyledOverlay>, 'visibility' | keyof SystemPositionProps>;
44
45
  /**
45
46
  * An `Overlay` is a flexible floating surface, used to display transient content such as menus,
@@ -92,6 +92,7 @@ const Overlay = /*#__PURE__*/React.forwardRef(({
92
92
  left,
93
93
  anchorSide,
94
94
  portalContainerName,
95
+ preventFocusOnOpen,
95
96
  ...rest
96
97
  }, forwardedRef) => {
97
98
  const overlayRef = useRef(null);
@@ -107,7 +108,8 @@ const Overlay = /*#__PURE__*/React.forwardRef(({
107
108
  onEscape,
108
109
  ignoreClickRefs,
109
110
  onClickOutside,
110
- initialFocusRef
111
+ initialFocusRef,
112
+ preventFocusOnOpen
111
113
  });
112
114
  useEffect(() => {
113
115
  var _combinedRef$current;
@@ -36,7 +36,7 @@ function ProgressBar({
36
36
 
37
37
  ProgressBar.displayName = "ProgressBar";
38
38
  ProgressBar.defaultProps = {
39
- bg: 'bg.successInverse',
39
+ bg: 'success.emphasis',
40
40
  barSize: 'default'
41
41
  };
42
42
  export default ProgressBar;
@@ -19,34 +19,28 @@ const colorVariants = variant({
19
19
  prop: 'status',
20
20
  variants: {
21
21
  issueClosed: {
22
- backgroundColor: 'prState.closed.bg',
23
- color: 'prState.closed.text',
24
- borderColor: 'prState.closed.border'
22
+ backgroundColor: 'danger.emphasis',
23
+ color: 'fg.onEmphasis'
25
24
  },
26
25
  pullClosed: {
27
- backgroundColor: 'prState.closed.bg',
28
- color: 'prState.closed.text',
29
- borderColor: 'prState.closed.border'
26
+ backgroundColor: 'danger.emphasis',
27
+ color: 'fg.onEmphasis'
30
28
  },
31
29
  pullMerged: {
32
- backgroundColor: 'prState.merged.bg',
33
- color: 'prState.merged.text',
34
- borderColor: 'prState.merged.border'
30
+ backgroundColor: 'done.emphasis',
31
+ color: 'fg.onEmphasis'
35
32
  },
36
33
  issueOpened: {
37
- backgroundColor: 'prState.open.bg',
38
- color: 'prState.open.text',
39
- borderColor: 'prState.open.border'
34
+ backgroundColor: 'success.emphasis',
35
+ color: 'fg.onEmphasis'
40
36
  },
41
37
  pullOpened: {
42
- backgroundColor: 'prState.open.bg',
43
- color: 'prState.open.text',
44
- borderColor: 'prState.open.border'
38
+ backgroundColor: 'success.emphasis',
39
+ color: 'fg.onEmphasis'
45
40
  },
46
41
  draft: {
47
- backgroundColor: 'prState.draft.bg',
48
- color: 'prState.draft.text',
49
- borderColor: 'prState.draft.border'
42
+ backgroundColor: 'neutral.emphasis',
43
+ color: 'fg.onEmphasis'
50
44
  }
51
45
  }
52
46
  });
@@ -68,7 +62,7 @@ const sizeVariants = variant({
68
62
  const StateLabelBase = styled.span.withConfig({
69
63
  displayName: "StateLabel__StateLabelBase",
70
64
  componentId: "k4pd9e-0"
71
- })(["display:inline-flex;align-items:center;font-weight:", ";line-height:16px;color:", ";text-align:center;border-radius:", ";border-width:1px;border-style:solid;", ";", ";", ";", ";"], get('fontWeights.bold'), get('colors.canvas.default'), get('radii.3'), colorVariants, sizeVariants, COMMON, sx);
65
+ })(["display:inline-flex;align-items:center;font-weight:", ";line-height:16px;color:", ";text-align:center;border-radius:", ";", ";", ";", ";", ";"], get('fontWeights.bold'), get('colors.canvas.default'), get('radii.3'), colorVariants, sizeVariants, COMMON, sx);
72
66
 
73
67
  function StateLabel({
74
68
  children,
@@ -34,7 +34,7 @@ const getTokenButtonIconSize = size => parseInt(tokenSizes[size || defaultTokenS
34
34
  const StyledTokenButton = styled.span.withConfig({
35
35
  displayName: "_RemoveTokenButton__StyledTokenButton",
36
36
  componentId: "sc-14lvcw1-0"
37
- })(["background-color:transparent;font-family:inherit;color:currentColor;cursor:pointer;display:inline-flex;justify-content:center;align-items:center;user-select:none;appearance:none;text-decoration:none;padding:0;transform:", ";align-self:baseline;border:0;border-radius:999px;&:hover,&:focus{background-color:", ";}&:active{background-color:", ";}", " ", ""], props => `translate(${props.borderOffset}px, -${props.borderOffset}px)`, get('colors.fade.fg10'), get('colors.fade.fg15'), variants, sx);
37
+ })(["background-color:transparent;font-family:inherit;color:currentColor;cursor:pointer;display:inline-flex;justify-content:center;align-items:center;user-select:none;appearance:none;text-decoration:none;padding:0;transform:", ";align-self:baseline;border:0;border-radius:999px;&:hover,&:focus{background-color:", ";}&:active{background-color:", ";}", " ", ""], props => `translate(${props.borderOffset}px, -${props.borderOffset}px)`, get('colors.neutral.muted'), get('colors.neutral.subtle'), variants, sx);
38
38
 
39
39
  const RemoveTokenButton = ({
40
40
  'aria-label': ariaLabel,
@@ -0,0 +1 @@
1
+ import 'babel-polyfill';