@primer/components 0.0.0-2021828142042 → 0.0.0-2021828162730

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.
@@ -2,10 +2,12 @@ import { IconProps } from '@primer/octicons-react';
2
2
  import React from 'react';
3
3
  import { SxProp } from '../sx';
4
4
  import { ItemInput } from './List';
5
+ import { ForwardRefComponent as PolymorphicForwardRefComponent } from '@radix-ui/react-polymorphic';
6
+ import { AriaRole } from '../utils/types';
5
7
  /**
6
8
  * Contract for props passed to the `Item` component.
7
9
  */
8
- export interface ItemProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'id'>, SxProp {
10
+ export interface ItemProps extends SxProp {
9
11
  /**
10
12
  * Primary text which names an `Item`.
11
13
  */
@@ -68,6 +70,18 @@ export interface ItemProps extends Omit<React.ComponentPropsWithoutRef<'div'>, '
68
70
  * An id associated with this item. Should be unique between items
69
71
  */
70
72
  id?: number | string;
73
+ /**
74
+ * Node to be included inside the item before the text.
75
+ */
76
+ children?: React.ReactNode;
77
+ /**
78
+ * The ARIA role describing the function of `List` component. `option` is a common value.
79
+ */
80
+ role?: AriaRole;
81
+ /**
82
+ * An item to pass back in the `onAction` callback, meant as
83
+ */
84
+ item?: ItemInput;
71
85
  }
72
86
  export declare const TextContainer: import("styled-components").StyledComponent<"span", any, {
73
87
  dangerouslySetInnerHtml?: React.DOMAttributes<HTMLDivElement>['dangerouslySetInnerHTML'];
@@ -75,6 +89,5 @@ export declare const TextContainer: import("styled-components").StyledComponent<
75
89
  /**
76
90
  * An actionable or selectable `Item` with an optional icon and description.
77
91
  */
78
- export declare function Item(itemProps: Partial<ItemProps> & {
79
- item?: ItemInput;
80
- }): JSX.Element;
92
+ declare const Item: PolymorphicForwardRefComponent<"div", ItemProps>;
93
+ export { Item };
@@ -3,8 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.Item = Item;
7
- exports.TextContainer = void 0;
6
+ exports.Item = exports.TextContainer = void 0;
8
7
 
9
8
  var _octiconsReact = require("@primer/octicons-react");
10
9
 
@@ -90,7 +89,7 @@ const getItemVariant = (variant = 'default', disabled) => {
90
89
 
91
90
  default:
92
91
  return {
93
- color: 'inherit',
92
+ color: (0, _constants.get)('colors.fg.default'),
94
93
  iconColor: (0, _constants.get)('colors.fg.muted'),
95
94
  annotationColor: (0, _constants.get)('colors.fg.muted'),
96
95
  hoverCursor: 'pointer'
@@ -111,7 +110,7 @@ const MainContent = _styledComponents.default.div.withConfig({
111
110
  const StyledItem = _styledComponents.default.div.withConfig({
112
111
  displayName: "Item__StyledItem",
113
112
  componentId: "jqpvy8-2"
114
- })(["padding:6px ", ";display:flex;border-radius:", ";color:", ";transition:background 33.333ms linear;@media (hover:hover) and (pointer:fine){:hover{background:var(--item-hover-bg-override,", ");cursor:", ";}}:not(:first-of-type):not(", " + &):not(", " + &){margin-top:", ";", "::before{content:' ';display:block;position:absolute;width:100%;top:-7px;border:0 solid ", ";border-top-width:", ";}}&:hover ", "::before,:hover + * ", "::before{border-color:var(--item-hover-divider-border-color-override,transparent) !important;}&:focus ", "::before,:focus + * ", "::before,&[", "] ", "::before,[", "] + & ", "::before{border-color:transparent !important;}&[", "='", "']{background:", ";}&[", "='", "']{background:", ";}&:focus{background:", ";outline:none;}&:active{background:", ";}", ""], (0, _constants.get)('space.2'), (0, _constants.get)('radii.2'), ({
113
+ })(["padding:6px ", ";display:flex;border-radius:", ";color:", ";transition:background 33.333ms linear;text-decoration:none;@media (hover:hover) and (pointer:fine){:hover{background:var(--item-hover-bg-override,", ");cursor:", ";}}:not(:first-of-type):not(", " + &):not(", " + &){margin-top:", ";", "::before{content:' ';display:block;position:absolute;width:100%;top:-7px;border:0 solid ", ";border-top-width:", ";}}&:hover ", "::before,:hover + * ", "::before{border-color:var(--item-hover-divider-border-color-override,transparent) !important;}&:focus ", "::before,:focus + * ", "::before,&[", "] ", "::before,[", "] + & ", "::before{border-color:transparent !important;}&[", "='", "']{background:", ";}&[", "='", "']{background:", ";}&:focus{background:", ";outline:none;}&:active{background:", ";}", ""], (0, _constants.get)('space.2'), (0, _constants.get)('radii.2'), ({
115
114
  variant,
116
115
  item
117
116
  }) => getItemVariant(variant, item === null || item === void 0 ? void 0 : item.disabled).color, ({
@@ -178,8 +177,9 @@ const MultiSelectInput = _styledComponents.default.input.withConfig({
178
177
  */
179
178
 
180
179
 
181
- function Item(itemProps) {
180
+ const Item = /*#__PURE__*/_react.default.forwardRef((itemProps, ref) => {
182
181
  const {
182
+ as: Component,
183
183
  text,
184
184
  description,
185
185
  descriptionVariant = 'inline',
@@ -235,6 +235,8 @@ function Item(itemProps) {
235
235
  theme
236
236
  } = (0, _ThemeProvider.useTheme)();
237
237
  return /*#__PURE__*/_react.default.createElement(StyledItem, _extends({
238
+ ref: ref,
239
+ as: Component,
238
240
  tabIndex: disabled ? undefined : -1,
239
241
  variant: variant,
240
242
  showDivider: showDivider,
@@ -280,6 +282,6 @@ function Item(itemProps) {
280
282
  variant: variant,
281
283
  disabled: disabled
282
284
  }, trailingText, TrailingIcon && /*#__PURE__*/_react.default.createElement(TrailingIcon, null)) : null));
283
- }
285
+ });
284
286
 
285
- Item.displayName = "Item";
287
+ exports.Item = Item;
@@ -1,9 +1,12 @@
1
- import React from 'react';
1
+ import React, { Key } from 'react';
2
2
  import type { AriaRole } from '../utils/types';
3
3
  import { Group, GroupProps } from './Group';
4
- import { Item, ItemProps } from './Item';
5
- export declare type ItemInput = ItemProps | (Partial<ItemProps> & {
6
- renderItem: typeof Item;
4
+ import { ItemProps } from './Item';
5
+ declare type RenderItemFn = (props: ItemProps) => React.ReactElement;
6
+ export declare type ItemInput = ItemProps | ((Partial<ItemProps> & {
7
+ renderItem: RenderItemFn;
8
+ }) & {
9
+ key?: Key;
7
10
  });
8
11
  /**
9
12
  * Contract for props passed to the `List` component.
@@ -26,7 +29,7 @@ export interface ListPropsBase {
26
29
  * without a `Group`-level or `Item`-level custom `Item` renderer will be
27
30
  * rendered using this function component.
28
31
  */
29
- renderItem?: typeof Item;
32
+ renderItem?: RenderItemFn;
30
33
  /**
31
34
  * A `List`-level custom `Group` renderer. Every `Group` within this `List`
32
35
  * without a `Group`-level custom `Item` renderer will be rendered using
@@ -58,7 +61,7 @@ export interface GroupedListProps extends ListPropsBase {
58
61
  * and `Group`-level custom `Item` or `Group` renderers.
59
62
  */
60
63
  groupMetadata: ((Omit<GroupProps, 'items'> | Omit<Partial<GroupProps> & {
61
- renderItem?: typeof Item;
64
+ renderItem?: RenderItemFn;
62
65
  renderGroup?: typeof Group;
63
66
  }, 'items'>) & {
64
67
  groupId: string;
@@ -68,7 +71,7 @@ export interface GroupedListProps extends ListPropsBase {
68
71
  * and `Item`-level custom `Item` renderers.
69
72
  */
70
73
  items: ((ItemProps | (Partial<ItemProps> & {
71
- renderItem: typeof Item;
74
+ renderItem: RenderItemFn;
72
75
  })) & {
73
76
  groupId: string;
74
77
  })[];
@@ -81,3 +84,4 @@ export declare type ListProps = ListPropsBase | GroupedListProps;
81
84
  * Lists `Item`s, either grouped or ungrouped, with a `Divider` between each `Group`.
82
85
  */
83
86
  export declare const List: React.ForwardRefExoticComponent<ListProps & React.RefAttributes<HTMLDivElement>>;
87
+ export {};
@@ -106,11 +106,11 @@ const List = /*#__PURE__*/_react.default.forwardRef((props, forwardedRef) => {
106
106
 
107
107
 
108
108
  const renderItem = (itemProps, item, itemIndex) => {
109
- var _ref2, _itemProps$key, _itemProps$id;
109
+ var _ref2, _ref3, _itemProps$id;
110
110
 
111
111
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
112
112
  const ItemComponent = 'renderItem' in itemProps && itemProps.renderItem || props.renderItem || _Item.Item;
113
- const key = (_ref2 = (_itemProps$key = itemProps.key) !== null && _itemProps$key !== void 0 ? _itemProps$key : (_itemProps$id = itemProps.id) === null || _itemProps$id === void 0 ? void 0 : _itemProps$id.toString()) !== null && _ref2 !== void 0 ? _ref2 : itemIndex.toString();
113
+ const key = (_ref2 = (_ref3 = 'key' in itemProps ? itemProps.key : undefined) !== null && _ref3 !== void 0 ? _ref3 : (_itemProps$id = itemProps.id) === null || _itemProps$id === void 0 ? void 0 : _itemProps$id.toString()) !== null && _ref2 !== void 0 ? _ref2 : itemIndex.toString();
114
114
  return /*#__PURE__*/_react.default.createElement(ItemComponent, _extends({
115
115
  showDivider: props.showItemDividers,
116
116
  selectionVariant: props.selectionVariant
@@ -1,6 +1,5 @@
1
1
  /// <reference types="react" />
2
2
  import { Group } from './Group';
3
- import { Item } from './Item';
4
3
  import { Divider } from './Divider';
5
4
  export type { ListProps as ActionListProps } from './List';
6
5
  export type { GroupProps } from './Group';
@@ -12,7 +11,7 @@ export declare const ActionList: import("react").ForwardRefExoticComponent<impor
12
11
  /** Collects related `Items` in an `ActionList`. */
13
12
  Group: typeof Group;
14
13
  /** An actionable or selectable `Item` with an optional icon and description. */
15
- Item: typeof Item;
14
+ Item: import("@radix-ui/react-polymorphic").ForwardRefComponent<"div", import("./Item").ItemProps>;
16
15
  /** Visually separates `Item`s or `Group`s in an `ActionList`. */
17
16
  Divider: typeof Divider;
18
17
  };
@@ -117,13 +117,13 @@ const ConfirmationDialog = props => {
117
117
  }, [onClose]);
118
118
  const cancelButton = {
119
119
  content: cancelButtonContent,
120
- onClick: onCancelButtonClick
120
+ onClick: onCancelButtonClick,
121
+ autoFocus: true
121
122
  };
122
123
  const confirmButton = {
123
124
  content: confirmButtonContent,
124
125
  buttonType: confirmButtonType,
125
- onClick: onConfirmButtonClick,
126
- autoFocus: true
126
+ onClick: onConfirmButtonClick
127
127
  };
128
128
  const footerButtons = [cancelButton, confirmButton];
129
129
  return /*#__PURE__*/_react.default.createElement(_Dialog.Dialog, {
@@ -141,19 +141,10 @@ const _Dialog = /*#__PURE__*/_react.default.forwardRef((props, forwardedRef) =>
141
141
  onClose,
142
142
  role = 'dialog',
143
143
  width = 'xlarge',
144
- height = 'auto',
145
- footerButtons = []
144
+ height = 'auto'
146
145
  } = props;
147
146
  const dialogLabelId = (0, _ssr.useSSRSafeId)();
148
147
  const dialogDescriptionId = (0, _ssr.useSSRSafeId)();
149
- const autoFocusedFooterButtonRef = (0, _react.useRef)(null);
150
-
151
- for (const footerButton of footerButtons) {
152
- if (footerButton.autoFocus) {
153
- footerButton.ref = autoFocusedFooterButtonRef;
154
- }
155
- }
156
-
157
148
  const defaultedProps = { ...props,
158
149
  title,
159
150
  subtitle,
@@ -166,8 +157,7 @@ const _Dialog = /*#__PURE__*/_react.default.forwardRef((props, forwardedRef) =>
166
157
  const backdropRef = (0, _react.useRef)(null);
167
158
  (0, _useFocusTrap.useFocusTrap)({
168
159
  containerRef: dialogRef,
169
- restoreFocusOnCleanUp: true,
170
- initialFocusRef: autoFocusedFooterButtonRef
160
+ restoreFocusOnCleanUp: true
171
161
  });
172
162
  (0, _hooks.useOnEscapePress)(event => {
173
163
  onClose('escape');
@@ -222,16 +212,32 @@ const buttonTypes = {
222
212
  const Buttons = ({
223
213
  buttons
224
214
  }) => {
215
+ const autoFocusRef = (0, _react.useRef)(null);
216
+ let autoFocusCount = 0;
217
+ const [hasRendered, setHasRendered] = (0, _react.useState)(0);
218
+ (0, _react.useEffect)(() => {
219
+ // hack to work around dialogs originating from other focus traps.
220
+ if (hasRendered === 1) {
221
+ var _autoFocusRef$current;
222
+
223
+ (_autoFocusRef$current = autoFocusRef.current) === null || _autoFocusRef$current === void 0 ? void 0 : _autoFocusRef$current.focus();
224
+ } else {
225
+ setHasRendered(hasRendered + 1);
226
+ }
227
+ }, [hasRendered]);
225
228
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, buttons.map((dialogButtonProps, index) => {
226
229
  const {
227
230
  content,
228
231
  buttonType = 'normal',
232
+ autoFocus = false,
229
233
  ...buttonProps
230
234
  } = dialogButtonProps;
231
235
  const ButtonElement = buttonTypes[buttonType];
232
236
  return /*#__PURE__*/_react.default.createElement(ButtonElement, _extends({
233
237
  key: index
234
- }, buttonProps), content);
238
+ }, buttonProps, {
239
+ ref: autoFocus && autoFocusCount === 0 ? (autoFocusCount++, autoFocusRef) : null
240
+ }), content);
235
241
  }));
236
242
  };
237
243
 
@@ -2,10 +2,12 @@ import { IconProps } from '@primer/octicons-react';
2
2
  import React from 'react';
3
3
  import { SxProp } from '../sx';
4
4
  import { ItemInput } from './List';
5
+ import { ForwardRefComponent as PolymorphicForwardRefComponent } from '@radix-ui/react-polymorphic';
6
+ import { AriaRole } from '../utils/types';
5
7
  /**
6
8
  * Contract for props passed to the `Item` component.
7
9
  */
8
- export interface ItemProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'id'>, SxProp {
10
+ export interface ItemProps extends SxProp {
9
11
  /**
10
12
  * Primary text which names an `Item`.
11
13
  */
@@ -68,6 +70,18 @@ export interface ItemProps extends Omit<React.ComponentPropsWithoutRef<'div'>, '
68
70
  * An id associated with this item. Should be unique between items
69
71
  */
70
72
  id?: number | string;
73
+ /**
74
+ * Node to be included inside the item before the text.
75
+ */
76
+ children?: React.ReactNode;
77
+ /**
78
+ * The ARIA role describing the function of `List` component. `option` is a common value.
79
+ */
80
+ role?: AriaRole;
81
+ /**
82
+ * An item to pass back in the `onAction` callback, meant as
83
+ */
84
+ item?: ItemInput;
71
85
  }
72
86
  export declare const TextContainer: import("styled-components").StyledComponent<"span", any, {
73
87
  dangerouslySetInnerHtml?: React.DOMAttributes<HTMLDivElement>['dangerouslySetInnerHTML'];
@@ -75,6 +89,5 @@ export declare const TextContainer: import("styled-components").StyledComponent<
75
89
  /**
76
90
  * An actionable or selectable `Item` with an optional icon and description.
77
91
  */
78
- export declare function Item(itemProps: Partial<ItemProps> & {
79
- item?: ItemInput;
80
- }): JSX.Element;
92
+ declare const Item: PolymorphicForwardRefComponent<"div", ItemProps>;
93
+ export { Item };
@@ -11,10 +11,10 @@ import { StyledDivider } from './Divider';
11
11
  import { useColorSchemeVar, useTheme } from '../ThemeProvider';
12
12
  import { activeDescendantActivatedDirectly, activeDescendantActivatedIndirectly, isActiveDescendantAttribute } from '../behaviors/focusZone';
13
13
  import { useSSRSafeId } from '@react-aria/ssr';
14
+
14
15
  /**
15
16
  * These colors are not yet in our default theme. Need to remove this once they are added.
16
17
  */
17
-
18
18
  const customItemThemes = {
19
19
  default: {
20
20
  hover: {
@@ -66,7 +66,7 @@ const getItemVariant = (variant = 'default', disabled) => {
66
66
 
67
67
  default:
68
68
  return {
69
- color: 'inherit',
69
+ color: get('colors.fg.default'),
70
70
  iconColor: get('colors.fg.muted'),
71
71
  annotationColor: get('colors.fg.muted'),
72
72
  hoverCursor: 'pointer'
@@ -85,7 +85,7 @@ const MainContent = styled.div.withConfig({
85
85
  const StyledItem = styled.div.withConfig({
86
86
  displayName: "Item__StyledItem",
87
87
  componentId: "jqpvy8-2"
88
- })(["padding:6px ", ";display:flex;border-radius:", ";color:", ";transition:background 33.333ms linear;@media (hover:hover) and (pointer:fine){:hover{background:var(--item-hover-bg-override,", ");cursor:", ";}}:not(:first-of-type):not(", " + &):not(", " + &){margin-top:", ";", "::before{content:' ';display:block;position:absolute;width:100%;top:-7px;border:0 solid ", ";border-top-width:", ";}}&:hover ", "::before,:hover + * ", "::before{border-color:var(--item-hover-divider-border-color-override,transparent) !important;}&:focus ", "::before,:focus + * ", "::before,&[", "] ", "::before,[", "] + & ", "::before{border-color:transparent !important;}&[", "='", "']{background:", ";}&[", "='", "']{background:", ";}&:focus{background:", ";outline:none;}&:active{background:", ";}", ""], get('space.2'), get('radii.2'), ({
88
+ })(["padding:6px ", ";display:flex;border-radius:", ";color:", ";transition:background 33.333ms linear;text-decoration:none;@media (hover:hover) and (pointer:fine){:hover{background:var(--item-hover-bg-override,", ");cursor:", ";}}:not(:first-of-type):not(", " + &):not(", " + &){margin-top:", ";", "::before{content:' ';display:block;position:absolute;width:100%;top:-7px;border:0 solid ", ";border-top-width:", ";}}&:hover ", "::before,:hover + * ", "::before{border-color:var(--item-hover-divider-border-color-override,transparent) !important;}&:focus ", "::before,:focus + * ", "::before,&[", "] ", "::before,[", "] + & ", "::before{border-color:transparent !important;}&[", "='", "']{background:", ";}&[", "='", "']{background:", ";}&:focus{background:", ";outline:none;}&:active{background:", ";}", ""], get('space.2'), get('radii.2'), ({
89
89
  variant,
90
90
  item
91
91
  }) => getItemVariant(variant, item === null || item === void 0 ? void 0 : item.disabled).color, ({
@@ -144,8 +144,9 @@ const MultiSelectInput = styled.input.withConfig({
144
144
  * An actionable or selectable `Item` with an optional icon and description.
145
145
  */
146
146
 
147
- export function Item(itemProps) {
147
+ const Item = /*#__PURE__*/React.forwardRef((itemProps, ref) => {
148
148
  const {
149
+ as: Component,
149
150
  text,
150
151
  description,
151
152
  descriptionVariant = 'inline',
@@ -201,6 +202,8 @@ export function Item(itemProps) {
201
202
  theme
202
203
  } = useTheme();
203
204
  return /*#__PURE__*/React.createElement(StyledItem, _extends({
205
+ ref: ref,
206
+ as: Component,
204
207
  tabIndex: disabled ? undefined : -1,
205
208
  variant: variant,
206
209
  showDivider: showDivider,
@@ -246,5 +249,5 @@ export function Item(itemProps) {
246
249
  variant: variant,
247
250
  disabled: disabled
248
251
  }, trailingText, TrailingIcon && /*#__PURE__*/React.createElement(TrailingIcon, null)) : null));
249
- }
250
- Item.displayName = "Item";
252
+ });
253
+ export { Item };
@@ -1,9 +1,12 @@
1
- import React from 'react';
1
+ import React, { Key } from 'react';
2
2
  import type { AriaRole } from '../utils/types';
3
3
  import { Group, GroupProps } from './Group';
4
- import { Item, ItemProps } from './Item';
5
- export declare type ItemInput = ItemProps | (Partial<ItemProps> & {
6
- renderItem: typeof Item;
4
+ import { ItemProps } from './Item';
5
+ declare type RenderItemFn = (props: ItemProps) => React.ReactElement;
6
+ export declare type ItemInput = ItemProps | ((Partial<ItemProps> & {
7
+ renderItem: RenderItemFn;
8
+ }) & {
9
+ key?: Key;
7
10
  });
8
11
  /**
9
12
  * Contract for props passed to the `List` component.
@@ -26,7 +29,7 @@ export interface ListPropsBase {
26
29
  * without a `Group`-level or `Item`-level custom `Item` renderer will be
27
30
  * rendered using this function component.
28
31
  */
29
- renderItem?: typeof Item;
32
+ renderItem?: RenderItemFn;
30
33
  /**
31
34
  * A `List`-level custom `Group` renderer. Every `Group` within this `List`
32
35
  * without a `Group`-level custom `Item` renderer will be rendered using
@@ -58,7 +61,7 @@ export interface GroupedListProps extends ListPropsBase {
58
61
  * and `Group`-level custom `Item` or `Group` renderers.
59
62
  */
60
63
  groupMetadata: ((Omit<GroupProps, 'items'> | Omit<Partial<GroupProps> & {
61
- renderItem?: typeof Item;
64
+ renderItem?: RenderItemFn;
62
65
  renderGroup?: typeof Group;
63
66
  }, 'items'>) & {
64
67
  groupId: string;
@@ -68,7 +71,7 @@ export interface GroupedListProps extends ListPropsBase {
68
71
  * and `Item`-level custom `Item` renderers.
69
72
  */
70
73
  items: ((ItemProps | (Partial<ItemProps> & {
71
- renderItem: typeof Item;
74
+ renderItem: RenderItemFn;
72
75
  })) & {
73
76
  groupId: string;
74
77
  })[];
@@ -81,3 +84,4 @@ export declare type ListProps = ListPropsBase | GroupedListProps;
81
84
  * Lists `Item`s, either grouped or ungrouped, with a `Divider` between each `Group`.
82
85
  */
83
86
  export declare const List: React.ForwardRefExoticComponent<ListProps & React.RefAttributes<HTMLDivElement>>;
87
+ export {};
@@ -90,11 +90,11 @@ export const List = /*#__PURE__*/React.forwardRef((props, forwardedRef) => {
90
90
 
91
91
 
92
92
  const renderItem = (itemProps, item, itemIndex) => {
93
- var _ref2, _itemProps$key, _itemProps$id;
93
+ var _ref2, _ref3, _itemProps$id;
94
94
 
95
95
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
96
96
  const ItemComponent = 'renderItem' in itemProps && itemProps.renderItem || props.renderItem || Item;
97
- const key = (_ref2 = (_itemProps$key = itemProps.key) !== null && _itemProps$key !== void 0 ? _itemProps$key : (_itemProps$id = itemProps.id) === null || _itemProps$id === void 0 ? void 0 : _itemProps$id.toString()) !== null && _ref2 !== void 0 ? _ref2 : itemIndex.toString();
97
+ const key = (_ref2 = (_ref3 = 'key' in itemProps ? itemProps.key : undefined) !== null && _ref3 !== void 0 ? _ref3 : (_itemProps$id = itemProps.id) === null || _itemProps$id === void 0 ? void 0 : _itemProps$id.toString()) !== null && _ref2 !== void 0 ? _ref2 : itemIndex.toString();
98
98
  return /*#__PURE__*/React.createElement(ItemComponent, _extends({
99
99
  showDivider: props.showItemDividers,
100
100
  selectionVariant: props.selectionVariant
@@ -1,6 +1,5 @@
1
1
  /// <reference types="react" />
2
2
  import { Group } from './Group';
3
- import { Item } from './Item';
4
3
  import { Divider } from './Divider';
5
4
  export type { ListProps as ActionListProps } from './List';
6
5
  export type { GroupProps } from './Group';
@@ -12,7 +11,7 @@ export declare const ActionList: import("react").ForwardRefExoticComponent<impor
12
11
  /** Collects related `Items` in an `ActionList`. */
13
12
  Group: typeof Group;
14
13
  /** An actionable or selectable `Item` with an optional icon and description. */
15
- Item: typeof Item;
14
+ Item: import("@radix-ui/react-polymorphic").ForwardRefComponent<"div", import("./Item").ItemProps>;
16
15
  /** Visually separates `Item`s or `Group`s in an `ActionList`. */
17
16
  Divider: typeof Divider;
18
17
  };
@@ -97,13 +97,13 @@ export const ConfirmationDialog = props => {
97
97
  }, [onClose]);
98
98
  const cancelButton = {
99
99
  content: cancelButtonContent,
100
- onClick: onCancelButtonClick
100
+ onClick: onCancelButtonClick,
101
+ autoFocus: true
101
102
  };
102
103
  const confirmButton = {
103
104
  content: confirmButtonContent,
104
105
  buttonType: confirmButtonType,
105
- onClick: onConfirmButtonClick,
106
- autoFocus: true
106
+ onClick: onConfirmButtonClick
107
107
  };
108
108
  const footerButtons = [cancelButton, confirmButton];
109
109
  return /*#__PURE__*/React.createElement(Dialog, {
@@ -1,6 +1,6 @@
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
- import React, { useCallback, useRef } from 'react';
3
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
4
4
  import styled from 'styled-components';
5
5
  import Button, { ButtonPrimary, ButtonDanger } from '../Button';
6
6
  import Box from '../Box';
@@ -112,19 +112,10 @@ const _Dialog = /*#__PURE__*/React.forwardRef((props, forwardedRef) => {
112
112
  onClose,
113
113
  role = 'dialog',
114
114
  width = 'xlarge',
115
- height = 'auto',
116
- footerButtons = []
115
+ height = 'auto'
117
116
  } = props;
118
117
  const dialogLabelId = useSSRSafeId();
119
118
  const dialogDescriptionId = useSSRSafeId();
120
- const autoFocusedFooterButtonRef = useRef(null);
121
-
122
- for (const footerButton of footerButtons) {
123
- if (footerButton.autoFocus) {
124
- footerButton.ref = autoFocusedFooterButtonRef;
125
- }
126
- }
127
-
128
119
  const defaultedProps = { ...props,
129
120
  title,
130
121
  subtitle,
@@ -137,8 +128,7 @@ const _Dialog = /*#__PURE__*/React.forwardRef((props, forwardedRef) => {
137
128
  const backdropRef = useRef(null);
138
129
  useFocusTrap({
139
130
  containerRef: dialogRef,
140
- restoreFocusOnCleanUp: true,
141
- initialFocusRef: autoFocusedFooterButtonRef
131
+ restoreFocusOnCleanUp: true
142
132
  });
143
133
  useOnEscapePress(event => {
144
134
  onClose('escape');
@@ -193,16 +183,32 @@ const buttonTypes = {
193
183
  const Buttons = ({
194
184
  buttons
195
185
  }) => {
186
+ const autoFocusRef = useRef(null);
187
+ let autoFocusCount = 0;
188
+ const [hasRendered, setHasRendered] = useState(0);
189
+ useEffect(() => {
190
+ // hack to work around dialogs originating from other focus traps.
191
+ if (hasRendered === 1) {
192
+ var _autoFocusRef$current;
193
+
194
+ (_autoFocusRef$current = autoFocusRef.current) === null || _autoFocusRef$current === void 0 ? void 0 : _autoFocusRef$current.focus();
195
+ } else {
196
+ setHasRendered(hasRendered + 1);
197
+ }
198
+ }, [hasRendered]);
196
199
  return /*#__PURE__*/React.createElement(React.Fragment, null, buttons.map((dialogButtonProps, index) => {
197
200
  const {
198
201
  content,
199
202
  buttonType = 'normal',
203
+ autoFocus = false,
200
204
  ...buttonProps
201
205
  } = dialogButtonProps;
202
206
  const ButtonElement = buttonTypes[buttonType];
203
207
  return /*#__PURE__*/React.createElement(ButtonElement, _extends({
204
208
  key: index
205
- }, buttonProps), content);
209
+ }, buttonProps, {
210
+ ref: autoFocus && autoFocusCount === 0 ? (autoFocusCount++, autoFocusRef) : null
211
+ }), content);
206
212
  }));
207
213
  };
208
214
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primer/components",
3
- "version": "0.0.0-2021828142042",
3
+ "version": "0.0.0-2021828162730",
4
4
  "description": "Primer react components",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib-esm/index.js",
@@ -45,6 +45,7 @@
45
45
  "dependencies": {
46
46
  "@primer/octicons-react": "^13.0.0",
47
47
  "@primer/primitives": "4.7.1",
48
+ "@radix-ui/react-polymorphic": "0.0.14",
48
49
  "@react-aria/ssr": "3.1.0",
49
50
  "@styled-system/css": "5.1.5",
50
51
  "@styled-system/props": "5.1.5",