@primer/react 38.22.0-rc.1be1d855e → 38.22.0-rc.5cc83d1b1
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 +2 -2
- package/dist/ActionBar/ActionBar-a41224b2.css +2 -0
- package/dist/ActionBar/ActionBar-a41224b2.css.map +1 -0
- package/dist/ActionBar/ActionBar.d.ts +1 -1
- package/dist/ActionBar/ActionBar.d.ts.map +1 -1
- package/dist/ActionBar/ActionBar.js +379 -292
- package/dist/ActionBar/ActionBar.module.css.js +2 -2
- package/dist/ActionBar/index.d.ts +1 -1
- package/dist/AnchoredOverlay/AnchoredOverlay.d.ts.map +1 -1
- package/dist/AnchoredOverlay/AnchoredOverlay.js +67 -62
- package/dist/hooks/useAnchoredPosition.d.ts +1 -0
- package/dist/hooks/useAnchoredPosition.d.ts.map +1 -1
- package/dist/hooks/useAnchoredPosition.js +8 -4
- package/dist/hooks/useResizeObserver.d.ts +1 -1
- package/dist/hooks/useResizeObserver.d.ts.map +1 -1
- package/dist/hooks/useResizeObserver.js +5 -2
- package/package.json +1 -1
- package/dist/ActionBar/ActionBar-3f7b52a3.css +0 -2
- package/dist/ActionBar/ActionBar-3f7b52a3.css.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import './ActionBar-
|
|
1
|
+
import './ActionBar-a41224b2.css';
|
|
2
2
|
|
|
3
|
-
var styles = {"List":"prc-ActionBar-List-9uz46","
|
|
3
|
+
var styles = {"List":"prc-ActionBar-List-9uz46","Divider":"prc-ActionBar-Divider-6V8yH","Nav":"prc-ActionBar-Nav-9spON","Group":"prc-ActionBar-Group-peNCk"};
|
|
4
4
|
|
|
5
5
|
export { styles as default };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type { ActionBarProps, ActionBarMenuProps, ActionBarMenuItemProps } from './ActionBar';
|
|
2
2
|
declare const ActionBar: import("react").FC<import("react").PropsWithChildren<import("./ActionBar").ActionBarProps>> & {
|
|
3
3
|
IconButton: import("react").ForwardRefExoticComponent<import("./ActionBar").ActionBarIconButtonProps & import("react").RefAttributes<unknown>>;
|
|
4
|
-
Divider: () => import("react").JSX.Element;
|
|
4
|
+
Divider: () => import("react").JSX.Element | null;
|
|
5
5
|
Group: import("react").ForwardRefExoticComponent<{
|
|
6
6
|
children?: import("react").ReactNode | undefined;
|
|
7
7
|
} & import("react").RefAttributes<unknown>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnchoredOverlay.d.ts","sourceRoot":"","sources":["../../src/AnchoredOverlay/AnchoredOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,
|
|
1
|
+
{"version":3,"file":"AnchoredOverlay.d.ts","sourceRoot":"","sources":["../../src/AnchoredOverlay/AnchoredOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAmC,KAAK,GAAG,EAAC,MAAM,OAAO,CAAA;AAChE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,YAAY,CAAA;AAE5C,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,uBAAuB,CAAA;AAEhE,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,uBAAuB,CAAA;AAIhE,OAAO,KAAK,EAAC,cAAc,EAAE,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAC,KAAK,eAAe,EAAC,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAa,KAAK,eAAe,EAAC,MAAM,WAAW,CAAA;AAO1D,UAAU,8BAA8B;IACtC;;;OAGG;IACH,YAAY,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,YAAY,GAAG,iBAAiB,CAAC,EAChG,KAAK,EAAE,CAAC,KACL,GAAG,CAAC,OAAO,CAAA;IAEhB;;OAEG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAE/C;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,UAAU,iCAAiC;IACzC;;;OAGG;IACH,YAAY,EAAE,IAAI,CAAA;IAElB;;;OAGG;IACH,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAC9C;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,iCAAiC,GACzC,OAAO,CAAC,8BAA8B,CAAC,GACvC,iCAAiC,CAAA;AAErC,UAAU,wBAAyB,SAAQ,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC/E;;OAEG;IACH,IAAI,EAAE,OAAO,CAAA;IAEb;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,GAAG,kBAAkB,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,OAAO,CAAA;IAE5G;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,GAAG,eAAe,GAAG,QAAQ,GAAG,OAAO,KAAK,OAAO,CAAA;IAErF;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IAEpC;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAA;IAElD;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAA;IAElD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;OAEG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,YAAY,CAAC,CAAA;IAChE;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,EAAC,QAAQ,EAAC,EAAE;QAAC,QAAQ,EAAE,cAAc,CAAA;KAAC,KAAK,IAAI,CAAA;IACnE;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAA;IAC3C;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;CAChC;AAED,MAAM,MAAM,oBAAoB,GAAG,wBAAwB,GACzD,CAAC,8BAA8B,GAAG,iCAAiC,CAAC,GACpE,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,GAAG,MAAM,GAAG,cAAc,GAAG,iBAAiB,GAAG,mBAAmB,CAAC,CAAC,CAAA;AAS9G;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,CA2PnF,CAAA"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import useIsomorphicLayoutEffect from '../utils/useIsomorphicLayoutEffect.js';
|
|
1
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
3
2
|
import { useFocusTrap } from '../hooks/useFocusTrap.js';
|
|
4
3
|
import { useFocusZone } from '../hooks/useFocusZone.js';
|
|
5
4
|
import { useId } from '../hooks/useId.js';
|
|
@@ -52,13 +51,20 @@ const AnchoredOverlay = ({
|
|
|
52
51
|
renderAs = 'portal'
|
|
53
52
|
}) => {
|
|
54
53
|
const cssAnchorPositioningFlag = useFeatureFlag('primer_react_css_anchor_positioning');
|
|
55
|
-
|
|
56
|
-
//
|
|
57
|
-
const
|
|
54
|
+
// Lazy initial state so feature detection runs once per mount on the client.
|
|
55
|
+
// Guarded for SSR where `document` is undefined.
|
|
56
|
+
const [supportsNativeCSSAnchorPositioning] = useState(() => typeof document !== 'undefined' && 'anchorName' in document.documentElement.style);
|
|
57
|
+
const cssAnchorPositioning = cssAnchorPositioningFlag && supportsNativeCSSAnchorPositioning;
|
|
58
58
|
// Only use Popover API when both CSS anchor positioning is enabled AND renderAs is true
|
|
59
59
|
const shouldRenderAsPopover = cssAnchorPositioning && renderAs === 'popover';
|
|
60
60
|
const anchorRef = useProvidedRefOrCreate(externalAnchorRef);
|
|
61
|
+
const [anchorElement, setAnchorElement] = useState(null);
|
|
62
|
+
// eslint-disable-next-line react-hooks/refs
|
|
63
|
+
if (anchorRef.current !== anchorElement) {
|
|
64
|
+
setAnchorElement(anchorRef.current);
|
|
65
|
+
}
|
|
61
66
|
const [overlayRef, updateOverlayRef] = useRenderForcingRef();
|
|
67
|
+
const [overlayElement, setOverlayElement] = useState(null);
|
|
62
68
|
const anchorId = useId(externalAnchorId);
|
|
63
69
|
const onClickOutside = useCallback(() => onClose === null || onClose === void 0 ? void 0 : onClose('click-outside'), [onClose]);
|
|
64
70
|
const onEscape = useCallback(() => onClose === null || onClose === void 0 ? void 0 : onClose('escape'), [onClose]);
|
|
@@ -70,14 +76,14 @@ const AnchoredOverlay = ({
|
|
|
70
76
|
}
|
|
71
77
|
}
|
|
72
78
|
}, [open, onOpen]);
|
|
73
|
-
const onAnchorClick = useCallback(
|
|
74
|
-
if (
|
|
79
|
+
const onAnchorClick = useCallback(event => {
|
|
80
|
+
if (event.defaultPrevented || event.button !== 0) {
|
|
75
81
|
return;
|
|
76
82
|
}
|
|
77
83
|
// Prevent the browser's native popovertarget toggle so React
|
|
78
84
|
// stays the single source of truth for popover visibility.
|
|
79
85
|
if (cssAnchorPositioning) {
|
|
80
|
-
|
|
86
|
+
event.preventDefault();
|
|
81
87
|
}
|
|
82
88
|
if (!open) {
|
|
83
89
|
onOpen === null || onOpen === void 0 ? void 0 : onOpen('anchor-click');
|
|
@@ -93,7 +99,7 @@ const AnchoredOverlay = ({
|
|
|
93
99
|
}
|
|
94
100
|
};
|
|
95
101
|
const {
|
|
96
|
-
position
|
|
102
|
+
position
|
|
97
103
|
} = useAnchoredPosition({
|
|
98
104
|
anchorElementRef: anchorRef,
|
|
99
105
|
floatingElementRef: overlayRef,
|
|
@@ -103,13 +109,13 @@ const AnchoredOverlay = ({
|
|
|
103
109
|
alignmentOffset,
|
|
104
110
|
anchorOffset,
|
|
105
111
|
displayInViewport,
|
|
106
|
-
onPositionChange: positionChange
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
onPositionChange: positionChange,
|
|
113
|
+
// When native CSS anchor positioning is active, skip JS-based position
|
|
114
|
+
// computation, scroll listeners, and resize observers since the browser
|
|
115
|
+
// handles repositioning natively.
|
|
116
|
+
enabled: !cssAnchorPositioning
|
|
117
|
+
}, [overlayElement]);
|
|
110
118
|
useEffect(() => {
|
|
111
|
-
supportsNativeCSSAnchorPositioning.current = 'anchorName' in document.documentElement.style;
|
|
112
|
-
|
|
113
119
|
// ensure overlay ref gets cleared when closed, so position can reset between closing/re-opening
|
|
114
120
|
if (!open && overlayRef.current) {
|
|
115
121
|
updateOverlayRef(null);
|
|
@@ -117,64 +123,62 @@ const AnchoredOverlay = ({
|
|
|
117
123
|
}, [open, overlayRef, updateOverlayRef]);
|
|
118
124
|
useFocusZone({
|
|
119
125
|
containerRef: overlayRef,
|
|
120
|
-
disabled: !open || !
|
|
126
|
+
disabled: !open || !position && !cssAnchorPositioning,
|
|
121
127
|
...focusZoneSettings
|
|
122
128
|
});
|
|
123
129
|
useFocusTrap({
|
|
124
130
|
containerRef: overlayRef,
|
|
125
|
-
disabled: !open || !
|
|
131
|
+
disabled: !open || !position && !cssAnchorPositioning,
|
|
126
132
|
...focusTrapSettings
|
|
127
133
|
});
|
|
128
134
|
const popoverId = useId();
|
|
129
135
|
const id = popoverId.replaceAll(':', '_'); // popoverId can contain colons which are invalid in CSS custom property names, so we replace them with underscores
|
|
130
136
|
|
|
131
137
|
useEffect(() => {
|
|
132
|
-
if (!cssAnchorPositioning || !
|
|
133
|
-
const anchor = anchorRef.current;
|
|
134
|
-
const overlay = overlayRef.current;
|
|
135
|
-
anchor.style.setProperty('anchor-name', `--anchored-overlay-anchor-${id}`);
|
|
136
|
-
return () => {
|
|
137
|
-
anchor.style.removeProperty('anchor-name');
|
|
138
|
-
if (overlay) {
|
|
139
|
-
overlay.style.removeProperty('position-anchor');
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
// eslint-disable-next-line react-hooks/refs
|
|
143
|
-
}, [cssAnchorPositioning, anchorRef, overlayRef, id, open]);
|
|
144
|
-
|
|
145
|
-
// Track the overlay element so we can re-run the effect when it changes.
|
|
146
|
-
// The overlay unmounts when closed, so each open creates a new DOM node -
|
|
147
|
-
// that needs showPopover() called.
|
|
148
|
-
// eslint-disable-next-line react-hooks/refs
|
|
149
|
-
const overlayElement = overlayRef.current;
|
|
150
|
-
useIsomorphicLayoutEffect(() => {
|
|
151
|
-
// Read ref inside effect to get the value after child refs are attached
|
|
138
|
+
if (!cssAnchorPositioning || !anchorElement) return;
|
|
152
139
|
const currentOverlay = overlayRef.current;
|
|
153
|
-
if (!cssAnchorPositioning || !open || !currentOverlay) return;
|
|
154
|
-
currentOverlay.style.setProperty('position-anchor', `--anchored-overlay-anchor-${id}`);
|
|
155
|
-
const anchorElement = anchorRef.current;
|
|
156
|
-
if (anchorElement) {
|
|
157
|
-
const overlayWidth = width ? parseInt(widthMap[width]) : null;
|
|
158
|
-
const result = getDefaultPosition(anchorElement, overlayWidth);
|
|
159
|
-
currentOverlay.setAttribute('data-align', result.horizontal);
|
|
160
140
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
141
|
+
// Link the anchor and the overlay (when present) via CSS anchor positioning.
|
|
142
|
+
anchorElement.style.setProperty('anchor-name', `--anchored-overlay-anchor-${id}`);
|
|
143
|
+
let pendingPositionFrame = null;
|
|
144
|
+
if (open && currentOverlay) {
|
|
145
|
+
currentOverlay.style.setProperty('position-anchor', `--anchored-overlay-anchor-${id}`);
|
|
146
|
+
|
|
147
|
+
// Defer the getBoundingClientRect read into a `requestAnimationFrame` so the style write above
|
|
148
|
+
// does not force a synchronous layout.
|
|
149
|
+
pendingPositionFrame = requestAnimationFrame(() => {
|
|
150
|
+
pendingPositionFrame = null;
|
|
151
|
+
const overlayWidth = width ? parseInt(widthMap[width]) : null;
|
|
152
|
+
const result = getDefaultPosition(anchorElement, overlayWidth);
|
|
153
|
+
currentOverlay.setAttribute('data-align', result.horizontal);
|
|
154
|
+
|
|
155
|
+
// Apply offset only when viewport is too narrow
|
|
156
|
+
const offset = result.horizontal === 'left' ? result.leftOffset : result.rightOffset;
|
|
157
|
+
currentOverlay.style.setProperty(`--anchored-overlay-anchor-offset-${result.horizontal}`, `${offset || 0}px`);
|
|
158
|
+
});
|
|
165
159
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
160
|
+
// Only call showPopover when shouldRenderAsPopover is enabled
|
|
161
|
+
if (shouldRenderAsPopover) {
|
|
162
|
+
try {
|
|
163
|
+
if (!currentOverlay.matches(':popover-open')) {
|
|
164
|
+
currentOverlay.showPopover();
|
|
165
|
+
}
|
|
166
|
+
} catch {
|
|
167
|
+
// Ignore if popover is already showing or not supported
|
|
171
168
|
}
|
|
172
|
-
} catch {
|
|
173
|
-
// Ignore if popover is already showing or not supported
|
|
174
169
|
}
|
|
175
170
|
}
|
|
176
|
-
|
|
177
|
-
|
|
171
|
+
return () => {
|
|
172
|
+
if (pendingPositionFrame !== null) cancelAnimationFrame(pendingPositionFrame);
|
|
173
|
+
anchorElement.style.removeProperty('anchor-name');
|
|
174
|
+
// The overlay may no longer be in the DOM at this point, so we need to check for its presence before trying to update it.
|
|
175
|
+
if (currentOverlay) {
|
|
176
|
+
currentOverlay.style.removeProperty('position-anchor');
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
// overlayRef is a stable ref object; including it in deps is unnecessary.
|
|
180
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
181
|
+
}, [cssAnchorPositioning, shouldRenderAsPopover, open, anchorElement, overlayElement, id, width]);
|
|
178
182
|
const showXIcon = onClose && variant.narrow === 'fullscreen' && displayCloseButton;
|
|
179
183
|
const XButtonAriaLabelledBy = closeButtonProps['aria-labelledby'];
|
|
180
184
|
const XButtonAriaLabel = closeButtonProps['aria-label'];
|
|
@@ -203,13 +207,13 @@ const AnchoredOverlay = ({
|
|
|
203
207
|
ignoreClickRefs: [anchorRef],
|
|
204
208
|
onEscape: onEscape,
|
|
205
209
|
role: "none",
|
|
206
|
-
visibility: cssAnchorPositioning ||
|
|
210
|
+
visibility: cssAnchorPositioning || position ? 'visible' : 'hidden',
|
|
207
211
|
height: height,
|
|
208
212
|
width: width,
|
|
209
|
-
top: cssAnchorPositioning ? undefined : (
|
|
210
|
-
left: cssAnchorPositioning ? undefined : (
|
|
213
|
+
top: cssAnchorPositioning ? undefined : (position === null || position === void 0 ? void 0 : position.top) || 0,
|
|
214
|
+
left: cssAnchorPositioning ? undefined : (position === null || position === void 0 ? void 0 : position.left) || 0,
|
|
211
215
|
responsiveVariant: variant.narrow === 'fullscreen' ? 'fullscreen' : undefined,
|
|
212
|
-
anchorSide: cssAnchorPositioning ? undefined :
|
|
216
|
+
anchorSide: cssAnchorPositioning ? undefined : position === null || position === void 0 ? void 0 : position.anchorSide,
|
|
213
217
|
className: clsx(className, overlayClassName, cssAnchorPositioning ? classes.AnchoredOverlay : undefined),
|
|
214
218
|
preventOverflow: preventOverflow,
|
|
215
219
|
"data-component": "AnchoredOverlay",
|
|
@@ -226,9 +230,10 @@ const AnchoredOverlay = ({
|
|
|
226
230
|
assignRef(overlayProps.ref, node);
|
|
227
231
|
}
|
|
228
232
|
updateOverlayRef(node);
|
|
233
|
+
setOverlayElement(node);
|
|
229
234
|
},
|
|
230
235
|
"data-anchor-position": cssAnchorPositioning,
|
|
231
|
-
"data-side": cssAnchorPositioning ? side :
|
|
236
|
+
"data-side": cssAnchorPositioning ? side : position === null || position === void 0 ? void 0 : position.anchorSide,
|
|
232
237
|
children: [showXIcon ? /*#__PURE__*/jsx("div", {
|
|
233
238
|
className: classes.ResponsiveCloseButtonContainer,
|
|
234
239
|
children: /*#__PURE__*/jsx(IconButton, {
|
|
@@ -5,6 +5,7 @@ export interface AnchoredPositionHookSettings extends Partial<PositionSettings>
|
|
|
5
5
|
anchorElementRef?: React.RefObject<Element | null>;
|
|
6
6
|
pinPosition?: boolean;
|
|
7
7
|
onPositionChange?: (position: AnchorPosition | undefined) => void;
|
|
8
|
+
enabled?: boolean;
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
10
11
|
* Calculates the top and left values for an absolutely-positioned floating element
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAnchoredPosition.d.ts","sourceRoot":"","sources":["../../src/hooks/useAnchoredPosition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAC,cAAc,EAAE,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AA0BvE,MAAM,WAAW,4BAA6B,SAAQ,OAAO,CAAC,gBAAgB,CAAC;IAC7E,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IACpD,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IAClD,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,KAAK,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"useAnchoredPosition.d.ts","sourceRoot":"","sources":["../../src/hooks/useAnchoredPosition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAC,cAAc,EAAE,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AA0BvE,MAAM,WAAW,4BAA6B,SAAQ,OAAO,CAAC,gBAAgB,CAAC;IAC7E,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IACpD,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IAClD,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,KAAK,IAAI,CAAA;IACjE,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,CAAC,EAAE,4BAA4B,EACvC,YAAY,GAAE,KAAK,CAAC,cAAmB,GACtC;IACD,kBAAkB,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IACnD,gBAAgB,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IACjD,QAAQ,EAAE,cAAc,GAAG,SAAS,CAAA;CACrC,CAiIA"}
|
|
@@ -34,8 +34,10 @@ function getScrollableAncestors(element) {
|
|
|
34
34
|
* floating element.
|
|
35
35
|
*/
|
|
36
36
|
function useAnchoredPosition(settings, dependencies = []) {
|
|
37
|
+
var _settings$enabled;
|
|
37
38
|
const floatingElementRef = useProvidedRefOrCreate(settings === null || settings === void 0 ? void 0 : settings.floatingElementRef);
|
|
38
39
|
const anchorElementRef = useProvidedRefOrCreate(settings === null || settings === void 0 ? void 0 : settings.anchorElementRef);
|
|
40
|
+
const enabled = (_settings$enabled = settings === null || settings === void 0 ? void 0 : settings.enabled) !== null && _settings$enabled !== void 0 ? _settings$enabled : true;
|
|
39
41
|
const savedOnPositionChange = React.useRef(settings === null || settings === void 0 ? void 0 : settings.onPositionChange);
|
|
40
42
|
const [position, setPosition] = React.useState(undefined);
|
|
41
43
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -62,6 +64,7 @@ function useAnchoredPosition(settings, dependencies = []) {
|
|
|
62
64
|
};
|
|
63
65
|
const updatePosition = React.useCallback(() => {
|
|
64
66
|
var _floatingElementRef$c5;
|
|
67
|
+
if (!enabled) return;
|
|
65
68
|
if (floatingElementRef.current instanceof Element && anchorElementRef.current instanceof Element) {
|
|
66
69
|
const newPosition = getAnchoredPosition(floatingElementRef.current, anchorElementRef.current, settings);
|
|
67
70
|
setPosition(prev => {
|
|
@@ -88,7 +91,7 @@ function useAnchoredPosition(settings, dependencies = []) {
|
|
|
88
91
|
setPrevHeight((_floatingElementRef$c5 = floatingElementRef.current) === null || _floatingElementRef$c5 === void 0 ? void 0 : _floatingElementRef$c5.clientHeight);
|
|
89
92
|
},
|
|
90
93
|
// eslint-disable-next-line react-hooks/exhaustive-deps, react-hooks/use-memo
|
|
91
|
-
[floatingElementRef, anchorElementRef, ...dependencies]);
|
|
94
|
+
[floatingElementRef, anchorElementRef, enabled, ...dependencies]);
|
|
92
95
|
useIsomorphicLayoutEffect(() => {
|
|
93
96
|
savedOnPositionChange.current = settings === null || settings === void 0 ? void 0 : settings.onPositionChange;
|
|
94
97
|
}, [settings === null || settings === void 0 ? void 0 : settings.onPositionChange]);
|
|
@@ -111,12 +114,13 @@ function useAnchoredPosition(settings, dependencies = []) {
|
|
|
111
114
|
updatePosition();
|
|
112
115
|
}
|
|
113
116
|
}, [updatePosition]);
|
|
114
|
-
useResizeObserver(updatePosition); // watches for changes in window size
|
|
115
|
-
useResizeObserver(updatePosition, floatingElementRef); // watches for changes in floating element size
|
|
117
|
+
useResizeObserver(updatePosition, undefined, [], enabled); // watches for changes in window size
|
|
118
|
+
useResizeObserver(updatePosition, floatingElementRef, [], enabled); // watches for changes in floating element size
|
|
116
119
|
|
|
117
120
|
// Recalculate position when any scrollable ancestor of the anchor scrolls.
|
|
118
121
|
// Uses requestAnimationFrame to avoid layout thrashing during scroll.
|
|
119
122
|
React.useEffect(() => {
|
|
123
|
+
if (!enabled) return;
|
|
120
124
|
const anchorEl = anchorElementRef.current;
|
|
121
125
|
if (!anchorEl) return;
|
|
122
126
|
let rafId = null;
|
|
@@ -140,7 +144,7 @@ function useAnchoredPosition(settings, dependencies = []) {
|
|
|
140
144
|
cancelAnimationFrame(rafId);
|
|
141
145
|
}
|
|
142
146
|
};
|
|
143
|
-
}, [anchorElementRef, updatePosition]);
|
|
147
|
+
}, [anchorElementRef, updatePosition, enabled]);
|
|
144
148
|
return {
|
|
145
149
|
floatingElementRef,
|
|
146
150
|
anchorElementRef,
|
|
@@ -3,5 +3,5 @@ export type ResizeObserverCallback = (entries: ResizeObserverEntry[]) => void;
|
|
|
3
3
|
export interface ResizeObserverEntry {
|
|
4
4
|
contentRect: DOMRectReadOnly;
|
|
5
5
|
}
|
|
6
|
-
export declare function useResizeObserver<T extends HTMLElement>(callback: ResizeObserverCallback, target?: RefObject<T | null>, depsArray?: unknown[]): void;
|
|
6
|
+
export declare function useResizeObserver<T extends HTMLElement>(callback: ResizeObserverCallback, target?: RefObject<T | null>, depsArray?: unknown[], enabled?: boolean): void;
|
|
7
7
|
//# sourceMappingURL=useResizeObserver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useResizeObserver.d.ts","sourceRoot":"","sources":["../../src/hooks/useResizeObserver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAA;AAKpC,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,IAAI,CAAA;AAE7E,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,eAAe,CAAA;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,WAAW,EACrD,QAAQ,EAAE,sBAAsB,EAChC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,EAC5B,SAAS,GAAE,OAAO,EAAO,
|
|
1
|
+
{"version":3,"file":"useResizeObserver.d.ts","sourceRoot":"","sources":["../../src/hooks/useResizeObserver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAA;AAKpC,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,IAAI,CAAA;AAE7E,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,eAAe,CAAA;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,WAAW,EACrD,QAAQ,EAAE,sBAAsB,EAChC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,EAC5B,SAAS,GAAE,OAAO,EAAO,EACzB,OAAO,GAAE,OAAc,QAmDxB"}
|
|
@@ -3,13 +3,16 @@ import useIsomorphicLayoutEffect from '../utils/useIsomorphicLayoutEffect.js';
|
|
|
3
3
|
|
|
4
4
|
// https://gist.github.com/strothj/708afcf4f01dd04de8f49c92e88093c3
|
|
5
5
|
|
|
6
|
-
function useResizeObserver(callback, target, depsArray = []) {
|
|
6
|
+
function useResizeObserver(callback, target, depsArray = [], enabled = true) {
|
|
7
7
|
const [targetClientRect, setTargetClientRect] = useState(null);
|
|
8
8
|
const savedCallback = useRef(callback);
|
|
9
9
|
useIsomorphicLayoutEffect(() => {
|
|
10
10
|
savedCallback.current = callback;
|
|
11
11
|
});
|
|
12
12
|
useIsomorphicLayoutEffect(() => {
|
|
13
|
+
if (!enabled) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
13
16
|
const targetEl = target && 'current' in target ? target.current : document.documentElement;
|
|
14
17
|
if (!targetEl) {
|
|
15
18
|
return;
|
|
@@ -40,7 +43,7 @@ function useResizeObserver(callback, target, depsArray = []) {
|
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
43
|
-
}, [target === null || target === void 0 ? void 0 : target.current, ...depsArray]);
|
|
46
|
+
}, [target === null || target === void 0 ? void 0 : target.current, enabled, ...depsArray]);
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
export { useResizeObserver };
|
package/package.json
CHANGED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
.prc-ActionBar-List-9uz46{align-items:flex-start;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}.prc-ActionBar-List-9uz46:not([data-has-overflow]){animation:prc-ActionBar-detect-overflow-mAuJu linear;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-MoreButton-RHqpx{display:var(--morebutton-display,none)}
|
|
2
|
-
/*# sourceMappingURL=ActionBar-3f7b52a3.css.map */
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ActionBar/ActionBar.module.css.js"],"names":[],"mappings":"AAAA,0BASE,sBAAuB,CAPvB,YAAa,CAQb,yDAAqD,CAGrD,gEAA0D,CAL1D,eAAgB,CADhB,kBAAmB,CAJnB,WAAY,CAQZ,eAAgB,CAVhB,iBA2DF,CA5CE,mDAIE,oDAAiC,CACjC,qCACF,CAGA,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,WASF,CANA,uCAEE,cAAe,CAEf,wBAAyB,CACzB,eACF,CAEA,gCACE,sCACF","file":"ActionBar-3f7b52a3.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 /* Only apply scroll animation before overflow is calculated (for SSR/initial render) */\n &:not([data-has-overflow]) {\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\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\n.MoreButton {\n display: var(--morebutton-display, none);\n}\n"]}
|