@primer/react 38.34.0-rc.e4bb4194f → 38.34.0-rc.f86dc8614
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.
- package/CHANGELOG.md +0 -4
- package/dist/ActionList/Group.js +1 -1
- package/dist/ActionList/List.js +14 -20
- package/dist/AnchoredOverlay/AnchoredOverlay.js +3 -6
- package/dist/Autocomplete/AutocompleteInput.js +7 -10
- package/dist/ButtonGroup/ButtonGroup.js +8 -15
- package/dist/Checkbox/Checkbox.js +9 -16
- package/dist/Dialog/Dialog.js +5 -12
- package/dist/FeatureFlags/DefaultFeatureFlags.js +1 -2
- package/dist/FilteredActionList/FilteredActionList.js +20 -31
- package/dist/FilteredActionList/FilteredActionListInput.d.ts +1 -1
- package/dist/Link/Link.js +33 -33
- package/dist/Overlay/Overlay.js +1 -1
- package/dist/PageHeader/PageHeader.js +21 -30
- package/dist/SelectPanel/SelectPanel.js +1 -1
- package/dist/TextInput/TextInput.js +6 -13
- package/dist/TooltipV2/Tooltip.js +11 -18
- package/dist/experimental/Tabs/Tabs.js +2 -3
- package/dist/experimental/Tabs/types.d.ts +3 -10
- package/dist/experimental/Tabs/useTabList.js +10 -18
- package/dist/experimental/UnderlinePanels/UnderlinePanels.js +42 -69
- package/dist/experimental/index.js +5 -5
- package/dist/hooks/useMergedRefs.d.ts +4 -4
- package/dist/hooks/useMergedRefs.js +5 -8
- package/dist/hooks/useProvidedRefOrCreate.d.ts +10 -7
- package/dist/hooks/useProvidedRefOrCreate.js +10 -7
- package/package.json +2 -1
|
@@ -3,16 +3,15 @@ import { useResizeObserver } from "../../hooks/useResizeObserver.js";
|
|
|
3
3
|
import { useId as useId$1 } from "../../hooks/useId.js";
|
|
4
4
|
import { isSlot } from "../../utils/is-slot.js";
|
|
5
5
|
import { invariant } from "../../utils/invariant.js";
|
|
6
|
+
import { createComponent } from "../../utils/create-component.js";
|
|
6
7
|
import { UnderlineItem, UnderlineItemList, UnderlineWrapper } from "../../internal/components/UnderlineTabbedInterface.js";
|
|
7
8
|
import UnderlinePanels_module_css_default from "./UnderlinePanels.module.css.js";
|
|
8
|
-
import { useTab } from "../Tabs/useTab.js";
|
|
9
|
-
import { useTabList } from "../Tabs/useTabList.js";
|
|
10
|
-
import { useTabPanel } from "../Tabs/useTabPanel.js";
|
|
11
|
-
import { Tabs } from "../Tabs/Tabs.js";
|
|
12
9
|
import { clsx } from "clsx";
|
|
13
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
11
|
import React, { Children, cloneElement, createContext, isValidElement, useContext, useMemo, useRef, useState } from "react";
|
|
12
|
+
import { TabContainerElement } from "@github/tab-container-element";
|
|
15
13
|
//#region src/experimental/UnderlinePanels/UnderlinePanels.tsx
|
|
14
|
+
const TabContainerComponent = createComponent(TabContainerElement, "tab-container");
|
|
16
15
|
const UnderlinePanelsContext = /*#__PURE__*/ createContext({
|
|
17
16
|
iconsVisible: true,
|
|
18
17
|
loadingCounters: void 0
|
|
@@ -22,43 +21,27 @@ const UnderlinePanels = ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabel
|
|
|
22
21
|
const wrapperRef = useRef(null);
|
|
23
22
|
const listRef = useRef(null);
|
|
24
23
|
const parentId = useId$1(props.id);
|
|
25
|
-
const [tabs, tabPanels, tabsHaveIcons
|
|
24
|
+
const [tabs, tabPanels, tabsHaveIcons] = useMemo(() => {
|
|
26
25
|
let tabIndex = 0;
|
|
27
26
|
let panelIndex = 0;
|
|
28
27
|
const childrenWithProps = Children.map(children, (child) => {
|
|
29
|
-
if (/*#__PURE__*/ isValidElement(child) && (child.type === Tab || isSlot(child, Tab))) return /*#__PURE__*/ cloneElement(child, {
|
|
30
|
-
if (/*#__PURE__*/ isValidElement(child) && (child.type === Panel || isSlot(child, Panel))) return /*#__PURE__*/ cloneElement(child, {
|
|
28
|
+
if (/*#__PURE__*/ isValidElement(child) && (child.type === Tab || isSlot(child, Tab))) return /*#__PURE__*/ cloneElement(child, { id: `${parentId}-tab-${tabIndex++}` });
|
|
29
|
+
if (/*#__PURE__*/ isValidElement(child) && (child.type === Panel || isSlot(child, Panel))) return /*#__PURE__*/ cloneElement(child, { "aria-labelledby": `${parentId}-tab-${panelIndex++}` });
|
|
31
30
|
return child;
|
|
32
31
|
});
|
|
33
32
|
const tabs = [];
|
|
34
33
|
const tabPanels = [];
|
|
35
|
-
let selectedFromProps;
|
|
36
34
|
for (const child of Children.toArray(childrenWithProps)) {
|
|
37
35
|
if (!/*#__PURE__*/ isValidElement(child)) continue;
|
|
38
|
-
if (child.type === Tab || isSlot(child, Tab))
|
|
39
|
-
|
|
40
|
-
if (ariaSelected === true || ariaSelected === "true") selectedFromProps = `${tabs.length}`;
|
|
41
|
-
tabs.push(child);
|
|
42
|
-
} else if (child.type === Panel || isSlot(child, Panel)) tabPanels.push(child);
|
|
36
|
+
if (child.type === Tab || isSlot(child, Tab)) tabs.push(child);
|
|
37
|
+
else if (child.type === Panel || isSlot(child, Panel)) tabPanels.push(child);
|
|
43
38
|
}
|
|
44
39
|
return [
|
|
45
40
|
tabs,
|
|
46
41
|
tabPanels,
|
|
47
|
-
tabs.some((tab) => /*#__PURE__*/ React.isValidElement(tab) && tab.props.icon)
|
|
48
|
-
selectedFromProps
|
|
42
|
+
tabs.some((tab) => /*#__PURE__*/ React.isValidElement(tab) && tab.props.icon)
|
|
49
43
|
];
|
|
50
|
-
}, [children]);
|
|
51
|
-
const [selectedValue, setSelectedValue] = useState(() => selectedFromProps !== null && selectedFromProps !== void 0 ? selectedFromProps : "0");
|
|
52
|
-
const [prevSelectedFromProps, setPrevSelectedFromProps] = useState(selectedFromProps);
|
|
53
|
-
if (selectedFromProps !== prevSelectedFromProps) {
|
|
54
|
-
setPrevSelectedFromProps(selectedFromProps);
|
|
55
|
-
if (selectedFromProps !== void 0 && selectedFromProps !== selectedValue) setSelectedValue(selectedFromProps);
|
|
56
|
-
}
|
|
57
|
-
const { tabListProps } = useTabList({
|
|
58
|
-
"aria-label": ariaLabel,
|
|
59
|
-
"aria-labelledby": ariaLabelledBy,
|
|
60
|
-
ref: listRef
|
|
61
|
-
});
|
|
44
|
+
}, [children, parentId]);
|
|
62
45
|
const contextValue = useMemo(() => ({
|
|
63
46
|
iconsVisible,
|
|
64
47
|
loadingCounters
|
|
@@ -85,65 +68,55 @@ const UnderlinePanels = ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabel
|
|
|
85
68
|
!(tabs.length === tabPanels.length) && invariant(false, `The number of tabs and panels must be equal. Counted ${tabs.length} tabs and ${tabPanels.length} panels.`);
|
|
86
69
|
return /*#__PURE__*/ jsx(UnderlinePanelsContext.Provider, {
|
|
87
70
|
value: contextValue,
|
|
88
|
-
children: /*#__PURE__*/ jsxs(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
"aria-orientation": tabListProps["aria-orientation"],
|
|
103
|
-
onKeyDown: tabListProps.onKeyDown,
|
|
104
|
-
children: tabs
|
|
105
|
-
})
|
|
106
|
-
}), tabPanels]
|
|
107
|
-
})
|
|
71
|
+
children: /*#__PURE__*/ jsxs(TabContainerComponent, { children: [/*#__PURE__*/ jsx(UnderlineWrapper, {
|
|
72
|
+
ref: wrapperRef,
|
|
73
|
+
slot: "tablist-wrapper",
|
|
74
|
+
"data-icons-visible": iconsVisible,
|
|
75
|
+
className: clsx(className, UnderlinePanels_module_css_default.StyledUnderlineWrapper),
|
|
76
|
+
...props,
|
|
77
|
+
children: /*#__PURE__*/ jsx(UnderlineItemList, {
|
|
78
|
+
ref: listRef,
|
|
79
|
+
"aria-label": ariaLabel,
|
|
80
|
+
"aria-labelledby": ariaLabelledBy,
|
|
81
|
+
role: "tablist",
|
|
82
|
+
children: tabs
|
|
83
|
+
})
|
|
84
|
+
}), tabPanels] })
|
|
108
85
|
});
|
|
109
86
|
};
|
|
110
87
|
UnderlinePanels.displayName = "UnderlinePanels";
|
|
111
|
-
const TabImpl = ({
|
|
88
|
+
const TabImpl = ({ "aria-selected": ariaSelected, onSelect, ...props }) => {
|
|
112
89
|
const { loadingCounters } = useContext(UnderlinePanelsContext);
|
|
113
|
-
const
|
|
114
|
-
|
|
90
|
+
const clickHandler = React.useCallback((event) => {
|
|
91
|
+
if (!event.defaultPrevented && typeof onSelect === "function") onSelect(event);
|
|
92
|
+
}, [onSelect]);
|
|
93
|
+
const keyDownHandler = React.useCallback((event) => {
|
|
94
|
+
if ((event.key === " " || event.key === "Enter") && !event.defaultPrevented && typeof onSelect === "function") onSelect(event);
|
|
95
|
+
}, [onSelect]);
|
|
115
96
|
return /*#__PURE__*/ jsx(UnderlineItem, {
|
|
116
97
|
as: "button",
|
|
117
|
-
|
|
118
|
-
|
|
98
|
+
role: "tab",
|
|
99
|
+
tabIndex: ariaSelected ? 0 : -1,
|
|
100
|
+
"aria-selected": ariaSelected,
|
|
119
101
|
type: "button",
|
|
120
|
-
onClick:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
tabOnKeyDown === null || tabOnKeyDown === void 0 || tabOnKeyDown(event);
|
|
125
|
-
if ((event.key === " " || event.key === "Enter") && !event.defaultPrevented && typeof onSelect === "function") onSelect(event);
|
|
126
|
-
},
|
|
127
|
-
onMouseDown: tabOnMouseDown,
|
|
128
|
-
onFocus: tabOnFocus,
|
|
129
|
-
loadingCounters
|
|
102
|
+
onClick: clickHandler,
|
|
103
|
+
onKeyDown: keyDownHandler,
|
|
104
|
+
loadingCounters,
|
|
105
|
+
...props
|
|
130
106
|
});
|
|
131
107
|
};
|
|
132
108
|
TabImpl.displayName = "TabImpl";
|
|
133
109
|
TabImpl.displayName = "UnderlinePanels.Tab";
|
|
134
110
|
const Tab = /*#__PURE__*/ React.memo(TabImpl);
|
|
135
111
|
Tab.displayName = "UnderlinePanels.Tab";
|
|
136
|
-
const
|
|
137
|
-
const { tabPanelProps } = useTabPanel({ value: value !== null && value !== void 0 ? value : "" });
|
|
112
|
+
const Panel = ({ children, ...rest }) => {
|
|
138
113
|
return /*#__PURE__*/ jsx("div", {
|
|
139
|
-
|
|
140
|
-
...
|
|
114
|
+
role: "tabpanel",
|
|
115
|
+
...rest,
|
|
141
116
|
children
|
|
142
117
|
});
|
|
143
118
|
};
|
|
144
|
-
|
|
145
|
-
PanelImpl.displayName = "UnderlinePanels.Panel";
|
|
146
|
-
const Panel = PanelImpl;
|
|
119
|
+
Panel.displayName = "Panel";
|
|
147
120
|
Panel.displayName = "UnderlinePanels.Panel";
|
|
148
121
|
var UnderlinePanels_default = Object.assign(UnderlinePanels, {
|
|
149
122
|
Panel,
|
|
@@ -4,15 +4,15 @@ import { Announce } from "../live-region/Announce.js";
|
|
|
4
4
|
import { AriaAlert } from "../live-region/AriaAlert.js";
|
|
5
5
|
import { AriaStatus } from "../live-region/AriaStatus.js";
|
|
6
6
|
import { ButtonBase } from "../Button/ButtonBase.js";
|
|
7
|
-
import { DefaultFeatureFlags } from "../FeatureFlags/DefaultFeatureFlags.js";
|
|
8
|
-
import { FeatureFlags } from "../FeatureFlags/FeatureFlags.js";
|
|
9
|
-
import { useFeatureFlag } from "../FeatureFlags/useFeatureFlag.js";
|
|
10
7
|
import { KeybindingHint } from "../KeybindingHint/KeybindingHint.js";
|
|
11
8
|
import { getAccessibleKeybindingHintString } from "../KeybindingHint/utils.js";
|
|
12
9
|
import { Tooltip } from "../TooltipV2/Tooltip.js";
|
|
13
10
|
import { useOverflow } from "../hooks/useOverflow.js";
|
|
14
11
|
import { ScrollableRegion } from "../ScrollableRegion/ScrollableRegion.js";
|
|
15
12
|
import { Dialog } from "../Dialog/Dialog.js";
|
|
13
|
+
import { DefaultFeatureFlags } from "../FeatureFlags/DefaultFeatureFlags.js";
|
|
14
|
+
import { FeatureFlags } from "../FeatureFlags/FeatureFlags.js";
|
|
15
|
+
import { useFeatureFlag } from "../FeatureFlags/useFeatureFlag.js";
|
|
16
16
|
import { Stack } from "../Stack/index.js";
|
|
17
17
|
import { SkeletonBox } from "../Skeleton/SkeletonBox.js";
|
|
18
18
|
import { FilteredActionListLoadingTypes } from "../FilteredActionList/constants.js";
|
|
@@ -30,12 +30,12 @@ import { Table } from "../DataTable/index.js";
|
|
|
30
30
|
import { InlineMessage } from "../InlineMessage/InlineMessage.js";
|
|
31
31
|
import { Hidden } from "../Hidden/Hidden.js";
|
|
32
32
|
import { SelectPanel } from "./SelectPanel2/SelectPanel.js";
|
|
33
|
+
import UnderlinePanels_default from "./UnderlinePanels/UnderlinePanels.js";
|
|
34
|
+
import { IssueLabel } from "./IssueLabel/IssueLabel.js";
|
|
33
35
|
import { useTab } from "./Tabs/useTab.js";
|
|
34
36
|
import { useTabList } from "./Tabs/useTabList.js";
|
|
35
37
|
import { useTabPanel } from "./Tabs/useTabPanel.js";
|
|
36
38
|
import { Tabs } from "./Tabs/Tabs.js";
|
|
37
|
-
import UnderlinePanels_default from "./UnderlinePanels/UnderlinePanels.js";
|
|
38
|
-
import { IssueLabel } from "./IssueLabel/IssueLabel.js";
|
|
39
39
|
import { TopicTag } from "../TopicTag/index.js";
|
|
40
40
|
//#region src/experimental/index.ts
|
|
41
41
|
/**
|
|
@@ -17,18 +17,18 @@ import { ForwardedRef, Ref } from "react";
|
|
|
17
17
|
* // React 18
|
|
18
18
|
* const Example = forwardRef<HTMLButtonElement, {}>((props, forwardedRef) => {
|
|
19
19
|
* const ref = useRef<HTMLButtonElement>(null)
|
|
20
|
-
* const
|
|
20
|
+
* const combinedRef = useMergedRefs(forwardedRef, ref)
|
|
21
21
|
*
|
|
22
|
-
* return <button ref={
|
|
22
|
+
* return <button ref={combinedRef} />
|
|
23
23
|
* })
|
|
24
24
|
*
|
|
25
25
|
* @example
|
|
26
26
|
* // React 19
|
|
27
27
|
* const Example = ({ref: externalRef}: {ref?: Ref<HTMLButtonElement>}) => {
|
|
28
28
|
* const ref = useRef<HTMLButtonElement>(null)
|
|
29
|
-
* const
|
|
29
|
+
* const combinedRef = useMergedRefs(externalRef, ref)
|
|
30
30
|
*
|
|
31
|
-
* return <button ref={
|
|
31
|
+
* return <button ref={combinedRef} />
|
|
32
32
|
* }
|
|
33
33
|
*/
|
|
34
34
|
declare function useMergedRefs<T>(refA: Ref$1<T | null>, refB: Ref$1<T | null>): (value: T | null) => (() => void) | undefined;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { isExperimentalReactVersion, reactMajorVersion } from "../utils/environment.js";
|
|
2
2
|
import { c } from "react-compiler-runtime";
|
|
3
|
-
import
|
|
3
|
+
import "react";
|
|
4
4
|
//#region src/hooks/useMergedRefs.ts
|
|
5
|
-
var _version$split$;
|
|
6
|
-
const majorReactVersion = parseInt((_version$split$ = version.split(".")[0]) !== null && _version$split$ !== void 0 ? _version$split$ : "18", 10);
|
|
7
5
|
/**
|
|
8
6
|
* Cleanup functions for refs were introduced in React 19. For feature detection,
|
|
9
7
|
* we look to see if current version of React is >= 19 or if it is an
|
|
@@ -28,18 +26,18 @@ const supportsRefCleanup = reactMajorVersion >= 19 || isExperimentalReactVersion
|
|
|
28
26
|
* // React 18
|
|
29
27
|
* const Example = forwardRef<HTMLButtonElement, {}>((props, forwardedRef) => {
|
|
30
28
|
* const ref = useRef<HTMLButtonElement>(null)
|
|
31
|
-
* const
|
|
29
|
+
* const combinedRef = useMergedRefs(forwardedRef, ref)
|
|
32
30
|
*
|
|
33
|
-
* return <button ref={
|
|
31
|
+
* return <button ref={combinedRef} />
|
|
34
32
|
* })
|
|
35
33
|
*
|
|
36
34
|
* @example
|
|
37
35
|
* // React 19
|
|
38
36
|
* const Example = ({ref: externalRef}: {ref?: Ref<HTMLButtonElement>}) => {
|
|
39
37
|
* const ref = useRef<HTMLButtonElement>(null)
|
|
40
|
-
* const
|
|
38
|
+
* const combinedRef = useMergedRefs(externalRef, ref)
|
|
41
39
|
*
|
|
42
|
-
* return <button ref={
|
|
40
|
+
* return <button ref={combinedRef} />
|
|
43
41
|
* }
|
|
44
42
|
*/
|
|
45
43
|
function useMergedRefs(refA, refB) {
|
|
@@ -50,7 +48,6 @@ function useMergedRefs(refA, refB) {
|
|
|
50
48
|
const cleanupA = setRef(refA, value);
|
|
51
49
|
const cleanupB = setRef(refB, value);
|
|
52
50
|
if (!supportsRefCleanup) return;
|
|
53
|
-
if (majorReactVersion <= 18) return;
|
|
54
51
|
return () => {
|
|
55
52
|
if (cleanupA) cleanupA();
|
|
56
53
|
else setRef(refA, null);
|
|
@@ -9,14 +9,17 @@ import React from "react";
|
|
|
9
9
|
* @param providedRef The ref to use - if undefined, will use the ref from a call to React.useRef
|
|
10
10
|
* @type TRef The type of the RefObject which should be created.
|
|
11
11
|
*
|
|
12
|
-
* @
|
|
13
|
-
*
|
|
14
|
-
* {@linkcode useMergedRefs} instead.
|
|
12
|
+
* @deprecated This hook is incompatible with forwarded callback refs. Prefer `useMergedRefs` with an internally
|
|
13
|
+
* created ref instead.
|
|
15
14
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
15
|
+
* ```diff
|
|
16
|
+
* - const ref = useProvidedRefOrCreate(forwardedRef as RefObject<...>)
|
|
17
|
+
* + const ref = useRef(null)
|
|
18
|
+
* + const mergedRef = useMergedRefs(forwardedRef, ref)
|
|
19
|
+
*
|
|
20
|
+
* - return <div ref={ref} />
|
|
21
|
+
* + return <div ref={mergedRef} />
|
|
22
|
+
* ```
|
|
20
23
|
*/
|
|
21
24
|
declare function useProvidedRefOrCreate<TRef>(providedRef?: React.RefObject<TRef | null>): React.RefObject<TRef | null>;
|
|
22
25
|
//#endregion
|
|
@@ -8,14 +8,17 @@ import React from "react";
|
|
|
8
8
|
* @param providedRef The ref to use - if undefined, will use the ref from a call to React.useRef
|
|
9
9
|
* @type TRef The type of the RefObject which should be created.
|
|
10
10
|
*
|
|
11
|
-
* @
|
|
12
|
-
*
|
|
13
|
-
* {@linkcode useMergedRefs} instead.
|
|
11
|
+
* @deprecated This hook is incompatible with forwarded callback refs. Prefer `useMergedRefs` with an internally
|
|
12
|
+
* created ref instead.
|
|
14
13
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* ```diff
|
|
15
|
+
* - const ref = useProvidedRefOrCreate(forwardedRef as RefObject<...>)
|
|
16
|
+
* + const ref = useRef(null)
|
|
17
|
+
* + const mergedRef = useMergedRefs(forwardedRef, ref)
|
|
18
|
+
*
|
|
19
|
+
* - return <div ref={ref} />
|
|
20
|
+
* + return <div ref={mergedRef} />
|
|
21
|
+
* ```
|
|
19
22
|
*/
|
|
20
23
|
function useProvidedRefOrCreate(providedRef) {
|
|
21
24
|
const createdRef = React.useRef(null);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primer/react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "38.34.0-rc.
|
|
4
|
+
"version": "38.34.0-rc.f86dc8614",
|
|
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",
|
|
@@ -77,6 +77,7 @@
|
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"@github/mini-throttle": "^2.1.1",
|
|
79
79
|
"@github/relative-time-element": "^5.0.0",
|
|
80
|
+
"@github/tab-container-element": "^4.8.2",
|
|
80
81
|
"@lit-labs/react": "1.2.1",
|
|
81
82
|
"@oddbird/popover-polyfill": "^0.5.2",
|
|
82
83
|
"@primer/behaviors": "^1.10.3",
|