@primer/react 38.42.0-rc.fcbfbaea1 → 38.42.0

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 (51) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/ActionBar/ActionBar.js +498 -162
  3. package/dist/ActionBar/index.d.ts +2 -2
  4. package/dist/ActionList/Group.js +4 -5
  5. package/dist/ActionList/Item.js +2 -2
  6. package/dist/Banner/Banner.js +3 -5
  7. package/dist/Button/ButtonBase.js +3 -2
  8. package/dist/Button/IconButton.js +3 -4
  9. package/dist/Button/types.d.ts +2 -2
  10. package/dist/Card/Card.js +1 -2
  11. package/dist/Checkbox/Checkbox.js +145 -41
  12. package/dist/CounterLabel/CounterLabel.js +80 -18
  13. package/dist/Details/Details.js +2 -4
  14. package/dist/FeatureFlags/FeatureFlagScope.js +1 -0
  15. package/dist/FilteredActionList/constants.js +2 -0
  16. package/dist/FilteredActionList/useAnnouncements.js +148 -81
  17. package/dist/FormControl/FormControl.js +55 -80
  18. package/dist/FormControl/FormControlLabel.js +1 -2
  19. package/dist/InlineMessage/InlineMessage.js +1 -2
  20. package/dist/NavList/NavList.js +3 -4
  21. package/dist/Overlay/Overlay.d.ts +2 -0
  22. package/dist/Overlay/Overlay.js +300 -63
  23. package/dist/PageLayout/usePaneWidth.js +2 -2
  24. package/dist/Popover/Popover.js +3 -5
  25. package/dist/ProgressBar/ProgressBar.js +1 -2
  26. package/dist/SegmentedControl/SegmentedControlButton.js +1 -2
  27. package/dist/Select/Select.js +2 -2
  28. package/dist/SelectPanel/SelectPanel.d.ts +1 -1
  29. package/dist/SelectPanel/SelectPanel.js +1 -1
  30. package/dist/Spinner/Spinner.js +1 -2
  31. package/dist/TextInput/TextInput.js +242 -87
  32. package/dist/Textarea/Textarea.d.ts +2 -2
  33. package/dist/ToggleSwitch/ToggleSwitch.js +2 -3
  34. package/dist/Tooltip/Tooltip.js +98 -17
  35. package/dist/TooltipV2/Tooltip.js +295 -138
  36. package/dist/TopicTag/TopicTag.js +1 -2
  37. package/dist/Truncate/Truncate.js +87 -14
  38. package/dist/UnderlineNav/UnderlineNavItem.js +2 -4
  39. package/dist/deprecated/ActionList/List.js +1 -1
  40. package/dist/experimental/SelectPanel2/SelectPanel.d.ts +1 -1
  41. package/dist/hooks/useOpenAndCloseFocus.d.ts +3 -1
  42. package/dist/hooks/useOpenAndCloseFocus.js +28 -16
  43. package/dist/hooks/useOverlay.d.ts +3 -1
  44. package/dist/hooks/useOverlay.js +24 -22
  45. package/dist/internal/components/InputLabel.js +1 -2
  46. package/dist/internal/components/TextInputInnerAction.js +1 -2
  47. package/dist/internal/components/TextInputWrapper.d.ts +3 -0
  48. package/dist/internal/hooks/useThemeProvider.js +3 -3
  49. package/generated/components.json +34 -20
  50. package/generated/hooks.json +12 -0
  51. package/package.json +12 -13
@@ -6,12 +6,14 @@ type UseOpenAndCloseFocusSettings = {
6
6
  containerRef: React.RefObject<HTMLElement | null>;
7
7
  returnFocusRef: React.RefObject<HTMLElement | null>;
8
8
  preventFocusOnOpen?: boolean;
9
+ preventFocusOnClose?: boolean;
9
10
  };
10
11
  declare function useOpenAndCloseFocus({
11
12
  initialFocusRef,
12
13
  returnFocusRef,
13
14
  containerRef,
14
- preventFocusOnOpen
15
+ preventFocusOnOpen,
16
+ preventFocusOnClose
15
17
  }: UseOpenAndCloseFocusSettings): void;
16
18
  //#endregion
17
19
  export { UseOpenAndCloseFocusSettings, useOpenAndCloseFocus };
@@ -1,14 +1,24 @@
1
1
  import { c } from "../utils/react-compiler-runtime.js";
