@primer/react 38.40.0-rc.28e5764e2 → 38.40.0-rc.37bd8a025
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 +6 -0
- package/dist/ActionList/List.js +83 -79
- package/dist/ActionList/index.d.ts +1 -0
- package/dist/ActionList/shared.d.ts +4 -0
- package/dist/NavList/NavList.d.ts +2 -1
- package/dist/NavList/NavList.js +45 -38
- package/dist/TooltipV2/Tooltip.js +17 -7
- package/generated/components.json +16 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,12 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
7
|
+
- [#8422](https://github.com/primer/react/pull/8422) [`2909f19`](https://github.com/primer/react/commit/2909f19f64dbbc12aefb3455139596d88e5098b2) Thanks [@tay1orjones](https://github.com/tay1orjones)! - NavList, ActionList: Add a `disableItemGap` prop to render navigation items edge-to-edge.
|
|
8
|
+
|
|
7
9
|
- [#8386](https://github.com/primer/react/pull/8386) [`6c64598`](https://github.com/primer/react/commit/6c645987c5ad27d5c23f57190a10b8707b29c58c) Thanks [@rickyzhangca](https://github.com/rickyzhangca)! - DataTable: Add config-driven row groups that can be interleaved with standalone rows.
|
|
8
10
|
|
|
9
11
|
### Patch Changes
|
|
10
12
|
|
|
11
13
|
- [#8408](https://github.com/primer/react/pull/8408) [`c880319`](https://github.com/primer/react/commit/c8803199ddb0e669596f6e2370fd4117a055cfc3) Thanks [@janmaarten-a11y](https://github.com/janmaarten-a11y)! - Button and LinkButton: Limit link variant underlines to the text label when visuals are present
|
|
12
14
|
|
|
15
|
+
- [#8411](https://github.com/primer/react/pull/8411) [`8c52029`](https://github.com/primer/react/commit/8c520293151054fd39e5094f4740e97e89ce18d8) Thanks [@mattcosta7](https://github.com/mattcosta7)! - Tooltip: Prevent React Fragment triggers from crashing and provide a clear development warning
|
|
16
|
+
|
|
17
|
+
- [#8409](https://github.com/primer/react/pull/8409) [`9d0632c`](https://github.com/primer/react/commit/9d0632ccc6c23e92cbbe786ce922795c92931b04) Thanks [@iansan5653](https://github.com/iansan5653)! - Fix Tooltip ref handling to preserve child element ref
|
|
18
|
+
|
|
13
19
|
## 38.39.0
|
|
14
20
|
|
|
15
21
|
### Minor Changes
|
package/dist/ActionList/List.js
CHANGED
|
@@ -17,7 +17,7 @@ import { clsx } from "clsx";
|
|
|
17
17
|
//#region src/ActionList/List.tsx
|
|
18
18
|
const UnwrappedList = (props, forwardedRef) => {
|
|
19
19
|
var _slots$heading$props$;
|
|
20
|
-
const $ = c(
|
|
20
|
+
const $ = c(41);
|
|
21
21
|
let className;
|
|
22
22
|
let restProps;
|
|
23
23
|
let role;
|
|
@@ -26,8 +26,9 @@ const UnwrappedList = (props, forwardedRef) => {
|
|
|
26
26
|
let t1;
|
|
27
27
|
let t2;
|
|
28
28
|
let t3;
|
|
29
|
+
let t4;
|
|
29
30
|
if ($[0] !== props) {
|
|
30
|
-
({as: t0, variant: t1, selectionVariant, showDividers: t2, role, disableFocusZone: t3, className, ...restProps} = props);
|
|
31
|
+
({as: t0, variant: t1, selectionVariant, showDividers: t2, role, disableFocusZone: t3, disableItemGap: t4, className, ...restProps} = props);
|
|
31
32
|
$[0] = props;
|
|
32
33
|
$[1] = className;
|
|
33
34
|
$[2] = restProps;
|
|
@@ -37,6 +38,7 @@ const UnwrappedList = (props, forwardedRef) => {
|
|
|
37
38
|
$[6] = t1;
|
|
38
39
|
$[7] = t2;
|
|
39
40
|
$[8] = t3;
|
|
41
|
+
$[9] = t4;
|
|
40
42
|
} else {
|
|
41
43
|
className = $[1];
|
|
42
44
|
restProps = $[2];
|
|
@@ -46,17 +48,19 @@ const UnwrappedList = (props, forwardedRef) => {
|
|
|
46
48
|
t1 = $[6];
|
|
47
49
|
t2 = $[7];
|
|
48
50
|
t3 = $[8];
|
|
51
|
+
t4 = $[9];
|
|
49
52
|
}
|
|
50
53
|
const Component = t0 === void 0 ? "ul" : t0;
|
|
51
54
|
const variant = t1 === void 0 ? "inset" : t1;
|
|
52
55
|
const showDividers = t2 === void 0 ? false : t2;
|
|
53
56
|
const disableFocusZone = t3 === void 0 ? false : t3;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
const disableItemGap = t4 === void 0 ? false : t4;
|
|
58
|
+
let t5;
|
|
59
|
+
if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
|
|
60
|
+
t5 = { heading: Heading };
|
|
61
|
+
$[10] = t5;
|
|
62
|
+
} else t5 = $[10];
|
|
63
|
+
const [slots, childrenWithoutSlots] = useSlots(restProps.children, t5);
|
|
60
64
|
const headingId = useId$1();
|
|
61
65
|
const { listRole: listRoleFromContainer, listLabelledBy, selectionVariant: containerSelectionVariant, enableFocusZone: enableFocusZoneFromContainer, container } = React.useContext(ActionListContainerContext);
|
|
62
66
|
const ariaLabelledBy = slots.heading ? (_slots$heading$props$ = slots.heading.props.id) !== null && _slots$heading$props$ !== void 0 ? _slots$heading$props$ : headingId : listLabelledBy;
|
|
@@ -67,58 +71,58 @@ const UnwrappedList = (props, forwardedRef) => {
|
|
|
67
71
|
const providedOrCreatedRef = useProvidedRefOrCreate(forwardedRef);
|
|
68
72
|
const readRef = mergedRefEnabled ? listRef : providedOrCreatedRef;
|
|
69
73
|
const appliedRef = mergedRefEnabled ? mergedRef : providedOrCreatedRef;
|
|
70
|
-
const itemGapEnabled = useFeatureFlag("primer_react_action_list_item_gap") && container === "NavList";
|
|
74
|
+
const itemGapEnabled = useFeatureFlag("primer_react_action_list_item_gap") && !disableItemGap && container === "NavList";
|
|
71
75
|
let enableFocusZone = false;
|
|
72
76
|
if (enableFocusZoneFromContainer !== void 0) enableFocusZone = enableFocusZoneFromContainer;
|
|
73
77
|
else if (listRole && !disableFocusZone) {
|
|
74
|
-
let
|
|
75
|
-
if ($[
|
|
76
|
-
|
|
78
|
+
let t6;
|
|
79
|
+
if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
|
|
80
|
+
t6 = [
|
|
77
81
|
"menu",
|
|
78
82
|
"menubar",
|
|
79
83
|
"listbox"
|
|
80
84
|
];
|
|
81
|
-
$[
|
|
82
|
-
} else
|
|
83
|
-
enableFocusZone =
|
|
85
|
+
$[11] = t6;
|
|
86
|
+
} else t6 = $[11];
|
|
87
|
+
enableFocusZone = t6.includes(listRole);
|
|
84
88
|
}
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
let
|
|
88
|
-
if ($[
|
|
89
|
-
|
|
90
|
-
disabled:
|
|
89
|
+
const t6 = !enableFocusZone;
|
|
90
|
+
const t7 = listRole === "menu" || container === "SelectPanel" || container === "FilteredActionList" ? "wrap" : void 0;
|
|
91
|
+
let t8;
|
|
92
|
+
if ($[12] !== readRef || $[13] !== t6 || $[14] !== t7) {
|
|
93
|
+
t8 = {
|
|
94
|
+
disabled: t6,
|
|
91
95
|
containerRef: readRef,
|
|
92
96
|
bindKeys: FocusKeys.ArrowVertical | FocusKeys.HomeAndEnd | FocusKeys.PageUpDown,
|
|
93
|
-
focusOutBehavior:
|
|
97
|
+
focusOutBehavior: t7
|
|
94
98
|
};
|
|
95
|
-
$[
|
|
96
|
-
$[12] = t5;
|
|
99
|
+
$[12] = readRef;
|
|
97
100
|
$[13] = t6;
|
|
98
101
|
$[14] = t7;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
$[15] = t8;
|
|
103
|
+
} else t8 = $[15];
|
|
104
|
+
useFocusZone(t8);
|
|
105
|
+
const t9 = selectionVariant || containerSelectionVariant;
|
|
106
|
+
let t10;
|
|
107
|
+
if ($[16] !== headingId || $[17] !== listRole || $[18] !== showDividers || $[19] !== t9 || $[20] !== variant) {
|
|
108
|
+
t10 = {
|
|
105
109
|
variant,
|
|
106
|
-
selectionVariant:
|
|
110
|
+
selectionVariant: t9,
|
|
107
111
|
showDividers,
|
|
108
112
|
role: listRole,
|
|
109
113
|
headingId
|
|
110
114
|
};
|
|
111
|
-
$[
|
|
112
|
-
$[
|
|
113
|
-
$[
|
|
114
|
-
$[
|
|
115
|
-
$[
|
|
116
|
-
$[
|
|
117
|
-
} else
|
|
118
|
-
const listContextValue =
|
|
119
|
-
let
|
|
120
|
-
if ($[
|
|
121
|
-
|
|
115
|
+
$[16] = headingId;
|
|
116
|
+
$[17] = listRole;
|
|
117
|
+
$[18] = showDividers;
|
|
118
|
+
$[19] = t9;
|
|
119
|
+
$[20] = variant;
|
|
120
|
+
$[21] = t10;
|
|
121
|
+
} else t10 = $[21];
|
|
122
|
+
const listContextValue = t10;
|
|
123
|
+
let t11;
|
|
124
|
+
if ($[22] !== readRef.current) {
|
|
125
|
+
t11 = () => {
|
|
122
126
|
const list = readRef.current;
|
|
123
127
|
if (!list) return;
|
|
124
128
|
const hasMixed = list.querySelector("[data-has-description=\"true\"]") !== null && list.querySelector("[data-has-description=\"false\"]") !== null;
|
|
@@ -126,56 +130,56 @@ const UnwrappedList = (props, forwardedRef) => {
|
|
|
126
130
|
if (hasMixed && current !== "true") list.setAttribute("data-mixed-descriptions", "true");
|
|
127
131
|
else if (!hasMixed && current !== null) list.removeAttribute("data-mixed-descriptions");
|
|
128
132
|
};
|
|
129
|
-
$[
|
|
130
|
-
$[
|
|
131
|
-
} else
|
|
132
|
-
useIsomorphicLayoutEffect(
|
|
133
|
-
const
|
|
134
|
-
let
|
|
135
|
-
if ($[
|
|
136
|
-
|
|
137
|
-
$[
|
|
138
|
-
$[
|
|
139
|
-
} else
|
|
140
|
-
const
|
|
141
|
-
let
|
|
142
|
-
if ($[
|
|
143
|
-
|
|
144
|
-
className:
|
|
133
|
+
$[22] = readRef.current;
|
|
134
|
+
$[23] = t11;
|
|
135
|
+
} else t11 = $[23];
|
|
136
|
+
useIsomorphicLayoutEffect(t11);
|
|
137
|
+
const t12 = slots.heading;
|
|
138
|
+
let t13;
|
|
139
|
+
if ($[24] !== className) {
|
|
140
|
+
t13 = clsx(ActionList_module_css_default.ActionList, className);
|
|
141
|
+
$[24] = className;
|
|
142
|
+
$[25] = t13;
|
|
143
|
+
} else t13 = $[25];
|
|
144
|
+
const t14 = itemGapEnabled ? "" : void 0;
|
|
145
|
+
let t15;
|
|
146
|
+
if ($[26] !== Component || $[27] !== appliedRef || $[28] !== ariaLabelledBy || $[29] !== childrenWithoutSlots || $[30] !== listRole || $[31] !== restProps || $[32] !== showDividers || $[33] !== t13 || $[34] !== t14 || $[35] !== variant) {
|
|
147
|
+
t15 = /*#__PURE__*/ jsx(Component, {
|
|
148
|
+
className: t13,
|
|
145
149
|
role: listRole,
|
|
146
150
|
"aria-labelledby": ariaLabelledBy,
|
|
147
151
|
ref: appliedRef,
|
|
148
152
|
"data-component": "ActionList",
|
|
149
153
|
"data-dividers": showDividers,
|
|
150
154
|
"data-variant": variant,
|
|
151
|
-
"data-item-gap":
|
|
155
|
+
"data-item-gap": t14,
|
|
152
156
|
...restProps,
|
|
153
157
|
children: childrenWithoutSlots
|
|
154
158
|
});
|
|
155
|
-
$[
|
|
156
|
-
$[
|
|
157
|
-
$[
|
|
158
|
-
$[
|
|
159
|
-
$[
|
|
160
|
-
$[
|
|
161
|
-
$[
|
|
162
|
-
$[32] = t12;
|
|
159
|
+
$[26] = Component;
|
|
160
|
+
$[27] = appliedRef;
|
|
161
|
+
$[28] = ariaLabelledBy;
|
|
162
|
+
$[29] = childrenWithoutSlots;
|
|
163
|
+
$[30] = listRole;
|
|
164
|
+
$[31] = restProps;
|
|
165
|
+
$[32] = showDividers;
|
|
163
166
|
$[33] = t13;
|
|
164
|
-
$[34] =
|
|
165
|
-
$[35] =
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
$[34] = t14;
|
|
168
|
+
$[35] = variant;
|
|
169
|
+
$[36] = t15;
|
|
170
|
+
} else t15 = $[36];
|
|
171
|
+
let t16;
|
|
172
|
+
if ($[37] !== listContextValue || $[38] !== slots.heading || $[39] !== t15) {
|
|
173
|
+
t16 = /*#__PURE__*/ jsxs(ListContext.Provider, {
|
|
170
174
|
value: listContextValue,
|
|
171
|
-
children: [
|
|
175
|
+
children: [t12, t15]
|
|
172
176
|
});
|
|
173
|
-
$[
|
|
174
|
-
$[
|
|
175
|
-
$[38] = t14;
|
|
177
|
+
$[37] = listContextValue;
|
|
178
|
+
$[38] = slots.heading;
|
|
176
179
|
$[39] = t15;
|
|
177
|
-
|
|
178
|
-
|
|
180
|
+
$[40] = t16;
|
|
181
|
+
} else t16 = $[40];
|
|
182
|
+
return t16;
|
|
179
183
|
};
|
|
180
184
|
const List = fixedForwardRef(UnwrappedList);
|
|
181
185
|
Object.assign(List, { displayName: "ActionList" });
|
|
@@ -100,6 +100,10 @@ type ActionListProps<As extends React.ElementType = 'ul'> = PolymorphicProps<As,
|
|
|
100
100
|
*/
|
|
101
101
|
disableFocusZone?: boolean;
|
|
102
102
|
className?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Disable the gap between items when this `ActionList` is rendered in a `NavList`.
|
|
105
|
+
*/
|
|
106
|
+
disableItemGap?: boolean;
|
|
103
107
|
}>>;
|
|
104
108
|
//#endregion
|
|
105
109
|
export { ActionListItemProps, ActionListProps };
|
|
@@ -12,7 +12,8 @@ import { Icon } from "@primer/octicons-react";
|
|
|
12
12
|
//#region src/NavList/NavList.d.ts
|
|
13
13
|
type NavListHeadingLevels = 'h2' | 'h3';
|
|
14
14
|
type NavListProps = {
|
|
15
|
-
children: React.ReactNode;
|
|
15
|
+
children: React.ReactNode; /** Disable the gap between items when the item gap feature is enabled. */
|
|
16
|
+
disableItemGap?: boolean;
|
|
16
17
|
} & React.ComponentProps<'nav'>;
|
|
17
18
|
type NavListHeadingProps = {
|
|
18
19
|
/** Semantic heading level for the NavList. Also sets the default level for child group headings, which render one level deeper. */as?: NavListHeadingLevels; /** Visually hide the heading while keeping it available to assistive technology. */
|
package/dist/NavList/NavList.js
CHANGED
|
@@ -26,76 +26,83 @@ function levelToHeadingTag(level) {
|
|
|
26
26
|
}
|
|
27
27
|
const Root = /*#__PURE__*/ React.forwardRef((t0, ref) => {
|
|
28
28
|
var _heading$props$id, _ariaLabelledby;
|
|
29
|
-
const $ = c(
|
|
29
|
+
const $ = c(26);
|
|
30
30
|
let ariaLabel;
|
|
31
31
|
let ariaLabelledby;
|
|
32
32
|
let children;
|
|
33
|
+
let disableItemGap;
|
|
33
34
|
let props;
|
|
34
35
|
if ($[0] !== t0) {
|
|
35
|
-
({children, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...props} = t0);
|
|
36
|
+
({children, disableItemGap, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...props} = t0);
|
|
36
37
|
$[0] = t0;
|
|
37
38
|
$[1] = ariaLabel;
|
|
38
39
|
$[2] = ariaLabelledby;
|
|
39
40
|
$[3] = children;
|
|
40
|
-
$[4] =
|
|
41
|
+
$[4] = disableItemGap;
|
|
42
|
+
$[5] = props;
|
|
41
43
|
} else {
|
|
42
44
|
ariaLabel = $[1];
|
|
43
45
|
ariaLabelledby = $[2];
|
|
44
46
|
children = $[3];
|
|
45
|
-
|
|
47
|
+
disableItemGap = $[4];
|
|
48
|
+
props = $[5];
|
|
46
49
|
}
|
|
47
50
|
let t1;
|
|
48
|
-
if ($[
|
|
51
|
+
if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
|
|
49
52
|
t1 = { heading: Heading };
|
|
50
|
-
$[
|
|
51
|
-
} else t1 = $[
|
|
53
|
+
$[6] = t1;
|
|
54
|
+
} else t1 = $[6];
|
|
52
55
|
const [slots, childrenWithoutHeading] = useSlots(children, t1);
|
|
53
56
|
const fallbackHeadingId = useId$1();
|
|
54
57
|
const heading = slots.heading;
|
|
55
58
|
const headingId = heading ? (_heading$props$id = heading.props.id) !== null && _heading$props$id !== void 0 ? _heading$props$id : fallbackHeadingId : void 0;
|
|
56
59
|
let t2;
|
|
57
|
-
if ($[
|
|
60
|
+
if ($[7] !== heading) {
|
|
58
61
|
var _heading$props$as;
|
|
59
62
|
t2 = heading ? headingTagToLevel((_heading$props$as = heading.props.as) !== null && _heading$props$as !== void 0 ? _heading$props$as : "h2") : null;
|
|
60
|
-
$[
|
|
61
|
-
$[
|
|
62
|
-
} else t2 = $[
|
|
63
|
+
$[7] = heading;
|
|
64
|
+
$[8] = t2;
|
|
65
|
+
} else t2 = $[8];
|
|
63
66
|
const headingLevel = t2;
|
|
64
67
|
const navLabelledby = (_ariaLabelledby = ariaLabelledby) !== null && _ariaLabelledby !== void 0 ? _ariaLabelledby : ariaLabel ? void 0 : headingId;
|
|
65
68
|
let t3;
|
|
66
|
-
if ($[
|
|
69
|
+
if ($[9] !== heading || $[10] !== headingId) {
|
|
67
70
|
t3 = heading ? /*#__PURE__*/ React.cloneElement(heading, { id: headingId }) : null;
|
|
68
|
-
$[
|
|
69
|
-
$[
|
|
70
|
-
$[
|
|
71
|
-
} else t3 = $[
|
|
71
|
+
$[9] = heading;
|
|
72
|
+
$[10] = headingId;
|
|
73
|
+
$[11] = t3;
|
|
74
|
+
} else t3 = $[11];
|
|
72
75
|
let t4;
|
|
73
|
-
if ($[
|
|
76
|
+
if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
|
|
74
77
|
t4 = { container: "NavList" };
|
|
75
|
-
$[
|
|
76
|
-
} else t4 = $[
|
|
78
|
+
$[12] = t4;
|
|
79
|
+
} else t4 = $[12];
|
|
77
80
|
let t5;
|
|
78
|
-
if ($[
|
|
81
|
+
if ($[13] !== childrenWithoutHeading || $[14] !== disableItemGap) {
|
|
79
82
|
t5 = /*#__PURE__*/ jsx(ActionListContainerContext.Provider, {
|
|
80
83
|
value: t4,
|
|
81
|
-
children: /*#__PURE__*/ jsx(ActionList, {
|
|
84
|
+
children: /*#__PURE__*/ jsx(ActionList, {
|
|
85
|
+
disableItemGap,
|
|
86
|
+
children: childrenWithoutHeading
|
|
87
|
+
})
|
|
82
88
|
});
|
|
83
|
-
$[
|
|
84
|
-
$[
|
|
85
|
-
|
|
89
|
+
$[13] = childrenWithoutHeading;
|
|
90
|
+
$[14] = disableItemGap;
|
|
91
|
+
$[15] = t5;
|
|
92
|
+
} else t5 = $[15];
|
|
86
93
|
let t6;
|
|
87
|
-
if ($[
|
|
94
|
+
if ($[16] !== headingLevel || $[17] !== t3 || $[18] !== t5) {
|
|
88
95
|
t6 = /*#__PURE__*/ jsxs(NavListHeadingLevelContext.Provider, {
|
|
89
96
|
value: headingLevel,
|
|
90
97
|
children: [t3, t5]
|
|
91
98
|
});
|
|
92
|
-
$[
|
|
93
|
-
$[
|
|
94
|
-
$[
|
|
95
|
-
$[
|
|
96
|
-
} else t6 = $[
|
|
99
|
+
$[16] = headingLevel;
|
|
100
|
+
$[17] = t3;
|
|
101
|
+
$[18] = t5;
|
|
102
|
+
$[19] = t6;
|
|
103
|
+
} else t6 = $[19];
|
|
97
104
|
let t7;
|
|
98
|
-
if ($[
|
|
105
|
+
if ($[20] !== ariaLabel || $[21] !== navLabelledby || $[22] !== props || $[23] !== ref || $[24] !== t6) {
|
|
99
106
|
t7 = /*#__PURE__*/ jsx("nav", {
|
|
100
107
|
...props,
|
|
101
108
|
"aria-label": ariaLabel,
|
|
@@ -104,13 +111,13 @@ const Root = /*#__PURE__*/ React.forwardRef((t0, ref) => {
|
|
|
104
111
|
"data-component": "NavList",
|
|
105
112
|
children: t6
|
|
106
113
|
});
|
|
107
|
-
$[
|
|
108
|
-
$[
|
|
109
|
-
$[
|
|
110
|
-
$[
|
|
111
|
-
$[
|
|
112
|
-
$[
|
|
113
|
-
} else t7 = $[
|
|
114
|
+
$[20] = ariaLabel;
|
|
115
|
+
$[21] = navLabelledby;
|
|
116
|
+
$[22] = props;
|
|
117
|
+
$[23] = ref;
|
|
118
|
+
$[24] = t6;
|
|
119
|
+
$[25] = t7;
|
|
120
|
+
} else t7 = $[25];
|
|
114
121
|
return t7;
|
|
115
122
|
});
|
|
116
123
|
Root.displayName = "NavList";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { reactMajorVersion } from "../utils/environment.js";
|
|
1
2
|
import { useMergedRefs } from "../hooks/useMergedRefs.js";
|
|
2
3
|
import { useProvidedRefOrCreate } from "../hooks/useProvidedRefOrCreate.js";
|
|
3
4
|
import { useOnEscapePress } from "../hooks/useOnEscapePress.js";
|
|
@@ -82,10 +83,14 @@ const emptyKeybindingHints = [];
|
|
|
82
83
|
const Tooltip = /*#__PURE__*/ React.forwardRef(({ direction = "s", text, type = "description", children, id, className, keybindingHint = emptyKeybindingHints, delay = "short", _privateDisableTooltip = false, ...rest }, forwardedRef) => {
|
|
83
84
|
const tooltipId = useId$1(id);
|
|
84
85
|
const child = Children.only(children);
|
|
86
|
+
const isFragmentTrigger = /*#__PURE__*/ React.isValidElement(child) && child.type === React.Fragment;
|
|
87
|
+
warning(isFragmentTrigger, "The `Tooltip` component does not support a React Fragment as its trigger. Pass a single interactive element instead.");
|
|
88
|
+
const elementChild = /*#__PURE__*/ React.isValidElement(child) ? child : void 0;
|
|
89
|
+
const childRef = reactMajorVersion > 18 ? elementChild === null || elementChild === void 0 ? void 0 : elementChild.props.ref : elementChild === null || elementChild === void 0 ? void 0 : elementChild.ref;
|
|
85
90
|
const mergedRefEnabled = useFeatureFlag("primer_react_merged_forwarded_refs");
|
|
86
91
|
const triggerRef = useRef(null);
|
|
87
|
-
const mergedTriggerRef = useMergedRefs(triggerRef, forwardedRef);
|
|
88
|
-
const providedOrCreatedRef = useProvidedRefOrCreate(forwardedRef);
|
|
92
|
+
const mergedTriggerRef = useMergedRefs(triggerRef, useMergedRefs(forwardedRef, childRef));
|
|
93
|
+
const providedOrCreatedRef = useProvidedRefOrCreate(forwardedRef !== null && forwardedRef !== void 0 ? forwardedRef : childRef);
|
|
89
94
|
const readTriggerRef = mergedRefEnabled ? triggerRef : providedOrCreatedRef;
|
|
90
95
|
const appliedTriggerRef = mergedRefEnabled ? mergedTriggerRef : providedOrCreatedRef;
|
|
91
96
|
const tooltipElRef = useRef(null);
|
|
@@ -95,7 +100,7 @@ const Tooltip = /*#__PURE__*/ React.forwardRef(({ direction = "s", text, type =
|
|
|
95
100
|
const { safeSetTimeout, safeClearTimeout } = useSafeTimeout();
|
|
96
101
|
const openTooltip = () => {
|
|
97
102
|
try {
|
|
98
|
-
if (tooltipElRef.current && readTriggerRef.current && tooltipElRef.current.hasAttribute("popover") && !tooltipElRef.current.matches(":popover-open") && !_privateDisableTooltip) {
|
|
103
|
+
if (tooltipElRef.current && readTriggerRef.current instanceof HTMLElement && tooltipElRef.current.hasAttribute("popover") && !tooltipElRef.current.matches(":popover-open") && !_privateDisableTooltip) {
|
|
99
104
|
const tooltip = tooltipElRef.current;
|
|
100
105
|
const trigger = readTriggerRef.current;
|
|
101
106
|
tooltip.showPopover();
|
|
@@ -131,15 +136,19 @@ const Tooltip = /*#__PURE__*/ React.forwardRef(({ direction = "s", text, type =
|
|
|
131
136
|
const value = useMemo(() => ({ tooltipId }), [tooltipId]);
|
|
132
137
|
useEffect(() => {
|
|
133
138
|
if (!tooltipElRef.current || !readTriggerRef.current) return;
|
|
134
|
-
const
|
|
135
|
-
const
|
|
139
|
+
const trigger = readTriggerRef.current;
|
|
140
|
+
const isInvalidTrigger = !(trigger instanceof HTMLElement);
|
|
141
|
+
warning(isInvalidTrigger, "The `Tooltip` component expects its trigger ref to resolve to an HTML element. Ensure the trigger forwards its ref to a single interactive element instead of a React Fragment.");
|
|
142
|
+
if (isInvalidTrigger) return;
|
|
143
|
+
const isTriggerInteractive = isInteractive(trigger);
|
|
144
|
+
const triggerChildren = trigger.childNodes;
|
|
136
145
|
const hasInteractiveDescendant = Array.from(triggerChildren).some((child) => {
|
|
137
146
|
return child instanceof HTMLElement && isInteractive(child) || Array.from(child.childNodes).some((grandChild) => grandChild instanceof HTMLElement && isInteractive(grandChild));
|
|
138
147
|
});
|
|
139
148
|
!(isTriggerInteractive || hasInteractiveDescendant) && invariant(false, "The `Tooltip` component expects a single React element that contains interactive content. Consider using a `<button>` or equivalent interactive element instead.");
|
|
140
149
|
if (type === "label") {
|
|
141
|
-
const hasAriaLabel =
|
|
142
|
-
const hasAriaLabelInChildren = Array.from(
|
|
150
|
+
const hasAriaLabel = trigger.hasAttribute("aria-label");
|
|
151
|
+
const hasAriaLabelInChildren = Array.from(trigger.childNodes).some((child) => child instanceof HTMLElement && child.hasAttribute("aria-label"));
|
|
143
152
|
warning(hasAriaLabel || hasAriaLabelInChildren, "The label type `Tooltip` is going to be used here to label the trigger element. Please remove the aria-label from the trigger element.");
|
|
144
153
|
}
|
|
145
154
|
if (typeof window !== "undefined") {
|
|
@@ -162,6 +171,7 @@ const Tooltip = /*#__PURE__*/ React.forwardRef(({ direction = "s", text, type =
|
|
|
162
171
|
const platform = usePlatform();
|
|
163
172
|
const hasAriaLabel = "aria-label" in rest;
|
|
164
173
|
const keybindingHints = Array.isArray(keybindingHint) ? keybindingHint : [keybindingHint];
|
|
174
|
+
if (isFragmentTrigger) return child;
|
|
165
175
|
return /*#__PURE__*/ jsx(TooltipContext.Provider, {
|
|
166
176
|
value,
|
|
167
177
|
children: /*#__PURE__*/ jsxs(Fragment$1, { children: [/*#__PURE__*/ React.isValidElement(child) && /*#__PURE__*/ React.cloneElement(child, {
|
|
@@ -212,6 +212,10 @@
|
|
|
212
212
|
"id": "components-actionlist-features--item-dividers",
|
|
213
213
|
"code": "() => (\n <ActionList showDividers>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n </ActionList>\n)"
|
|
214
214
|
},
|
|
215
|
+
{
|
|
216
|
+
"id": "components-actionlist-features--disable-item-gap",
|
|
217
|
+
"code": "() => (\n <FeatureFlags\n flags={{\n primer_react_action_list_item_gap: true,\n }}\n >\n <ActionList.ContainerContext.Provider\n value={{\n container: 'NavList',\n }}\n >\n <Heading as=\"h3\">Default item gap</Heading>\n <ActionList>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n </ActionList>\n\n <Heading as=\"h3\">Item gap disabled</Heading>\n <ActionList disableItemGap>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n </ActionList>\n </ActionList.ContainerContext.Provider>\n </FeatureFlags>\n)"
|
|
218
|
+
},
|
|
215
219
|
{
|
|
216
220
|
"id": "components-actionlist-features--single-divider",
|
|
217
221
|
"code": "() => (\n <ActionList>\n <ActionList.Item>Copy link</ActionList.Item>\n <ActionList.Item>Quote reply</ActionList.Item>\n <ActionList.Item>Edit comment</ActionList.Item>\n <ActionList.Divider />\n <ActionList.Item variant=\"danger\">Delete file</ActionList.Item>\n </ActionList>\n)"
|
|
@@ -365,6 +369,12 @@
|
|
|
365
369
|
"type": "AriaRole",
|
|
366
370
|
"defaultValue": "",
|
|
367
371
|
"description": "ARIA role describing the function of the list. `listbox` and `menu` are a common values."
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
"name": "disableItemGap",
|
|
375
|
+
"type": "boolean",
|
|
376
|
+
"description": "Disable the gap between items when this `ActionList` is rendered in a `NavList`.",
|
|
377
|
+
"defaultValue": "false"
|
|
368
378
|
}
|
|
369
379
|
],
|
|
370
380
|
"subcomponents": [
|
|
@@ -4234,6 +4244,12 @@
|
|
|
4234
4244
|
"defaultValue": "",
|
|
4235
4245
|
"description": ""
|
|
4236
4246
|
},
|
|
4247
|
+
{
|
|
4248
|
+
"name": "disableItemGap",
|
|
4249
|
+
"type": "boolean",
|
|
4250
|
+
"defaultValue": "false",
|
|
4251
|
+
"description": "Disable the gap between items when the item gap feature is enabled."
|
|
4252
|
+
},
|
|
4237
4253
|
{
|
|
4238
4254
|
"name": "ref",
|
|
4239
4255
|
"type": "React.RefObject<HTMLElement>"
|
package/package.json
CHANGED