@primer/react 38.34.0-rc.d17f87af7 → 38.34.0-rc.dad320815
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
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
- [#8169](https://github.com/primer/react/pull/8169) [`1d6f559`](https://github.com/primer/react/commit/1d6f5593f5e482d1d03027522bc882560c7b1f06) Thanks [@liuliu-dev](https://github.com/liuliu-dev)! - Timeline: `Timeline.Actions` now wraps onto a new row below `Timeline.Body`, left-aligned with the body content, when `Timeline.Item` is narrower than 480px.
|
|
14
14
|
|
|
15
|
+
- [#8214](https://github.com/primer/react/pull/8214) [`41705f4`](https://github.com/primer/react/commit/41705f430ce0f64eb61c2665313f36a88cf6f16c) Thanks [@rickyzhangca](https://github.com/rickyzhangca)! - UnderlinePanels: The experimental `UnderlinePanels` component is now built on the experimental `Tabs` component instead of `@github/tab-container-element`. Its public API and behavior are unchanged.
|
|
16
|
+
|
|
15
17
|
## 38.33.0
|
|
16
18
|
|
|
17
19
|
### Minor Changes
|
|
@@ -13,10 +13,11 @@ import React, { useId } from "react";
|
|
|
13
13
|
* The `Tab`, `TabList`, and `TabPanel` components are provided for convenience to showcase the API & implementation.
|
|
14
14
|
*/
|
|
15
15
|
function Tabs(props) {
|
|
16
|
-
var _props$defaultValue;
|
|
16
|
+
var _props$id, _props$defaultValue;
|
|
17
17
|
const $ = c(13);
|
|
18
18
|
const { children, onValueChange } = props;
|
|
19
|
-
const
|
|
19
|
+
const generatedId = useId();
|
|
20
|
+
const groupId = (_props$id = props.id) !== null && _props$id !== void 0 ? _props$id : generatedId;
|
|
20
21
|
const t0 = (_props$defaultValue = props.defaultValue) !== null && _props$defaultValue !== void 0 ? _props$defaultValue : props.value;
|
|
21
22
|
let t1;
|
|
22
23
|
if ($[0] !== props.value || $[1] !== t0) {
|
|
@@ -45,7 +45,14 @@ type UncontrolledTabsProps = {
|
|
|
45
45
|
value: string;
|
|
46
46
|
}) => void;
|
|
47
47
|
};
|
|
48
|
-
type
|
|
48
|
+
type CommonTabsProps = {
|
|
49
|
+
/**
|
|
50
|
+
* Optional id used as the base for generated tab and panel ids. If omitted, a
|
|
51
|
+
* unique id is generated automatically.
|
|
52
|
+
*/
|
|
53
|
+
id?: string;
|
|
54
|
+
};
|
|
55
|
+
type TabsProps = PropsWithChildren<(ControlledTabsProps | UncontrolledTabsProps) & CommonTabsProps>;
|
|
49
56
|
type Label = {
|
|
50
57
|
'aria-label': string;
|
|
51
58
|
};
|
|
@@ -3,15 +3,16 @@ 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";
|
|
7
6
|
import { UnderlineItem, UnderlineItemList, UnderlineWrapper } from "../../internal/components/UnderlineTabbedInterface.js";
|
|
8
7
|
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";
|
|
9
12
|
import { clsx } from "clsx";
|
|
10
13
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
14
|
import React, { Children, cloneElement, createContext, isValidElement, useContext, useMemo, useRef, useState } from "react";
|
|
12
|
-
import { TabContainerElement } from "@github/tab-container-element";
|
|
13
15
|
//#region src/experimental/UnderlinePanels/UnderlinePanels.tsx
|
|
14
|
-
const TabContainerComponent = createComponent(TabContainerElement, "tab-container");
|
|
15
16
|
const UnderlinePanelsContext = /*#__PURE__*/ createContext({
|
|
16
17
|
iconsVisible: true,
|
|
17
18
|
loadingCounters: void 0
|
|
@@ -21,27 +22,43 @@ const UnderlinePanels = ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabel
|
|
|
21
22
|
const wrapperRef = useRef(null);
|
|
22
23
|
const listRef = useRef(null);
|
|
23
24
|
const parentId = useId$1(props.id);
|
|
24
|
-
const [tabs, tabPanels, tabsHaveIcons] = useMemo(() => {
|
|
25
|
+
const [tabs, tabPanels, tabsHaveIcons, selectedFromProps] = useMemo(() => {
|
|
25
26
|
let tabIndex = 0;
|
|
26
27
|
let panelIndex = 0;
|
|
27
28
|
const childrenWithProps = Children.map(children, (child) => {
|
|
28
|
-
if (/*#__PURE__*/ isValidElement(child) && (child.type === Tab || isSlot(child, Tab))) return /*#__PURE__*/ cloneElement(child, {
|
|
29
|
-
if (/*#__PURE__*/ isValidElement(child) && (child.type === Panel || isSlot(child, Panel))) return /*#__PURE__*/ cloneElement(child, {
|
|
29
|
+
if (/*#__PURE__*/ isValidElement(child) && (child.type === Tab || isSlot(child, Tab))) return /*#__PURE__*/ cloneElement(child, { value: `${tabIndex++}` });
|
|
30
|
+
if (/*#__PURE__*/ isValidElement(child) && (child.type === Panel || isSlot(child, Panel))) return /*#__PURE__*/ cloneElement(child, { value: `${panelIndex++}` });
|
|
30
31
|
return child;
|
|
31
32
|
});
|
|
32
33
|
const tabs = [];
|
|
33
34
|
const tabPanels = [];
|
|
35
|
+
let selectedFromProps;
|
|
34
36
|
for (const child of Children.toArray(childrenWithProps)) {
|
|
35
37
|
if (!/*#__PURE__*/ isValidElement(child)) continue;
|
|
36
|
-
if (child.type === Tab || isSlot(child, Tab))
|
|
37
|
-
|
|
38
|
+
if (child.type === Tab || isSlot(child, Tab)) {
|
|
39
|
+
const ariaSelected = child.props["aria-selected"];
|
|
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);
|
|
38
43
|
}
|
|
39
44
|
return [
|
|
40
45
|
tabs,
|
|
41
46
|
tabPanels,
|
|
42
|
-
tabs.some((tab) => /*#__PURE__*/ React.isValidElement(tab) && tab.props.icon)
|
|
47
|
+
tabs.some((tab) => /*#__PURE__*/ React.isValidElement(tab) && tab.props.icon),
|
|
48
|
+
selectedFromProps
|
|
43
49
|
];
|
|
44
|
-
}, [children
|
|
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
|
+
});
|
|
45
62
|
const contextValue = useMemo(() => ({
|
|
46
63
|
iconsVisible,
|
|
47
64
|
loadingCounters
|
|
@@ -68,55 +85,65 @@ const UnderlinePanels = ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabel
|
|
|
68
85
|
!(tabs.length === tabPanels.length) && invariant(false, `The number of tabs and panels must be equal. Counted ${tabs.length} tabs and ${tabPanels.length} panels.`);
|
|
69
86
|
return /*#__PURE__*/ jsx(UnderlinePanelsContext.Provider, {
|
|
70
87
|
value: contextValue,
|
|
71
|
-
children: /*#__PURE__*/ jsxs(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
children: /*#__PURE__*/ jsxs(Tabs, {
|
|
89
|
+
id: parentId,
|
|
90
|
+
value: selectedValue,
|
|
91
|
+
onValueChange: ({ value }) => setSelectedValue(value),
|
|
92
|
+
children: [/*#__PURE__*/ jsx(UnderlineWrapper, {
|
|
93
|
+
ref: wrapperRef,
|
|
94
|
+
"data-icons-visible": iconsVisible,
|
|
95
|
+
className: clsx(className, UnderlinePanels_module_css_default.StyledUnderlineWrapper),
|
|
96
|
+
...props,
|
|
97
|
+
children: /*#__PURE__*/ jsx(UnderlineItemList, {
|
|
98
|
+
ref: listRef,
|
|
99
|
+
role: tabListProps.role,
|
|
100
|
+
"aria-label": tabListProps["aria-label"],
|
|
101
|
+
"aria-labelledby": tabListProps["aria-labelledby"],
|
|
102
|
+
"aria-orientation": tabListProps["aria-orientation"],
|
|
103
|
+
onKeyDown: tabListProps.onKeyDown,
|
|
104
|
+
children: tabs
|
|
105
|
+
})
|
|
106
|
+
}), tabPanels]
|
|
107
|
+
})
|
|
85
108
|
});
|
|
86
109
|
};
|
|
87
110
|
UnderlinePanels.displayName = "UnderlinePanels";
|
|
88
|
-
const TabImpl = ({
|
|
111
|
+
const TabImpl = ({ onSelect, value, ...itemProps }) => {
|
|
89
112
|
const { loadingCounters } = useContext(UnderlinePanelsContext);
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
}, [onSelect]);
|
|
93
|
-
const keyDownHandler = React.useCallback((event) => {
|
|
94
|
-
if ((event.key === " " || event.key === "Enter") && !event.defaultPrevented && typeof onSelect === "function") onSelect(event);
|
|
95
|
-
}, [onSelect]);
|
|
113
|
+
const { tabProps } = useTab({ value: value !== null && value !== void 0 ? value : "" });
|
|
114
|
+
const { onKeyDown: tabOnKeyDown, onMouseDown: tabOnMouseDown, onFocus: tabOnFocus, ...restTabProps } = tabProps;
|
|
96
115
|
return /*#__PURE__*/ jsx(UnderlineItem, {
|
|
97
116
|
as: "button",
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"aria-selected": ariaSelected,
|
|
117
|
+
...itemProps,
|
|
118
|
+
...restTabProps,
|
|
101
119
|
type: "button",
|
|
102
|
-
onClick:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
120
|
+
onClick: (event) => {
|
|
121
|
+
if (!event.defaultPrevented && typeof onSelect === "function") onSelect(event);
|
|
122
|
+
},
|
|
123
|
+
onKeyDown: (event) => {
|
|
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
|
|
106
130
|
});
|
|
107
131
|
};
|
|
108
132
|
TabImpl.displayName = "TabImpl";
|
|
109
133
|
TabImpl.displayName = "UnderlinePanels.Tab";
|
|
110
134
|
const Tab = /*#__PURE__*/ React.memo(TabImpl);
|
|
111
135
|
Tab.displayName = "UnderlinePanels.Tab";
|
|
112
|
-
const
|
|
136
|
+
const PanelImpl = ({ children, value, ...panelRest }) => {
|
|
137
|
+
const { tabPanelProps } = useTabPanel({ value: value !== null && value !== void 0 ? value : "" });
|
|
113
138
|
return /*#__PURE__*/ jsx("div", {
|
|
114
|
-
|
|
115
|
-
...
|
|
139
|
+
...panelRest,
|
|
140
|
+
...tabPanelProps,
|
|
116
141
|
children
|
|
117
142
|
});
|
|
118
143
|
};
|
|
119
|
-
|
|
144
|
+
PanelImpl.displayName = "PanelImpl";
|
|
145
|
+
PanelImpl.displayName = "UnderlinePanels.Panel";
|
|
146
|
+
const Panel = PanelImpl;
|
|
120
147
|
Panel.displayName = "UnderlinePanels.Panel";
|
|
121
148
|
var UnderlinePanels_default = Object.assign(UnderlinePanels, {
|
|
122
149
|
Panel,
|
|
@@ -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";
|
|
35
33
|
import { useTab } from "./Tabs/useTab.js";
|
|
36
34
|
import { useTabList } from "./Tabs/useTabList.js";
|
|
37
35
|
import { useTabPanel } from "./Tabs/useTabPanel.js";
|
|
38
36
|
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
|
/**
|
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.dad320815",
|
|
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,7 +77,6 @@
|
|
|
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",
|
|
81
80
|
"@lit-labs/react": "1.2.1",
|
|
82
81
|
"@oddbird/popover-polyfill": "^0.5.2",
|
|
83
82
|
"@primer/behaviors": "^1.10.3",
|