@primer/behaviors 0.0.0-20251214172529 → 0.0.0-20251214174237

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.
@@ -269,48 +269,52 @@ function focusZone(container, settings) {
269
269
  if (!preventInitialFocus)
270
270
  updateFocusedElement(initialElement);
271
271
  const observer = new MutationObserver(mutations => {
272
- const elementsToRemove = [];
273
- const elementsToAdd = [];
274
- const attributeRemovals = [];
275
- const attributeAdditions = [];
272
+ const elementsToRemove = new Set();
273
+ const elementsToAdd = new Set();
274
+ const attributeRemovals = new Set();
275
+ const attributeAdditions = new Set();
276
276
  for (const mutation of mutations) {
277
277
  if (mutation.type === 'childList') {
278
278
  for (const removedNode of mutation.removedNodes) {
279
279
  if (removedNode instanceof HTMLElement) {
280
- elementsToRemove.push(removedNode);
280
+ elementsToRemove.add(removedNode);
281
281
  }
282
282
  }
283
283
  for (const addedNode of mutation.addedNodes) {
284
284
  if (addedNode instanceof HTMLElement) {
285
- elementsToAdd.push(addedNode);
285
+ elementsToAdd.add(addedNode);
286
286
  }
287
287
  }
288
288
  }
289
289
  else if (mutation.type === 'attributes' && mutation.target instanceof HTMLElement) {
290
- if (mutation.oldValue === null) {
291
- attributeRemovals.push(mutation.target);
290
+ const attributeName = mutation.attributeName;
291
+ const hasAttribute = attributeName ? mutation.target.hasAttribute(attributeName) : false;
292
+ if (hasAttribute) {
293
+ attributeRemovals.add(mutation.target);
292
294
  }
293
295
  else {
294
- attributeAdditions.push(mutation.target);
296
+ attributeAdditions.add(mutation.target);
295
297
  }
296
298
  }
297
299
  }
298
- if (elementsToRemove.length > 0) {
299
- const toRemove = elementsToRemove.flatMap(node => [...iterateFocusableElements.iterateFocusableElements(node)]);
300
+ if (elementsToRemove.size > 0) {
301
+ const toRemove = [...elementsToRemove].flatMap(node => [...iterateFocusableElements.iterateFocusableElements(node)]);
300
302
  if (toRemove.length > 0) {
301
303
  endFocusManagement(...toRemove);
302
304
  }
303
305
  }
304
- if (attributeRemovals.length > 0) {
306
+ if (attributeRemovals.size > 0) {
305
307
  endFocusManagement(...attributeRemovals);
306
308
  }
307
- if (elementsToAdd.length > 0) {
308
- const toAdd = elementsToAdd.flatMap(node => [...iterateFocusableElements.iterateFocusableElements(node, iterateFocusableElementsOptions)]);
309
+ if (elementsToAdd.size > 0) {
310
+ const toAdd = [...elementsToAdd].flatMap(node => [
311
+ ...iterateFocusableElements.iterateFocusableElements(node, iterateFocusableElementsOptions),
312
+ ]);
309
313
  if (toAdd.length > 0) {
310
314
  beginFocusManagement(...toAdd);
311
315
  }
312
316
  }
313
- if (attributeAdditions.length > 0) {
317
+ if (attributeAdditions.size > 0) {
314
318
  beginFocusManagement(...attributeAdditions);
315
319
  }
316
320
  });
@@ -49,13 +49,14 @@ function isFocusable(elem, strict = false) {
49
49
  const offsetParent = elem.offsetParent;
50
50
  if (offsetWidth === 0 || offsetHeight === 0)
51
51
  return false;
52
- if (!offsetParent)
53
- return false;
54
52
  const style = getComputedStyle(elem);
55
53
  if (style.display === 'none')
56
54
  return false;
57
55
  if (style.visibility === 'hidden' || style.visibility === 'collapse')
58
56
  return false;
57
+ const position = style.position;
58
+ if (!offsetParent && position !== 'fixed' && position !== 'sticky')
59
+ return false;
59
60
  if (elem.getClientRects().length === 0)
60
61
  return false;
61
62
  }
@@ -267,48 +267,52 @@ function focusZone(container, settings) {
267
267
  if (!preventInitialFocus)
268
268
  updateFocusedElement(initialElement);
269
269
  const observer = new MutationObserver(mutations => {
270
- const elementsToRemove = [];
271
- const elementsToAdd = [];
272
- const attributeRemovals = [];
273
- const attributeAdditions = [];
270
+ const elementsToRemove = new Set();
271
+ const elementsToAdd = new Set();
272
+ const attributeRemovals = new Set();
273
+ const attributeAdditions = new Set();
274
274
  for (const mutation of mutations) {
275
275
  if (mutation.type === 'childList') {
276
276
  for (const removedNode of mutation.removedNodes) {
277
277
  if (removedNode instanceof HTMLElement) {
278
- elementsToRemove.push(removedNode);
278
+ elementsToRemove.add(removedNode);
279
279
  }
280
280
  }
281
281
  for (const addedNode of mutation.addedNodes) {
282
282
  if (addedNode instanceof HTMLElement) {
283
- elementsToAdd.push(addedNode);
283
+ elementsToAdd.add(addedNode);
284
284
  }
285
285
  }
286
286
  }
287
287
  else if (mutation.type === 'attributes' && mutation.target instanceof HTMLElement) {
288
- if (mutation.oldValue === null) {
289
- attributeRemovals.push(mutation.target);
288
+ const attributeName = mutation.attributeName;
289
+ const hasAttribute = attributeName ? mutation.target.hasAttribute(attributeName) : false;
290
+ if (hasAttribute) {
291
+ attributeRemovals.add(mutation.target);
290
292
  }
291
293
  else {
292
- attributeAdditions.push(mutation.target);
294
+ attributeAdditions.add(mutation.target);
293
295
  }
294
296
  }
295
297
  }
296
- if (elementsToRemove.length > 0) {
297
- const toRemove = elementsToRemove.flatMap(node => [...iterateFocusableElements(node)]);
298
+ if (elementsToRemove.size > 0) {
299
+ const toRemove = [...elementsToRemove].flatMap(node => [...iterateFocusableElements(node)]);
298
300
  if (toRemove.length > 0) {
299
301
  endFocusManagement(...toRemove);
300
302
  }
301
303
  }
302
- if (attributeRemovals.length > 0) {
304
+ if (attributeRemovals.size > 0) {
303
305
  endFocusManagement(...attributeRemovals);
304
306
  }
305
- if (elementsToAdd.length > 0) {
306
- const toAdd = elementsToAdd.flatMap(node => [...iterateFocusableElements(node, iterateFocusableElementsOptions)]);
307
+ if (elementsToAdd.size > 0) {
308
+ const toAdd = [...elementsToAdd].flatMap(node => [
309
+ ...iterateFocusableElements(node, iterateFocusableElementsOptions),
310
+ ]);
307
311
  if (toAdd.length > 0) {
308
312
  beginFocusManagement(...toAdd);
309
313
  }
310
314
  }
311
- if (attributeAdditions.length > 0) {
315
+ if (attributeAdditions.size > 0) {
312
316
  beginFocusManagement(...attributeAdditions);
313
317
  }
314
318
  });
@@ -47,13 +47,14 @@ function isFocusable(elem, strict = false) {
47
47
  const offsetParent = elem.offsetParent;
48
48
  if (offsetWidth === 0 || offsetHeight === 0)
49
49
  return false;
50
- if (!offsetParent)
51
- return false;
52
50
  const style = getComputedStyle(elem);
53
51
  if (style.display === 'none')
54
52
  return false;
55
53
  if (style.visibility === 'hidden' || style.visibility === 'collapse')
56
54
  return false;
55
+ const position = style.position;
56
+ if (!offsetParent && position !== 'fixed' && position !== 'sticky')
57
+ return false;
57
58
  if (elem.getClientRects().length === 0)
58
59
  return false;
59
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primer/behaviors",
3
- "version": "0.0.0-20251214172529",
3
+ "version": "0.0.0-20251214174237",
4
4
  "description": "Shared behaviors for JavaScript components",
5
5
  "type": "commonjs",
6
6
  "main": "dist/cjs/index.js",