@primer/react 38.31.0-rc.f96563b64 → 38.31.1-rc.43134a516

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.
@@ -0,0 +1,157 @@
1
+ import useIsomorphicLayoutEffect from "../../utils/useIsomorphicLayoutEffect.js";
2
+ import { OverflowObserverContext } from "../hooks/useOverflowObserver.js";
3
+ import { c } from "react-compiler-runtime";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { useEffect, useRef } from "react";
6
+ //#region src/internal/components/OverflowObserverProvider.tsx
7
+ /**
8
+ * Owns a single `IntersectionObserver` shared by every descendant that calls `useIsClipped`, instead of each item
9
+ * creating its own observer. Each observed element maps to a set of change callbacks; one observer notification fans
10
+ * out to all of them.
11
+ *
12
+ * `rootRef` must point to the element that clips overflowing children (typically a single-row, `overflow: hidden`
13
+ * container). The observer is root-scoped to that element so children that wrap onto a clipped row are reported as
14
+ * overflowing. Until the root is attached the provider stays inert (it never falls back to the viewport, which would
15
+ * not reflect the container's clipping) and re-checks on later renders.
16
+ */
17
+ function OverflowObserverProvider(t0) {
18
+ const $ = c(15);
19
+ const { children, rootRef } = t0;
20
+ let t1;
21
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
22
+ t1 = /* @__PURE__ */ new Map();
23
+ $[0] = t1;
24
+ } else t1 = $[0];
25
+ const subscribersRef = useRef(t1);
26
+ let t2;
27
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
28
+ t2 = /* @__PURE__ */ new Set();
29
+ $[1] = t2;
30
+ } else t2 = $[1];
31
+ const observedElementsRef = useRef(t2);
32
+ const observerRef = useRef(null);
33
+ const observerRootRef = useRef(null);
34
+ let t3;
35
+ if ($[2] !== rootRef) {
36
+ t3 = () => {
37
+ var _observerRef$current;
38
+ if (!supportsIntersectionObserver()) return null;
39
+ const root = rootRef.current;
40
+ if (root === null) return null;
41
+ if (observerRef.current && observerRootRef.current === root) return observerRef.current;
42
+ (_observerRef$current = observerRef.current) === null || _observerRef$current === void 0 || _observerRef$current.disconnect();
43
+ observedElementsRef.current.clear();
44
+ observerRef.current = new IntersectionObserver((entries) => {
45
+ for (const entry of entries) {
46
+ const callbacks = subscribersRef.current.get(entry.target);
47
+ if (!callbacks) continue;
48
+ const isOverflowing = getIsOverflowing(entry);
49
+ for (const cb of callbacks) cb(isOverflowing);
50
+ }
51
+ }, {
52
+ root,
53
+ threshold: [0, 1]
54
+ });
55
+ observerRootRef.current = root;
56
+ return observerRef.current;
57
+ };
58
+ $[2] = rootRef;
59
+ $[3] = t3;
60
+ } else t3 = $[3];
61
+ const getObserver = t3;
62
+ let t4;
63
+ if ($[4] !== getObserver) {
64
+ t4 = () => {
65
+ const observer = getObserver();
66
+ if (!observer) return;
67
+ for (const element of subscribersRef.current.keys()) if (!observedElementsRef.current.has(element)) {
68
+ observer.observe(element);
69
+ observedElementsRef.current.add(element);
70
+ }
71
+ };
72
+ $[4] = getObserver;
73
+ $[5] = t4;
74
+ } else t4 = $[5];
75
+ const observeSubscribedElements = t4;
76
+ let t5;
77
+ if ($[6] !== observeSubscribedElements) {
78
+ t5 = (element_0, onOverflowChange) => {
79
+ let callbacks_0 = subscribersRef.current.get(element_0);
80
+ if (!callbacks_0) {
81
+ callbacks_0 = /* @__PURE__ */ new Set();
82
+ subscribersRef.current.set(element_0, callbacks_0);
83
+ }
84
+ callbacks_0.add(onOverflowChange);
85
+ observeSubscribedElements();
86
+ return () => {
87
+ const set = subscribersRef.current.get(element_0);
88
+ if (!set) return;
89
+ set.delete(onOverflowChange);
90
+ if (set.size === 0) {
91
+ var _observerRef$current2;
92
+ subscribersRef.current.delete(element_0);
93
+ observedElementsRef.current.delete(element_0);
94
+ (_observerRef$current2 = observerRef.current) === null || _observerRef$current2 === void 0 || _observerRef$current2.unobserve(element_0);
95
+ }
96
+ };
97
+ };
98
+ $[6] = observeSubscribedElements;
99
+ $[7] = t5;
100
+ } else t5 = $[7];
101
+ const observe = t5;
102
+ let t6;
103
+ if ($[8] !== observeSubscribedElements) {
104
+ t6 = () => {
105
+ observeSubscribedElements();
106
+ };
107
+ $[8] = observeSubscribedElements;
108
+ $[9] = t6;
109
+ } else t6 = $[9];
110
+ useIsomorphicLayoutEffect(t6);
111
+ let t7;
112
+ let t8;
113
+ if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
114
+ t7 = () => {
115
+ const subscribers = subscribersRef.current;
116
+ const observedElements = observedElementsRef.current;
117
+ return () => {
118
+ var _observerRef$current3;
119
+ (_observerRef$current3 = observerRef.current) === null || _observerRef$current3 === void 0 || _observerRef$current3.disconnect();
120
+ observerRef.current = null;
121
+ observedElements.clear();
122
+ subscribers.clear();
123
+ };
124
+ };
125
+ t8 = [];
126
+ $[10] = t7;
127
+ $[11] = t8;
128
+ } else {
129
+ t7 = $[10];
130
+ t8 = $[11];
131
+ }
132
+ useEffect(t7, t8);
133
+ let t9;
134
+ if ($[12] !== children || $[13] !== observe) {
135
+ t9 = /*#__PURE__*/ jsx(OverflowObserverContext.Provider, {
136
+ value: observe,
137
+ children
138
+ });
139
+ $[12] = children;
140
+ $[13] = observe;
141
+ $[14] = t9;
142
+ } else t9 = $[14];
143
+ return t9;
144
+ }
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.
149
+ */
150
+ function getIsOverflowing(entry) {
151
+ return !entry.isIntersecting || entry.intersectionRatio < 1;
152
+ }
153
+ function supportsIntersectionObserver() {
154
+ return typeof IntersectionObserver !== "undefined";
155
+ }
156
+ //#endregion
157
+ export { OverflowObserverProvider };
@@ -0,0 +1,57 @@
1
+ import { c } from "react-compiler-runtime";
2
+ import { createContext, useContext, useRef, useSyncExternalStore } from "react";
3
+ //#region src/internal/hooks/useOverflowObserver.ts
4
+ /** Subscribe a single observed element to the shared `IntersectionObserver`. Returns an unsubscribe function. */
5
+ /** Provided by `OverflowObserverProvider`; `null` when no provider is present. Consumed via `useIsClipped`. */
6
+ const OverflowObserverContext = /*#__PURE__*/ createContext(null);
7
+ /**
8
+ * Track whether `ref`'s element is currently clipped (overflowing) by the nearest `OverflowObserverProvider`'s
9
+ * root-scoped `IntersectionObserver`.
10
+ *
11
+ * Returns `false` when there is no surrounding provider, during SSR, when `IntersectionObserver` is unavailable, or when
12
+ * `disabled` is set.
13
+ *
14
+ * @param ref Ref to the element whose overflow state should be tracked.
15
+ * @param options.disabled When true, skips observer subscription entirely and always reports `false`. Useful for items
16
+ * whose overflow is determined by an ancestor (e.g. ActionBar items inside an overflowing group).
17
+ */
18
+ function useIsClipped(ref, options) {
19
+ var _options$disabled;
20
+ const $ = c(6);
21
+ const disabled = (_options$disabled = options === null || options === void 0 ? void 0 : options.disabled) !== null && _options$disabled !== void 0 ? _options$disabled : false;
22
+ const observe = useContext(OverflowObserverContext);
23
+ const isOverflowingRef = useRef(false);
24
+ let t0;
25
+ if ($[0] !== disabled || $[1] !== observe || $[2] !== ref) {
26
+ t0 = (onChange) => {
27
+ if (disabled) return _temp;
28
+ const element = ref.current;
29
+ if (!element || observe === null) return _temp2;
30
+ const updateOverflowState = (isOverflowing) => {
31
+ if (isOverflowing !== isOverflowingRef.current) {
32
+ isOverflowingRef.current = isOverflowing;
33
+ onChange();
34
+ }
35
+ };
36
+ return observe(element, updateOverflowState);
37
+ };
38
+ $[0] = disabled;
39
+ $[1] = observe;
40
+ $[2] = ref;
41
+ $[3] = t0;
42
+ } else t0 = $[3];
43
+ const subscribe = t0;
44
+ let t1;
45
+ if ($[4] !== disabled) {
46
+ t1 = () => disabled ? false : isOverflowingRef.current;
47
+ $[4] = disabled;
48
+ $[5] = t1;
49
+ } else t1 = $[5];
50
+ return useSyncExternalStore(subscribe, t1, getOverflowServerSnapshot);
51
+ }
52
+ /** Stable server snapshot for `useIsClipped`: overflow is never measured during SSR. */
53
+ function _temp2() {}
54
+ function _temp() {}
55
+ const getOverflowServerSnapshot = () => false;
56
+ //#endregion
57
+ export { OverflowObserverContext, useIsClipped };
@@ -89,25 +89,57 @@ function createDescendantRegistry() {
89
89
  const unsetValue = Symbol("unset");
90
90
  /** Provide context for registering descendant components. This only needs to wrap `children`. */
91
91
  function Provider(t0) {
92
- const $ = c(14);
92
+ const $ = c(17);
93
93
  const { children, setRegistry } = t0;
94
94
  const workingRegistryRef = useRef("queued");
95
95
  const [key, rebuildRegistry] = useReducer(_temp, 0);
96
+ const pendingRebuildRef = useRef(false);
97
+ const isMountedRef = useRef(true);
96
98
  let t1;
97
99
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
98
- t1 = function instantiateNewRegistry() {
99
- if (workingRegistryRef.current === "queued") workingRegistryRef.current = /* @__PURE__ */ new Map();
100
+ t1 = () => {
101
+ if (pendingRebuildRef.current) return;
102
+ pendingRebuildRef.current = true;
103
+ scheduleMicrotask(() => {
104
+ pendingRebuildRef.current = false;
105
+ if (isMountedRef.current) rebuildRegistry();
106
+ });
100
107
  };
101
108
  $[0] = t1;
102
109
  } else t1 = $[0];
103
- useIsomorphicLayoutEffect(t1);
110
+ const scheduleRebuild = t1;
104
111
  let t2;
105
- if ($[1] !== setRegistry) {
106
- t2 = (id) => {
112
+ let t3;
113
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
114
+ t2 = () => {
115
+ isMountedRef.current = true;
116
+ return () => {
117
+ isMountedRef.current = false;
118
+ };
119
+ };
120
+ t3 = [];
121
+ $[1] = t2;
122
+ $[2] = t3;
123
+ } else {
124
+ t2 = $[1];
125
+ t3 = $[2];
126
+ }
127
+ useEffect(t2, t3);
128
+ let t4;
129
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
130
+ t4 = function instantiateNewRegistry() {
131
+ if (workingRegistryRef.current === "queued") workingRegistryRef.current = /* @__PURE__ */ new Map();
132
+ };
133
+ $[3] = t4;
134
+ } else t4 = $[3];
135
+ useIsomorphicLayoutEffect(t4);
136
+ let t5;
137
+ if ($[4] !== setRegistry) {
138
+ t5 = (id) => {
107
139
  if (workingRegistryRef.current instanceof Map) workingRegistryRef.current.set(id, unsetValue);
108
140
  else if (workingRegistryRef.current === "idle") {
109
141
  workingRegistryRef.current = "queued";
110
- rebuildRegistry();
142
+ scheduleRebuild();
111
143
  }
112
144
  return function unregister() {
113
145
  if (workingRegistryRef.current instanceof Map) workingRegistryRef.current.delete(id);
@@ -118,57 +150,57 @@ function createDescendantRegistry() {
118
150
  });
119
151
  };
120
152
  };
121
- $[1] = setRegistry;
122
- $[2] = t2;
123
- } else t2 = $[2];
124
- const register = t2;
125
- let t3;
126
- if ($[3] !== setRegistry) {
127
- t3 = (id_0, value) => {
153
+ $[4] = setRegistry;
154
+ $[5] = t5;
155
+ } else t5 = $[5];
156
+ const register = t5;
157
+ let t6;
158
+ if ($[6] !== setRegistry) {
159
+ t6 = (id_0, value) => {
128
160
  if (workingRegistryRef.current instanceof Map) workingRegistryRef.current.set(id_0, value);
129
161
  else if (workingRegistryRef.current === "idle") setRegistry((prev_1) => new Map(prev_1).set(id_0, value));
130
162
  };
131
- $[3] = setRegistry;
132
- $[4] = t3;
133
- } else t3 = $[4];
134
- const updateValue = t3;
135
- let t4;
136
- if ($[5] !== setRegistry) {
137
- t4 = function commitWorkingRegistry() {
163
+ $[6] = setRegistry;
164
+ $[7] = t6;
165
+ } else t6 = $[7];
166
+ const updateValue = t6;
167
+ let t7;
168
+ if ($[8] !== setRegistry) {
169
+ t7 = function commitWorkingRegistry() {
138
170
  if (workingRegistryRef.current instanceof Map) {
139
171
  const setEntries = Array.from(workingRegistryRef.current.entries()).filter(_temp2);
140
172
  setRegistry(new Map(setEntries));
141
173
  workingRegistryRef.current = "idle";
142
174
  }
143
175
  };
144
- $[5] = setRegistry;
145
- $[6] = t4;
146
- } else t4 = $[6];
147
- useEffect(t4);
148
- let t5;
149
- if ($[7] !== key || $[8] !== register || $[9] !== updateValue) {
150
- t5 = {
176
+ $[8] = setRegistry;
177
+ $[9] = t7;
178
+ } else t7 = $[9];
179
+ useEffect(t7);
180
+ let t8;
181
+ if ($[10] !== key || $[11] !== register || $[12] !== updateValue) {
182
+ t8 = {
151
183
  register,
152
184
  updateValue,
153
185
  key
154
186
  };
155
- $[7] = key;
156
- $[8] = register;
157
- $[9] = updateValue;
158
- $[10] = t5;
159
- } else t5 = $[10];
160
- const contextValue = t5;
161
- let t6;
162
- if ($[11] !== children || $[12] !== contextValue) {
163
- t6 = /*#__PURE__*/ jsx(Context.Provider, {
187
+ $[10] = key;
188
+ $[11] = register;
189
+ $[12] = updateValue;
190
+ $[13] = t8;
191
+ } else t8 = $[13];
192
+ const contextValue = t8;
193
+ let t9;
194
+ if ($[14] !== children || $[15] !== contextValue) {
195
+ t9 = /*#__PURE__*/ jsx(Context.Provider, {
164
196
  value: contextValue,
165
197
  children
166
198
  });
167
- $[11] = children;
168
- $[12] = contextValue;
169
- $[13] = t6;
170
- } else t6 = $[13];
171
- return t6;
199
+ $[14] = children;
200
+ $[15] = contextValue;
201
+ $[16] = t9;
202
+ } else t9 = $[16];
203
+ return t9;
172
204
  }
173
205
  function _temp2(entry) {
174
206
  return entry[1] !== unsetValue;
@@ -182,5 +214,10 @@ function createDescendantRegistry() {
182
214
  useRegisterDescendant
183
215
  };
184
216
  }
217
+ /** Schedule a callback on a microtask, with a fallback for environments that lack `queueMicrotask`. */
218
+ function scheduleMicrotask(callback) {
219
+ if (typeof queueMicrotask === "function") queueMicrotask(callback);
220
+ else setTimeout(callback);
221
+ }
185
222
  //#endregion
186
223
  export { createDescendantRegistry };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@primer/react",
3
3
  "type": "module",
4
- "version": "38.31.0-rc.f96563b64",
4
+ "version": "38.31.1-rc.43134a516",
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",