@primer/react 38.34.0-rc.6e2d5aac5 → 38.34.0-rc.8fa435aeb

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,8 +1,6 @@
1
- import { useMergedRefs } from "../hooks/useMergedRefs.js";
2
1
  import { useProvidedRefOrCreate } from "../hooks/useProvidedRefOrCreate.js";
3
2
  import { warning } from "../utils/warning.js";
4
3
  import { isSlot } from "../utils/is-slot.js";
5
- import { useFeatureFlag } from "../FeatureFlags/useFeatureFlag.js";
6
4
  import { isResponsiveValue } from "../hooks/useResponsiveValue.js";
7
5
  import { getResponsiveAttributes } from "../internal/utils/getResponsiveAttributes.js";
8
6
  import Heading from "../Heading/Heading.js";
@@ -12,7 +10,7 @@ import PageHeader_module_css_default from "./PageHeader.module.css.js";
12
10
  import { c } from "react-compiler-runtime";
13
11
  import { clsx } from "clsx";
14
12
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
15
- import React, { useEffect, useRef } from "react";
13
+ import React, { useEffect } from "react";
16
14
  import { ArrowLeftIcon } from "@primer/octicons-react";
17
15
  //#region src/PageHeader/PageHeader.tsx
18
16
  const hiddenOnRegularAndWide = {
@@ -29,12 +27,7 @@ const Root = /*#__PURE__*/ React.forwardRef((t0, forwardedRef) => {
29
27
  const $ = c(17);
30
28
  const { children, className, as: t1, "aria-label": ariaLabel, role, hasBorder } = t0;
31
29
  const BaseComponent = t1 === void 0 ? "div" : t1;
32
- const mergedRefEnabled = useFeatureFlag("primer_react_merged_forwarded_refs");
33
- const rootRef = useRef(null);
34
- const mergedRef = useMergedRefs(rootRef, forwardedRef);
35
- const providedOrCreatedRef = useProvidedRefOrCreate(forwardedRef);
36
- const readRef = mergedRefEnabled ? rootRef : providedOrCreatedRef;
37
- const appliedRef = mergedRefEnabled ? mergedRef : providedOrCreatedRef;
30
+ const rootRef = useProvidedRefOrCreate(forwardedRef);
38
31
  const hoistChildState = (nodes) => {
39
32
  const result = { hasNavigation: false };
40
33
  for (const child of React.Children.toArray(nodes)) {
@@ -61,12 +54,12 @@ const Root = /*#__PURE__*/ React.forwardRef((t0, forwardedRef) => {
61
54
  const isInteractive = _temp;
62
55
  let t2;
63
56
  let t3;
64
- if ($[0] !== children || $[1] !== readRef) {
57
+ if ($[0] !== children || $[1] !== rootRef) {
65
58
  t2 = function validateInteractiveElementsInTitle() {
66
59
  let hasContextArea = false;
67
60
  let hasLeadingAction = false;
68
- if (!readRef.current || readRef.current.children.length <= 0) return;
69
- const titleArea = Array.from(readRef.current.children).find(_temp2);
61
+ if (!rootRef.current || rootRef.current.children.length <= 0) return;
62
+ const titleArea = Array.from(rootRef.current.children).find(_temp2);
70
63
  if (!titleArea) return;
71
64
  for (const child_1 of React.Children.toArray(children)) {
72
65
  if (/*#__PURE__*/ React.isValidElement(child_1) && (child_1.type === ContextArea || isSlot(child_1, ContextArea))) hasContextArea = true;
@@ -74,9 +67,9 @@ const Root = /*#__PURE__*/ React.forwardRef((t0, forwardedRef) => {
74
67
  }
75
68
  warning(Array.from(titleArea.childNodes).some((child_2) => child_2 instanceof HTMLElement && isInteractive(child_2) || Array.from(child_2.childNodes).some((child_3) => child_3 instanceof HTMLElement && isInteractive(child_3))) && (hasContextArea || hasLeadingAction), "When PageHeader.ContextArea or PageHeader.LeadingAction is present, we recommended not to include any interactive items in the PageHeader.TitleArea to make sure the focus order is logical.");
76
69
  };
77
- t3 = [children, readRef];
70
+ t3 = [children, rootRef];
78
71
  $[0] = children;
79
- $[1] = readRef;
72
+ $[1] = rootRef;
80
73
  $[2] = t2;
81
74
  $[3] = t3;
82
75
  } else {
@@ -96,9 +89,9 @@ const Root = /*#__PURE__*/ React.forwardRef((t0, forwardedRef) => {
96
89
  const t8 = getResponsiveAttributes("title-size-variant", titleVariant);
97
90
  const t9 = getNavHiddenDataAttributes(navigationHidden);
98
91
  let t10;
99
- if ($[6] !== BaseComponent || $[7] !== appliedRef || $[8] !== ariaLabel || $[9] !== children || $[10] !== role || $[11] !== t4 || $[12] !== t6 || $[13] !== t7 || $[14] !== t8 || $[15] !== t9) {
92
+ if ($[6] !== BaseComponent || $[7] !== ariaLabel || $[8] !== children || $[9] !== role || $[10] !== rootRef || $[11] !== t4 || $[12] !== t6 || $[13] !== t7 || $[14] !== t8 || $[15] !== t9) {
100
93
  t10 = /*#__PURE__*/ jsx(BaseComponent, {
101
- ref: appliedRef,
94
+ ref: rootRef,
102
95
  className: t4,
103
96
  "data-component": t5,
104
97
  "data-has-border": t6,
@@ -110,10 +103,10 @@ const Root = /*#__PURE__*/ React.forwardRef((t0, forwardedRef) => {
110
103
  children
111
104
  });
112
105
  $[6] = BaseComponent;
113
- $[7] = appliedRef;
114
- $[8] = ariaLabel;
115
- $[9] = children;
116
- $[10] = role;
106
+ $[7] = ariaLabel;
107
+ $[8] = children;
108
+ $[9] = role;
109
+ $[10] = rootRef;
117
110
  $[11] = t4;
118
111
  $[12] = t6;
119
112
  $[13] = t7;
@@ -302,9 +295,7 @@ const TitleArea = /*#__PURE__*/ React.forwardRef((t0, forwardedRef) => {
302
295
  const { children, className, hidden: t1, variant: t2 } = t0;
303
296
  const hidden = t1 === void 0 ? false : t1;
304
297
  const variant = t2 === void 0 ? "medium" : t2;
305
- const mergedRefEnabled = useFeatureFlag("primer_react_merged_forwarded_refs");
306
- const providedOrCreatedRef = useProvidedRefOrCreate(forwardedRef);
307
- const appliedRef = mergedRefEnabled ? forwardedRef : providedOrCreatedRef;
298
+ const titleAreaRef = useProvidedRefOrCreate(forwardedRef);
308
299
  let t3;
309
300
  if ($[0] !== className) {
310
301
  t3 = clsx(PageHeader_module_css_default.TitleArea, className);
@@ -324,20 +315,20 @@ const TitleArea = /*#__PURE__*/ React.forwardRef((t0, forwardedRef) => {
324
315
  $[5] = t5;
325
316
  } else t5 = $[5];
326
317
  let t6;
327
- if ($[6] !== appliedRef || $[7] !== children || $[8] !== t3 || $[9] !== t4 || $[10] !== t5) {
318
+ if ($[6] !== children || $[7] !== t3 || $[8] !== t4 || $[9] !== t5 || $[10] !== titleAreaRef) {
328
319
  t6 = /*#__PURE__*/ jsx("div", {
329
320
  className: t3,
330
- ref: appliedRef,
321
+ ref: titleAreaRef,
331
322
  "data-component": "TitleArea",
332
323
  ...t4,
333
324
  ...t5,
334
325
  children
335
326
  });
336
- $[6] = appliedRef;
337
- $[7] = children;
338
- $[8] = t3;
339
- $[9] = t4;
340
- $[10] = t5;
327
+ $[6] = children;
328
+ $[7] = t3;
329
+ $[8] = t4;
330
+ $[9] = t5;
331
+ $[10] = titleAreaRef;
341
332
  $[11] = t6;
342
333
  } else t6 = $[11];
343
334
  return t6;
@@ -2,13 +2,13 @@ import { useProvidedRefOrCreate } from "../hooks/useProvidedRefOrCreate.js";
2
2
  import { useProvidedStateOrCreate } from "../hooks/useProvidedStateOrCreate.js";
3
3
  import { isAlphabetKey } from "../hooks/useMnemonics.js";
4
4
  import { useId as useId$1 } from "../hooks/useId.js";
5
- import { useFeatureFlag } from "../FeatureFlags/useFeatureFlag.js";
6
5
  import useSafeTimeout from "../hooks/useSafeTimeout.js";
7
6
  import { IconButton } from "../Button/IconButton.js";
8
7
  import { LinkButton } from "../Button/LinkButton.js";
9
8
  import { ButtonComponent } from "../Button/Button.js";
10
9
  import { useResponsiveValue } from "../hooks/useResponsiveValue.js";
11
10
  import Heading from "../Heading/Heading.js";
11
+ import { useFeatureFlag } from "../FeatureFlags/useFeatureFlag.js";
12
12
  import { AnchoredOverlay } from "../AnchoredOverlay/AnchoredOverlay.js";
13
13
  import { Banner } from "../Banner/index.js";
14
14
  import { useFormControlContext } from "../FormControl/_FormControlContext.js";
@@ -1,7 +1,5 @@
1
- import { useMergedRefs } from "../hooks/useMergedRefs.js";
2
1
  import { useProvidedRefOrCreate } from "../hooks/useProvidedRefOrCreate.js";
3
2
  import { AriaStatus } from "../live-region/AriaStatus.js";
4
- import { useFeatureFlag } from "../FeatureFlags/useFeatureFlag.js";
5
3
  import Text_default from "../Text/Text.js";
6
4
  import _VisuallyHidden_module_css_default from "../_VisuallyHidden.module.css.js";
7
5
  import VisuallyHidden from "../_VisuallyHidden.js";
@@ -13,19 +11,14 @@ import UnstyledTextInput from "../internal/components/UnstyledTextInput.js";
13
11
  import { getCharacterCountState } from "../utils/character-counter.js";
14
12
  import { clsx } from "clsx";
15
13
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
16
- import React, { useCallback, useId, useRef, useState } from "react";
14
+ import React, { useCallback, useId, useState } from "react";
17
15
  import { isValidElementType } from "react-is";
18
16
  import { AlertFillIcon } from "@primer/octicons-react";
19
17
  //#region src/TextInput/TextInput.tsx
20
18
  const TextInput = /*#__PURE__*/ React.forwardRef(({ icon: IconComponent, leadingVisual: LeadingVisual, trailingVisual: TrailingVisual, trailingAction, block, className, contrast, disabled, loading, loaderPosition = "auto", loaderText = "Loading", monospace, validationStatus, size: sizeProp, onFocus, onBlur, variant: variantProp, width: widthProp, minWidth: minWidthProp, maxWidth: maxWidthProp, type = "text", required, characterLimit, onChange, value, defaultValue, "data-component": dataComponent, ...inputProps }, ref) => {
21
19
  var _counter$isOverLimit;
22
20
  const [isInputFocused, setIsInputFocused] = useState(false);
23
- const mergedRefEnabled = useFeatureFlag("primer_react_merged_forwarded_refs");
24
- const inputRef = useRef(null);
25
- const mergedRef = useMergedRefs(inputRef, ref);
26
- const providedOrCreatedRef = useProvidedRefOrCreate(ref);
27
- const readRef = mergedRefEnabled ? inputRef : providedOrCreatedRef;
28
- const appliedRef = mergedRefEnabled ? mergedRef : providedOrCreatedRef;
21
+ const inputRef = useProvidedRefOrCreate(ref);
29
22
  const isControlled = value !== void 0;
30
23
  const [uncontrolledLength, setUncontrolledLength] = useState(() => defaultValue !== void 0 ? String(defaultValue).length : 0);
31
24
  const currentLength = isControlled ? String(value).length : uncontrolledLength;
@@ -36,9 +29,9 @@ const TextInput = /*#__PURE__*/ React.forwardRef(({ icon: IconComponent, leading
36
29
  const showTrailingLoadingIndicator = loading && (loaderPosition === "trailing" || Boolean(loaderPosition === "auto" && !LeadingVisual));
37
30
  const isSegmentedInputType = type === "date" || type === "time" || type === "datetime-local";
38
31
  const focusInput = (e) => {
39
- if (e.target !== readRef.current || !isSegmentedInputType) {
40
- var _readRef$current;
41
- (_readRef$current = readRef.current) === null || _readRef$current === void 0 || _readRef$current.focus();
32
+ if (e.target !== inputRef.current || !isSegmentedInputType) {
33
+ var _inputRef$current;
34
+ (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus();
42
35
  }
43
36
  };
44
37
  const leadingVisualId = useId();
@@ -95,7 +88,7 @@ const TextInput = /*#__PURE__*/ React.forwardRef(({ icon: IconComponent, leading
95
88
  children: typeof LeadingVisual !== "string" && isValidElementType(LeadingVisual) ? /*#__PURE__*/ jsx(LeadingVisual, {}) : LeadingVisual
96
89
  }),
97
90
  /*#__PURE__*/ jsx(UnstyledTextInput, {
98
- ref: appliedRef,
91
+ ref: inputRef,
99
92
  disabled,
100
93
  onFocus: handleInputFocus,
101
94
  onBlur: handleInputBlur,
@@ -1,9 +1,7 @@
1
- import { useMergedRefs } from "../hooks/useMergedRefs.js";
2
1
  import { useProvidedRefOrCreate } from "../hooks/useProvidedRefOrCreate.js";
3
2
  import { useOnEscapePress } from "../hooks/useOnEscapePress.js";
4
3
  import { useId as useId$1 } from "../hooks/useId.js";
5
4
  import { warning } from "../utils/warning.js";
6
- import { useFeatureFlag } from "../FeatureFlags/useFeatureFlag.js";
7
5
  import { invariant } from "../utils/invariant.js";
8
6
  import Tooltip_module_css_default from "./Tooltip.module.css.js";
9
7
  import VisuallyHidden from "../_VisuallyHidden.js";
@@ -82,12 +80,7 @@ const emptyKeybindingHints = [];
82
80
  const Tooltip = /*#__PURE__*/ React.forwardRef(({ direction = "s", text, type = "description", children, id, className, keybindingHint = emptyKeybindingHints, delay = "short", _privateDisableTooltip = false, ...rest }, forwardedRef) => {
83
81
  const tooltipId = useId$1(id);
84
82
  const child = Children.only(children);
85
- const mergedRefEnabled = useFeatureFlag("primer_react_merged_forwarded_refs");
86
- const triggerRef = useRef(null);
87
- const mergedTriggerRef = useMergedRefs(triggerRef, forwardedRef);
88
- const providedOrCreatedRef = useProvidedRefOrCreate(forwardedRef);
89
- const readTriggerRef = mergedRefEnabled ? triggerRef : providedOrCreatedRef;
90
- const appliedTriggerRef = mergedRefEnabled ? mergedTriggerRef : providedOrCreatedRef;
83
+ const triggerRef = useProvidedRefOrCreate(forwardedRef);
91
84
  const tooltipElRef = useRef(null);
92
85
  const [calculatedDirection, setCalculatedDirection] = useState(direction);
93
86
  const [isPopoverOpen, setIsPopoverOpen] = useState(false);
@@ -95,9 +88,9 @@ const Tooltip = /*#__PURE__*/ React.forwardRef(({ direction = "s", text, type =
95
88
  const { safeSetTimeout, safeClearTimeout } = useSafeTimeout();
96
89
  const openTooltip = () => {
97
90
  try {
98
- if (tooltipElRef.current && readTriggerRef.current && tooltipElRef.current.hasAttribute("popover") && !tooltipElRef.current.matches(":popover-open") && !_privateDisableTooltip) {
91
+ if (tooltipElRef.current && triggerRef.current && tooltipElRef.current.hasAttribute("popover") && !tooltipElRef.current.matches(":popover-open") && !_privateDisableTooltip) {
99
92
  const tooltip = tooltipElRef.current;
100
- const trigger = readTriggerRef.current;
93
+ const trigger = triggerRef.current;
101
94
  tooltip.showPopover();
102
95
  setIsPopoverOpen(true);
103
96
  const { top, left, anchorAlign, anchorSide } = getAnchoredPosition(tooltip, trigger, {
@@ -119,7 +112,7 @@ const Tooltip = /*#__PURE__*/ React.forwardRef(({ direction = "s", text, type =
119
112
  openTimeoutRef.current = null;
120
113
  }
121
114
  try {
122
- if (tooltipElRef.current && readTriggerRef.current && tooltipElRef.current.hasAttribute("popover") && tooltipElRef.current.matches(":popover-open")) {
115
+ if (tooltipElRef.current && triggerRef.current && tooltipElRef.current.hasAttribute("popover") && tooltipElRef.current.matches(":popover-open")) {
123
116
  tooltipElRef.current.hidePopover();
124
117
  setIsPopoverOpen(false);
125
118
  } else setIsPopoverOpen(false);
@@ -129,16 +122,16 @@ const Tooltip = /*#__PURE__*/ React.forwardRef(({ direction = "s", text, type =
129
122
  };
130
123
  const value = useMemo(() => ({ tooltipId }), [tooltipId]);
131
124
  useEffect(() => {
132
- if (!tooltipElRef.current || !readTriggerRef.current) return;
133
- const isTriggerInteractive = isInteractive(readTriggerRef.current);
134
- const triggerChildren = readTriggerRef.current.childNodes;
125
+ if (!tooltipElRef.current || !triggerRef.current) return;
126
+ const isTriggerInteractive = isInteractive(triggerRef.current);
127
+ const triggerChildren = triggerRef.current.childNodes;
135
128
  const hasInteractiveDescendant = Array.from(triggerChildren).some((child) => {
136
129
  return child instanceof HTMLElement && isInteractive(child) || Array.from(child.childNodes).some((grandChild) => grandChild instanceof HTMLElement && isInteractive(grandChild));
137
130
  });
138
131
  !(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.");
139
132
  if (type === "label") {
140
- const hasAriaLabel = readTriggerRef.current.hasAttribute("aria-label");
141
- const hasAriaLabelInChildren = Array.from(readTriggerRef.current.childNodes).some((child) => child instanceof HTMLElement && child.hasAttribute("aria-label"));
133
+ const hasAriaLabel = triggerRef.current.hasAttribute("aria-label");
134
+ const hasAriaLabelInChildren = Array.from(triggerRef.current.childNodes).some((child) => child instanceof HTMLElement && child.hasAttribute("aria-label"));
142
135
  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.");
143
136
  }
144
137
  if (typeof window !== "undefined") {
@@ -147,7 +140,7 @@ const Tooltip = /*#__PURE__*/ React.forwardRef(({ direction = "s", text, type =
147
140
  tooltipElRef.current.setAttribute("popover", "auto");
148
141
  }, [
149
142
  tooltipElRef,
150
- readTriggerRef,
143
+ triggerRef,
151
144
  direction,
152
145
  type
153
146
  ]);
@@ -164,7 +157,7 @@ const Tooltip = /*#__PURE__*/ React.forwardRef(({ direction = "s", text, type =
164
157
  return /*#__PURE__*/ jsx(TooltipContext.Provider, {
165
158
  value,
166
159
  children: /*#__PURE__*/ jsxs(Fragment, { children: [/*#__PURE__*/ React.isValidElement(child) && /*#__PURE__*/ React.cloneElement(child, {
167
- ref: appliedTriggerRef,
160
+ ref: triggerRef,
168
161
  "aria-describedby": (() => {
169
162
  if (type !== "description") return child.props["aria-describedby"];
170
163
  const existingDescribedBy = child.props["aria-describedby"];
@@ -13,11 +13,10 @@ 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$id, _props$defaultValue;
16
+ var _props$defaultValue;
17
17
  const $ = c(13);
18
18
  const { children, onValueChange } = props;
19
- const generatedId = useId();
20
- const groupId = (_props$id = props.id) !== null && _props$id !== void 0 ? _props$id : generatedId;
19
+ const groupId = useId();
21
20
  const t0 = (_props$defaultValue = props.defaultValue) !== null && _props$defaultValue !== void 0 ? _props$defaultValue : props.value;
22
21
  let t1;
23
22
  if ($[0] !== props.value || $[1] !== t0) {
@@ -45,14 +45,7 @@ type UncontrolledTabsProps = {
45
45
  value: string;
46
46
  }) => void;
47
47
  };
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>;
48
+ type TabsProps = PropsWithChildren<ControlledTabsProps | UncontrolledTabsProps>;
56
49
  type Label = {
57
50
  'aria-label': string;
58
51
  };
@@ -80,7 +73,7 @@ type TabPanelProps = {
80
73
  value: string;
81
74
  };
82
75
  type TabListHookProps<T extends HTMLElement> = TabListProps & {
83
- /** Optional ref to use for the tablist. If none is provided, one will be generated automatically */ref?: React.Ref<T | null>;
76
+ /** Optional ref to use for the tablist. If none is provided, one will be generated automatically */ref?: React.RefObject<T>;
84
77
  };
85
78
  type TabListHookResult<T extends HTMLElement> = {
86
79
  /** Props to be spread onto the tablist element */tabListProps: {
@@ -88,7 +81,7 @@ type TabListHookResult<T extends HTMLElement> = {
88
81
  'aria-orientation': AriaAttributes['aria-orientation'];
89
82
  'aria-label': AriaAttributes['aria-label'];
90
83
  'aria-labelledby': AriaAttributes['aria-labelledby'];
91
- ref: React.Ref<T | null>;
84
+ ref: React.RefObject<T | null>;
92
85
  role: 'tablist';
93
86
  };
94
87
  };
@@ -1,22 +1,14 @@
1
- import { useMergedRefs } from "../../hooks/useMergedRefs.js";
2
1
  import { useProvidedRefOrCreate } from "../../hooks/useProvidedRefOrCreate.js";
3
- import { useFeatureFlag } from "../../FeatureFlags/useFeatureFlag.js";
4
2
  import { c } from "react-compiler-runtime";
5
- import { useRef } from "react";
6
3
  //#region src/experimental/Tabs/useTabList.ts
7
4
  function useTabList(props) {
8
5
  const $ = c(9);
9
6
  const { "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-orientation": ariaOrientation } = props;
10
- const mergedRefEnabled = useFeatureFlag("primer_react_merged_forwarded_refs");
11
- const tabListRef = useRef(null);
12
- const mergedRef = useMergedRefs(tabListRef, props.ref);
13
- const providedOrCreatedRef = useProvidedRefOrCreate(props.ref);
14
- const readRef = mergedRefEnabled ? tabListRef : providedOrCreatedRef;
15
- const appliedRef = mergedRefEnabled ? mergedRef : providedOrCreatedRef;
7
+ const ref = useProvidedRefOrCreate(props.ref);
16
8
  let t0;
17
- if ($[0] !== ariaOrientation || $[1] !== readRef) {
9
+ if ($[0] !== ariaOrientation || $[1] !== ref) {
18
10
  t0 = (event) => {
19
- const { current: tablist } = readRef;
11
+ const { current: tablist } = ref;
20
12
  if (tablist === null) return;
21
13
  const tabs = getFocusableTabs(tablist);
22
14
  const isVertical = ariaOrientation === "vertical";
@@ -41,25 +33,25 @@ function useTabList(props) {
41
33
  }
42
34
  };
43
35
  $[0] = ariaOrientation;
44
- $[1] = readRef;
36
+ $[1] = ref;
45
37
  $[2] = t0;
46
38
  } else t0 = $[2];
47
39
  const onKeyDown = t0;
48
40
  const t1 = ariaOrientation !== null && ariaOrientation !== void 0 ? ariaOrientation : "horizontal";
49
41
  let t2;
50
- if ($[3] !== appliedRef || $[4] !== ariaLabel || $[5] !== ariaLabelledby || $[6] !== onKeyDown || $[7] !== t1) {
42
+ if ($[3] !== ariaLabel || $[4] !== ariaLabelledby || $[5] !== onKeyDown || $[6] !== ref || $[7] !== t1) {
51
43
  t2 = { tabListProps: {
52
- ref: appliedRef,
44
+ ref,
53
45
  "aria-label": ariaLabel,
54
46
  "aria-labelledby": ariaLabelledby,
55
47
  "aria-orientation": t1,
56
48
  role: "tablist",
57
49
  onKeyDown
58
50
  } };
59
- $[3] = appliedRef;
60
- $[4] = ariaLabel;
61
- $[5] = ariaLabelledby;
62
- $[6] = onKeyDown;
51
+ $[3] = ariaLabel;
52
+ $[4] = ariaLabelledby;
53
+ $[5] = onKeyDown;
54
+ $[6] = ref;
63
55
  $[7] = t1;
64
56
  $[8] = t2;
65
57
  } else t2 = $[8];
@@ -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, selectedFromProps] = useMemo(() => {
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, { value: `${tabIndex++}` });
30
- if (/*#__PURE__*/ isValidElement(child) && (child.type === Panel || isSlot(child, Panel))) return /*#__PURE__*/ cloneElement(child, { value: `${panelIndex++}` });
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
- 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);
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(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
- })
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 = ({ onSelect, value, ...itemProps }) => {
88
+ const TabImpl = ({ "aria-selected": ariaSelected, onSelect, ...props }) => {
112
89
  const { loadingCounters } = useContext(UnderlinePanelsContext);
113
- const { tabProps } = useTab({ value: value !== null && value !== void 0 ? value : "" });
114
- const { onKeyDown: tabOnKeyDown, onMouseDown: tabOnMouseDown, onFocus: tabOnFocus, ...restTabProps } = tabProps;
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
- ...itemProps,
118
- ...restTabProps,
98
+ role: "tab",
99
+ tabIndex: ariaSelected ? 0 : -1,
100
+ "aria-selected": ariaSelected,
119
101
  type: "button",
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
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 PanelImpl = ({ children, value, ...panelRest }) => {
137
- const { tabPanelProps } = useTabPanel({ value: value !== null && value !== void 0 ? value : "" });
112
+ const Panel = ({ children, ...rest }) => {
138
113
  return /*#__PURE__*/ jsx("div", {
139
- ...panelRest,
140
- ...tabPanelProps,
114
+ role: "tabpanel",
115
+ ...rest,
141
116
  children
142
117
  });
143
118
  };
144
- PanelImpl.displayName = "PanelImpl";
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 mergedRef = useMergedRefs(forwardedRef, ref)
20
+ * const combinedRef = useMergedRefs(forwardedRef, ref)
21
21
  *
22
- * return <button ref={mergedRef} />
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 mergedRef = useMergedRefs(externalRef, ref)
29
+ * const combinedRef = useMergedRefs(externalRef, ref)
30
30
  *
31
- * return <button ref={mergedRef} />
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;