@primer/components 0.0.0-2021111211759 → 0.0.0-2021111212257

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.
@@ -1,10 +1,10 @@
1
1
  /** This context can be used by components that compose ActionList inside a Menu */
2
2
  import React from 'react';
3
3
  declare type ContextProps = {
4
- parent?: string;
4
+ container?: string;
5
5
  listRole?: string;
6
6
  itemRole?: string;
7
- afterSelect?: () => void;
7
+ afterSelect?: Function;
8
8
  };
9
- export declare const MenuContext: React.Context<ContextProps>;
9
+ export declare const ActionListContainerContext: React.Context<ContextProps>;
10
10
  export {};
@@ -3,13 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.MenuContext = void 0;
6
+ exports.ActionListContainerContext = void 0;
7
7
 
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
 
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
11
 
12
12
  /** This context can be used by components that compose ActionList inside a Menu */
13
- const MenuContext = /*#__PURE__*/_react.default.createContext({});
13
+ const ActionListContainerContext = /*#__PURE__*/_react.default.createContext({});
14
14
 
15
- exports.MenuContext = MenuContext;
15
+ exports.ActionListContainerContext = ActionListContainerContext;
@@ -21,7 +21,7 @@ var _createSlots = _interopRequireDefault(require("../utils/create-slots"));
21
21
 
22
22
  var _List = require("./List");
23
23
 
24
- var _MenuContext = require("./MenuContext");
24
+ var _ActionListContainerContext = require("./ActionListContainerContext");
25
25
 
26
26
  var _Selection = require("./Selection");
27
27
 