2
+ import { useEffectCallback } from "../internal/hooks/useEffectCallback.js";
2
3
  import { useEffect } from "react";
3
4
  import { iterateFocusableElements } from "@primer/behaviors/utils";
4
5
  //#region src/hooks/useOpenAndCloseFocus.ts
5
6
  function useOpenAndCloseFocus(t0) {
6
- const $ = c(6);
7
- const { initialFocusRef, returnFocusRef, containerRef, preventFocusOnOpen } = t0;
7
+ const $ = c(9);
8
+ const { initialFocusRef, returnFocusRef, containerRef, preventFocusOnOpen, preventFocusOnClose } = t0;
8
9
  let t1;
10
+ if ($[0] !== preventFocusOnClose) {
11
+ t1 = (element) => {
12
+ if (!preventFocusOnClose) element === null || element === void 0 || element.focus();
13
+ };
14
+ $[0] = preventFocusOnClose;
15
+ $[1] = t1;
16
+ } else t1 = $[1];
17
+ const restoreFocus = useEffectCallback(t1);
9
18
  let t2;
10
- if ($[0] !== containerRef || $[1] !== initialFocusRef || $[2] !== preventFocusOnOpen || $[3] !== returnFocusRef) {
11
- t1 = () => {
19
+ let t3;
20
+ if ($[2] !== containerRef || $[3] !== initialFocusRef || $[4] !== preventFocusOnOpen || $[5] !== restoreFocus || $[6] !== returnFocusRef) {
21
+ t2 = () => {
12
22
  if (!preventFocusOnOpen) {
13
23
  if (initialFocusRef && initialFocusRef.current) initialFocusRef.current.focus();
14
24
  else if (containerRef.current) {
@@ -18,26 +28,28 @@ function useOpenAndCloseFocus(t0) {
18
28
  }
19
29
  const returnFocusRefCurrent = returnFocusRef.current;
20
30
  return function() {
21
- returnFocusRefCurrent === null || returnFocusRefCurrent === void 0 || returnFocusRefCurrent.focus();
31
+ restoreFocus(returnFocusRefCurrent);
22
32
  };
23
33
  };
24
- t2 = [
34
+ t3 = [
25
35
  initialFocusRef,
26
36
  returnFocusRef,
27
37
  containerRef,
28
- preventFocusOnOpen
38
+ preventFocusOnOpen,
39
+ restoreFocus
29
40
  ];
30
- $[0] = containerRef;
31
- $[1] = initialFocusRef;
32
- $[2] = preventFocusOnOpen;
33
- $[3] = returnFocusRef;
34
- $[4] = t1;
35
- $[5] = t2;
41
+ $[2] = containerRef;
42
+ $[3] = initialFocusRef;
43
+ $[4] = preventFocusOnOpen;
44
+ $[5] = restoreFocus;
45
+ $[6] = returnFocusRef;
46
+ $[7] = t2;
47
+ $[8] = t3;
36
48
  } else {
37
- t1 = $[4];
38
- t2 = $[5];
49
+ t2 = $[7];
50
+ t3 = $[8];
39
51
  }
40
- useEffect(t1, t2);
52
+ useEffect(t2, t3);
41
53
  }
42
54
  //#endregion
43
55
  export { useOpenAndCloseFocus };
@@ -9,6 +9,7 @@ type UseOverlaySettings = {
9
9
  onClickOutside: (e: TouchOrMouseEvent) => void;
10
10
  overlayRef?: React.RefObject<HTMLDivElement | null>;
11
11
  preventFocusOnOpen?: boolean;
12
+ preventFocusOnClose?: boolean;
12
13
  };
13
14
  type OverlayReturnProps = {
14
15
  ref: React.RefObject<HTMLDivElement | null>;
@@ -20,7 +21,8 @@ declare const useOverlay: ({
20
21
  onEscape,
21
22
  ignoreClickRefs,
22
23
  onClickOutside,
23
- preventFocusOnOpen
24
+ preventFocusOnOpen,
25
+ preventFocusOnClose
24
26
  }: UseOverlaySettings) => OverlayReturnProps;
25
27
  //#endregion
26
28
  export { OverlayReturnProps, UseOverlaySettings, useOverlay };
@@ -5,53 +5,55 @@ import { useOnEscapePress } from "./useOnEscapePress.js";
5
5
  import { useOpenAndCloseFocus } from "./useOpenAndCloseFocus.js";
6
6
  //#region src/hooks/useOverlay.tsx
7
7
  const useOverlay = (t0) => {
8
- const $ = c(13);
9
- const { overlayRef: _overlayRef, returnFocusRef, initialFocusRef, onEscape, ignoreClickRefs, onClickOutside, preventFocusOnOpen } = t0;
8
+ const $ = c(14);
9
+ const { overlayRef: _overlayRef, returnFocusRef, initialFocusRef, onEscape, ignoreClickRefs, onClickOutside, preventFocusOnOpen, preventFocusOnClose } = t0;
10
10
  const overlayRef = useProvidedRefOrCreate(_overlayRef);
11
11
  let t1;
12
- if ($[0] !== initialFocusRef || $[1] !== overlayRef || $[2] !== preventFocusOnOpen || $[3] !== returnFocusRef) {
12
+ if ($[0] !== initialFocusRef || $[1] !== overlayRef || $[2] !== preventFocusOnClose || $[3] !== preventFocusOnOpen || $[4] !== returnFocusRef) {
13
13
  t1 = {
14
14
  containerRef: overlayRef,
15
15
  returnFocusRef,
16
16
  initialFocusRef,
17
- preventFocusOnOpen
17
+ preventFocusOnOpen,
18
+ preventFocusOnClose
18
19
  };
19
20
  $[0] = initialFocusRef;
20
21
  $[1] = overlayRef;
21
- $[2] = preventFocusOnOpen;
22
- $[3] = returnFocusRef;
23
- $[4] = t1;
24
- } else t1 = $[4];
22
+ $[2] = preventFocusOnClose;
23
+ $[3] = preventFocusOnOpen;
24
+ $[4] = returnFocusRef;
25
+ $[5] = t1;
26
+ } else t1 = $[5];
25
27
  useOpenAndCloseFocus(t1);
26
28
  let t2;
27
- if ($[5] !== ignoreClickRefs || $[6] !== onClickOutside || $[7] !== overlayRef) {
29
+ if ($[6] !== ignoreClickRefs || $[7] !== onClickOutside || $[8] !== overlayRef) {
28
30
  t2 = {
29
31
  containerRef: overlayRef,
30
32
  ignoreClickRefs,
31
33
  onClickOutside
32
34
  };
33
- $[5] = ignoreClickRefs;
34
- $[6] = onClickOutside;
35
- $[7] = overlayRef;
36
- $[8] = t2;
37
- } else t2 = $[8];
35
+ $[6] = ignoreClickRefs;
36
+ $[7] = onClickOutside;
37
+ $[8] = overlayRef;
38
+ $[9] = t2;
39
+ } else t2 = $[9];
38
40
  useOnOutsideClick(t2);
39
41
  let t3;
40
- if ($[9] !== onEscape) {
42
+ if ($[10] !== onEscape) {
41
43
  t3 = (event) => {
42
44
  onEscape(event);
43
45
  event.preventDefault();
44
46
  };
45
- $[9] = onEscape;
46
- $[10] = t3;
47
- } else t3 = $[10];
47
+ $[10] = onEscape;
48
+ $[11] = t3;
49
+ } else t3 = $[11];
48
50
  useOnEscapePress(t3);
49
51
  let t4;
50
- if ($[11] !== overlayRef) {
52
+ if ($[12] !== overlayRef) {
51
53
  t4 = { ref: overlayRef };
52
- $[11] = overlayRef;
53
- $[12] = t4;
54
- } else t4 = $[12];
54
+ $[12] = overlayRef;
55
+ $[13] = t4;
56
+ } else t4 = $[13];
55
57
  return t4;
56
58
  };
57
59
  //#endregion
@@ -54,12 +54,11 @@ function InputLabel(t0) {
54
54
  } else t4 = $[13];
55
55
  let t5;
56
56
  if ($[14] !== children || $[15] !== required || $[16] !== requiredIndicator || $[17] !== requiredText) {
57
- var _requiredText;
58
57
  t5 = required || requiredText ? /* @__PURE__ */ jsxs("span", {
59
58
  className: InputLabel_module_css_default.RequiredText,
60
59
  children: [/* @__PURE__ */ jsx("span", { children }), /* @__PURE__ */ jsx("span", {
61
60
  "aria-hidden": requiredIndicator ? void 0 : true,
62
- children: (_requiredText = requiredText) !== null && _requiredText !== void 0 ? _requiredText : "*"
61
+ children: requiredText !== null && requiredText !== void 0 ? requiredText : "*"
63
62
  })]
64
63
  }) : children;
65
64
  $[14] = children;
@@ -94,13 +94,12 @@ const TextInputAction = /*#__PURE__*/ forwardRef((t0, forwardedRef) => {
94
94
  } else t6 = $[17];
95
95
  let t7;
96
96
  if ($[18] !== accessibleLabel || $[19] !== ariaLabel || $[20] !== children || $[21] !== forwardedRef || $[22] !== icon || $[23] !== rest || $[24] !== styleProps || $[25] !== tooltipDirection || $[26] !== variant) {
97
- var _tooltipDirection;
98
97
  t7 = /* @__PURE__ */ jsx("span", {
99
98
  className: t6,
100
99
  "data-component": "TextInput.Action",
101
100
  children: icon && !children && ariaLabel ? /* @__PURE__ */ jsx(IconButton, {
102
101
  ...accessibleLabel,
103
- tooltipDirection: (_tooltipDirection = tooltipDirection) !== null && _tooltipDirection !== void 0 ? _tooltipDirection : "s",
102
+ tooltipDirection: tooltipDirection !== null && tooltipDirection !== void 0 ? tooltipDirection : "s",
104
103
  variant,
105
104
  type: "button",
106
105
  icon,
@@ -5,6 +5,9 @@ import React, { ComponentProps } from "react";
5
5
  type TextInputSizes = 'small' | 'medium' | 'large';
6
6
  type StyledTextInputBaseWrapperProps = {
7
7
  block?: boolean;
8
+ /**
9
+ * @deprecated Omit this prop to use the default background.
10
+ */
8
11
  contrast?: boolean;
9
12
  disabled?: boolean;
10
13
  hasTrailingAction?: boolean;
@@ -53,7 +53,7 @@ function useThemeProvider(props) {
53
53
  }
54
54
  function subscribeToSystemColorMode(callback) {
55
55
  var _window, _window$matchMedia;
56
- const media = (_window = window) === null || _window === void 0 ? void 0 : (_window$matchMedia = _window.matchMedia) === null || _window$matchMedia === void 0 ? void 0 : _window$matchMedia.call(_window, "(prefers-color-scheme: dark)");
56
+ const media = (_window = window) === null || _window === void 0 || (_window$matchMedia = _window.matchMedia) === null || _window$matchMedia === void 0 ? void 0 : _window$matchMedia.call(_window, "(prefers-color-scheme: dark)");
57
57
  media === null || media === void 0 || media.addEventListener("change", callback);
58
58
  return () => media === null || media === void 0 ? void 0 : media.removeEventListener("change", callback);
59
59
  }
@@ -64,8 +64,8 @@ function _temp() {
64
64
  return "day";
65
65
  }
66
66
  function getSystemColorMode() {
67
- var _window2, _window2$matchMedia, _window2$matchMedia$c;
68
- return (_window2 = window) !== null && _window2 !== void 0 && (_window2$matchMedia = _window2.matchMedia) !== null && _window2$matchMedia !== void 0 && (_window2$matchMedia$c = _window2$matchMedia.call(_window2, "(prefers-color-scheme: dark)")) !== null && _window2$matchMedia$c !== void 0 && _window2$matchMedia$c.matches ? "night" : "day";
67
+ var _window2, _window2$matchMedia;
68
+ return (_window2 = window) !== null && _window2 !== void 0 && (_window2$matchMedia = _window2.matchMedia) !== null && _window2$matchMedia !== void 0 && (_window2$matchMedia = _window2$matchMedia.call(_window2, "(prefers-color-scheme: dark)")) !== null && _window2$matchMedia !== void 0 && _window2$matchMedia.matches ? "night" : "day";
69
69
  }
70
70
  //#endregion
71
71
  export { useThemeProvider };
@@ -10,7 +10,7 @@
10
10
  "stories": [
11
11
  {
12
12
  "id": "experimental-components-actionbar--default",
13
- "code": "() => (\n <ActionBar aria-label=\"Toolbar\">\n <ActionBar.IconButton\n icon={BoldIcon}\n aria-label=\"Bold\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={ItalicIcon}\n aria-label=\"Italic\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={CodeIcon}\n aria-label=\"Code\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={LinkIcon}\n aria-label=\"Link\"\n ></ActionBar.IconButton>\n <ActionBar.Divider />\n <ActionBar.IconButton\n icon={FileAddedIcon}\n aria-label=\"File Added\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={SearchIcon}\n aria-label=\"Search\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={QuoteIcon}\n aria-label=\"Insert Quote\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={ListUnorderedIcon}\n aria-label=\"Unordered List\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={ListOrderedIcon}\n aria-label=\"Ordered List\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={TasklistIcon}\n aria-label=\"Task List\"\n onClick={() => alert('Task List clicked')}\n ></ActionBar.IconButton>\n </ActionBar>\n)"
13
+ "code": "() => (\n <ActionBar aria-label=\"Toolbar\">\n <ActionBar.IconButton\n icon={<BoldIcon />}\n aria-label=\"Bold\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={<ItalicIcon />}\n aria-label=\"Italic\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={<CodeIcon />}\n aria-label=\"Code\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={<LinkIcon />}\n aria-label=\"Link\"\n ></ActionBar.IconButton>\n <ActionBar.Divider />\n <ActionBar.IconButton\n icon={<FileAddedIcon />}\n aria-label=\"File Added\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={<SearchIcon />}\n aria-label=\"Search\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={<QuoteIcon />}\n aria-label=\"Insert Quote\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={<ListUnorderedIcon />}\n aria-label=\"Unordered List\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={<ListOrderedIcon />}\n aria-label=\"Ordered List\"\n ></ActionBar.IconButton>\n <ActionBar.IconButton\n icon={<TasklistIcon />}\n aria-label=\"Task List\"\n onClick={() => alert('Task List clicked')}\n ></ActionBar.IconButton>\n </ActionBar>\n)"
14
14
  }
15
15
  ],
16
16
  "importPath": "@primer/react",
@@ -832,6 +832,12 @@
832
832
  "defaultValue": "",
833
833
  "description": "Callback that is called when the position of the overlay changes"
834
834
  },
835
+ {
836
+ "name": "preventFocusOnClose",
837
+ "type": "boolean",
838
+ "defaultValue": "false",
839
+ "description": "If true, focus will not be returned to the anchor or returnFocusRef when the menu closes. Consumers must manage focus themselves."
840
+ },
835
841
  {
836
842
  "name": "data-test-id",
837
843
  "type": "unknown",
@@ -1997,63 +2003,63 @@
1997
2003
  "stories": [
1998
2004
  {
1999
2005
  "id": "components-iconbutton--default",
2000
- "code": "() => <IconButton icon={HeartIcon} aria-label=\"Favorite\" />"
2006
+ "code": "() => <IconButton icon={<HeartIcon />} aria-label=\"Favorite\" />"
2001
2007
  },
2002
2008
  {
2003
2009
  "id": "components-iconbutton-features--primary",
2004
- "code": "() => <IconButton icon={HeartIcon} variant=\"primary\" aria-label=\"Favorite\" />"
2010
+ "code": "() => (\n <IconButton icon={<HeartIcon />} variant=\"primary\" aria-label=\"Favorite\" />\n)"
2005
2011
  },
2006
2012
  {
2007
2013
  "id": "components-iconbutton-features--danger",
2008
- "code": "() => <IconButton icon={HeartIcon} variant=\"danger\" aria-label=\"Favorite\" />"
2014
+ "code": "() => (\n <IconButton icon={<HeartIcon />} variant=\"danger\" aria-label=\"Favorite\" />\n)"
2009
2015
  },
2010
2016
  {
2011
2017
  "id": "components-iconbutton-features--invisible",
2012
- "code": "() => <IconButton icon={HeartIcon} variant=\"invisible\" aria-label=\"Favorite\" />"
2018
+ "code": "() => (\n <IconButton icon={<HeartIcon />} variant=\"invisible\" aria-label=\"Favorite\" />\n)"
2013
2019
  },
2014
2020
  {
2015
2021
  "id": "components-iconbutton-features--disabled",
2016
- "code": "() => <IconButton disabled icon={HeartIcon} aria-label=\"Favorite\" />"
2022
+ "code": "() => <IconButton disabled icon={<HeartIcon />} aria-label=\"Favorite\" />"
2017
2023
  },
2018
2024
  {
2019
2025
  "id": "components-iconbutton-features--small",
2020
- "code": "() => <IconButton size=\"small\" icon={HeartIcon} aria-label=\"Favorite\" />"
2026
+ "code": "() => <IconButton size=\"small\" icon={<HeartIcon />} aria-label=\"Favorite\" />"
2021
2027
  },
2022
2028
  {
2023
2029
  "id": "components-iconbutton-features--medium",
2024
- "code": "() => <IconButton size=\"medium\" icon={HeartIcon} aria-label=\"Favorite\" />"
2030
+ "code": "() => <IconButton size=\"medium\" icon={<HeartIcon />} aria-label=\"Favorite\" />"
2025
2031
  },
2026
2032
  {
2027
2033
  "id": "components-iconbutton-features--large",
2028
- "code": "() => <IconButton size=\"large\" icon={HeartIcon} aria-label=\"Favorite\" />"
2034
+ "code": "() => <IconButton size=\"large\" icon={<HeartIcon />} aria-label=\"Favorite\" />"
2029
2035
  },
2030
2036
  {
2031
2037
  "id": "components-iconbutton-features--with-description",
2032
- "code": "() => (\n <IconButton\n icon={InboxIcon}\n aria-label=\"Notifications\"\n description=\"You have no unread notifications.\"\n />\n)"
2038
+ "code": "() => (\n <IconButton\n icon={<InboxIcon />}\n aria-label=\"Notifications\"\n description=\"You have no unread notifications.\"\n />\n)"
2033
2039
  },
2034
2040
  {
2035
2041
  "id": "components-iconbutton-features--external-tooltip",
2036
- "code": "() => (\n <Tooltip\n text=\"this is a supportive description for icon button\"\n direction=\"se\"\n >\n <IconButton icon={HeartIcon} aria-label=\"HeartIcon\" />\n </Tooltip>\n)"
2042
+ "code": "() => (\n <Tooltip\n text=\"this is a supportive description for icon button\"\n direction=\"se\"\n >\n <IconButton icon={<HeartIcon />} aria-label=\"HeartIcon\" />\n </Tooltip>\n)"
2037
2043
  },
2038
2044
  {
2039
2045
  "id": "components-iconbutton-features--as-a-menu-anchor",
2040
- "code": "() => (\n <ActionMenu>\n <ActionMenu.Anchor>\n <IconButton icon={ChevronDownIcon} aria-label=\"Something\" />\n </ActionMenu.Anchor>\n\n <ActionMenu.Overlay width=\"medium\">\n <ActionList>\n <ActionList.Item onSelect={() => alert('Copy link clicked')}>\n Copy link\n <ActionList.TrailingVisual>⌘C</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Quote reply clicked')}>\n Quote reply\n <ActionList.TrailingVisual>⌘Q</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Edit comment clicked')}>\n Edit comment\n <ActionList.TrailingVisual>⌘E</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item\n variant=\"danger\"\n onSelect={() => alert('Delete file clicked')}\n >\n Delete file\n <ActionList.TrailingVisual>⌘D</ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n)"
2046
+ "code": "() => (\n <ActionMenu>\n <ActionMenu.Anchor>\n <IconButton icon={<ChevronDownIcon />} aria-label=\"Something\" />\n </ActionMenu.Anchor>\n\n <ActionMenu.Overlay width=\"medium\">\n <ActionList>\n <ActionList.Item onSelect={() => alert('Copy link clicked')}>\n Copy link\n <ActionList.TrailingVisual>⌘C</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Quote reply clicked')}>\n Quote reply\n <ActionList.TrailingVisual>⌘Q</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Item onSelect={() => alert('Edit comment clicked')}>\n Edit comment\n <ActionList.TrailingVisual>⌘E</ActionList.TrailingVisual>\n </ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item\n variant=\"danger\"\n onSelect={() => alert('Delete file clicked')}\n >\n Delete file\n <ActionList.TrailingVisual>⌘D</ActionList.TrailingVisual>\n </ActionList.Item>\n </ActionList>\n </ActionMenu.Overlay>\n </ActionMenu>\n)"
2041
2047
  },
2042
2048
  {
2043
2049
  "id": "components-iconbutton-features--loading",
2044
- "code": "() => (\n <IconButton loading icon={HeartIcon} variant=\"primary\" aria-label=\"Primary\" />\n)"
2050
+ "code": "() => (\n <IconButton\n loading\n icon={<HeartIcon />}\n variant=\"primary\"\n aria-label=\"Primary\"\n />\n)"
2045
2051
  },
2046
2052
  {
2047
2053
  "id": "components-iconbutton-features--loading-trigger",
2048
- "code": "() => {\n const [isLoading, setIsLoading] = useState(false)\n const handleClick = () => {\n setIsLoading(true)\n setTimeout(() => {\n setIsLoading(false)\n }, 3000)\n }\n return (\n <IconButton\n loading={isLoading}\n onClick={handleClick}\n icon={DownloadIcon}\n aria-label=\"Download\"\n />\n )\n}"
2054
+ "code": "() => {\n const [isLoading, setIsLoading] = useState(false)\n const handleClick = () => {\n setIsLoading(true)\n setTimeout(() => {\n setIsLoading(false)\n }, 3000)\n }\n return (\n <IconButton\n loading={isLoading}\n onClick={handleClick}\n icon={<DownloadIcon />}\n aria-label=\"Download\"\n />\n )\n}"
2049
2055
  },
2050
2056
  {
2051
2057
  "id": "components-iconbutton-features--keybinding-hint-on-description",
2052
- "code": "() => (\n <IconButton\n icon={InboxIcon}\n aria-label=\"Notifications\"\n description=\"You have unread notifications\"\n keybindingHint=\"G+N\"\n />\n)"
2058
+ "code": "() => (\n <IconButton\n icon={<InboxIcon />}\n aria-label=\"Notifications\"\n description=\"You have unread notifications\"\n keybindingHint=\"G+N\"\n />\n)"
2053
2059
  },
2054
2060
  {
2055
2061
  "id": "components-iconbutton-features--keybinding-hint",
2056
- "code": "() => <IconButton icon={BoldIcon} aria-label=\"Bold\" keybindingHint=\"Mod+B\" />"
2062
+ "code": "() => (\n <IconButton icon={<BoldIcon />} aria-label=\"Bold\" keybindingHint=\"Mod+B\" />\n)"
2057
2063
  }
2058
2064
  ],
2059
2065
  "importPath": "@primer/react",
@@ -2094,9 +2100,9 @@
2094
2100
  },
2095
2101
  {
2096
2102
  "name": "icon",
2097
- "type": "Component",
2103
+ "type": "React.ReactNode | React.ComponentType<IconProps> | React.ExoticComponent<IconProps>",
2098
2104
  "defaultValue": "",
2099
- "description": "provide an octicon. It will be placed in the center of the button"
2105
+ "description": "Provide an icon component or React node. It will be placed in the center of the button. Use a React element when passing an icon from a Server Component."
2100
2106
  },
2101
2107
  {
2102
2108
  "name": "aria-label",
@@ -4739,6 +4745,12 @@
4739
4745
  ],
4740
4746
  "importPath": "@primer/react",
4741
4747
  "props": [
4748
+ {
4749
+ "name": "preventFocusOnClose",
4750
+ "type": "boolean",
4751
+ "defaultValue": "false",
4752
+ "description": "If true, focus will not be returned to returnFocusRef when the Overlay is unmounted. Consumers must manage focus themselves."
4753
+ },
4742
4754
  {
4743
4755
  "name": "returnFocusRef",
4744
4756
  "type": "React.RefObject<HTMLElement>",
@@ -8036,7 +8048,8 @@
8036
8048
  "name": "contrast",
8037
8049
  "type": "boolean",
8038
8050
  "defaultValue": "false",
8039
- "description": "Changes background color to a higher contrast color"
8051
+ "deprecated": true,
8052
+ "description": "Deprecated. Omit this prop to use the default background."
8040
8053
  },
8041
8054
  {
8042
8055
  "name": "size",
@@ -8386,7 +8399,8 @@
8386
8399
  "name": "contrast",
8387
8400
  "type": "boolean",
8388
8401
  "defaultValue": "false",
8389
- "description": "Changes background color to a higher contrast color"
8402
+ "deprecated": true,
8403
+ "description": "Deprecated. Omit this prop to use the default background."
8390
8404
  },
8391
8405
  {
8392
8406
  "name": "validationStatus",
@@ -696,6 +696,12 @@
696
696
  "type": "boolean",
697
697
  "defaultValue": "false",
698
698
  "description": "If true, focus will not be set when the container is opened."
699
+ },
700
+ {
701
+ "name": "preventFocusOnClose",
702
+ "type": "boolean",
703
+ "defaultValue": "false",
704
+ "description": "If true, focus will not be returned to returnFocusRef when the hook is cleaned up. Consumers must manage focus themselves."
699
705
  }
700
706
  ]
701
707
  }
@@ -769,6 +775,12 @@
769
775
  "name": "preventFocusOnOpen",
770
776
  "type": "boolean",
771
777
  "description": "Flag to prevent focus on the overlay when it is opened."
778
+ },
779
+ {
780
+ "name": "preventFocusOnClose",
781
+ "type": "boolean",
782
+ "defaultValue": "false",
783
+ "description": "If true, focus will not be returned to returnFocusRef when the overlay is unmounted. Consumers must manage focus themselves."
772
784
  }
773
785
  ]
774
786
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@primer/react",
3
3
  "type": "module",
4
- "version": "38.42.0-rc.fcbfbaea1",
4
+ "version": "38.42.0",
5
5
  "description": "An implementation of GitHub's Primer Design System using React",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -94,14 +94,16 @@
94
94
  },
95
95
  "devDependencies": {
96
96
  "@actions/core": "1.11.1",
97
- "@babel/cli": "7.28.6",
98
- "@babel/core": "7.29.6",
99
- "@babel/parser": "7.29.0",
100
- "@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6",
101
- "@babel/plugin-proposal-optional-chaining": "7.21.0",
102
- "@babel/plugin-transform-modules-commonjs": "7.28.6",
103
- "@babel/preset-react": "7.28.5",
104
- "@babel/preset-typescript": "7.28.5",
97
+ "@babel/cli": "8.0.6",
98
+ "@babel/core": "8.0.6",
99
+ "@babel/generator": "8.0.6",
100
+ "@babel/parser": "8.0.6",
101
+ "@babel/plugin-transform-nullish-coalescing-operator": "8.0.1",
102
+ "@babel/plugin-transform-optional-chaining": "8.0.5",
103
+ "@babel/plugin-transform-modules-commonjs": "8.0.1",
104
+ "@babel/preset-react": "8.0.1",
105
+ "@babel/preset-typescript": "8.0.1",
106
+ "@babel/types": "8.0.6",
105
107
  "@figma/code-connect": "1.3.2",
106
108
  "@primer/css": "^21.5.1",
107
109
  "@primer/doc-gen": "^0.0.1",
@@ -118,7 +120,6 @@
118
120
  "@testing-library/react": "^16.3.0",
119
121
  "@testing-library/react-hooks": "^8.0.1",
120
122
  "@testing-library/user-event": "^14.5.2",
121
- "@types/babel__core": "^7.20.5",
122
123
  "@types/lodash.groupby": "4.6.9",
123
124
  "@types/lodash.isempty": "4.4.9",
124
125
  "@types/lodash.isobject": "3.0.9",
@@ -131,13 +132,11 @@
131
132
  "afterframe": "^1.0.2",
132
133
  "ajv": "8.18.0",
133
134
  "axe-core": "4.9.1",
134
- "babel-core": "7.0.0-bridge.0",
135
135
  "babel-plugin-add-react-displayname": "0.0.5",
136
136
  "babel-plugin-dev-expression": "0.2.3",
137
137
  "babel-plugin-macros": "3.1.0",
138
138
  "babel-plugin-open-source": "1.3.4",
139
139
  "babel-plugin-transform-replace-expressions": "0.2.0",
140
- "babel-polyfill": "6.26.0",
141
140
  "chalk": "^5.4.1",
142
141
  "change-case": "5.4.4",
143
142
  "concurrently": "9.1.2",
@@ -166,7 +165,7 @@
166
165
  "react-is": "18.3.1",
167
166
  "recast": "0.23.7",
168
167
  "rimraf": "5.0.5",
169
- "rolldown": "^1.2.11",
168
+ "rolldown": "^1.2.12",
170
169
  "rolldown-plugin-dts": "^0.26.0",
171
170
  "rolldown-plugin-import-css": "^0.0.0",
172
171
  "rolldown-plugin-preserve-directives": "^0.0.0",