@primer/react 38.32.1-rc.ea8470aaa → 38.33.0-rc.01176969a

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
@@ -1,11 +1,21 @@
1
1
  # @primer/react
2
2
 
3
- ## 38.32.1
3
+ ## 38.33.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#8160](https://github.com/primer/react/pull/8160) [`f8e7cf2`](https://github.com/primer/react/commit/f8e7cf2e1bd3eb02d4106b4932b487bb8ff108e6) Thanks [@TylerJDev](https://github.com/TylerJDev)! - PageLayout: Export the resize primitives `usePaneWidth` and `DragHandle` (with `defaultPaneWidth` and related types) so pane-resize behavior can be reused outside of `PageLayout`.
4
8
 
5
9
  ### Patch Changes
6
10
 
7
11
  - [#8064](https://github.com/primer/react/pull/8064) [`eb447fe`](https://github.com/primer/react/commit/eb447fef0f1565934dc38d09df21d8063957aa9d) Thanks [@copilot-swe-agent](https://github.com/apps/copilot-swe-agent)! - Update the ActionBar overflow menu anchor label to `More items`
8
12
 
13
+ - [#8166](https://github.com/primer/react/pull/8166) [`4045abe`](https://github.com/primer/react/commit/4045abea621d0940edcd1120fc70e6ed5f797205) Thanks [@mattcosta7](https://github.com/mattcosta7)! - Add `contain: layout` to high-churn overflow containers (`ActionBar`, `UnderlineNav`, `UnderlinePanels`, and `LabelGroup`) so their frequent reflows no longer invalidate ancestor layout.
14
+
15
+ - [#8176](https://github.com/primer/react/pull/8176) [`f061bc4`](https://github.com/primer/react/commit/f061bc41483211bef1ec8b1dfe07937f20a9ddd6) Thanks [@francinelucca](https://github.com/francinelucca)! - FeatureFlags: Guard against missing context in `useFeatureFlag` so it returns `false` instead of throwing when used outside a provider
16
+
17
+ - [#8188](https://github.com/primer/react/pull/8188) [`2a67c19`](https://github.com/primer/react/commit/2a67c191a0038df64d2225c0bc11c020c2def03c) Thanks [@iansan5653](https://github.com/iansan5653)! - Fix `UnderlineNav` items all being considered overflowing on Safari with text size overrides
18
+
9
19
  - [#8116](https://github.com/primer/react/pull/8116) [`cade4af`](https://github.com/primer/react/commit/cade4af9a70f3fd2622031af585dc07dccd79e11) Thanks [@mattcosta7](https://github.com/mattcosta7)! - `useAnchoredPosition`: improve performance by caching the scrollable-ancestor walk per anchor, reducing repositioning work for overlays, menus, and tooltips.
10
20
 
11
21
  - [#8164](https://github.com/primer/react/pull/8164) [`f86e5a6`](https://github.com/primer/react/commit/f86e5a6420e857e7476c3954d419f4e228bdcf1a) Thanks [@jonrohan](https://github.com/jonrohan)! - Fix `UnderlineNav` tab list not filling the full width of the underline nav in Safari
@@ -0,0 +1,2 @@
1
+ .prc-ActionBar-List-9uz46{align-items:flex-start;animation:prc-ActionBar-detect-overflow-mAuJu linear;display:flex;gap:var(--actionbar-gap,var(--stack-gap-condensed,.5rem));height:var(--actionbar-height,var(--control-small-size,1.75rem));list-style:none;margin-bottom:-1px;min-width:0;overflow:hidden;position:relative;animation-timeline:scroll(self block);contain:layout}.prc-ActionBar-List-9uz46[data-has-overflow=true]{--morebutton-display:flex}.prc-ActionBar-List-9uz46:where([data-size=small]){--actionbar-height:var(--control-small-size,1.75rem)}.prc-ActionBar-List-9uz46:where([data-size=medium]){--actionbar-height:var(--control-medium-size,2rem)}.prc-ActionBar-List-9uz46:where([data-size=large]){--actionbar-height:var(--control-large-size,2.5rem)}.prc-ActionBar-List-9uz46:where([data-gap=none]){--actionbar-gap:0}.prc-ActionBar-List-9uz46:where([data-gap=none]) .prc-ActionBar-Divider-6V8yH{padding:0 var(--base-size-8,.5rem)}.prc-ActionBar-List-9uz46:where([data-gap=condensed]){--actionbar-gap:var(--stack-gap-condensed,0.5rem)}.prc-ActionBar-List-9uz46 [data-overflowing]{visibility:hidden!important}@keyframes prc-ActionBar-detect-overflow-mAuJu{0%,to{--morebutton-display:flex}}.prc-ActionBar-Nav-9spON{align-items:center;display:flex;justify-content:flex-end;padding-inline:var(--base-size-16,1rem)}.prc-ActionBar-Nav-9spON:where([data-flush=true]){padding-inline:0}.prc-ActionBar-Divider-6V8yH:before{background:var(--borderColor-muted,#d1d9e0b3);content:"";display:block;height:var(--base-size-20,1.25rem);margin-top:calc((var(--actionbar-height) - var(--base-size-20,1.25rem))/2);width:var(--borderWidth-thin,.0625rem)}.prc-ActionBar-Group-peNCk,.prc-ActionBar-OverflowContainer-AkYZs{display:flex;gap:inherit}.prc-ActionBar-OverflowContainer-AkYZs{contain:layout;flex-wrap:wrap;justify-content:flex-end;overflow:hidden}.prc-ActionBar-OverflowContainer-AkYZs .prc-ActionBar-OverflowSpacer-tbHkV{height:var(--actionbar-height)}.prc-ActionBar-MoreButton-RHqpx{display:var(--morebutton-display,none)}
2
+ /*# sourceMappingURL=ActionBar-3767d551.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ActionBar/ActionBar.module.css.js"],"names":[],"mappings":"AAAA,0BASE,sBAAuB,CASvB,oDAAiC,CAhBjC,YAAa,CAQb,yDAAqD,CAGrD,gEAA0D,CAL1D,eAAgB,CADhB,kBAAmB,CAJnB,WAAY,CAQZ,eAAgB,CAVhB,iBAAkB,CAkBlB,qCAAsC,CAKtC,cAsCF,CAnCE,kDACE,yBACF,CAEA,mDACE,oDACF,CAEA,oDACE,kDACF,CAEA,mDACE,mDACF,CAGA,iDACE,iBAKF,CAHE,8EACE,kCACF,CAGF,sDACE,iDACF,CAEA,6CAIE,2BACF,CAGF,+CACE,MAEE,yBACF,CACF,CAEA,yBAIE,kBAAmB,CAHnB,YAAa,CAEb,wBAAyB,CADzB,uCAOF,CAHE,kDACE,gBACF,CAIA,oCAME,6CAAoC,CAFpC,UAAW,CAHX,aAAc,CAEd,kCAA2B,CAK3B,0EAAqE,CANrE,sCAOF,CAQF,kEAJE,YAAa,CACb,WAgBF,CAbA,uCAQE,cAAe,CANf,cAAe,CAEf,wBAAyB,CACzB,eAQF,CAHE,2EACE,8BACF,CAGF,gCACE,sCACF","file":"ActionBar-3767d551.css","sourcesContent":[".List {\n position: relative;\n display: flex;\n min-width: 0;\n\n /* wonder why this is here */\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: -1px;\n list-style: none;\n align-items: flex-start;\n gap: var(--actionbar-gap, var(--stack-gap-condensed));\n overflow: hidden;\n /* Explicit height is required to clip wrapped items */\n height: var(--actionbar-height, var(--control-small-size));\n\n /* Scroll-based animations have no effect unless the container is scrollable (has overflow, even with overflow:hidden)\n so we can use them to detect overflow. It would be cleaner to use scroll-state container queries for this, but\n browser support for scroll-driven animations is slightly better. */\n animation: detect-overflow linear;\n animation-timeline: scroll(self block);\n\n /* Isolate the frequent overflow-driven reflows (JS visibility toggling + item wrapping) so they\n can't invalidate ancestor layout. Safe because the list already clips (overflow: hidden) and the\n More menu is portaled, so it isn't affected by the new containing block/stacking context. */\n contain: layout;\n\n /* After initial render, JS is used to control visibility which provides progressive enhancement for unsupported browsers */\n &[data-has-overflow='true'] {\n --morebutton-display: flex;\n }\n\n &:where([data-size='small']) {\n --actionbar-height: var(--control-small-size);\n }\n\n &:where([data-size='medium']) {\n --actionbar-height: var(--control-medium-size);\n }\n\n &:where([data-size='large']) {\n --actionbar-height: var(--control-large-size);\n }\n\n /* Gap scale (mirrors Stack) */\n &:where([data-gap='none']) {\n --actionbar-gap: 0;\n\n .Divider {\n padding: 0 var(--base-size-8);\n }\n }\n\n &:where([data-gap='condensed']) {\n --actionbar-gap: var(--stack-gap-condensed);\n }\n\n & [data-overflowing] {\n /* Hide overflowing items. Even though they are clipped by `overflow: hidden`, setting `visibility: hidden` ensures\n they can't accidentally be shown and also hides them from screen readers / keyboard nav. `!important` prevents\n consumers from unintentionally overriding this and breaking accessibility. */\n visibility: hidden !important;\n }\n}\n\n@keyframes detect-overflow {\n 0%,\n 100% {\n --morebutton-display: flex;\n }\n}\n\n.Nav {\n display: flex;\n padding-inline: var(--base-size-16);\n justify-content: flex-end;\n align-items: center;\n\n &:where([data-flush='true']) {\n padding-inline: 0;\n }\n}\n\n.Divider {\n &::before {\n display: block;\n width: var(--borderWidth-thin);\n height: var(--base-size-20);\n content: '';\n /* stylelint-disable-next-line primer/colors */\n background: var(--borderColor-muted);\n /* stylelint-disable-next-line primer/spacing */\n margin-top: calc((var(--actionbar-height) - var(--base-size-20)) / 2);\n }\n}\n\n.Group {\n display: flex;\n gap: inherit;\n}\n\n.OverflowContainer {\n display: flex;\n flex-wrap: wrap;\n gap: inherit;\n justify-content: flex-end;\n overflow: hidden;\n\n /* Contain the wrap/measure reflows to this subtree. */\n contain: layout;\n\n .OverflowSpacer {\n height: var(--actionbar-height);\n }\n}\n\n.MoreButton {\n display: var(--morebutton-display, none);\n}\n"]}
@@ -1,4 +1,4 @@
1
- import "./ActionBar-e63def3c.css";
1
+ import "./ActionBar-3767d551.css";
2
2
  //#region src/ActionBar/ActionBar.module.css.js
3
3
  var ActionBar_module_css_default = {
4
4
  "List": "prc-ActionBar-List-9uz46",
@@ -10,7 +10,8 @@ function useFeatureFlag(flag) {
10
10
  const context = useContext(FeatureFlagContext);
11
11
  let t0;
12
12
  if ($[0] !== context || $[1] !== flag) {
13
- t0 = context.enabled(flag);
13
+ var _context$enabled;
14
+ t0 = (_context$enabled = context === null || context === void 0 ? void 0 : context.enabled(flag)) !== null && _context$enabled !== void 0 ? _context$enabled : false;
14
15
  $[0] = context;
15
16
  $[1] = flag;
16
17
  $[2] = t0;
@@ -0,0 +1,2 @@
1
+ .prc-LabelGroup-Container-E-ePP{contain:layout;display:flex;flex-wrap:nowrap;gap:var(--base-size-4,.25rem);line-height:1;max-width:100%;overflow:hidden}.prc-LabelGroup-Container-E-ePP:where([data-overflow=inline]){flex-wrap:wrap}.prc-LabelGroup-Container-E-ePP:where([data-list]){list-style-type:none;margin-block-end:0;margin-block-start:0;padding-inline-start:0}.prc-LabelGroup-ItemWrapper-GkO4t{align-items:center;display:flex;min-height:28px}.prc-LabelGroup-ItemWrapper--hidden-mdrB0{order:9999;pointer-events:none;visibility:hidden}.prc-LabelGroup-OverlayContainer-duQvd{align-items:flex-start;display:flex}.prc-LabelGroup-OverlayInner-nDXRC{display:flex;flex-wrap:wrap;gap:var(--base-size-4,.25rem)}.prc-LabelGroup-CloseButton-IyLno{flex-shrink:0}
2
+ /*# sourceMappingURL=LabelGroup-db41f443.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/LabelGroup/LabelGroup.module.css.js"],"names":[],"mappings":"AAAA,gCAYE,cAAe,CAXf,YAAa,CACb,gBAAiB,CACjB,6BAAuB,CAEvB,aAAc,CACd,cAAe,CACf,eAiBF,CAVE,8DACE,cACF,CAEA,mDAIE,oBAAqB,CADrB,kBAAmB,CADnB,oBAAqB,CADrB,sBAIF,CAGF,kCAEE,kBAAmB,CADnB,YAAa,CAOb,eACF,CAEA,0CACE,UAAW,CACX,mBAAoB,CACpB,iBACF,CAEA,uCACE,sBAAuB,CACvB,YACF,CAEA,mCACE,YAAa,CACb,cAAe,CACf,6BACF,CAEA,kCACE,aACF","file":"LabelGroup-db41f443.css","sourcesContent":[".Container {\n display: flex;\n flex-wrap: nowrap;\n gap: var(--base-size-4);\n /* stylelint-disable-next-line primer/typography */\n line-height: 1;\n max-width: 100%;\n overflow: hidden;\n\n /* Isolate the IntersectionObserver-driven show/hide of overflowing labels so it can't invalidate\n ancestor layout. Safe because the row already clips (overflow: hidden) and the expanded overlay is\n rendered separately, so it isn't affected by the new containing block/stacking context. */\n contain: layout;\n\n &:where([data-overflow='inline']) {\n flex-wrap: wrap;\n }\n\n &:where([data-list]) {\n padding-inline-start: 0;\n margin-block-start: 0;\n margin-block-end: 0;\n list-style-type: none;\n }\n}\n\n.ItemWrapper {\n display: flex;\n align-items: center;\n /* This min-height matches the height of the expand/collapse button.\n Without it, the labels/tokens will do a slight layout shift when expanded.\n This is because the height of the first row will match the token sizes,\n but the height of the second row will be the height of the collapse button.\n */\n min-height: 28px;\n}\n\n.ItemWrapper--hidden {\n order: 9999;\n pointer-events: none;\n visibility: hidden;\n}\n\n.OverlayContainer {\n align-items: flex-start;\n display: flex;\n}\n\n.OverlayInner {\n display: flex;\n flex-wrap: wrap;\n gap: var(--base-size-4);\n}\n\n.CloseButton {\n flex-shrink: 0;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import "./LabelGroup-7d19205a.css";
1
+ import "./LabelGroup-db41f443.css";
2
2
  //#region src/LabelGroup/LabelGroup.module.css.js
3
3
  var LabelGroup_module_css_default = {
4
4
  "Container": "prc-LabelGroup-Container-E-ePP",
@@ -0,0 +1,45 @@
1
+ import React from "react";
2
+
3
+ //#region src/PageLayout/DragHandle.d.ts
4
+ type DragHandleProps = {
5
+ /** Ref for imperative ARIA updates during drag */handleRef: React.RefObject<HTMLDivElement>; /** Called once when drag starts with initial cursor X position */
6
+ onDragStart: (clientX: number) => void; /** Called on each drag tick with cursor position (pointer) or delta (keyboard) */
7
+ onDrag: (value: number, isKeyboard: boolean) => void; /** Called when drag operation completes */
8
+ onDragEnd: () => void; /** Reset width on double-click */
9
+ onDoubleClick?: React.MouseEventHandler<HTMLDivElement>;
10
+ /**
11
+ * Accessible name for the slider. Defaults to `'Draggable pane splitter'`.
12
+ * Provide a context-specific or localized label for standalone usage.
13
+ * Ignored when `aria-labelledby` is provided.
14
+ */
15
+ 'aria-label'?: string; /** Id of an element that labels the slider. Takes precedence over `aria-label`. */
16
+ 'aria-labelledby'?: string; /** ARIA slider min value */
17
+ 'aria-valuemin'?: number; /** ARIA slider max value */
18
+ 'aria-valuemax'?: number; /** ARIA slider current value */
19
+ 'aria-valuenow'?: number;
20
+ /**
21
+ * Ref to the element that receives drag-time styling/containment optimizations
22
+ * (e.g. the resizable pane). When omitted, those side effects are skipped.
23
+ */
24
+ dragTargetRef?: React.RefObject<HTMLElement | null>;
25
+ /**
26
+ * Ref to a content wrapper element that receives drag-time containment.
27
+ * Only needed for layouts (like PageLayout) that optimize sibling content during drag.
28
+ */
29
+ contentWrapperRef?: React.RefObject<HTMLElement | null>;
30
+ /**
31
+ * Formats the `aria-valuetext` announced for the current width.
32
+ * @default valueNow => `Pane width ${valueNow} pixels`
33
+ */
34
+ formatValueText?: (valueNow: number) => string; /** Value for the `data-component` attribute. */
35
+ 'data-component'?: string;
36
+ };
37
+ /**
38
+ * DragHandle - handles all pointer and keyboard interactions for resizing.
39
+ * ARIA values are set in JSX for SSR accessibility, then updated via DOM
40
+ * manipulation during drag for performance. The consumer owns writing the width
41
+ * (via the `onDrag` callback); this component only reports interactions.
42
+ */
43
+ declare const DragHandle: React.NamedExoticComponent<DragHandleProps>;
44
+ //#endregion
45
+ export { DragHandle, DragHandleProps };
@@ -0,0 +1,224 @@
1
+ import PageLayout_module_css_default from "./PageLayout.module.css.js";
2
+ import { defaultFormatValueText } from "./usePaneWidth.js";
3
+ import { removeDraggingStyles, setDraggingStyles } from "./paneUtils.js";
4
+ import { c } from "react-compiler-runtime";
5
+ import { jsx } from "react/jsx-runtime";
6
+ import React, { memo } from "react";
7
+ //#region src/PageLayout/DragHandle.tsx
8
+ const isArrowKey = (key) => key === "ArrowLeft" || key === "ArrowRight" || key === "ArrowUp" || key === "ArrowDown";
9
+ const isShrinkKey = (key) => key === "ArrowLeft" || key === "ArrowDown";
10
+ /**
11
+ * DragHandle - handles all pointer and keyboard interactions for resizing.
12
+ * ARIA values are set in JSX for SSR accessibility, then updated via DOM
13
+ * manipulation during drag for performance. The consumer owns writing the width
14
+ * (via the `onDrag` callback); this component only reports interactions.
15
+ */
16
+ const DragHandle = /*#__PURE__*/ memo(function DragHandle(t0) {
17
+ const $ = c(41);
18
+ const { handleRef, onDragStart, onDrag, onDragEnd, onDoubleClick, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-valuemin": ariaValueMin, "aria-valuemax": ariaValueMax, "aria-valuenow": ariaValueNow, dragTargetRef, contentWrapperRef, formatValueText: t1, "data-component": t2 } = t0;
19
+ const formatValueText = t1 === void 0 ? defaultFormatValueText : t1;
20
+ const dataComponent = t2 === void 0 ? "PageLayout.DragHandle" : t2;
21
+ const stableOnDragStart = React.useRef(onDragStart);
22
+ const stableOnDrag = React.useRef(onDrag);
23
+ const stableOnDragEnd = React.useRef(onDragEnd);
24
+ let t3;
25
+ if ($[0] !== onDrag || $[1] !== onDragEnd || $[2] !== onDragStart) {
26
+ t3 = () => {
27
+ stableOnDragStart.current = onDragStart;
28
+ stableOnDrag.current = onDrag;
29
+ stableOnDragEnd.current = onDragEnd;
30
+ };
31
+ $[0] = onDrag;
32
+ $[1] = onDragEnd;
33
+ $[2] = onDragStart;
34
+ $[3] = t3;
35
+ } else t3 = $[3];
36
+ React.useEffect(t3);
37
+ const isDraggingRef = React.useRef(false);
38
+ let t4;
39
+ if ($[4] !== contentWrapperRef || $[5] !== dragTargetRef || $[6] !== handleRef) {
40
+ t4 = () => {
41
+ var _dragTargetRef$curren, _contentWrapperRef$cu;
42
+ if (isDraggingRef.current) return;
43
+ setDraggingStyles({
44
+ handle: handleRef.current,
45
+ pane: (_dragTargetRef$curren = dragTargetRef === null || dragTargetRef === void 0 ? void 0 : dragTargetRef.current) !== null && _dragTargetRef$curren !== void 0 ? _dragTargetRef$curren : null,
46
+ contentWrapper: (_contentWrapperRef$cu = contentWrapperRef === null || contentWrapperRef === void 0 ? void 0 : contentWrapperRef.current) !== null && _contentWrapperRef$cu !== void 0 ? _contentWrapperRef$cu : null
47
+ });
48
+ isDraggingRef.current = true;
49
+ };
50
+ $[4] = contentWrapperRef;
51
+ $[5] = dragTargetRef;
52
+ $[6] = handleRef;
53
+ $[7] = t4;
54
+ } else t4 = $[7];
55
+ const startDragging = t4;
56
+ let t5;
57
+ if ($[8] !== contentWrapperRef || $[9] !== dragTargetRef || $[10] !== handleRef) {
58
+ t5 = () => {
59
+ var _dragTargetRef$curren2, _contentWrapperRef$cu2;
60
+ if (!isDraggingRef.current) return;
61
+ removeDraggingStyles({
62
+ handle: handleRef.current,
63
+ pane: (_dragTargetRef$curren2 = dragTargetRef === null || dragTargetRef === void 0 ? void 0 : dragTargetRef.current) !== null && _dragTargetRef$curren2 !== void 0 ? _dragTargetRef$curren2 : null,
64
+ contentWrapper: (_contentWrapperRef$cu2 = contentWrapperRef === null || contentWrapperRef === void 0 ? void 0 : contentWrapperRef.current) !== null && _contentWrapperRef$cu2 !== void 0 ? _contentWrapperRef$cu2 : null
65
+ });
66
+ isDraggingRef.current = false;
67
+ };
68
+ $[8] = contentWrapperRef;
69
+ $[9] = dragTargetRef;
70
+ $[10] = handleRef;
71
+ $[11] = t5;
72
+ } else t5 = $[11];
73
+ const endDragging = t5;
74
+ let t6;
75
+ if ($[12] !== startDragging) {
76
+ t6 = (event) => {
77
+ if (event.button !== 0) return;
78
+ event.preventDefault();
79
+ const target = event.currentTarget;
80
+ try {
81
+ target.setPointerCapture(event.pointerId);
82
+ } catch {}
83
+ stableOnDragStart.current(event.clientX);
84
+ startDragging();
85
+ };
86
+ $[12] = startDragging;
87
+ $[13] = t6;
88
+ } else t6 = $[13];
89
+ const handlePointerDown = t6;
90
+ const rafIdRef = React.useRef(null);
91
+ const pendingClientXRef = React.useRef(null);
92
+ let t7;
93
+ if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
94
+ t7 = (event_0) => {
95
+ if (!isDraggingRef.current) return;
96
+ event_0.preventDefault();
97
+ pendingClientXRef.current = event_0.clientX;
98
+ if (rafIdRef.current === null) rafIdRef.current = requestAnimationFrame(() => {
99
+ rafIdRef.current = null;
100
+ if (pendingClientXRef.current !== null) {
101
+ stableOnDrag.current(pendingClientXRef.current, false);
102
+ pendingClientXRef.current = null;
103
+ }
104
+ });
105
+ };
106
+ $[14] = t7;
107
+ } else t7 = $[14];
108
+ const handlePointerMove = t7;
109
+ let t8;
110
+ if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
111
+ t8 = (event_1) => {
112
+ if (!isDraggingRef.current) return;
113
+ event_1.preventDefault();
114
+ };
115
+ $[15] = t8;
116
+ } else t8 = $[15];
117
+ const handlePointerUp = t8;
118
+ let t9;
119
+ if ($[16] !== endDragging) {
120
+ t9 = () => {
121
+ if (!isDraggingRef.current) return;
122
+ if (rafIdRef.current !== null) {
123
+ cancelAnimationFrame(rafIdRef.current);
124
+ rafIdRef.current = null;
125
+ pendingClientXRef.current = null;
126
+ }
127
+ endDragging();
128
+ stableOnDragEnd.current();
129
+ };
130
+ $[16] = endDragging;
131
+ $[17] = t9;
132
+ } else t9 = $[17];
133
+ const handleLostPointerCapture = t9;
134
+ let t10;
135
+ if ($[18] !== startDragging) {
136
+ t10 = (event_2) => {
137
+ if (!isArrowKey(event_2.key)) return;
138
+ event_2.preventDefault();
139
+ const delta = isShrinkKey(event_2.key) ? -3 : 3;
140
+ if (!isDraggingRef.current) startDragging();
141
+ stableOnDrag.current(delta, true);
142
+ };
143
+ $[18] = startDragging;
144
+ $[19] = t10;
145
+ } else t10 = $[19];
146
+ const handleKeyDown = t10;
147
+ let t11;
148
+ if ($[20] !== endDragging) {
149
+ t11 = (event_3) => {
150
+ if (!isArrowKey(event_3.key)) return;
151
+ event_3.preventDefault();
152
+ endDragging();
153
+ stableOnDragEnd.current();
154
+ };
155
+ $[20] = endDragging;
156
+ $[21] = t11;
157
+ } else t11 = $[21];
158
+ const handleKeyUp = t11;
159
+ let t12;
160
+ let t13;
161
+ if ($[22] === Symbol.for("react.memo_cache_sentinel")) {
162
+ t12 = () => () => {
163
+ if (rafIdRef.current !== null) {
164
+ cancelAnimationFrame(rafIdRef.current);
165
+ rafIdRef.current = null;
166
+ }
167
+ };
168
+ t13 = [];
169
+ $[22] = t12;
170
+ $[23] = t13;
171
+ } else {
172
+ t12 = $[22];
173
+ t13 = $[23];
174
+ }
175
+ React.useEffect(t12, t13);
176
+ const t14 = ariaLabelledBy ? void 0 : ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : "Draggable pane splitter";
177
+ let t15;
178
+ if ($[24] !== ariaValueNow || $[25] !== formatValueText) {
179
+ t15 = ariaValueNow !== void 0 ? formatValueText(ariaValueNow) : void 0;
180
+ $[24] = ariaValueNow;
181
+ $[25] = formatValueText;
182
+ $[26] = t15;
183
+ } else t15 = $[26];
184
+ let t16;
185
+ if ($[27] !== ariaLabelledBy || $[28] !== ariaValueMax || $[29] !== ariaValueMin || $[30] !== ariaValueNow || $[31] !== dataComponent || $[32] !== handleKeyDown || $[33] !== handleKeyUp || $[34] !== handleLostPointerCapture || $[35] !== handlePointerDown || $[36] !== handleRef || $[37] !== onDoubleClick || $[38] !== t14 || $[39] !== t15) {
186
+ t16 = /*#__PURE__*/ jsx("div", {
187
+ ref: handleRef,
188
+ className: PageLayout_module_css_default.DraggableHandle,
189
+ "data-component": dataComponent,
190
+ role: "slider",
191
+ "aria-label": t14,
192
+ "aria-labelledby": ariaLabelledBy,
193
+ "aria-valuemin": ariaValueMin,
194
+ "aria-valuemax": ariaValueMax,
195
+ "aria-valuenow": ariaValueNow,
196
+ "aria-valuetext": t15,
197
+ tabIndex: 0,
198
+ onPointerDown: handlePointerDown,
199
+ onPointerMove: handlePointerMove,
200
+ onPointerUp: handlePointerUp,
201
+ onLostPointerCapture: handleLostPointerCapture,
202
+ onKeyDown: handleKeyDown,
203
+ onKeyUp: handleKeyUp,
204
+ onDoubleClick
205
+ });
206
+ $[27] = ariaLabelledBy;
207
+ $[28] = ariaValueMax;
208
+ $[29] = ariaValueMin;
209
+ $[30] = ariaValueNow;
210
+ $[31] = dataComponent;
211
+ $[32] = handleKeyDown;
212
+ $[33] = handleKeyUp;
213
+ $[34] = handleLostPointerCapture;
214
+ $[35] = handlePointerDown;
215
+ $[36] = handleRef;
216
+ $[37] = onDoubleClick;
217
+ $[38] = t14;
218
+ $[39] = t15;
219
+ $[40] = t16;
220
+ } else t16 = $[40];
221
+ return t16;
222
+ });
223
+ //#endregion
224
+ export { DragHandle };
@@ -7,14 +7,12 @@ import { useOverflow } from "../hooks/useOverflow.js";
7
7
  import { getResponsiveAttributes } from "../internal/utils/getResponsiveAttributes.js";
8
8
  import PageLayout_module_css_default from "./PageLayout.module.css.js";
9
9
  import { isCustomWidthOptions, isPaneWidth, updateAriaValues, usePaneWidth } from "./usePaneWidth.js";
10
- import { removeDraggingStyles, setDraggingStyles } from "./paneUtils.js";
10
+ import { DragHandle } from "./DragHandle.js";
11
11
  import { c } from "react-compiler-runtime";
12
12
  import { clsx } from "clsx";
13
13
  import { jsx, jsxs } from "react/jsx-runtime";
14
14
  import React, { memo, useRef } from "react";
15
15
  //#region src/PageLayout/PageLayout.tsx
16
- const isArrowKey = (key) => key === "ArrowLeft" || key === "ArrowRight" || key === "ArrowUp" || key === "ArrowDown";
17
- const isShrinkKey = (key) => key === "ArrowLeft" || key === "ArrowDown";
18
16
  const PageLayoutContext = /*#__PURE__*/ React.createContext({
19
17
  padding: "normal",
20
18
  rowGap: "normal",
@@ -267,9 +265,9 @@ const VerticalDivider = /*#__PURE__*/ memo((t0) => {
267
265
  });
268
266
  VerticalDivider.displayName = "VerticalDivider";
269
267
  const SidebarDivider = /*#__PURE__*/ memo(function SidebarDivider(t0) {
270
- const $ = c(22);
268
+ const $ = c(23);
271
269
  const { position, divider, resizable, minPaneWidth, maxPaneWidth, currentWidth, currentWidthRef, handleRef, sidebarRef, dragStartClientXRef, dragStartWidthRef, dragMaxWidthRef, getMaxPaneWidth, getDefaultWidth, saveWidth } = t0;
272
- const { columnGap } = React.useContext(PageLayoutContext);
270
+ const { columnGap, sidebarContentWrapperRef } = React.useContext(PageLayoutContext);
273
271
  const t1 = resizable ? "line" : divider;
274
272
  const t2 = `var(--spacing-${columnGap})`;
275
273
  let t3;
@@ -280,9 +278,11 @@ const SidebarDivider = /*#__PURE__*/ memo(function SidebarDivider(t0) {
280
278
  } else t3 = $[1];
281
279
  const t4 = t3;
282
280
  let t5;
283
- if ($[2] !== currentWidth || $[3] !== currentWidthRef || $[4] !== dragMaxWidthRef || $[5] !== dragStartClientXRef || $[6] !== dragStartWidthRef || $[7] !== getDefaultWidth || $[8] !== getMaxPaneWidth || $[9] !== handleRef || $[10] !== maxPaneWidth || $[11] !== minPaneWidth || $[12] !== position || $[13] !== resizable || $[14] !== saveWidth || $[15] !== sidebarRef) {
281
+ if ($[2] !== currentWidth || $[3] !== currentWidthRef || $[4] !== dragMaxWidthRef || $[5] !== dragStartClientXRef || $[6] !== dragStartWidthRef || $[7] !== getDefaultWidth || $[8] !== getMaxPaneWidth || $[9] !== handleRef || $[10] !== maxPaneWidth || $[11] !== minPaneWidth || $[12] !== position || $[13] !== resizable || $[14] !== saveWidth || $[15] !== sidebarContentWrapperRef || $[16] !== sidebarRef) {
284
282
  t5 = resizable ? /*#__PURE__*/ jsx(DragHandle, {
285
283
  handleRef,
284
+ dragTargetRef: sidebarRef,
285
+ contentWrapperRef: sidebarContentWrapperRef,
286
286
  "aria-valuemin": minPaneWidth,
287
287
  "aria-valuemax": maxPaneWidth,
288
288
  "aria-valuenow": currentWidth,
@@ -347,11 +347,12 @@ const SidebarDivider = /*#__PURE__*/ memo(function SidebarDivider(t0) {
347
347
  $[12] = position;
348
348
  $[13] = resizable;
349
349
  $[14] = saveWidth;
350
- $[15] = sidebarRef;
351
- $[16] = t5;
352
- } else t5 = $[16];
350
+ $[15] = sidebarContentWrapperRef;
351
+ $[16] = sidebarRef;
352
+ $[17] = t5;
353
+ } else t5 = $[17];
353
354
  let t6;
354
- if ($[17] !== position || $[18] !== t1 || $[19] !== t4 || $[20] !== t5) {
355
+ if ($[18] !== position || $[19] !== t1 || $[20] !== t4 || $[21] !== t5) {
355
356
  t6 = /*#__PURE__*/ jsx(VerticalDivider, {
356
357
  variant: t1,
357
358
  position,
@@ -359,212 +360,14 @@ const SidebarDivider = /*#__PURE__*/ memo(function SidebarDivider(t0) {
359
360
  style: t4,
360
361
  children: t5
361
362
  });
362
- $[17] = position;
363
- $[18] = t1;
364
- $[19] = t4;
365
- $[20] = t5;
366
- $[21] = t6;
367
- } else t6 = $[21];
363
+ $[18] = position;
364
+ $[19] = t1;
365
+ $[20] = t4;
366
+ $[21] = t5;
367
+ $[22] = t6;
368
+ } else t6 = $[22];
368
369
  return t6;
369
370
  });
370
- /**
371
- * DragHandle - handles all pointer and keyboard interactions for resizing
372
- * ARIA values are set in JSX for SSR accessibility,
373
- * then updated via DOM manipulation during drag for performance
374
- */
375
- const DragHandle = /*#__PURE__*/ memo(function DragHandle(t0) {
376
- const $ = c(35);
377
- const { handleRef, onDragStart, onDrag, onDragEnd, onDoubleClick, "aria-valuemin": ariaValueMin, "aria-valuemax": ariaValueMax, "aria-valuenow": ariaValueNow } = t0;
378
- const stableOnDragStart = React.useRef(onDragStart);
379
- const stableOnDrag = React.useRef(onDrag);
380
- const stableOnDragEnd = React.useRef(onDragEnd);
381
- let t1;
382
- if ($[0] !== onDrag || $[1] !== onDragEnd || $[2] !== onDragStart) {
383
- t1 = () => {
384
- stableOnDragStart.current = onDragStart;
385
- stableOnDrag.current = onDrag;
386
- stableOnDragEnd.current = onDragEnd;
387
- };
388
- $[0] = onDrag;
389
- $[1] = onDragEnd;
390
- $[2] = onDragStart;
391
- $[3] = t1;
392
- } else t1 = $[3];
393
- React.useEffect(t1);
394
- const { paneRef, contentWrapperRef } = React.useContext(PageLayoutContext);
395
- const isDraggingRef = React.useRef(false);
396
- let t2;
397
- if ($[4] !== contentWrapperRef || $[5] !== handleRef || $[6] !== paneRef) {
398
- t2 = () => {
399
- if (isDraggingRef.current) return;
400
- setDraggingStyles({
401
- handle: handleRef.current,
402
- pane: paneRef.current,
403
- contentWrapper: contentWrapperRef.current
404
- });
405
- isDraggingRef.current = true;
406
- };
407
- $[4] = contentWrapperRef;
408
- $[5] = handleRef;
409
- $[6] = paneRef;
410
- $[7] = t2;
411
- } else t2 = $[7];
412
- const startDragging = t2;
413
- let t3;
414
- if ($[8] !== contentWrapperRef || $[9] !== handleRef || $[10] !== paneRef) {
415
- t3 = () => {
416
- if (!isDraggingRef.current) return;
417
- removeDraggingStyles({
418
- handle: handleRef.current,
419
- pane: paneRef.current,
420
- contentWrapper: contentWrapperRef.current
421
- });
422
- isDraggingRef.current = false;
423
- };
424
- $[8] = contentWrapperRef;
425
- $[9] = handleRef;
426
- $[10] = paneRef;
427
- $[11] = t3;
428
- } else t3 = $[11];
429
- const endDragging = t3;
430
- let t4;
431
- if ($[12] !== startDragging) {
432
- t4 = (event) => {
433
- if (event.button !== 0) return;
434
- event.preventDefault();
435
- const target = event.currentTarget;
436
- try {
437
- target.setPointerCapture(event.pointerId);
438
- } catch {}
439
- stableOnDragStart.current(event.clientX);
440
- startDragging();
441
- };
442
- $[12] = startDragging;
443
- $[13] = t4;
444
- } else t4 = $[13];
445
- const handlePointerDown = t4;
446
- const rafIdRef = React.useRef(null);
447
- const pendingClientXRef = React.useRef(null);
448
- let t5;
449
- if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
450
- t5 = (event_0) => {
451
- if (!isDraggingRef.current) return;
452
- event_0.preventDefault();
453
- pendingClientXRef.current = event_0.clientX;
454
- if (rafIdRef.current === null) rafIdRef.current = requestAnimationFrame(() => {
455
- rafIdRef.current = null;
456
- if (pendingClientXRef.current !== null) {
457
- stableOnDrag.current(pendingClientXRef.current, false);
458
- pendingClientXRef.current = null;
459
- }
460
- });
461
- };
462
- $[14] = t5;
463
- } else t5 = $[14];
464
- const handlePointerMove = t5;
465
- let t6;
466
- if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
467
- t6 = (event_1) => {
468
- if (!isDraggingRef.current) return;
469
- event_1.preventDefault();
470
- };
471
- $[15] = t6;
472
- } else t6 = $[15];
473
- const handlePointerUp = t6;
474
- let t7;
475
- if ($[16] !== endDragging) {
476
- t7 = () => {
477
- if (!isDraggingRef.current) return;
478
- if (rafIdRef.current !== null) {
479
- cancelAnimationFrame(rafIdRef.current);
480
- rafIdRef.current = null;
481
- pendingClientXRef.current = null;
482
- }
483
- endDragging();
484
- stableOnDragEnd.current();
485
- };
486
- $[16] = endDragging;
487
- $[17] = t7;
488
- } else t7 = $[17];
489
- const handleLostPointerCapture = t7;
490
- let t8;
491
- if ($[18] !== startDragging) {
492
- t8 = (event_2) => {
493
- if (!isArrowKey(event_2.key)) return;
494
- event_2.preventDefault();
495
- const delta = isShrinkKey(event_2.key) ? -3 : 3;
496
- if (!isDraggingRef.current) startDragging();
497
- stableOnDrag.current(delta, true);
498
- };
499
- $[18] = startDragging;
500
- $[19] = t8;
501
- } else t8 = $[19];
502
- const handleKeyDown = t8;
503
- let t9;
504
- if ($[20] !== endDragging) {
505
- t9 = (event_3) => {
506
- if (!isArrowKey(event_3.key)) return;
507
- event_3.preventDefault();
508
- endDragging();
509
- stableOnDragEnd.current();
510
- };
511
- $[20] = endDragging;
512
- $[21] = t9;
513
- } else t9 = $[21];
514
- const handleKeyUp = t9;
515
- let t10;
516
- let t11;
517
- if ($[22] === Symbol.for("react.memo_cache_sentinel")) {
518
- t10 = () => () => {
519
- if (rafIdRef.current !== null) {
520
- cancelAnimationFrame(rafIdRef.current);
521
- rafIdRef.current = null;
522
- }
523
- };
524
- t11 = [];
525
- $[22] = t10;
526
- $[23] = t11;
527
- } else {
528
- t10 = $[22];
529
- t11 = $[23];
530
- }
531
- React.useEffect(t10, t11);
532
- const t12 = ariaValueNow !== void 0 ? `Pane width ${ariaValueNow} pixels` : void 0;
533
- let t13;
534
- if ($[24] !== ariaValueMax || $[25] !== ariaValueMin || $[26] !== ariaValueNow || $[27] !== handleKeyDown || $[28] !== handleKeyUp || $[29] !== handleLostPointerCapture || $[30] !== handlePointerDown || $[31] !== handleRef || $[32] !== onDoubleClick || $[33] !== t12) {
535
- t13 = /*#__PURE__*/ jsx("div", {
536
- ref: handleRef,
537
- className: PageLayout_module_css_default.DraggableHandle,
538
- "data-component": "PageLayout.DragHandle",
539
- role: "slider",
540
- "aria-label": "Draggable pane splitter",
541
- "aria-valuemin": ariaValueMin,
542
- "aria-valuemax": ariaValueMax,
543
- "aria-valuenow": ariaValueNow,
544
- "aria-valuetext": t12,
545
- tabIndex: 0,
546
- onPointerDown: handlePointerDown,
547
- onPointerMove: handlePointerMove,
548
- onPointerUp: handlePointerUp,
549
- onLostPointerCapture: handleLostPointerCapture,
550
- onKeyDown: handleKeyDown,
551
- onKeyUp: handleKeyUp,
552
- onDoubleClick
553
- });
554
- $[24] = ariaValueMax;
555
- $[25] = ariaValueMin;
556
- $[26] = ariaValueNow;
557
- $[27] = handleKeyDown;
558
- $[28] = handleKeyUp;
559
- $[29] = handleLostPointerCapture;
560
- $[30] = handlePointerDown;
561
- $[31] = handleRef;
562
- $[32] = onDoubleClick;
563
- $[33] = t12;
564
- $[34] = t13;
565
- } else t13 = $[34];
566
- return t13;
567
- });
568
371
  const Header = (t0) => {
569
372
  const $ = c(29);
570
373
  const { "aria-label": label, "aria-labelledby": labelledBy, padding: t1, divider: t2, dividerWhenNarrow: t3, hidden: t4, children, style, className, "data-component": t5 } = t0;
@@ -745,7 +548,7 @@ const overflowProps = {
745
548
  role: "region"
746
549
  };
747
550
  const Pane = /*#__PURE__*/ React.forwardRef((t0, forwardRef) => {
748
- const $ = c(97);
551
+ const $ = c(98);
749
552
  const { "aria-label": label, "aria-labelledby": labelledBy, position: t1, positionWhenNarrow: t2, width: t3, minWidth: t4, currentWidth: controlledWidth, onResizeEnd, padding: t5, resizable: t6, widthStorageKey: t7, divider: t8, dividerWhenNarrow: t9, sticky: t10, offsetHeader: t11, hidden: t12, children, id, className, style, "data-component": t13 } = t0;
750
553
  const responsivePosition = t1 === void 0 ? "end" : t1;
751
554
  const positionWhenNarrow = t2 === void 0 ? "inherit" : t2;
@@ -998,9 +801,11 @@ const Pane = /*#__PURE__*/ React.forwardRef((t0, forwardRef) => {
998
801
  } else t48 = $[70];
999
802
  const t49 = t48;
1000
803
  let t50;
1001
- if ($[71] !== currentWidth || $[72] !== currentWidthRef || $[73] !== getDefaultWidth || $[74] !== getMaxPaneWidth || $[75] !== maxPaneWidth || $[76] !== minPaneWidth || $[77] !== paneRef || $[78] !== position || $[79] !== resizable || $[80] !== saveWidth) {
804
+ if ($[71] !== contentWrapperRef || $[72] !== currentWidth || $[73] !== currentWidthRef || $[74] !== getDefaultWidth || $[75] !== getMaxPaneWidth || $[76] !== maxPaneWidth || $[77] !== minPaneWidth || $[78] !== paneRef || $[79] !== position || $[80] !== resizable || $[81] !== saveWidth) {
1002
805
  t50 = resizable ? /*#__PURE__*/ jsx(DragHandle, {
1003
806
  handleRef,
807
+ dragTargetRef: paneRef,
808
+ contentWrapperRef,
1004
809
  "aria-valuemin": minPaneWidth,
1005
810
  "aria-valuemax": maxPaneWidth,
1006
811
  "aria-valuenow": currentWidth,
@@ -1052,20 +857,21 @@ const Pane = /*#__PURE__*/ React.forwardRef((t0, forwardRef) => {
1052
857
  saveWidth(resetWidth);
1053
858
  }
1054
859
  }) : null;
1055
- $[71] = currentWidth;
1056
- $[72] = currentWidthRef;
1057
- $[73] = getDefaultWidth;
1058
- $[74] = getMaxPaneWidth;
1059
- $[75] = maxPaneWidth;
1060
- $[76] = minPaneWidth;
1061
- $[77] = paneRef;
1062
- $[78] = position;
1063
- $[79] = resizable;
1064
- $[80] = saveWidth;
1065
- $[81] = t50;
1066
- } else t50 = $[81];
860
+ $[71] = contentWrapperRef;
861
+ $[72] = currentWidth;
862
+ $[73] = currentWidthRef;
863
+ $[74] = getDefaultWidth;
864
+ $[75] = getMaxPaneWidth;
865
+ $[76] = maxPaneWidth;
866
+ $[77] = minPaneWidth;
867
+ $[78] = paneRef;
868
+ $[79] = position;
869
+ $[80] = resizable;
870
+ $[81] = saveWidth;
871
+ $[82] = t50;
872
+ } else t50 = $[82];
1067
873
  let t51;
1068
- if ($[82] !== positionProp || $[83] !== resizable || $[84] !== t46 || $[85] !== t49 || $[86] !== t50) {
874
+ if ($[83] !== positionProp || $[84] !== resizable || $[85] !== t46 || $[86] !== t49 || $[87] !== t50) {
1069
875
  t51 = /*#__PURE__*/ jsx(VerticalDivider, {
1070
876
  variant: t46,
1071
877
  draggable: resizable,
@@ -1074,15 +880,15 @@ const Pane = /*#__PURE__*/ React.forwardRef((t0, forwardRef) => {
1074
880
  style: t49,
1075
881
  children: t50
1076
882
  });
1077
- $[82] = positionProp;
1078
- $[83] = resizable;
1079
- $[84] = t46;
1080
- $[85] = t49;
1081
- $[86] = t50;
1082
- $[87] = t51;
1083
- } else t51 = $[87];
883
+ $[83] = positionProp;
884
+ $[84] = resizable;
885
+ $[85] = t46;
886
+ $[86] = t49;
887
+ $[87] = t50;
888
+ $[88] = t51;
889
+ } else t51 = $[88];
1084
890
  let t52;
1085
- if ($[88] !== t19 || $[89] !== t24 || $[90] !== t25 || $[91] !== t26 || $[92] !== t27 || $[93] !== t32 || $[94] !== t45 || $[95] !== t51) {
891
+ if ($[89] !== t19 || $[90] !== t24 || $[91] !== t25 || $[92] !== t26 || $[93] !== t27 || $[94] !== t32 || $[95] !== t45 || $[96] !== t51) {
1086
892
  t52 = /*#__PURE__*/ jsxs("div", {
1087
893
  className: t19,
1088
894
  style: t24,
@@ -1095,16 +901,16 @@ const Pane = /*#__PURE__*/ React.forwardRef((t0, forwardRef) => {
1095
901
  t51
1096
902
  ]
1097
903
  });
1098
- $[88] = t19;
1099
- $[89] = t24;
1100
- $[90] = t25;
1101
- $[91] = t26;
1102
- $[92] = t27;
1103
- $[93] = t32;
1104
- $[94] = t45;
1105
- $[95] = t51;
1106
- $[96] = t52;
1107
- } else t52 = $[96];
904
+ $[89] = t19;
905
+ $[90] = t24;
906
+ $[91] = t25;
907
+ $[92] = t26;
908
+ $[93] = t27;
909
+ $[94] = t32;
910
+ $[95] = t45;
911
+ $[96] = t51;
912
+ $[97] = t52;
913
+ } else t52 = $[97];
1108
914
  return t52;
1109
915
  });
1110
916
  Pane.displayName = "PageLayout.Pane";
@@ -1,2 +1,4 @@
1
+ import { CustomWidthOptions, PaneWidth, PaneWidthValue, UsePaneWidthOptions, UsePaneWidthResult, defaultPaneWidth, usePaneWidth } from "./usePaneWidth.js";
1
2
  import { PageLayout, PageLayoutContentProps, PageLayoutFooterProps, PageLayoutHeaderProps, PageLayoutPaneBaseProps, PageLayoutPaneProps, PageLayoutProps, PageLayoutSidebarBaseProps, PageLayoutSidebarProps } from "./PageLayout.js";
2
- export { PageLayout, PageLayoutContentProps, PageLayoutFooterProps, PageLayoutHeaderProps, PageLayoutPaneBaseProps, PageLayoutPaneProps, PageLayoutProps, PageLayoutSidebarBaseProps, PageLayoutSidebarProps };
3
+ import { DragHandle, DragHandleProps } from "./DragHandle.js";
4
+ export { type CustomWidthOptions, DragHandle, type DragHandleProps, PageLayout, PageLayoutContentProps, PageLayoutFooterProps, PageLayoutHeaderProps, PageLayoutPaneBaseProps, PageLayoutPaneProps, PageLayoutProps, PageLayoutSidebarBaseProps, PageLayoutSidebarProps, type PaneWidth, type PaneWidthValue, type UsePaneWidthOptions, type UsePaneWidthResult, defaultPaneWidth, usePaneWidth };
@@ -14,5 +14,67 @@ type PaneWidth = 'small' | 'medium' | 'large';
14
14
  * - `CustomWidthOptions`: Explicit min/default/max constraints
15
15
  */
16
16
  type PaneWidthValue = PaneWidth | CustomWidthOptions;
17
+ type UsePaneWidthOptions = {
18
+ width: PaneWidthValue;
19
+ minWidth: number;
20
+ resizable: boolean; /** localStorage key for persisting width. When undefined, localStorage is not used. */
21
+ widthStorageKey?: string;
22
+ paneRef: React.RefObject<HTMLDivElement | null>;
23
+ handleRef: React.RefObject<HTMLDivElement | null>;
24
+ /**
25
+ * Optional ref to the content wrapper element. Only used by PageLayout for its
26
+ * viewport/content math during resize. Standalone consumers can omit this.
27
+ */
28
+ contentWrapperRef?: React.RefObject<HTMLDivElement | null>;
29
+ /**
30
+ * When true, custom max width values are capped to the viewport-based max.
31
+ * This prevents overflow in non-wrapping flex layouts (e.g., Sidebar).
32
+ * @default false
33
+ */
34
+ constrainToViewport?: boolean; /** Callback fired when a resize operation ends (drag release or keyboard key up) */
35
+ onResizeEnd?: (width: number) => void; /** Current/controlled width value in pixels (used instead of internal state; default from `width` is still used for reset) */
36
+ currentWidth?: number;
37
+ /**
38
+ * Formats the `aria-valuetext` written during mount and viewport resize.
39
+ * Should match the formatter passed to `DragHandle` so screen-reader output
40
+ * stays consistent across drag, mount, and resize updates.
41
+ * @default valueNow => `Pane width ${valueNow} pixels`
42
+ */
43
+ formatValueText?: (valueNow: number) => string;
44
+ };
45
+ type UsePaneWidthResult = {
46
+ /** Current width for React state (used in ARIA attributes) */currentWidth: number; /** Mutable ref tracking width during drag operations */
47
+ currentWidthRef: React.MutableRefObject<number>; /** Minimum allowed pane width */
48
+ minPaneWidth: number; /** Maximum allowed pane width (updates on viewport resize) */
49
+ maxPaneWidth: number; /** Calculate current max width constraint */
50
+ getMaxPaneWidth: () => number; /** Persist width to localStorage and sync React state */
51
+ saveWidth: (value: number) => void; /** Reset to default width */
52
+ getDefaultWidth: () => number;
53
+ };
54
+ /** Default widths for preset size options */
55
+ declare const defaultPaneWidth: Record<PaneWidth, number>;
56
+ /**
57
+ * Manages pane width state with storage persistence and viewport constraints.
58
+ * Handles initialization from storage, clamping on viewport resize, and provides
59
+ * functions to save and reset width.
60
+ *
61
+ * Storage behavior:
62
+ * - When `resizable` is `true` and `onResizeEnd` is not provided: Uses localStorage
63
+ * - When `onResizeEnd` is provided: Calls the callback instead of localStorage
64
+ * - When `resizable` is `false` or `undefined`: Not resizable, no persistence
65
+ */
66
+ declare function usePaneWidth({
67
+ width,
68
+ minWidth,
69
+ resizable,
70
+ widthStorageKey,
71
+ paneRef,
72
+ handleRef,
73
+ contentWrapperRef,
74
+ constrainToViewport,
75
+ onResizeEnd,
76
+ currentWidth: controlledWidth,
77
+ formatValueText
78
+ }: UsePaneWidthOptions): UsePaneWidthResult;
17
79
  //#endregion
18
- export { CustomWidthOptions, PaneWidth, PaneWidthValue };
80
+ export { CustomWidthOptions, PaneWidth, PaneWidthValue, UsePaneWidthOptions, UsePaneWidthResult, defaultPaneWidth, usePaneWidth };
@@ -47,13 +47,19 @@ function getMaxWidthDiffFromViewport() {
47
47
  if (!canUseDOM) return DEFAULT_MAX_WIDTH_DIFF;
48
48
  return window.innerWidth >= DEFAULT_PANE_MAX_WIDTH_DIFF_BREAKPOINT ? WIDE_MAX_WIDTH_DIFF : DEFAULT_MAX_WIDTH_DIFF;
49
49
  }
50
- const updateAriaValues = (handle, values) => {
50
+ /**
51
+ * Default formatter for the drag handle's `aria-valuetext`.
52
+ * Kept in sync between the rendered attribute and drag-time DOM writes.
53
+ */
54
+ const defaultFormatValueText = (valueNow) => `Pane width ${valueNow} pixels`;
55
+ const updateAriaValues = (handle, values, formatValueText) => {
51
56
  if (!handle) return;
57
+ const format = formatValueText !== null && formatValueText !== void 0 ? formatValueText : defaultFormatValueText;
52
58
  if (values.min !== void 0) handle.setAttribute("aria-valuemin", String(values.min));
53
59
  if (values.max !== void 0) handle.setAttribute("aria-valuemax", String(values.max));
54
60
  if (values.current !== void 0) {
55
61
  handle.setAttribute("aria-valuenow", String(values.current));
56
- handle.setAttribute("aria-valuetext", `Pane width ${values.current} pixels`);
62
+ handle.setAttribute("aria-valuetext", format(values.current));
57
63
  }
58
64
  };
59
65
  const localStoragePersister = {
@@ -84,8 +90,8 @@ const localStoragePersister = {
84
90
  * - When `resizable` is `false` or `undefined`: Not resizable, no persistence
85
91
  */
86
92
  function usePaneWidth(t0) {
87
- const $ = c(42);
88
- const { width, minWidth, resizable, widthStorageKey, paneRef, handleRef, contentWrapperRef, constrainToViewport: t1, onResizeEnd, currentWidth: controlledWidth } = t0;
93
+ const $ = c(44);
94
+ const { width, minWidth, resizable, widthStorageKey, paneRef, handleRef, contentWrapperRef, constrainToViewport: t1, onResizeEnd, currentWidth: controlledWidth, formatValueText } = t0;
89
95
  const constrainToViewport = t1 === void 0 ? false : t1;
90
96
  const isCustomWidth = isCustomWidthOptions(width);
91
97
  const minPaneWidth = isCustomWidth ? parseInt(width.min, 10) : minWidth;
@@ -218,10 +224,20 @@ function usePaneWidth(t0) {
218
224
  $[25] = t11;
219
225
  } else t11 = $[25];
220
226
  useIsomorphicLayoutEffect(t11);
227
+ const formatValueTextRef = React.useRef(formatValueText);
221
228
  let t12;
222
- let t13;
223
- if ($[26] !== constrainToViewport || $[27] !== contentWrapperRef || $[28] !== customMaxWidth || $[29] !== handleRef || $[30] !== minPaneWidth || $[31] !== paneRef || $[32] !== resizable) {
229
+ if ($[26] !== formatValueText) {
224
230
  t12 = () => {
231
+ formatValueTextRef.current = formatValueText;
232
+ };
233
+ $[26] = formatValueText;
234
+ $[27] = t12;
235
+ } else t12 = $[27];
236
+ useIsomorphicLayoutEffect(t12);
237
+ let t13;
238
+ let t14;
239
+ if ($[28] !== constrainToViewport || $[29] !== contentWrapperRef || $[30] !== customMaxWidth || $[31] !== handleRef || $[32] !== minPaneWidth || $[33] !== paneRef || $[34] !== resizable) {
240
+ t13 = () => {
225
241
  var _paneRef$current3;
226
242
  if (!resizable) return;
227
243
  let lastViewportWidth = window.innerWidth;
@@ -242,7 +258,7 @@ function usePaneWidth(t0) {
242
258
  updateAriaValues(handleRef.current, {
243
259
  max: actualMax,
244
260
  current: currentWidthRef.current
245
- });
261
+ }, formatValueTextRef.current);
246
262
  if (actualMax !== maxPaneWidthRef.current || wasClamped) {
247
263
  maxPaneWidthRef.current = actualMax;
248
264
  startTransition(() => {
@@ -259,7 +275,7 @@ function usePaneWidth(t0) {
259
275
  min: minPaneWidth,
260
276
  max: initialMax,
261
277
  current: currentWidthRef.current
262
- });
278
+ }, formatValueTextRef.current);
263
279
  startTransition(() => {
264
280
  setMaxPaneWidth(initialMax);
265
281
  });
@@ -274,14 +290,14 @@ function usePaneWidth(t0) {
274
290
  if (isResizing) return;
275
291
  isResizing = true;
276
292
  (_paneRef$current4 = paneRef.current) === null || _paneRef$current4 === void 0 || _paneRef$current4.setAttribute("data-dragging", "true");
277
- (_contentWrapperRef$cu = contentWrapperRef.current) === null || _contentWrapperRef$cu === void 0 || _contentWrapperRef$cu.setAttribute("data-dragging", "true");
293
+ contentWrapperRef === null || contentWrapperRef === void 0 || (_contentWrapperRef$cu = contentWrapperRef.current) == null || _contentWrapperRef$cu.setAttribute("data-dragging", "true");
278
294
  };
279
295
  const endResizeOptimizations = () => {
280
296
  var _paneRef$current5, _contentWrapperRef$cu2;
281
297
  if (!isResizing) return;
282
298
  isResizing = false;
283
299
  (_paneRef$current5 = paneRef.current) === null || _paneRef$current5 === void 0 || _paneRef$current5.removeAttribute("data-dragging");
284
- (_contentWrapperRef$cu2 = contentWrapperRef.current) === null || _contentWrapperRef$cu2 === void 0 || _contentWrapperRef$cu2.removeAttribute("data-dragging");
300
+ contentWrapperRef === null || contentWrapperRef === void 0 || (_contentWrapperRef$cu2 = contentWrapperRef.current) == null || _contentWrapperRef$cu2.removeAttribute("data-dragging");
285
301
  };
286
302
  const handleResize = () => {
287
303
  startResizeOptimizations();
@@ -312,7 +328,7 @@ function usePaneWidth(t0) {
312
328
  window.removeEventListener("resize", handleResize);
313
329
  };
314
330
  };
315
- t13 = [
331
+ t14 = [
316
332
  resizable,
317
333
  customMaxWidth,
318
334
  constrainToViewport,
@@ -321,23 +337,23 @@ function usePaneWidth(t0) {
321
337
  handleRef,
322
338
  contentWrapperRef
323
339
  ];
324
- $[26] = constrainToViewport;
325
- $[27] = contentWrapperRef;
326
- $[28] = customMaxWidth;
327
- $[29] = handleRef;
328
- $[30] = minPaneWidth;
329
- $[31] = paneRef;
330
- $[32] = resizable;
331
- $[33] = t12;
332
- $[34] = t13;
340
+ $[28] = constrainToViewport;
341
+ $[29] = contentWrapperRef;
342
+ $[30] = customMaxWidth;
343
+ $[31] = handleRef;
344
+ $[32] = minPaneWidth;
345
+ $[33] = paneRef;
346
+ $[34] = resizable;
347
+ $[35] = t13;
348
+ $[36] = t14;
333
349
  } else {
334
- t12 = $[33];
335
- t13 = $[34];
350
+ t13 = $[35];
351
+ t14 = $[36];
336
352
  }
337
- useIsomorphicLayoutEffect(t12, t13);
338
- let t14;
339
- if ($[35] !== currentWidth || $[36] !== getDefaultWidth || $[37] !== getMaxPaneWidth || $[38] !== maxPaneWidth || $[39] !== minPaneWidth || $[40] !== saveWidth) {
340
- t14 = {
353
+ useIsomorphicLayoutEffect(t13, t14);
354
+ let t15;
355
+ if ($[37] !== currentWidth || $[38] !== getDefaultWidth || $[39] !== getMaxPaneWidth || $[40] !== maxPaneWidth || $[41] !== minPaneWidth || $[42] !== saveWidth) {
356
+ t15 = {
341
357
  currentWidth,
342
358
  currentWidthRef,
343
359
  minPaneWidth,
@@ -346,15 +362,15 @@ function usePaneWidth(t0) {
346
362
  saveWidth,
347
363
  getDefaultWidth
348
364
  };
349
- $[35] = currentWidth;
350
- $[36] = getDefaultWidth;
351
- $[37] = getMaxPaneWidth;
352
- $[38] = maxPaneWidth;
353
- $[39] = minPaneWidth;
354
- $[40] = saveWidth;
355
- $[41] = t14;
356
- } else t14 = $[41];
357
- return t14;
365
+ $[37] = currentWidth;
366
+ $[38] = getDefaultWidth;
367
+ $[39] = getMaxPaneWidth;
368
+ $[40] = maxPaneWidth;
369
+ $[41] = minPaneWidth;
370
+ $[42] = saveWidth;
371
+ $[43] = t15;
372
+ } else t15 = $[43];
373
+ return t15;
358
374
  }
359
375
  //#endregion
360
- export { DEFAULT_MAX_WIDTH_DIFF, DEFAULT_SIDEBAR_MAX_WIDTH_DIFF, defaultPaneWidth, getDefaultPaneWidth, getMaxWidthDiffFromViewport, isCustomWidthOptions, isPaneWidth, updateAriaValues, usePaneWidth };
376
+ export { DEFAULT_MAX_WIDTH_DIFF, DEFAULT_SIDEBAR_MAX_WIDTH_DIFF, defaultFormatValueText, defaultPaneWidth, getDefaultPaneWidth, getMaxWidthDiffFromViewport, isCustomWidthOptions, isPaneWidth, updateAriaValues, usePaneWidth };
package/dist/index.d.ts CHANGED
@@ -16,7 +16,9 @@ import { LinkButton, LinkButtonProps } from "./Button/LinkButton.js";
16
16
  import { ButtonComponent } from "./Button/Button.js";
17
17
  import { ButtonBase } from "./Button/ButtonBase.js";
18
18
  import { ResponsiveValue, useResponsiveValue } from "./hooks/useResponsiveValue.js";
19
+ import { CustomWidthOptions, PaneWidth, PaneWidthValue, UsePaneWidthOptions, UsePaneWidthResult, defaultPaneWidth, usePaneWidth } from "./PageLayout/usePaneWidth.js";
19
20
  import { PageLayout, PageLayoutContentProps, PageLayoutFooterProps, PageLayoutHeaderProps, PageLayoutPaneProps, PageLayoutProps } from "./PageLayout/PageLayout.js";
21
+ import { DragHandle, DragHandleProps } from "./PageLayout/DragHandle.js";
20
22
  import { SplitPageLayout, SplitPageLayoutContentProps, SplitPageLayoutFooterProps, SplitPageLayoutHeaderProps, SplitPageLayoutPaneProps, SplitPageLayoutProps } from "./SplitPageLayout/SplitPageLayout.js";
21
23
  import useDetails from "./hooks/useDetails.js";
22
24
  import useSafeTimeout from "./hooks/useSafeTimeout.js";
@@ -117,4 +119,4 @@ import { ActionsProps, ChildrenPropTypes, PageHeader, PageHeaderProps, TitleArea
117
119
  import { SkeletonBox, SkeletonBoxProps } from "./Skeleton/SkeletonBox.js";
118
120
  import { ActionMenu, ActionMenuAnchorProps, ActionMenuButtonProps, ActionMenuProps } from "./ActionMenu/ActionMenu.js";
119
121
  import Overlay, { OverlayProps } from "./Overlay/Overlay.js";
120
- export { ActionBar, type ActionBarProps, ActionList, type ActionListDescriptionProps, type ActionListDividerProps, type ActionListGroupHeadingProps, type ActionListGroupHeadingTrailingActionProps, type ActionListGroupProps, type ActionListItemProps, type ActionListLeadingVisualProps, type ActionListLinkItemProps, type ActionListProps, type ActionListTrailingActionProps, type ActionListTrailingVisualProps, ActionMenu, type ActionMenuAnchorProps, type ActionMenuButtonProps, type ActionMenuProps, AnchoredOverlay, type AnchoredOverlayProps, type AnchoredPositionHookSettings, _default as Autocomplete, type AutocompleteInputProps, type AutocompleteMenuProps, type AutocompleteOverlayProps, Avatar, type AvatarProps, AvatarStack, type AvatarStackProps, Banner, type BannerProps, BaseStyles, type BaseStylesProps, _default$1 as BranchName, type BranchNameProps, Breadcrumb, type BreadcrumbItemProps, type BreadcrumbProps, _default$2 as Breadcrumbs, type BreadcrumbsItemProps, type BreadcrumbsProps, ButtonComponent as Button, ButtonBase, type ButtonBaseProps, ButtonGroup, type ButtonGroupProps, type ButtonProps, _default$3 as Checkbox, _default$4 as CheckboxGroup, type CheckboxGroupProps, type CheckboxProps, _default$5 as CircleBadge, type CircleBadgeIconProps, type CircleBadgeProps, ConfirmationDialog, type ConfirmationDialogProps, CounterLabel, type CounterLabelProps, Details, type DetailsProps, Dialog, type DialogButtonProps, type DialogHeaderProps, type DialogHeight, type DialogProps, type DialogWidth, type FCWithSlotMarker, Flash, type FlashProps, FocusKeys, type FocusTrapHookSettings, type FocusZoneHookSettings, _default$6 as FormControl, type FormControlCaptionProps, type Props as FormControlLabelProps, type FormControlProps, type FormControlValidationProps, _default$7 as Header, type HeaderItemProps, type HeaderLinkProps, type HeaderProps, Heading, type HeadingProps, IconButton, type IconButtonProps, IssueLabelToken, type IssueLabelTokenProps, Label, type LabelColorOptions, LabelGroup, type LabelGroupProps, type LabelProps, Link, LinkButton, type LinkButtonProps, type LinkProps, NavList, type NavListDividerProps, type NavListGroupHeadingProps, type NavListGroupProps, type NavListItemProps, type NavListLeadingVisualProps, type NavListProps, type NavListSubNavProps, type NavListTrailingVisualProps, Overlay, type OverlayProps, PageHeader, type ActionsProps as PageHeaderActionsProps, type ChildrenPropTypes as PageHeaderChildrenPropTypes, type PageHeaderProps, type TitleAreaProps as PageHeaderTitleAreaProps, type TitleProps as PageHeaderTitleProps, PageLayout, type PageLayoutContentProps, type PageLayoutFooterProps, type PageLayoutHeaderProps, type PageLayoutPaneProps, type PageLayoutProps, Pagination, type PaginationProps, _default$8 as Popover, type PopoverContentProps, type PopoverProps, Portal, PortalContext, type PortalProps, ProgressBar, type ProgressBarItemProps, type ProgressBarProps, _default$9 as Radio, _default$10 as RadioGroup, type RadioGroupProps, type RadioProps, RelativeTime, type RelativeTimeProps, type ResponsiveValue, SegmentedControl, type SegmentedControlButtonProps, type SegmentedControlIconButtonProps, type SegmentedControlProps, _default$11 as Select, SelectPanel, type GroupedListProps as SelectPanelGroupedListProps, type ItemInput as SelectPanelItemInput, type FilteredActionListItemProps as SelectPanelItemProps, type SelectPanelProps, type SelectProps, _default$12 as SideNav, type SideNavLinkProps, type SideNavProps, SkeletonBox, type SkeletonBoxProps, type SlotMarker, Spinner, type SpinnerProps, SplitPageLayout, type SplitPageLayoutContentProps, type SplitPageLayoutFooterProps, type SplitPageLayoutHeaderProps, type SplitPageLayoutPaneProps, type SplitPageLayoutProps, Stack, type StackItemProps, type StackProps, StateLabel, type StateLabelProps, _default$13 as SubNav, type SubNavLinkProps, type SubNavLinksProps, type SubNavProps, _default$14 as Text, _default$15 as TextInput, type TextInputActionProps, type TextInputProps, _default$16 as TextInputWithTokens, type TextInputWithTokensProps, type TextProps, _default$17 as Textarea, type TextareaProps, type ThemeColorPaths, ThemeProvider, type ThemeProviderProps, type ThemeShadowPaths, _default$18 as Timeline, type TimelineActionsProps, type TimelineAvatarProps, type TimelineBadgeProps, type TimelineBadgeVariant, type TimelineBodyProps, type TimelineBreakProps, type TimelineItemProps, type TimelineItemsProps, type TimelineProps, ToggleSwitch, type ToggleSwitchProps, Token, type TokenProps, Tooltip, type TooltipProps, type TouchOrMouseEvent, TreeView, type TreeViewErrorDialogProps, type TreeViewItemProps, type TreeViewProps, type TreeViewSubTreeProps, type TreeViewVisualProps, Truncate, type TruncateProps, UnderlineNav, type UnderlineNavItemProps, type UnderlineNavProps, VisuallyHidden, type VisuallyHiddenProps, type WithSlotMarker, asSlot, createComponent, isSlot, registerPortalRoot, theme, useAnchoredPosition, useColorSchemeVar, useConfirm, useDetails, useFocusTrap, useFocusZone, useFormControlForwardedProps, useId, useIsomorphicLayoutEffect, useMergedRefs, useOnEscapePress, useOnOutsideClick, useOpenAndCloseFocus, useOverlay, useProvidedRefOrCreate, useRefObjectAsForwardedRef, useResizeObserver, useResponsiveValue, useRovingTabIndex, useSafeTimeout, useSlots, useSyncedState, useTheme };
122
+ export { ActionBar, type ActionBarProps, ActionList, type ActionListDescriptionProps, type ActionListDividerProps, type ActionListGroupHeadingProps, type ActionListGroupHeadingTrailingActionProps, type ActionListGroupProps, type ActionListItemProps, type ActionListLeadingVisualProps, type ActionListLinkItemProps, type ActionListProps, type ActionListTrailingActionProps, type ActionListTrailingVisualProps, ActionMenu, type ActionMenuAnchorProps, type ActionMenuButtonProps, type ActionMenuProps, AnchoredOverlay, type AnchoredOverlayProps, type AnchoredPositionHookSettings, _default as Autocomplete, type AutocompleteInputProps, type AutocompleteMenuProps, type AutocompleteOverlayProps, Avatar, type AvatarProps, AvatarStack, type AvatarStackProps, Banner, type BannerProps, BaseStyles, type BaseStylesProps, _default$1 as BranchName, type BranchNameProps, Breadcrumb, type BreadcrumbItemProps, type BreadcrumbProps, _default$2 as Breadcrumbs, type BreadcrumbsItemProps, type BreadcrumbsProps, ButtonComponent as Button, ButtonBase, type ButtonBaseProps, ButtonGroup, type ButtonGroupProps, type ButtonProps, _default$3 as Checkbox, _default$4 as CheckboxGroup, type CheckboxGroupProps, type CheckboxProps, _default$5 as CircleBadge, type CircleBadgeIconProps, type CircleBadgeProps, ConfirmationDialog, type ConfirmationDialogProps, CounterLabel, type CounterLabelProps, type CustomWidthOptions, Details, type DetailsProps, Dialog, type DialogButtonProps, type DialogHeaderProps, type DialogHeight, type DialogProps, type DialogWidth, DragHandle, type DragHandleProps, type FCWithSlotMarker, Flash, type FlashProps, FocusKeys, type FocusTrapHookSettings, type FocusZoneHookSettings, _default$6 as FormControl, type FormControlCaptionProps, type Props as FormControlLabelProps, type FormControlProps, type FormControlValidationProps, _default$7 as Header, type HeaderItemProps, type HeaderLinkProps, type HeaderProps, Heading, type HeadingProps, IconButton, type IconButtonProps, IssueLabelToken, type IssueLabelTokenProps, Label, type LabelColorOptions, LabelGroup, type LabelGroupProps, type LabelProps, Link, LinkButton, type LinkButtonProps, type LinkProps, NavList, type NavListDividerProps, type NavListGroupHeadingProps, type NavListGroupProps, type NavListItemProps, type NavListLeadingVisualProps, type NavListProps, type NavListSubNavProps, type NavListTrailingVisualProps, Overlay, type OverlayProps, PageHeader, type ActionsProps as PageHeaderActionsProps, type ChildrenPropTypes as PageHeaderChildrenPropTypes, type PageHeaderProps, type TitleAreaProps as PageHeaderTitleAreaProps, type TitleProps as PageHeaderTitleProps, PageLayout, type PageLayoutContentProps, type PageLayoutFooterProps, type PageLayoutHeaderProps, type PageLayoutPaneProps, type PageLayoutProps, Pagination, type PaginationProps, type PaneWidth, type PaneWidthValue, _default$8 as Popover, type PopoverContentProps, type PopoverProps, Portal, PortalContext, type PortalProps, ProgressBar, type ProgressBarItemProps, type ProgressBarProps, _default$9 as Radio, _default$10 as RadioGroup, type RadioGroupProps, type RadioProps, RelativeTime, type RelativeTimeProps, type ResponsiveValue, SegmentedControl, type SegmentedControlButtonProps, type SegmentedControlIconButtonProps, type SegmentedControlProps, _default$11 as Select, SelectPanel, type GroupedListProps as SelectPanelGroupedListProps, type ItemInput as SelectPanelItemInput, type FilteredActionListItemProps as SelectPanelItemProps, type SelectPanelProps, type SelectProps, _default$12 as SideNav, type SideNavLinkProps, type SideNavProps, SkeletonBox, type SkeletonBoxProps, type SlotMarker, Spinner, type SpinnerProps, SplitPageLayout, type SplitPageLayoutContentProps, type SplitPageLayoutFooterProps, type SplitPageLayoutHeaderProps, type SplitPageLayoutPaneProps, type SplitPageLayoutProps, Stack, type StackItemProps, type StackProps, StateLabel, type StateLabelProps, _default$13 as SubNav, type SubNavLinkProps, type SubNavLinksProps, type SubNavProps, _default$14 as Text, _default$15 as TextInput, type TextInputActionProps, type TextInputProps, _default$16 as TextInputWithTokens, type TextInputWithTokensProps, type TextProps, _default$17 as Textarea, type TextareaProps, type ThemeColorPaths, ThemeProvider, type ThemeProviderProps, type ThemeShadowPaths, _default$18 as Timeline, type TimelineActionsProps, type TimelineAvatarProps, type TimelineBadgeProps, type TimelineBadgeVariant, type TimelineBodyProps, type TimelineBreakProps, type TimelineItemProps, type TimelineItemsProps, type TimelineProps, ToggleSwitch, type ToggleSwitchProps, Token, type TokenProps, Tooltip, type TooltipProps, type TouchOrMouseEvent, TreeView, type TreeViewErrorDialogProps, type TreeViewItemProps, type TreeViewProps, type TreeViewSubTreeProps, type TreeViewVisualProps, Truncate, type TruncateProps, UnderlineNav, type UnderlineNavItemProps, type UnderlineNavProps, type UsePaneWidthOptions, type UsePaneWidthResult, VisuallyHidden, type VisuallyHiddenProps, type WithSlotMarker, asSlot, createComponent, defaultPaneWidth, isSlot, registerPortalRoot, theme, useAnchoredPosition, useColorSchemeVar, useConfirm, useDetails, useFocusTrap, useFocusZone, useFormControlForwardedProps, useId, useIsomorphicLayoutEffect, useMergedRefs, useOnEscapePress, useOnOutsideClick, useOpenAndCloseFocus, useOverlay, usePaneWidth, useProvidedRefOrCreate, useRefObjectAsForwardedRef, useResizeObserver, useResponsiveValue, useRovingTabIndex, useSafeTimeout, useSlots, useSyncedState, useTheme };
package/dist/index.js CHANGED
@@ -28,6 +28,8 @@ import { IconButton } from "./Button/IconButton.js";
28
28
  import { LinkButton } from "./Button/LinkButton.js";
29
29
  import { ButtonComponent } from "./Button/Button.js";
30
30
  import { useResponsiveValue } from "./hooks/useResponsiveValue.js";
31
+ import { defaultPaneWidth, usePaneWidth } from "./PageLayout/usePaneWidth.js";
32
+ import { DragHandle } from "./PageLayout/DragHandle.js";
31
33
  import { PageLayout } from "./PageLayout/PageLayout.js";
32
34
  import { SplitPageLayout } from "./SplitPageLayout/SplitPageLayout.js";
33
35
  import useDetails from "./hooks/useDetails.js";
@@ -92,4 +94,4 @@ import { TreeView } from "./TreeView/TreeView.js";
92
94
  import { UnderlineNav } from "./UnderlineNav/index.js";
93
95
  import { ActionBar } from "./ActionBar/index.js";
94
96
  import { PageHeader } from "./PageHeader/PageHeader.js";
95
- export { ActionBar, ActionList, ActionMenu, AnchoredOverlay, Autocomplete_default as Autocomplete, Avatar, AvatarStack, Banner, BaseStyles, BranchName_default as BranchName, Breadcrumb, Breadcrumbs_default as Breadcrumbs, ButtonComponent as Button, ButtonBase, ButtonGroup, Checkbox, CheckboxGroup_default as CheckboxGroup, CircleBadge_default as CircleBadge, ConfirmationDialog, CounterLabel, Details, Dialog, Flash, FocusKeys, FormControl_default as FormControl, Header_default as Header, Heading, IconButton, IssueLabelToken, Label_default as Label, LabelGroup, Link, LinkButton, NavList, Overlay, PageHeader, PageLayout, Pagination_default as Pagination, Popover_default as Popover, Portal_default as Portal, PortalContext, ProgressBar, Radio, RadioGroup_default as RadioGroup, RelativeTime, SegmentedControl, Select_default as Select, SelectPanel, SideNav_default as SideNav, SkeletonBox, Spinner, SplitPageLayout, Stack, StateLabel, SubNav_default as SubNav, Text_default as Text, TextInput_default as TextInput, TextInputWithTokens, Textarea, ThemeProvider, Timeline_default as Timeline, ToggleSwitch, Token, Tooltip, TreeView, Truncate, UnderlineNav, VisuallyHidden, asSlot, createComponent, isSlot, registerPortalRoot, theme, useAnchoredPosition, useColorSchemeVar, useConfirm, useDetails, useFocusTrap, useFocusZone, useFormControlForwardedProps, useId, useIsomorphicLayoutEffect, useMergedRefs, useOnEscapePress, useOnOutsideClick, useOpenAndCloseFocus, useOverlay, useProvidedRefOrCreate, useRefObjectAsForwardedRef, useResizeObserver, useResponsiveValue, useRovingTabIndex, useSafeTimeout, useSlots, useSyncedState, useTheme };
97
+ export { ActionBar, ActionList, ActionMenu, AnchoredOverlay, Autocomplete_default as Autocomplete, Avatar, AvatarStack, Banner, BaseStyles, BranchName_default as BranchName, Breadcrumb, Breadcrumbs_default as Breadcrumbs, ButtonComponent as Button, ButtonBase, ButtonGroup, Checkbox, CheckboxGroup_default as CheckboxGroup, CircleBadge_default as CircleBadge, ConfirmationDialog, CounterLabel, Details, Dialog, DragHandle, Flash, FocusKeys, FormControl_default as FormControl, Header_default as Header, Heading, IconButton, IssueLabelToken, Label_default as Label, LabelGroup, Link, LinkButton, NavList, Overlay, PageHeader, PageLayout, Pagination_default as Pagination, Popover_default as Popover, Portal_default as Portal, PortalContext, ProgressBar, Radio, RadioGroup_default as RadioGroup, RelativeTime, SegmentedControl, Select_default as Select, SelectPanel, SideNav_default as SideNav, SkeletonBox, Spinner, SplitPageLayout, Stack, StateLabel, SubNav_default as SubNav, Text_default as Text, TextInput_default as TextInput, TextInputWithTokens, Textarea, ThemeProvider, Timeline_default as Timeline, ToggleSwitch, Token, Tooltip, TreeView, Truncate, UnderlineNav, VisuallyHidden, asSlot, createComponent, defaultPaneWidth, isSlot, registerPortalRoot, theme, useAnchoredPosition, useColorSchemeVar, useConfirm, useDetails, useFocusTrap, useFocusZone, useFormControlForwardedProps, useId, useIsomorphicLayoutEffect, useMergedRefs, useOnEscapePress, useOnOutsideClick, useOpenAndCloseFocus, useOverlay, usePaneWidth, useProvidedRefOrCreate, useRefObjectAsForwardedRef, useResizeObserver, useResponsiveValue, useRovingTabIndex, useSafeTimeout, useSlots, useSyncedState, useTheme };
@@ -50,7 +50,7 @@ function OverflowObserverProvider(t0) {
50
50
  }
51
51
  }, {
52
52
  root,
53
- threshold: [0, 1]
53
+ threshold: [0, .95]
54
54
  });
55
55
  observerRootRef.current = root;
56
56
  return observerRef.current;
@@ -143,12 +143,12 @@ function OverflowObserverProvider(t0) {
143
143
  return t9;
144
144
  }
145
145
  /**
146
- * Treat any target that is not fully visible within the observer root as overflowing. Wrapped items should be fully
147
- * clipped (`isIntersecting: false`, `intersectionRatio: 0`), but partial ratios also count as overflowing to guard
148
- * against sub-pixel boundary cases.
146
+ * Treat any target that is not fully visible within the observer root as overflowing. Unwrapped items should be fully
147
+ * visible, but in some scenarios the layout isn't perfectly accurate (ie, in Safari with extra-large text size) so we
148
+ * allow for up to 5% to be clipped before hiding the item.
149
149
  */
150
150
  function getIsOverflowing(entry) {
151
- return !entry.isIntersecting || entry.intersectionRatio < 1;
151
+ return !entry.isIntersecting || entry.intersectionRatio < .95;
152
152
  }
153
153
  function supportsIntersectionObserver() {
154
154
  return typeof IntersectionObserver !== "undefined";
@@ -0,0 +1,2 @@
1
+ .prc-components-UnderlineWrapper-eT-Yj{align-items:flex-start;box-shadow:inset 0 -1px var(--borderColor-muted,#d1d9e0b3);display:flex;justify-content:flex-start;min-height:var(--control-xlarge-size,3rem);padding-top:var(--base-size-8,.5rem);padding-inline:var(--stack-padding-normal,1rem)}.prc-components-UnderlineWrapper-eT-Yj[data-variant=flush]{padding-inline:unset}.prc-components-UnderlineWrapper-eT-Yj[data-overflow-mode=wrap]{border-block:0!important;box-sizing:border-box;max-height:var(--control-xlarge-size,3rem);overflow:hidden;padding-block:var(--base-size-8,.5rem) 0!important}.prc-components-UnderlineWrapper-eT-Yj[data-overflow-mode=wrap] .prc-components-UnderlineItemList-xKlKC{flex-grow:1;flex-wrap:wrap;overflow:hidden}.prc-components-UnderlineItemList-xKlKC{contain:layout;display:flex;gap:var(--stack-gap-condensed,.5rem);list-style:none;margin:0;padding:0;white-space:nowrap}.prc-components-UnderlineItem-7fP-n,.prc-components-UnderlineItemList-xKlKC{align-items:center;position:relative}.prc-components-UnderlineItem-7fP-n{appearance:none;background-color:transparent;border:0;border-radius:var(--borderRadius-medium,.375rem);color:var(--fgColor-default,#1f2328);cursor:pointer;display:inline-flex;font:inherit;font-size:var(--text-body-size-medium,.875rem);height:var(--base-size-32,2rem);line-height:var(--text-body-lineHeight-medium,1.4285);margin-bottom:var(--base-size-8,.5rem);max-width:100%;padding-block:var(--base-size-6,.375rem);padding-inline:var(--base-size-8,.5rem);text-align:center;-webkit-text-decoration:none;text-decoration:none}@media (hover:hover){.prc-components-UnderlineItem-7fP-n:hover{background-color:var(--bgColor-neutral-muted,#818b981f);-webkit-text-decoration:none;text-decoration:none;transition:background-color .12s ease-out}}.prc-components-UnderlineItem-7fP-n:focus{box-shadow:inset 0 0 0 2px var(--fgColor-accent,#0969da);outline:2px solid transparent}.prc-components-UnderlineItem-7fP-n:focus:not(:focus-visible){box-shadow:none}.prc-components-UnderlineItem-7fP-n:focus-visible{box-shadow:inset 0 0 0 2px var(--fgColor-accent,#0969da);outline:2px solid transparent}.prc-components-UnderlineItem-7fP-n [data-content]:before{content:attr(data-content);display:block;font-weight:var(--base-text-weight-semibold,600);height:0;visibility:hidden;white-space:nowrap}.prc-components-UnderlineItem-7fP-n [data-component=icon]{align-items:center;color:var(--fgColor-muted,#59636e);display:inline-flex;margin-inline-end:var(--base-size-8,.5rem)}.prc-components-UnderlineItem-7fP-n [data-component=text]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.prc-components-UnderlineItem-7fP-n [data-component=counter]{align-items:center;display:flex;margin-inline-start:var(--base-size-8,.5rem)}.prc-components-UnderlineItem-7fP-n:after{background-color:transparent;content:"";height:2px;inset:auto 0 0;margin-bottom:calc(var(--base-size-8,.5rem)*-1);pointer-events:none;position:absolute}.prc-components-UnderlineItem-7fP-n[aria-current]:not([aria-current=false]) [data-component=text],.prc-components-UnderlineItem-7fP-n[aria-selected=true] [data-component=text]{font-weight:var(--base-text-weight-semibold,600)}.prc-components-UnderlineItem-7fP-n[aria-current]:not([aria-current=false]):after,.prc-components-UnderlineItem-7fP-n[aria-selected=true]:after{background-color:var(--underlineNav-borderColor-active,var(--color-primer-border-active,#fd8c73))}@media (forced-colors:active){.prc-components-UnderlineItem-7fP-n[aria-current]:not([aria-current=false]):after,.prc-components-UnderlineItem-7fP-n[aria-selected=true]:after{background-color:LinkText}}.prc-components-LoadingCounter-dBuLy{animation:prc-components-loadingCounterKeyFrames-8tMlf 1.2s ease-in-out infinite alternate;background-color:var(--bgColor-neutral-muted,#818b981f);border-color:var(--borderColor-default,#d1d9e0);border-radius:20px;display:inline-block;height:1rem;width:1.5rem}@keyframes prc-components-loadingCounterKeyFrames-8tMlf{0%{opacity:1}to{opacity:.2}}
2
+ /*# sourceMappingURL=UnderlineTabbedInterface-798ef3cb.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/internal/components/UnderlineTabbedInterface.module.css.js"],"names":[],"mappings":"AAAA,uCAME,sBAAuB,CAOvB,0DAAiD,CAZjD,YAAa,CAIb,0BAA2B,CAI3B,0CAAsC,CAPtC,oCAA+B,CAE/B,+CAgCF,CArBE,2DAEE,oBACF,CAEA,gEAOE,wBAA0B,CAD1B,qBAAsB,CAHtB,0CAAsC,CADtC,eAAgB,CAMhB,kDAOF,CALE,wGACE,WAAY,CACZ,cAAe,CACf,eACF,CAIJ,wCAaE,cAAe,CAXf,YAAa,CAMb,oCAA+B,CAF/B,eAAgB,CAFhB,QAAS,CADT,SAAU,CAEV,kBASF,CAEA,4EATE,kBAAmB,CANnB,iBA8CF,CA/BA,oCAmBE,eAAgB,CARhB,4BAA6B,CAC7B,QAAS,CACT,gDAAyC,CANzC,oCAA6B,CAG7B,cAAe,CAPf,mBAAoB,CACpB,YAAa,CACb,8CAAuC,CAWvC,+BAA2B,CAV3B,qDAAuD,CASvD,sCAAiC,CADjC,cAAe,CAOf,wCAAiC,CADjC,uCAAkC,CAZlC,iBAAkB,CAClB,4BAAqB,CAArB,oBAsBF,CAPE,qBACE,0CAEE,uDAA8C,CAD9C,4BAAqB,CAArB,oBAAqB,CAErB,yCACF,CACF,CAGF,0CAGE,wDAAiD,CAFjD,6BAQF,CAHE,8DACE,eACF,CAGF,kDAGE,wDAAiD,CAFjD,6BAGF,CAGA,0DAME,0BAA2B,CAL3B,aAAc,CAEd,gDAA6C,CAD7C,QAAS,CAGT,iBAAkB,CADlB,kBAGF,CAEA,0DAGE,kBAAmB,CADnB,kCAA2B,CAD3B,mBAAoB,CAGpB,0CACF,CAGA,0DACE,eAAgB,CAChB,sBAAuB,CACvB,kBACF,CAEA,6DAGE,kBAAmB,CADnB,YAAa,CADb,4CAGF,CAEA,0CAOE,4BAA6B,CAD7B,UAAW,CAFX,UAAW,CAFX,cAAe,CACf,+CAA4C,CAE5C,mBAAoB,CAJpB,iBAOF,CAEA,gLAEE,gDACF,CAEA,gJAGE,iGAMF,CAJE,8BALF,gJAOI,yBAEJ,CADE,CAGF,qCASE,0FAAsE,CAJtE,uDAA8C,CAC9C,+CAAwC,CAExC,kBAAmB,CAPnB,oBAAqB,CAErB,WAAY,CADZ,YAQF,CAEA,wDACE,GACE,SACF,CAEA,GACE,UACF,CACF","file":"UnderlineTabbedInterface-798ef3cb.css","sourcesContent":[".UnderlineWrapper {\n display: flex;\n padding-top: var(--base-size-8);\n /* stylelint-disable-next-line primer/spacing */\n padding-inline: var(--stack-padding-normal);\n justify-content: flex-start;\n align-items: flex-start;\n\n /* make space for the underline */\n min-height: var(--control-xlarge-size);\n\n /* using a box-shadow instead of a border to accommodate 'overflow-y: hidden' on UnderlinePanels */\n /* stylelint-disable-next-line primer/box-shadow */\n box-shadow: inset 0 -1px var(--borderColor-muted);\n\n &[data-variant='flush'] {\n /* stylelint-disable-next-line primer/spacing */\n padding-inline: unset;\n }\n\n &[data-overflow-mode='wrap'] {\n /* Wrap items onto hidden next lines */\n overflow: hidden;\n max-height: var(--control-xlarge-size);\n\n /* Pin the vertical box model so external border/padding overrides can't change the height budget and incorrectly trigger the overflow \"more\" menu */\n box-sizing: border-box;\n border-block: 0 !important;\n padding-block: var(--base-size-8) 0 !important;\n\n .UnderlineItemList {\n flex-grow: 1;\n flex-wrap: wrap;\n overflow: hidden;\n }\n }\n}\n\n.UnderlineItemList {\n position: relative;\n display: flex;\n padding: 0;\n margin: 0;\n white-space: nowrap;\n list-style: none;\n align-items: center;\n gap: var(--stack-gap-condensed);\n\n /* Isolate the ResizeObserver-driven item swapping (UnderlineNav overflow menu / UnderlinePanels)\n so it can't invalidate ancestor layout. Safe because UnderlineNav's overflow menu is rendered via ActionMenu.Overlay\n (portal by default), and layout containment does not clip. */\n contain: layout;\n}\n\n.UnderlineItem {\n /* underline tab specific styles */\n position: relative;\n display: inline-flex;\n font: inherit;\n font-size: var(--text-body-size-medium);\n line-height: var(--text-body-lineHeight-medium, 1.4285);\n color: var(--fgColor-default);\n text-align: center;\n text-decoration: none;\n cursor: pointer;\n background-color: transparent;\n border: 0;\n border-radius: var(--borderRadius-medium);\n max-width: 100%;\n margin-bottom: var(--base-size-8);\n height: var(--base-size-32);\n\n /* button resets */\n appearance: none;\n padding-inline: var(--base-size-8);\n padding-block: var(--base-size-6);\n align-items: center;\n\n @media (hover: hover) {\n &:hover {\n text-decoration: none;\n background-color: var(--bgColor-neutral-muted);\n transition: background-color 0.12s ease-out;\n }\n }\n}\n\n.UnderlineItem:focus {\n outline: 2px solid transparent;\n /* stylelint-disable-next-line primer/box-shadow */\n box-shadow: inset 0 0 0 2px var(--fgColor-accent);\n\n /* where focus-visible is supported, remove the focus box-shadow */\n &:not(:focus-visible) {\n box-shadow: none;\n }\n}\n\n.UnderlineItem:focus-visible {\n outline: 2px solid transparent;\n /* stylelint-disable-next-line primer/box-shadow */\n box-shadow: inset 0 0 0 2px var(--fgColor-accent);\n}\n\n/* renders a visibly hidden \"copy\" of the label in bold, reserving box space for when label becomes bold on selected */\n.UnderlineItem [data-content]::before {\n display: block;\n height: 0;\n font-weight: var(--base-text-weight-semibold);\n white-space: nowrap;\n visibility: hidden;\n content: attr(data-content);\n}\n\n.UnderlineItem [data-component='icon'] {\n display: inline-flex;\n color: var(--fgColor-muted);\n align-items: center;\n margin-inline-end: var(--base-size-8);\n}\n\n/* Truncate items if necessary (should only ever apply to the last item after everything else overflows) */\n.UnderlineItem [data-component='text'] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.UnderlineItem [data-component='counter'] {\n margin-inline-start: var(--base-size-8);\n display: flex;\n align-items: center;\n}\n\n.UnderlineItem::after {\n position: absolute;\n inset: auto 0 0;\n margin-bottom: calc(-1 * var(--base-size-8));\n height: 2px;\n pointer-events: none;\n content: '';\n background-color: transparent;\n}\n\n.UnderlineItem[aria-current]:not([aria-current='false']) [data-component='text'],\n.UnderlineItem[aria-selected='true'] [data-component='text'] {\n font-weight: var(--base-text-weight-semibold);\n}\n\n.UnderlineItem[aria-current]:not([aria-current='false'])::after,\n.UnderlineItem[aria-selected='true']::after {\n /* stylelint-disable-next-line primer/colors */\n background-color: var(--underlineNav-borderColor-active, var(--color-primer-border-active, #fd8c73));\n\n @media (forced-colors: active) {\n /* Support for Window Force Color Mode https://learn.microsoft.com/en-us/fluent-ui/web-components/design-system/high-contrast */\n background-color: LinkText;\n }\n}\n\n.LoadingCounter {\n display: inline-block;\n width: 1.5rem;\n height: 1rem;\n /* 16px */\n background-color: var(--bgColor-neutral-muted);\n border-color: var(--borderColor-default);\n /* stylelint-disable-next-line primer/borders */\n border-radius: 20px;\n animation: loadingCounterKeyFrames 1.2s ease-in-out infinite alternate;\n}\n\n@keyframes loadingCounterKeyFrames {\n from {\n opacity: 1;\n }\n\n to {\n opacity: 0.2;\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import "./UnderlineTabbedInterface-93bd865a.css";
1
+ import "./UnderlineTabbedInterface-798ef3cb.css";
2
2
  //#region src/internal/components/UnderlineTabbedInterface.module.css.js
3
3
  var UnderlineTabbedInterface_module_css_default = {
4
4
  "UnderlineWrapper": "prc-components-UnderlineWrapper-eT-Yj",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@primer/react",
3
3
  "type": "module",
4
- "version": "38.32.1-rc.ea8470aaa",
4
+ "version": "38.33.0-rc.01176969a",
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",
@@ -1,2 +0,0 @@
1
- .prc-ActionBar-List-9uz46{align-items:flex-start;animation:prc-ActionBar-detect-overflow-mAuJu linear;display:flex;gap:var(--actionbar-gap,var(--stack-gap-condensed,.5rem));height:var(--actionbar-height,var(--control-small-size,1.75rem));list-style:none;margin-bottom:-1px;min-width:0;overflow:hidden;position:relative;animation-timeline:scroll(self block)}.prc-ActionBar-List-9uz46[data-has-overflow=true]{--morebutton-display:flex}.prc-ActionBar-List-9uz46:where([data-size=small]){--actionbar-height:var(--control-small-size,1.75rem)}.prc-ActionBar-List-9uz46:where([data-size=medium]){--actionbar-height:var(--control-medium-size,2rem)}.prc-ActionBar-List-9uz46:where([data-size=large]){--actionbar-height:var(--control-large-size,2.5rem)}.prc-ActionBar-List-9uz46:where([data-gap=none]){--actionbar-gap:0}.prc-ActionBar-List-9uz46:where([data-gap=none]) .prc-ActionBar-Divider-6V8yH{padding:0 var(--base-size-8,.5rem)}.prc-ActionBar-List-9uz46:where([data-gap=condensed]){--actionbar-gap:var(--stack-gap-condensed,0.5rem)}.prc-ActionBar-List-9uz46 [data-overflowing]{visibility:hidden!important}@keyframes prc-ActionBar-detect-overflow-mAuJu{0%,to{--morebutton-display:flex}}.prc-ActionBar-Nav-9spON{align-items:center;display:flex;justify-content:flex-end;padding-inline:var(--base-size-16,1rem)}.prc-ActionBar-Nav-9spON:where([data-flush=true]){padding-inline:0}.prc-ActionBar-Divider-6V8yH:before{background:var(--borderColor-muted,#d1d9e0b3);content:"";display:block;height:var(--base-size-20,1.25rem);margin-top:calc((var(--actionbar-height) - var(--base-size-20,1.25rem))/2);width:var(--borderWidth-thin,.0625rem)}.prc-ActionBar-Group-peNCk,.prc-ActionBar-OverflowContainer-AkYZs{display:flex;gap:inherit}.prc-ActionBar-OverflowContainer-AkYZs{flex-wrap:wrap;justify-content:flex-end;overflow:hidden}.prc-ActionBar-OverflowContainer-AkYZs .prc-ActionBar-OverflowSpacer-tbHkV{height:var(--actionbar-height)}.prc-ActionBar-MoreButton-RHqpx{display:var(--morebutton-display,none)}
2
- /*# sourceMappingURL=ActionBar-e63def3c.css.map */
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/ActionBar/ActionBar.module.css.js"],"names":[],"mappings":"AAAA,0BASE,sBAAuB,CASvB,oDAAiC,CAhBjC,YAAa,CAQb,yDAAqD,CAGrD,gEAA0D,CAL1D,eAAgB,CADhB,kBAAmB,CAJnB,WAAY,CAQZ,eAAgB,CAVhB,iBAAkB,CAkBlB,qCAsCF,CAnCE,kDACE,yBACF,CAEA,mDACE,oDACF,CAEA,oDACE,kDACF,CAEA,mDACE,mDACF,CAGA,iDACE,iBAKF,CAHE,8EACE,kCACF,CAGF,sDACE,iDACF,CAEA,6CAIE,2BACF,CAGF,+CACE,MAEE,yBACF,CACF,CAEA,yBAIE,kBAAmB,CAHnB,YAAa,CAEb,wBAAyB,CADzB,uCAOF,CAHE,kDACE,gBACF,CAIA,oCAME,6CAAoC,CAFpC,UAAW,CAHX,aAAc,CAEd,kCAA2B,CAK3B,0EAAqE,CANrE,sCAOF,CAQF,kEAJE,YAAa,CACb,WAaF,CAVA,uCAEE,cAAe,CAEf,wBAAyB,CACzB,eAKF,CAHE,2EACE,8BACF,CAGF,gCACE,sCACF","file":"ActionBar-e63def3c.css","sourcesContent":[".List {\n position: relative;\n display: flex;\n min-width: 0;\n\n /* wonder why this is here */\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: -1px;\n list-style: none;\n align-items: flex-start;\n gap: var(--actionbar-gap, var(--stack-gap-condensed));\n overflow: hidden;\n /* Explicit height is required to clip wrapped items */\n height: var(--actionbar-height, var(--control-small-size));\n\n /* Scroll-based animations have no effect unless the container is scrollable (has overflow, even with overflow:hidden)\n so we can use them to detect overflow. It would be cleaner to use scroll-state container queries for this, but\n browser support for scroll-driven animations is slightly better. */\n animation: detect-overflow linear;\n animation-timeline: scroll(self block);\n\n /* After initial render, JS is used to control visibility which provides progressive enhancement for unsupported browsers */\n &[data-has-overflow='true'] {\n --morebutton-display: flex;\n }\n\n &:where([data-size='small']) {\n --actionbar-height: var(--control-small-size);\n }\n\n &:where([data-size='medium']) {\n --actionbar-height: var(--control-medium-size);\n }\n\n &:where([data-size='large']) {\n --actionbar-height: var(--control-large-size);\n }\n\n /* Gap scale (mirrors Stack) */\n &:where([data-gap='none']) {\n --actionbar-gap: 0;\n\n .Divider {\n padding: 0 var(--base-size-8);\n }\n }\n\n &:where([data-gap='condensed']) {\n --actionbar-gap: var(--stack-gap-condensed);\n }\n\n & [data-overflowing] {\n /* Hide overflowing items. Even though they are clipped by `overflow: hidden`, setting `visibility: hidden` ensures\n they can't accidentally be shown and also hides them from screen readers / keyboard nav. `!important` prevents\n consumers from unintentionally overriding this and breaking accessibility. */\n visibility: hidden !important;\n }\n}\n\n@keyframes detect-overflow {\n 0%,\n 100% {\n --morebutton-display: flex;\n }\n}\n\n.Nav {\n display: flex;\n padding-inline: var(--base-size-16);\n justify-content: flex-end;\n align-items: center;\n\n &:where([data-flush='true']) {\n padding-inline: 0;\n }\n}\n\n.Divider {\n &::before {\n display: block;\n width: var(--borderWidth-thin);\n height: var(--base-size-20);\n content: '';\n /* stylelint-disable-next-line primer/colors */\n background: var(--borderColor-muted);\n /* stylelint-disable-next-line primer/spacing */\n margin-top: calc((var(--actionbar-height) - var(--base-size-20)) / 2);\n }\n}\n\n.Group {\n display: flex;\n gap: inherit;\n}\n\n.OverflowContainer {\n display: flex;\n flex-wrap: wrap;\n gap: inherit;\n justify-content: flex-end;\n overflow: hidden;\n\n .OverflowSpacer {\n height: var(--actionbar-height);\n }\n}\n\n.MoreButton {\n display: var(--morebutton-display, none);\n}\n"]}
@@ -1,2 +0,0 @@
1
- .prc-LabelGroup-Container-E-ePP{display:flex;flex-wrap:nowrap;gap:var(--base-size-4,.25rem);line-height:1;max-width:100%;overflow:hidden}.prc-LabelGroup-Container-E-ePP:where([data-overflow=inline]){flex-wrap:wrap}.prc-LabelGroup-Container-E-ePP:where([data-list]){list-style-type:none;margin-block-end:0;margin-block-start:0;padding-inline-start:0}.prc-LabelGroup-ItemWrapper-GkO4t{align-items:center;display:flex;min-height:28px}.prc-LabelGroup-ItemWrapper--hidden-mdrB0{order:9999;pointer-events:none;visibility:hidden}.prc-LabelGroup-OverlayContainer-duQvd{align-items:flex-start;display:flex}.prc-LabelGroup-OverlayInner-nDXRC{display:flex;flex-wrap:wrap;gap:var(--base-size-4,.25rem)}.prc-LabelGroup-CloseButton-IyLno{flex-shrink:0}
2
- /*# sourceMappingURL=LabelGroup-7d19205a.css.map */
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/LabelGroup/LabelGroup.module.css.js"],"names":[],"mappings":"AAAA,gCACE,YAAa,CACb,gBAAiB,CACjB,6BAAuB,CAEvB,aAAc,CACd,cAAe,CACf,eAYF,CAVE,8DACE,cACF,CAEA,mDAIE,oBAAqB,CADrB,kBAAmB,CADnB,oBAAqB,CADrB,sBAIF,CAGF,kCAEE,kBAAmB,CADnB,YAAa,CAOb,eACF,CAEA,0CACE,UAAW,CACX,mBAAoB,CACpB,iBACF,CAEA,uCACE,sBAAuB,CACvB,YACF,CAEA,mCACE,YAAa,CACb,cAAe,CACf,6BACF,CAEA,kCACE,aACF","file":"LabelGroup-7d19205a.css","sourcesContent":[".Container {\n display: flex;\n flex-wrap: nowrap;\n gap: var(--base-size-4);\n /* stylelint-disable-next-line primer/typography */\n line-height: 1;\n max-width: 100%;\n overflow: hidden;\n\n &:where([data-overflow='inline']) {\n flex-wrap: wrap;\n }\n\n &:where([data-list]) {\n padding-inline-start: 0;\n margin-block-start: 0;\n margin-block-end: 0;\n list-style-type: none;\n }\n}\n\n.ItemWrapper {\n display: flex;\n align-items: center;\n /* This min-height matches the height of the expand/collapse button.\n Without it, the labels/tokens will do a slight layout shift when expanded.\n This is because the height of the first row will match the token sizes,\n but the height of the second row will be the height of the collapse button.\n */\n min-height: 28px;\n}\n\n.ItemWrapper--hidden {\n order: 9999;\n pointer-events: none;\n visibility: hidden;\n}\n\n.OverlayContainer {\n align-items: flex-start;\n display: flex;\n}\n\n.OverlayInner {\n display: flex;\n flex-wrap: wrap;\n gap: var(--base-size-4);\n}\n\n.CloseButton {\n flex-shrink: 0;\n}\n"]}
@@ -1,2 +0,0 @@
1
- .prc-components-UnderlineWrapper-eT-Yj{align-items:flex-start;box-shadow:inset 0 -1px var(--borderColor-muted,#d1d9e0b3);display:flex;justify-content:flex-start;min-height:var(--control-xlarge-size,3rem);padding-top:var(--base-size-8,.5rem);padding-inline:var(--stack-padding-normal,1rem)}.prc-components-UnderlineWrapper-eT-Yj[data-variant=flush]{padding-inline:unset}.prc-components-UnderlineWrapper-eT-Yj[data-overflow-mode=wrap]{border-block:0!important;box-sizing:border-box;max-height:var(--control-xlarge-size,3rem);overflow:hidden;padding-block:var(--base-size-8,.5rem) 0!important}.prc-components-UnderlineWrapper-eT-Yj[data-overflow-mode=wrap] .prc-components-UnderlineItemList-xKlKC{flex-grow:1;flex-wrap:wrap;overflow:hidden}.prc-components-UnderlineItemList-xKlKC{display:flex;gap:var(--stack-gap-condensed,.5rem);list-style:none;margin:0;padding:0;white-space:nowrap}.prc-components-UnderlineItem-7fP-n,.prc-components-UnderlineItemList-xKlKC{align-items:center;position:relative}.prc-components-UnderlineItem-7fP-n{appearance:none;background-color:transparent;border:0;border-radius:var(--borderRadius-medium,.375rem);color:var(--fgColor-default,#1f2328);cursor:pointer;display:inline-flex;font:inherit;font-size:var(--text-body-size-medium,.875rem);height:32px;line-height:var(--text-body-lineHeight-medium,1.4285);margin-bottom:var(--base-size-8,.5rem);max-width:100%;padding-block:var(--base-size-6,.375rem);padding-inline:var(--base-size-8,.5rem);text-align:center;-webkit-text-decoration:none;text-decoration:none}@media (hover:hover){.prc-components-UnderlineItem-7fP-n:hover{background-color:var(--bgColor-neutral-muted,#818b981f);-webkit-text-decoration:none;text-decoration:none;transition:background-color .12s ease-out}}.prc-components-UnderlineItem-7fP-n:focus{box-shadow:inset 0 0 0 2px var(--fgColor-accent,#0969da);outline:2px solid transparent}.prc-components-UnderlineItem-7fP-n:focus:not(:focus-visible){box-shadow:none}.prc-components-UnderlineItem-7fP-n:focus-visible{box-shadow:inset 0 0 0 2px var(--fgColor-accent,#0969da);outline:2px solid transparent}.prc-components-UnderlineItem-7fP-n [data-content]:before{content:attr(data-content);display:block;font-weight:var(--base-text-weight-semibold,600);height:0;visibility:hidden;white-space:nowrap}.prc-components-UnderlineItem-7fP-n [data-component=icon]{align-items:center;color:var(--fgColor-muted,#59636e);display:inline-flex;margin-inline-end:var(--base-size-8,.5rem)}.prc-components-UnderlineItem-7fP-n [data-component=text]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.prc-components-UnderlineItem-7fP-n [data-component=counter]{align-items:center;display:flex;margin-inline-start:var(--base-size-8,.5rem)}.prc-components-UnderlineItem-7fP-n:after{background-color:transparent;content:"";height:2px;inset:auto 0 0;margin-bottom:calc(var(--base-size-8,.5rem)*-1);pointer-events:none;position:absolute}.prc-components-UnderlineItem-7fP-n[aria-current]:not([aria-current=false]) [data-component=text],.prc-components-UnderlineItem-7fP-n[aria-selected=true] [data-component=text]{font-weight:var(--base-text-weight-semibold,600)}.prc-components-UnderlineItem-7fP-n[aria-current]:not([aria-current=false]):after,.prc-components-UnderlineItem-7fP-n[aria-selected=true]:after{background-color:var(--underlineNav-borderColor-active,var(--color-primer-border-active,#fd8c73))}@media (forced-colors:active){.prc-components-UnderlineItem-7fP-n[aria-current]:not([aria-current=false]):after,.prc-components-UnderlineItem-7fP-n[aria-selected=true]:after{background-color:LinkText}}.prc-components-LoadingCounter-dBuLy{animation:prc-components-loadingCounterKeyFrames-8tMlf 1.2s ease-in-out infinite alternate;background-color:var(--bgColor-neutral-muted,#818b981f);border-color:var(--borderColor-default,#d1d9e0);border-radius:20px;display:inline-block;height:1rem;width:1.5rem}@keyframes prc-components-loadingCounterKeyFrames-8tMlf{0%{opacity:1}to{opacity:.2}}
2
- /*# sourceMappingURL=UnderlineTabbedInterface-93bd865a.css.map */
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/internal/components/UnderlineTabbedInterface.module.css.js"],"names":[],"mappings":"AAAA,uCAME,sBAAuB,CAOvB,0DAAiD,CAZjD,YAAa,CAIb,0BAA2B,CAI3B,0CAAsC,CAPtC,oCAA+B,CAE/B,+CAgCF,CArBE,2DAEE,oBACF,CAEA,gEAOE,wBAA0B,CAD1B,qBAAsB,CAHtB,0CAAsC,CADtC,eAAgB,CAMhB,kDAOF,CALE,wGACE,WAAY,CACZ,cAAe,CACf,eACF,CAIJ,wCAEE,YAAa,CAMb,oCAA+B,CAF/B,eAAgB,CAFhB,QAAS,CADT,SAAU,CAEV,kBAIF,CAEA,4EAJE,kBAAmB,CANnB,iBAyCF,CA/BA,oCAmBE,eAAgB,CARhB,4BAA6B,CAC7B,QAAS,CACT,gDAAyC,CANzC,oCAA6B,CAG7B,cAAe,CAPf,mBAAoB,CACpB,YAAa,CACb,8CAAuC,CAWvC,WAAY,CAVZ,qDAAuD,CASvD,sCAAiC,CADjC,cAAe,CAOf,wCAAiC,CADjC,uCAAkC,CAZlC,iBAAkB,CAClB,4BAAqB,CAArB,oBAsBF,CAPE,qBACE,0CAEE,uDAA8C,CAD9C,4BAAqB,CAArB,oBAAqB,CAErB,yCACF,CACF,CAGF,0CAGE,wDAAiD,CAFjD,6BAQF,CAHE,8DACE,eACF,CAGF,kDAGE,wDAAiD,CAFjD,6BAGF,CAGA,0DAME,0BAA2B,CAL3B,aAAc,CAEd,gDAA6C,CAD7C,QAAS,CAGT,iBAAkB,CADlB,kBAGF,CAEA,0DAGE,kBAAmB,CADnB,kCAA2B,CAD3B,mBAAoB,CAGpB,0CACF,CAGA,0DACE,eAAgB,CAChB,sBAAuB,CACvB,kBACF,CAEA,6DAGE,kBAAmB,CADnB,YAAa,CADb,4CAGF,CAEA,0CAOE,4BAA6B,CAD7B,UAAW,CAFX,UAAW,CAFX,cAAe,CACf,+CAA4C,CAE5C,mBAAoB,CAJpB,iBAOF,CAEA,gLAEE,gDACF,CAEA,gJAGE,iGAMF,CAJE,8BALF,gJAOI,yBAEJ,CADE,CAGF,qCASE,0FAAsE,CAJtE,uDAA8C,CAC9C,+CAAwC,CAExC,kBAAmB,CAPnB,oBAAqB,CAErB,WAAY,CADZ,YAQF,CAEA,wDACE,GACE,SACF,CAEA,GACE,UACF,CACF","file":"UnderlineTabbedInterface-93bd865a.css","sourcesContent":[".UnderlineWrapper {\n display: flex;\n padding-top: var(--base-size-8);\n /* stylelint-disable-next-line primer/spacing */\n padding-inline: var(--stack-padding-normal);\n justify-content: flex-start;\n align-items: flex-start;\n\n /* make space for the underline */\n min-height: var(--control-xlarge-size);\n\n /* using a box-shadow instead of a border to accommodate 'overflow-y: hidden' on UnderlinePanels */\n /* stylelint-disable-next-line primer/box-shadow */\n box-shadow: inset 0 -1px var(--borderColor-muted);\n\n &[data-variant='flush'] {\n /* stylelint-disable-next-line primer/spacing */\n padding-inline: unset;\n }\n\n &[data-overflow-mode='wrap'] {\n /* Wrap items onto hidden next lines */\n overflow: hidden;\n max-height: var(--control-xlarge-size);\n\n /* Pin the vertical box model so external border/padding overrides can't change the height budget and incorrectly trigger the overflow \"more\" menu */\n box-sizing: border-box;\n border-block: 0 !important;\n padding-block: var(--base-size-8) 0 !important;\n\n .UnderlineItemList {\n flex-grow: 1;\n flex-wrap: wrap;\n overflow: hidden;\n }\n }\n}\n\n.UnderlineItemList {\n position: relative;\n display: flex;\n padding: 0;\n margin: 0;\n white-space: nowrap;\n list-style: none;\n align-items: center;\n gap: var(--stack-gap-condensed);\n}\n\n.UnderlineItem {\n /* underline tab specific styles */\n position: relative;\n display: inline-flex;\n font: inherit;\n font-size: var(--text-body-size-medium);\n line-height: var(--text-body-lineHeight-medium, 1.4285);\n color: var(--fgColor-default);\n text-align: center;\n text-decoration: none;\n cursor: pointer;\n background-color: transparent;\n border: 0;\n border-radius: var(--borderRadius-medium);\n max-width: 100%;\n margin-bottom: var(--base-size-8);\n height: 32px;\n\n /* button resets */\n appearance: none;\n padding-inline: var(--base-size-8);\n padding-block: var(--base-size-6);\n align-items: center;\n\n @media (hover: hover) {\n &:hover {\n text-decoration: none;\n background-color: var(--bgColor-neutral-muted);\n transition: background-color 0.12s ease-out;\n }\n }\n}\n\n.UnderlineItem:focus {\n outline: 2px solid transparent;\n /* stylelint-disable-next-line primer/box-shadow */\n box-shadow: inset 0 0 0 2px var(--fgColor-accent);\n\n /* where focus-visible is supported, remove the focus box-shadow */\n &:not(:focus-visible) {\n box-shadow: none;\n }\n}\n\n.UnderlineItem:focus-visible {\n outline: 2px solid transparent;\n /* stylelint-disable-next-line primer/box-shadow */\n box-shadow: inset 0 0 0 2px var(--fgColor-accent);\n}\n\n/* renders a visibly hidden \"copy\" of the label in bold, reserving box space for when label becomes bold on selected */\n.UnderlineItem [data-content]::before {\n display: block;\n height: 0;\n font-weight: var(--base-text-weight-semibold);\n white-space: nowrap;\n visibility: hidden;\n content: attr(data-content);\n}\n\n.UnderlineItem [data-component='icon'] {\n display: inline-flex;\n color: var(--fgColor-muted);\n align-items: center;\n margin-inline-end: var(--base-size-8);\n}\n\n/* Truncate items if necessary (should only ever apply to the last item after everything else overflows) */\n.UnderlineItem [data-component='text'] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.UnderlineItem [data-component='counter'] {\n margin-inline-start: var(--base-size-8);\n display: flex;\n align-items: center;\n}\n\n.UnderlineItem::after {\n position: absolute;\n inset: auto 0 0;\n margin-bottom: calc(-1 * var(--base-size-8));\n height: 2px;\n pointer-events: none;\n content: '';\n background-color: transparent;\n}\n\n.UnderlineItem[aria-current]:not([aria-current='false']) [data-component='text'],\n.UnderlineItem[aria-selected='true'] [data-component='text'] {\n font-weight: var(--base-text-weight-semibold);\n}\n\n.UnderlineItem[aria-current]:not([aria-current='false'])::after,\n.UnderlineItem[aria-selected='true']::after {\n /* stylelint-disable-next-line primer/colors */\n background-color: var(--underlineNav-borderColor-active, var(--color-primer-border-active, #fd8c73));\n\n @media (forced-colors: active) {\n /* Support for Window Force Color Mode https://learn.microsoft.com/en-us/fluent-ui/web-components/design-system/high-contrast */\n background-color: LinkText;\n }\n}\n\n.LoadingCounter {\n display: inline-block;\n width: 1.5rem;\n height: 1rem;\n /* 16px */\n background-color: var(--bgColor-neutral-muted);\n border-color: var(--borderColor-default);\n /* stylelint-disable-next-line primer/borders */\n border-radius: 20px;\n animation: loadingCounterKeyFrames 1.2s ease-in-out infinite alternate;\n}\n\n@keyframes loadingCounterKeyFrames {\n from {\n opacity: 1;\n }\n\n to {\n opacity: 0.2;\n }\n}\n"]}