@@ -96,7 +96,7 @@ const Item = /*#__PURE__*/_react.default.forwardRef(({
96
96
  const {
97
97
  itemRole,
98
98
  afterSelect
99
- } = _react.default.useContext(_MenuContext.MenuContext);
99
+ } = _react.default.useContext(_ActionListContainerContext.ActionListContainerContext);
100
100
 
101
101
  const {
102
102
  theme
@@ -171,22 +171,20 @@ const Item = /*#__PURE__*/_react.default.forwardRef(({
171
171
  };
172
172
 
173
173
  const clickHandler = _react.default.useCallback(event => {
174
- if (typeof onSelect !== 'function') return;
175
174
  if (disabled) return;
176
175
 
177
176
  if (!event.defaultPrevented) {
178
- onSelect(event); // if this Item is inside a Menu, close the Menu
177
+ if (typeof onSelect === 'function') onSelect(event); // if this Item is inside a Menu, close the Menu
179
178
 
180
179
  if (typeof afterSelect === 'function') afterSelect();
181
180
  }
182
181
  }, [onSelect, disabled, afterSelect]);
183
182
 
184
183
  const keyPressHandler = _react.default.useCallback(event => {
185
- if (typeof onSelect !== 'function') return;
186
184
  if (disabled) return;
187
185
 
188
186
  if (!event.defaultPrevented && [' ', 'Enter'].includes(event.key)) {
189
- onSelect(event); // if this Item is inside a Menu, close the Menu
187
+ if (typeof onSelect === 'function') onSelect(event); // if this Item is inside a Menu, close the Menu
190
188
 
191
189
  if (typeof afterSelect === 'function') afterSelect();
192
190
  }
@@ -11,7 +11,7 @@ var _styledComponents = _interopRequireDefault(require("styled-components"));
11
11
 
12
12
  var _sx = _interopRequireWildcard(require("../sx"));
13
13
 
14
- var _MenuContext = require("./MenuContext");
14
+ var _ActionListContainerContext = require("./ActionListContainerContext");
15
15
 
16
16
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
17
17
 
@@ -48,7 +48,7 @@ const List = /*#__PURE__*/_react.default.forwardRef(({
48
48
 
49
49
  const {
50
50
  listRole
51
- } = _react.default.useContext(_MenuContext.MenuContext);
51
+ } = _react.default.useContext(_ActionListContainerContext.ActionListContainerContext);
52
52
 
53
53
  return /*#__PURE__*/_react.default.createElement(ListBox, _extends({
54
54
  sx: (0, _sx.merge)(styles, sxProp),
@@ -13,7 +13,7 @@ var _List = require("./List");
13
13
 
14
14
  var _Group = require("./Group");
15
15
 
16
- var _MenuContext = require("./MenuContext");
16
+ var _ActionListContainerContext = require("./ActionListContainerContext");
17
17
 
18
18
  var _Visuals = require("./Visuals");
19
19
 
@@ -31,8 +31,8 @@ const Selection = ({
31
31
  } = _react.default.useContext(_Group.GroupContext);
32
32
 
33
33
  const {
34
- parent
35
- } = _react.default.useContext(_MenuContext.MenuContext);
34
+ container
35
+ } = _react.default.useContext(_ActionListContainerContext.ActionListContainerContext);
36
36
  /** selectionVariant in Group can override the selectionVariant in List root */
37
37
 
38
38
 
@@ -44,7 +44,7 @@ const Selection = ({
44
44
  return null;
45
45
  }
46
46
 
47
- if (parent === 'ActionMenu') {
47
+ if (container === 'ActionMenu') {
48
48
  throw new Error('ActionList cannot have a selectionVariant inside ActionMenu, please use DropdownMenu or SelectPanel instead. More information: https://primer.style/design/components/action-list#application');
49
49
  return null;
50
50
  }
@@ -1,10 +1,12 @@
1
1
  import { ButtonProps } from './Button';
2
2
  import React from 'react';
3
+ import { AnchoredOverlayProps } from './AnchoredOverlay';
3
4
  import { OverlayProps } from './Overlay';
4
- import { AnchoredOverlayWrapperAnchorProps } from './AnchoredOverlay/AnchoredOverlay';
5
- declare type ActionMenuBaseProps = {
5
+ declare type MenuContextProps = Pick<AnchoredOverlayProps, 'anchorRef' | 'renderAnchor' | 'open' | 'onOpen' | 'onClose'>;
6
+ export declare const MenuContext: React.Context<MenuContextProps>;
7
+ export declare type ActionMenuProps = {
6
8
  /**
7
- * Recommended: `ActionMenu.Button` or `ActionMenu.Anchor` with ActionList`
9
+ * Recommended: `ActionMenu.Button` or `ActionMenu.Anchor` with `ActionMenu.Overlay`
8
10
  */
9
11
  children: React.ReactElement[] | React.ReactElement;
10
12
  /**
@@ -15,17 +17,18 @@ declare type ActionMenuBaseProps = {
15
17
  * If defined, will control the open/closed state of the overlay. Must be used in conjuction with `open`.
16
18
  */
17
19
  onOpenChange?: (s: boolean) => void;
18
- /**
19
- * Props to be spread on the internal `Overlay` component.
20
- */
21
- overlayProps?: Partial<OverlayProps>;
22
- };
23
- export declare type ActionMenuProps = ActionMenuBaseProps & AnchoredOverlayWrapperAnchorProps;
20
+ } & Pick<AnchoredOverlayProps, 'anchorRef'>;
24
21
  export declare type MenuAnchorProps = {
25
22
  children: React.ReactElement;
26
23
  };
27
24
  /** this component is syntactical sugar 🍭 */
28
25
  export declare type MenuButtonProps = ButtonProps;
26
+ declare type MenuOverlayProps = Partial<OverlayProps> & {
27
+ /**
28
+ * Recommended: `ActionList`
29
+ */
30
+ children: React.ReactElement[] | React.ReactElement;
31
+ };
29
32
  export declare const ActionMenu: React.FC<ActionMenuProps> & {
30
33
  Button: React.ForwardRefExoticComponent<Pick<{
31
34
  color?: string | undefined;
@@ -305,6 +308,7 @@ export declare const ActionMenu: React.FC<ActionMenuProps> & {
305
308
  theme?: any;
306
309
  }, "color" | "translate" | "hidden" | "children" | "theme" | "value" | "form" | "slot" | "style" | "title" | "variant" | "role" | "sx" | "type" | "name" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "id" | "lang" | "placeholder" | "spellCheck" | "tabIndex" | "radioGroup" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "css" | "as" | "disabled" | "autoFocus" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget"> & React.RefAttributes<React.RefObject<HTMLElement> | undefined>>;
307
310
  Anchor: React.ForwardRefExoticComponent<MenuAnchorProps & React.RefAttributes<React.RefObject<HTMLElement> | undefined>>;
311
+ Overlay: React.FC<MenuOverlayProps>;
308
312
  Divider: React.FC<import("./sx").SxProp>;
309
313
  };
310
314
  export {};
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.ActionMenu = void 0;
6
+ exports.ActionMenu = exports.MenuContext = void 0;
7
7
 
8
8
  var _Button = _interopRequireDefault(require("./Button"));
9
9
 
@@ -11,59 +11,60 @@ var _react = _interopRequireDefault(require("react"));
11
11
 
12
12
  var _AnchoredOverlay = require("./AnchoredOverlay");
13
13
 
14
- var _useProvidedStateOrCreate = require("./hooks/useProvidedStateOrCreate");
15
-
16
14
  var _hooks = require("./hooks");
17
15
 
18
16
  var _Divider = require("./ActionList2/Divider");
19
17
 
20
- var _MenuContext = require("./ActionList2/MenuContext");
18
+ var _ActionListContainerContext = require("./ActionList2/ActionListContainerContext");
21
19
 
22
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
21
 
24
- const ActionMenuBase = ({
22
+ const MenuContext = /*#__PURE__*/_react.default.createContext({
23
+ renderAnchor: null,
24
+ open: false
25
+ });
26
+
27
+ exports.MenuContext = MenuContext;
28
+
29
+ const Menu = ({
25
30
  anchorRef: externalAnchorRef,
26
31
  open,
27
32
  onOpenChange,
28
- overlayProps,
29
33
  children
30
34
  }) => {
31
- const [combinedOpenState, setCombinedOpenState] = (0, _useProvidedStateOrCreate.useProvidedStateOrCreate)(open, onOpenChange, false);
32
- const anchorRef = (0, _hooks.useProvidedRefOrCreate)(externalAnchorRef);
35
+ const [combinedOpenState, setCombinedOpenState] = (0, _hooks.useProvidedStateOrCreate)(open, onOpenChange, false);
33
36
 
34
37
  const onOpen = _react.default.useCallback(() => setCombinedOpenState(true), [setCombinedOpenState]);
35
38
 
36
39
  const onClose = _react.default.useCallback(() => setCombinedOpenState(false), [setCombinedOpenState]);
37
40
 
38
- let renderAnchor = null;
39
- const contents = [];
41
+ const anchorRef = (0, _hooks.useProvidedRefOrCreate)(externalAnchorRef);
42
+ let renderAnchor = null; // 🚨 Hack for good API!
43
+ // we strip out Anchor from children and pass it to AnchoredOverlay to render
44
+ // with additional props for accessibility
40
45
 
41
- _react.default.Children.map(children, child => {
46
+ const contents = _react.default.Children.map(children, child => {
42
47
  if (child.type === MenuButton || child.type === Anchor) {
43
48
  renderAnchor = anchorProps => /*#__PURE__*/_react.default.cloneElement(child, anchorProps);
44
- } else {
45
- contents.push(child);
49
+
50
+ return null;
46
51
  }
52
+
53
+ return child;
47
54
  });
48
55
 
49
- return /*#__PURE__*/_react.default.createElement(_AnchoredOverlay.AnchoredOverlay, {
50
- renderAnchor: renderAnchor,
51
- anchorRef: anchorRef,
52
- open: combinedOpenState,
53
- onOpen: onOpen,
54
- onClose: onClose,
55
- overlayProps: overlayProps
56
- }, /*#__PURE__*/_react.default.createElement(_MenuContext.MenuContext.Provider, {
56
+ return /*#__PURE__*/_react.default.createElement(MenuContext.Provider, {
57
57
  value: {
58
- parent: 'ActionMenu',
59
- listRole: 'menu',
60
- itemRole: 'menuitem',
61
- afterSelect: onClose
58
+ anchorRef,
59
+ renderAnchor,
60
+ open: combinedOpenState,
61
+ onOpen,
62
+ onClose
62
63
  }
63
- }, contents));
64
+ }, contents);
64
65
  };
65
66
 
66
- ActionMenuBase.displayName = "ActionMenuBase";
67
+ Menu.displayName = "Menu";
67
68
 
68
69
  const Anchor = /*#__PURE__*/_react.default.forwardRef(({
69
70
  children,
@@ -82,10 +83,43 @@ const MenuButton = /*#__PURE__*/_react.default.forwardRef((props, anchorRef) =>
82
83
  }, /*#__PURE__*/_react.default.createElement(_Button.default, props));
83
84
  });
84
85
 
85
- ActionMenuBase.displayName = 'ActionMenu';
86
- const ActionMenu = Object.assign(ActionMenuBase, {
86
+ const Overlay = ({
87
+ children,
88
+ ...overlayProps
89
+ }) => {
90
+ // we typecast anchorRef as required instead of optional
91
+ // because we know that we're setting it in context in Menu
92
+ const {
93
+ anchorRef,
94
+ renderAnchor,
95
+ open,
96
+ onOpen,
97
+ onClose
98
+ } = _react.default.useContext(MenuContext);
99
+
100
+ return /*#__PURE__*/_react.default.createElement(_AnchoredOverlay.AnchoredOverlay, {
101
+ anchorRef: anchorRef,
102
+ renderAnchor: renderAnchor,
103
+ open: open,
104
+ onOpen: onOpen,
105
+ onClose: onClose,
106
+ overlayProps: overlayProps
107
+ }, /*#__PURE__*/_react.default.createElement(_ActionListContainerContext.ActionListContainerContext.Provider, {
108
+ value: {
109
+ container: 'ActionMenu',
110
+ listRole: 'menu',
111
+ itemRole: 'menuitem',
112
+ afterSelect: onClose
113
+ }
114
+ }, children));
115
+ };
116
+
117
+ Overlay.displayName = "Overlay";
118
+ Menu.displayName = 'ActionMenu';
119
+ const ActionMenu = Object.assign(Menu, {
87
120
  Button: MenuButton,
88
121
  Anchor,
122
+ Overlay,
89
123
  Divider: _Divider.Divider
90
124
  });
91
125
  exports.ActionMenu = ActionMenu;
@@ -9,3 +9,4 @@ export { useAnchoredPosition } from './useAnchoredPosition';
9
9
  export { useOverlay } from './useOverlay';
10
10
  export type { UseOverlaySettings } from './useOverlay';
11
11
  export { useRenderForcingRef } from './useRenderForcingRef';
12
+ export { useProvidedStateOrCreate } from './useProvidedStateOrCreate';
@@ -45,6 +45,12 @@ Object.defineProperty(exports, "useRenderForcingRef", {
45
45
  return _useRenderForcingRef.useRenderForcingRef;
46
46
  }
47
47
  });
48
+ Object.defineProperty(exports, "useProvidedStateOrCreate", {
49
+ enumerable: true,
50
+ get: function () {
51
+ return _useProvidedStateOrCreate.useProvidedStateOrCreate;
52
+ }
53
+ });
48
54
 
49
55
  var _useOnOutsideClick = require("./useOnOutsideClick");
50
56
 
@@ -58,4 +64,6 @@ var _useAnchoredPosition = require("./useAnchoredPosition");
58
64
 
59
65
  var _useOverlay = require("./useOverlay");
60
66
 
61
- var _useRenderForcingRef = require("./useRenderForcingRef");
67
+ var _useRenderForcingRef = require("./useRenderForcingRef");
68
+
69
+ var _useProvidedStateOrCreate = require("./useProvidedStateOrCreate");
@@ -1,10 +1,10 @@
1
1
  /** This context can be used by components that compose ActionList inside a Menu */
2
2
  import React from 'react';
3
3
  declare type ContextProps = {
4
- parent?: string;
4
+ container?: string;
5
5
  listRole?: string;
6
6
  itemRole?: string;
7
- afterSelect?: () => void;
7
+ afterSelect?: Function;
8
8
  };
9
- export declare const MenuContext: React.Context<ContextProps>;
9
+ export declare const ActionListContainerContext: React.Context<ContextProps>;
10
10
  export {};
@@ -1,3 +1,3 @@
1
1
  /** This context can be used by components that compose ActionList inside a Menu */
2
2
  import React from 'react';
3
- export const MenuContext = /*#__PURE__*/React.createContext({});
3
+ export const ActionListContainerContext = /*#__PURE__*/React.createContext({});
@@ -8,7 +8,7 @@ import Box from '../Box';
8
8
  import sx, { merge } from '../sx';
9
9
  import createSlots from '../utils/create-slots';
10
10
  import { ListContext } from './List';
11
- import { MenuContext } from './MenuContext';
11
+ import { ActionListContainerContext } from './ActionListContainerContext';
12
12
  import { Selection } from './Selection';
13
13
  export const getVariantStyles = (variant, disabled) => {
14
14
  if (disabled) {
@@ -66,7 +66,7 @@ export const Item = /*#__PURE__*/React.forwardRef(({
66
66
  const {
67
67
  itemRole,
68
68
  afterSelect
69
- } = React.useContext(MenuContext);
69
+ } = React.useContext(ActionListContainerContext);
70
70
  const {
71
71
  theme
72
72
  } = useTheme();
@@ -139,21 +139,19 @@ export const Item = /*#__PURE__*/React.forwardRef(({
139
139
  }
140
140
  };
141
141
  const clickHandler = React.useCallback(event => {
142
- if (typeof onSelect !== 'function') return;
143
142
  if (disabled) return;
144
143
 
145
144
  if (!event.defaultPrevented) {
146
- onSelect(event); // if this Item is inside a Menu, close the Menu
145
+ if (typeof onSelect === 'function') onSelect(event); // if this Item is inside a Menu, close the Menu
147
146
 
148
147
  if (typeof afterSelect === 'function') afterSelect();
149
148
  }
150
149
  }, [onSelect, disabled, afterSelect]);
151
150
  const keyPressHandler = React.useCallback(event => {
152
- if (typeof onSelect !== 'function') return;
153
151
  if (disabled) return;
154
152
 
155
153
  if (!event.defaultPrevented && [' ', 'Enter'].includes(event.key)) {
156
- onSelect(event); // if this Item is inside a Menu, close the Menu
154
+ if (typeof onSelect === 'function') onSelect(event); // if this Item is inside a Menu, close the Menu
157
155
 
158
156
  if (typeof afterSelect === 'function') afterSelect();
159
157
  }
@@ -3,7 +3,7 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
3
3
  import React from 'react';
4
4
  import styled from 'styled-components';
5
5
  import sx, { merge } from '../sx';
6
- import { MenuContext } from './MenuContext';
6
+ import { ActionListContainerContext } from './ActionListContainerContext';
7
7
  export const ListContext = /*#__PURE__*/React.createContext({});
8
8
  const ListBox = styled.ul.withConfig({
9
9
  displayName: "List__ListBox",
@@ -27,7 +27,7 @@ export const List = /*#__PURE__*/React.forwardRef(({
27
27
 
28
28
  const {
29
29
  listRole
30
- } = React.useContext(MenuContext);
30
+ } = React.useContext(ActionListContainerContext);
31
31
  return /*#__PURE__*/React.createElement(ListBox, _extends({
32
32
  sx: merge(styles, sxProp),
33
33
  role: role || listRole
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { CheckIcon } from '@primer/octicons-react';
3
3
  import { ListContext } from './List';
4
4
  import { GroupContext } from './Group';
5
- import { MenuContext } from './MenuContext';
5
+ import { ActionListContainerContext } from './ActionListContainerContext';
6
6
  import { LeadingVisualContainer } from './Visuals';
7
7
  export const Selection = ({
8
8
  selected
@@ -14,8 +14,8 @@ export const Selection = ({
14
14
  selectionVariant: groupSelectionVariant
15
15
  } = React.useContext(GroupContext);
16
16
  const {
17
- parent
18
- } = React.useContext(MenuContext);
17
+ container
18
+ } = React.useContext(ActionListContainerContext);
19
19
  /** selectionVariant in Group can override the selectionVariant in List root */
20
20
 
21
21
  const selectionVariant = typeof groupSelectionVariant !== 'undefined' ? groupSelectionVariant : listSelectionVariant; // if selectionVariant is not set on List, don't show selection
@@ -26,7 +26,7 @@ export const Selection = ({
26
26
  return null;
27
27
  }
28
28
 
29
- if (parent === 'ActionMenu') {
29
+ if (container === 'ActionMenu') {
30
30
  throw new Error('ActionList cannot have a selectionVariant inside ActionMenu, please use DropdownMenu or SelectPanel instead. More information: https://primer.style/design/components/action-list#application');
31
31
  return null;
32
32
  }
@@ -1,10 +1,12 @@
1
1
  import { ButtonProps } from './Button';
2
2
  import React from 'react';
3
+ import { AnchoredOverlayProps } from './AnchoredOverlay';
3
4
  import { OverlayProps } from './Overlay';
4
- import { AnchoredOverlayWrapperAnchorProps } from './AnchoredOverlay/AnchoredOverlay';
5
- declare type ActionMenuBaseProps = {
5
+ declare type MenuContextProps = Pick<AnchoredOverlayProps, 'anchorRef' | 'renderAnchor' | 'open' | 'onOpen' | 'onClose'>;
6
+ export declare const MenuContext: React.Context<MenuContextProps>;
7
+ export declare type ActionMenuProps = {
6
8
  /**
7
- * Recommended: `ActionMenu.Button` or `ActionMenu.Anchor` with ActionList`
9
+ * Recommended: `ActionMenu.Button` or `ActionMenu.Anchor` with `ActionMenu.Overlay`
8
10
  */
9
11
  children: React.ReactElement[] | React.ReactElement;
10
12
  /**
@@ -15,17 +17,18 @@ declare type ActionMenuBaseProps = {
15
17
  * If defined, will control the open/closed state of the overlay. Must be used in conjuction with `open`.
16
18
  */
17
19
  onOpenChange?: (s: boolean) => void;
18
- /**
19
- * Props to be spread on the internal `Overlay` component.
20
- */
21
- overlayProps?: Partial<OverlayProps>;
22
- };
23
- export declare type ActionMenuProps = ActionMenuBaseProps & AnchoredOverlayWrapperAnchorProps;
20
+ } & Pick<AnchoredOverlayProps, 'anchorRef'>;
24
21
  export declare type MenuAnchorProps = {
25
22
  children: React.ReactElement;
26
23
  };
27
24
  /** this component is syntactical sugar 🍭 */
28
25
  export declare type MenuButtonProps = ButtonProps;
26
+ declare type MenuOverlayProps = Partial<OverlayProps> & {
27
+ /**
28
+ * Recommended: `ActionList`
29
+ */
30
+ children: React.ReactElement[] | React.ReactElement;
31
+ };
29
32
  export declare const ActionMenu: React.FC<ActionMenuProps> & {
30
33
  Button: React.ForwardRefExoticComponent<Pick<{
31
34
  color?: string | undefined;
@@ -305,6 +308,7 @@ export declare const ActionMenu: React.FC<ActionMenuProps> & {
305
308
  theme?: any;
306
309
  }, "color" | "translate" | "hidden" | "children" | "theme" | "value" | "form" | "slot" | "style" | "title" | "variant" | "role" | "sx" | "type" | "name" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "id" | "lang" | "placeholder" | "spellCheck" | "tabIndex" | "radioGroup" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "css" | "as" | "disabled" | "autoFocus" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget"> & React.RefAttributes<React.RefObject<HTMLElement> | undefined>>;
307
310
  Anchor: React.ForwardRefExoticComponent<MenuAnchorProps & React.RefAttributes<React.RefObject<HTMLElement> | undefined>>;
311
+ Overlay: React.FC<MenuOverlayProps>;
308
312
  Divider: React.FC<import("./sx").SxProp>;
309
313
  };
310
314
  export {};
@@ -1,49 +1,49 @@
1
1
  import Button from './Button';
2
2
  import React from 'react';
3
3
  import { AnchoredOverlay } from './AnchoredOverlay';
4
- import { useProvidedStateOrCreate } from './hooks/useProvidedStateOrCreate';
5
- import { useProvidedRefOrCreate } from './hooks';
4
+ import { useProvidedRefOrCreate, useProvidedStateOrCreate } from './hooks';
6
5
  import { Divider } from './ActionList2/Divider';
7
- import { MenuContext as ActionListMenuContext } from './ActionList2/MenuContext';
6
+ import { ActionListContainerContext } from './ActionList2/ActionListContainerContext';
7
+ export const MenuContext = /*#__PURE__*/React.createContext({
8
+ renderAnchor: null,
9
+ open: false
10
+ });
8
11
 
9
- const ActionMenuBase = ({
12
+ const Menu = ({
10
13
  anchorRef: externalAnchorRef,
11
14
  open,
12
15
  onOpenChange,
13
- overlayProps,
14
16
  children
15
17
  }) => {
16
18
  const [combinedOpenState, setCombinedOpenState] = useProvidedStateOrCreate(open, onOpenChange, false);
17
- const anchorRef = useProvidedRefOrCreate(externalAnchorRef);
18
19
  const onOpen = React.useCallback(() => setCombinedOpenState(true), [setCombinedOpenState]);
19
20
  const onClose = React.useCallback(() => setCombinedOpenState(false), [setCombinedOpenState]);
20
- let renderAnchor = null;
21
- const contents = [];
22
- React.Children.map(children, child => {
21
+ const anchorRef = useProvidedRefOrCreate(externalAnchorRef);
22
+ let renderAnchor = null; // 🚨 Hack for good API!
23
+ // we strip out Anchor from children and pass it to AnchoredOverlay to render
24
+ // with additional props for accessibility
25
+
26
+ const contents = React.Children.map(children, child => {
23
27
  if (child.type === MenuButton || child.type === Anchor) {
24
28
  renderAnchor = anchorProps => /*#__PURE__*/React.cloneElement(child, anchorProps);
25
- } else {
26
- contents.push(child);
29
+
30
+ return null;
27
31
  }
32
+
33
+ return child;
28
34
  });
29
- return /*#__PURE__*/React.createElement(AnchoredOverlay, {
30
- renderAnchor: renderAnchor,
31
- anchorRef: anchorRef,
32
- open: combinedOpenState,
33
- onOpen: onOpen,
34
- onClose: onClose,
35
- overlayProps: overlayProps
36
- }, /*#__PURE__*/React.createElement(ActionListMenuContext.Provider, {
35
+ return /*#__PURE__*/React.createElement(MenuContext.Provider, {
37
36
  value: {
38
- parent: 'ActionMenu',
39
- listRole: 'menu',
40
- itemRole: 'menuitem',
41
- afterSelect: onClose
37
+ anchorRef,
38
+ renderAnchor,
39
+ open: combinedOpenState,
40
+ onOpen,
41
+ onClose
42
42
  }
43
- }, contents));
43
+ }, contents);
44
44
  };
45
45
 
46
- ActionMenuBase.displayName = "ActionMenuBase";
46
+ Menu.displayName = "Menu";
47
47
  const Anchor = /*#__PURE__*/React.forwardRef(({
48
48
  children,
49
49
  ...anchorProps
@@ -59,9 +59,42 @@ const MenuButton = /*#__PURE__*/React.forwardRef((props, anchorRef) => {
59
59
  ref: anchorRef
60
60
  }, /*#__PURE__*/React.createElement(Button, props));
61
61
  });
62
- ActionMenuBase.displayName = 'ActionMenu';
63
- export const ActionMenu = Object.assign(ActionMenuBase, {
62
+
63
+ const Overlay = ({
64
+ children,
65
+ ...overlayProps
66
+ }) => {
67
+ // we typecast anchorRef as required instead of optional
68
+ // because we know that we're setting it in context in Menu
69
+ const {
70
+ anchorRef,
71
+ renderAnchor,
72
+ open,
73
+ onOpen,
74
+ onClose
75
+ } = React.useContext(MenuContext);
76
+ return /*#__PURE__*/React.createElement(AnchoredOverlay, {
77
+ anchorRef: anchorRef,
78
+ renderAnchor: renderAnchor,
79
+ open: open,
80
+ onOpen: onOpen,
81
+ onClose: onClose,
82
+ overlayProps: overlayProps
83
+ }, /*#__PURE__*/React.createElement(ActionListContainerContext.Provider, {
84
+ value: {
85
+ container: 'ActionMenu',
86
+ listRole: 'menu',
87
+ itemRole: 'menuitem',
88
+ afterSelect: onClose
89
+ }
90
+ }, children));
91
+ };
92
+
93
+ Overlay.displayName = "Overlay";
94
+ Menu.displayName = 'ActionMenu';
95
+ export const ActionMenu = Object.assign(Menu, {
64
96
  Button: MenuButton,
65
97
  Anchor,
98
+ Overlay,
66
99
  Divider
67
100
  });