@primer/behaviors 0.0.0-20251203212431 → 0.0.0-20251203213711

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/README.md CHANGED
@@ -7,10 +7,10 @@ Shared behaviors for JavaScript components
7
7
 
8
8
  ## Documentation
9
9
 
10
- - [Anchored Position](/docs/anchored-position.md)
11
- - [Focus Trap](/docs/focus-trap.md)
12
- - [Focus Zone](/docs/focus-zone.md)
13
- - [Scroll Into View](/docs/scroll-into-view.md)
10
+ * [Anchored Position](/docs/anchored-position.md)
11
+ * [Focus Trap](/docs/focus-trap.md)
12
+ * [Focus Zone](/docs/focus-zone.md)
13
+ * [Scroll Into View](/docs/scroll-into-view.md)
14
14
 
15
15
  ## Installation
16
16
 
@@ -18,14 +18,8 @@ Shared behaviors for JavaScript components
18
18
  npm install @primer/behaviors
19
19
  ```
20
20
 
21
- or
21
+ or
22
22
 
23
23
  ```bash
24
24
  yarn add @primer/behaviors
25
25
  ```
26
-
27
- ## Storybook
28
-
29
- ```bash
30
- npm run storybook
31
- ```
@@ -25,8 +25,9 @@ export type FocusZoneSettings = IterateFocusableElements & {
25
25
  abortSignal?: AbortSignal;
26
26
  activeDescendantControl?: HTMLElement;
27
27
  onActiveDescendantChanged?: (newActiveDescendant: HTMLElement | undefined, previousActiveDescendant: HTMLElement | undefined, directlyActivated: boolean) => void;
28
- focusInStrategy?: 'first' | 'closest' | 'previous' | 'initial' | ((previousFocusedElement: Element) => HTMLElement | undefined);
28
+ focusInStrategy?: 'first' | 'closest' | 'previous' | ((previousFocusedElement: Element) => HTMLElement | undefined);
29
29
  preventScroll?: boolean;
30
+ ignoreHoverEvents?: boolean;
30
31
  };
31
32
  export declare const isActiveDescendantAttribute = "data-is-active-descendant";
32
33
  export declare const activeDescendantActivatedDirectly = "activated-directly";
@@ -129,7 +129,7 @@ const activeDescendantActivatedDirectly = 'activated-directly';
129
129
  const activeDescendantActivatedIndirectly = 'activated-indirectly';
130
130
  const hasActiveDescendantAttribute = 'data-has-active-descendant';
131
131
  function focusZone(container, settings) {
132
- var _a, _b, _c, _d, _e;
132
+ var _a, _b, _c, _d, _e, _f;
133
133
  const focusableElements = [];
134
134
  const savedTabIndex = new WeakMap();
135
135
  const bindKeys = (_a = settings === null || settings === void 0 ? void 0 : settings.bindKeys) !== null && _a !== void 0 ? _a : ((settings === null || settings === void 0 ? void 0 : settings.getNextFocusable) ? exports.FocusKeys.ArrowAll : exports.FocusKeys.ArrowVertical) | exports.FocusKeys.HomeAndEnd;
@@ -137,9 +137,9 @@ function focusZone(container, settings) {
137
137
  const focusInStrategy = (_c = settings === null || settings === void 0 ? void 0 : settings.focusInStrategy) !== null && _c !== void 0 ? _c : 'previous';
138
138
  const activeDescendantControl = settings === null || settings === void 0 ? void 0 : settings.activeDescendantControl;
139
139
  const activeDescendantCallback = settings === null || settings === void 0 ? void 0 : settings.onActiveDescendantChanged;
140
+ const ignoreHoverEvents = (_d = settings === null || settings === void 0 ? void 0 : settings.ignoreHoverEvents) !== null && _d !== void 0 ? _d : false;
140
141
  let currentFocusedElement;
141
- const preventScroll = (_d = settings === null || settings === void 0 ? void 0 : settings.preventScroll) !== null && _d !== void 0 ? _d : false;
142
- const preventInitialFocus = focusInStrategy === 'initial' && (settings === null || settings === void 0 ? void 0 : settings.activeDescendantControl);
142
+ const preventScroll = (_e = settings === null || settings === void 0 ? void 0 : settings.preventScroll) !== null && _e !== void 0 ? _e : false;
143
143
  function getFirstFocusableElement() {
144
144
  return focusableElements[0];
145
145
  }
@@ -203,7 +203,7 @@ function focusZone(container, settings) {
203
203
  }
204
204
  element.setAttribute('tabindex', '-1');
205
205
  }
206
- if (!currentFocusedElement && !preventInitialFocus) {
206
+ if (!currentFocusedElement) {
207
207
  updateFocusedElement(getFirstFocusableElement());
208
208
  }
209
209
  }
@@ -257,8 +257,7 @@ function focusZone(container, settings) {
257
257
  };
258
258
  beginFocusManagement(...iterateFocusableElements.iterateFocusableElements(container, iterateFocusableElementsOptions));
259
259
  const initialElement = typeof focusInStrategy === 'function' ? focusInStrategy(document.body) : getFirstFocusableElement();
260
- if (!preventInitialFocus)
261
- updateFocusedElement(initialElement);
260
+ updateFocusedElement(initialElement);
262
261
  const observer = new MutationObserver(mutations => {
263
262
  for (const mutation of mutations) {
264
263
  for (const removedNode of mutation.removedNodes) {
@@ -292,7 +291,7 @@ function focusZone(container, settings) {
292
291
  attributeOldValue: true,
293
292
  });
294
293
  const controller = new AbortController();
295
- const signal = (_e = settings === null || settings === void 0 ? void 0 : settings.abortSignal) !== null && _e !== void 0 ? _e : controller.signal;
294
+ const signal = (_f = settings === null || settings === void 0 ? void 0 : settings.abortSignal) !== null && _f !== void 0 ? _f : controller.signal;
296
295
  signal.addEventListener('abort', () => {
297
296
  endFocusManagement(...focusableElements);
298
297
  });
@@ -309,19 +308,20 @@ function focusZone(container, settings) {
309
308
  updateFocusedElement(event.target);
310
309
  }
311
310
  }, { signal });
312
- container.addEventListener('mousemove', ({ target }) => {
313
- if (!(target instanceof Node)) {
314
- return;
315
- }
316
- const focusableElement = focusableElements.find(element => element.contains(target));
317
- if (focusableElement) {
318
- updateFocusedElement(focusableElement);
319
- }
320
- }, { signal, capture: true });
311
+ if (!ignoreHoverEvents) {
312
+ container.addEventListener('mousemove', ({ target }) => {
313
+ if (!(target instanceof Node)) {
314
+ return;
315
+ }
316
+ const focusableElement = focusableElements.find(element => element.contains(target));
317
+ if (focusableElement) {
318
+ updateFocusedElement(focusableElement);
319
+ }
320
+ }, { signal, capture: true });
321
+ }
321
322
  activeDescendantControl.addEventListener('focusin', () => {
322
323
  if (!currentFocusedElement) {
323
- if (!preventInitialFocus)
324
- updateFocusedElement(getFirstFocusableElement());
324
+ updateFocusedElement(getFirstFocusableElement());
325
325
  }
326
326
  else {
327
327
  setActiveDescendant(undefined, currentFocusedElement);
@@ -389,7 +389,7 @@ function focusZone(container, settings) {
389
389
  }
390
390
  function getCurrentFocusedIndex() {
391
391
  if (!currentFocusedElement) {
392
- return preventInitialFocus ? -1 : 0;
392
+ return 0;
393
393
  }
394
394
  const focusedIndex = focusableElements.indexOf(currentFocusedElement);
395
395
  const fallbackIndex = currentFocusedElement === container ? -1 : 0;
@@ -25,8 +25,9 @@ export type FocusZoneSettings = IterateFocusableElements & {
25
25
  abortSignal?: AbortSignal;
26
26
  activeDescendantControl?: HTMLElement;
27
27
  onActiveDescendantChanged?: (newActiveDescendant: HTMLElement | undefined, previousActiveDescendant: HTMLElement | undefined, directlyActivated: boolean) => void;
28
- focusInStrategy?: 'first' | 'closest' | 'previous' | 'initial' | ((previousFocusedElement: Element) => HTMLElement | undefined);
28
+ focusInStrategy?: 'first' | 'closest' | 'previous' | ((previousFocusedElement: Element) => HTMLElement | undefined);
29
29
  preventScroll?: boolean;
30
+ ignoreHoverEvents?: boolean;
30
31
  };
31
32
  export declare const isActiveDescendantAttribute = "data-is-active-descendant";
32
33
  export declare const activeDescendantActivatedDirectly = "activated-directly";
@@ -127,7 +127,7 @@ const activeDescendantActivatedDirectly = 'activated-directly';
127
127
  const activeDescendantActivatedIndirectly = 'activated-indirectly';
128
128
  const hasActiveDescendantAttribute = 'data-has-active-descendant';
129
129
  function focusZone(container, settings) {
130
- var _a, _b, _c, _d, _e;
130
+ var _a, _b, _c, _d, _e, _f;
131
131
  const focusableElements = [];
132
132
  const savedTabIndex = new WeakMap();
133
133
  const bindKeys = (_a = settings === null || settings === void 0 ? void 0 : settings.bindKeys) !== null && _a !== void 0 ? _a : ((settings === null || settings === void 0 ? void 0 : settings.getNextFocusable) ? FocusKeys.ArrowAll : FocusKeys.ArrowVertical) | FocusKeys.HomeAndEnd;
@@ -135,9 +135,9 @@ function focusZone(container, settings) {
135
135
  const focusInStrategy = (_c = settings === null || settings === void 0 ? void 0 : settings.focusInStrategy) !== null && _c !== void 0 ? _c : 'previous';
136
136
  const activeDescendantControl = settings === null || settings === void 0 ? void 0 : settings.activeDescendantControl;
137
137
  const activeDescendantCallback = settings === null || settings === void 0 ? void 0 : settings.onActiveDescendantChanged;
138
+ const ignoreHoverEvents = (_d = settings === null || settings === void 0 ? void 0 : settings.ignoreHoverEvents) !== null && _d !== void 0 ? _d : false;
138
139
  let currentFocusedElement;
139
- const preventScroll = (_d = settings === null || settings === void 0 ? void 0 : settings.preventScroll) !== null && _d !== void 0 ? _d : false;
140
- const preventInitialFocus = focusInStrategy === 'initial' && (settings === null || settings === void 0 ? void 0 : settings.activeDescendantControl);
140
+ const preventScroll = (_e = settings === null || settings === void 0 ? void 0 : settings.preventScroll) !== null && _e !== void 0 ? _e : false;
141
141
  function getFirstFocusableElement() {
142
142
  return focusableElements[0];
143
143
  }
@@ -201,7 +201,7 @@ function focusZone(container, settings) {
201
201
  }
202
202
  element.setAttribute('tabindex', '-1');
203
203
  }
204
- if (!currentFocusedElement && !preventInitialFocus) {
204
+ if (!currentFocusedElement) {
205
205
  updateFocusedElement(getFirstFocusableElement());
206
206
  }
207
207
  }
@@ -255,8 +255,7 @@ function focusZone(container, settings) {
255
255
  };
256
256
  beginFocusManagement(...iterateFocusableElements(container, iterateFocusableElementsOptions));
257
257
  const initialElement = typeof focusInStrategy === 'function' ? focusInStrategy(document.body) : getFirstFocusableElement();
258
- if (!preventInitialFocus)
259
- updateFocusedElement(initialElement);
258
+ updateFocusedElement(initialElement);
260
259
  const observer = new MutationObserver(mutations => {
261
260
  for (const mutation of mutations) {
262
261
  for (const removedNode of mutation.removedNodes) {
@@ -290,7 +289,7 @@ function focusZone(container, settings) {
290
289
  attributeOldValue: true,
291
290
  });
292
291
  const controller = new AbortController();
293
- const signal = (_e = settings === null || settings === void 0 ? void 0 : settings.abortSignal) !== null && _e !== void 0 ? _e : controller.signal;
292
+ const signal = (_f = settings === null || settings === void 0 ? void 0 : settings.abortSignal) !== null && _f !== void 0 ? _f : controller.signal;
294
293
  signal.addEventListener('abort', () => {
295
294
  endFocusManagement(...focusableElements);
296
295
  });
@@ -307,19 +306,20 @@ function focusZone(container, settings) {
307
306
  updateFocusedElement(event.target);
308
307
  }
309
308
  }, { signal });
310
- container.addEventListener('mousemove', ({ target }) => {
311
- if (!(target instanceof Node)) {
312
- return;
313
- }
314
- const focusableElement = focusableElements.find(element => element.contains(target));
315
- if (focusableElement) {
316
- updateFocusedElement(focusableElement);
317
- }
318
- }, { signal, capture: true });
309
+ if (!ignoreHoverEvents) {
310
+ container.addEventListener('mousemove', ({ target }) => {
311
+ if (!(target instanceof Node)) {
312
+ return;
313
+ }
314
+ const focusableElement = focusableElements.find(element => element.contains(target));
315
+ if (focusableElement) {
316
+ updateFocusedElement(focusableElement);
317
+ }
318
+ }, { signal, capture: true });
319
+ }
319
320
  activeDescendantControl.addEventListener('focusin', () => {
320
321
  if (!currentFocusedElement) {
321
- if (!preventInitialFocus)
322
- updateFocusedElement(getFirstFocusableElement());
322
+ updateFocusedElement(getFirstFocusableElement());
323
323
  }
324
324
  else {
325
325
  setActiveDescendant(undefined, currentFocusedElement);
@@ -387,7 +387,7 @@ function focusZone(container, settings) {
387
387
  }
388
388
  function getCurrentFocusedIndex() {
389
389
  if (!currentFocusedElement) {
390
- return preventInitialFocus ? -1 : 0;
390
+ return 0;
391
391
  }
392
392
  const focusedIndex = focusableElements.indexOf(currentFocusedElement);
393
393
  const fallbackIndex = currentFocusedElement === container ? -1 : 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primer/behaviors",
3
- "version": "0.0.0-20251203212431",
3
+ "version": "0.0.0-20251203213711",
4
4
  "description": "Shared behaviors for JavaScript components",
5
5
  "type": "commonjs",
6
6
  "main": "dist/cjs/index.js",
@@ -43,9 +43,7 @@
43
43
  "prebuild": "npm run clean",
44
44
  "release": "npm run build && changeset publish",
45
45
  "size-limit": "npm run build && size-limit",
46
- "type-check": "tsc --noEmit",
47
- "storybook": "storybook dev -p 6006 --no-open",
48
- "build-storybook": "storybook build"
46
+ "type-check": "tsc --noEmit"
49
47
  },
50
48
  "repository": {
51
49
  "type": "git",
@@ -77,21 +75,17 @@
77
75
  "@github/prettier-config": "^0.0.6",
78
76
  "@rollup/plugin-typescript": "^12.1.0",
79
77
  "@rollup/wasm-node": "^4.19.1",
80
- "@size-limit/preset-small-lib": "^12.0.0",
81
- "@storybook/react-vite": "^10.0.8",
78
+ "@size-limit/preset-small-lib": "^11.1.4",
82
79
  "@testing-library/react": "^16.0.0",
83
80
  "@testing-library/user-event": "^14.5.1",
84
81
  "@types/jest": "^30.0.0",
85
82
  "@types/node": "^24.0.10",
86
83
  "@types/react": "^19.0.1",
87
- "@types/react-dom": "^19.2.3",
88
- "clsx": "^2.1.1",
89
84
  "esbuild": "^0.27.0",
90
85
  "esbuild-jest": "^0.5.0",
91
86
  "eslint": "^8.50.0",
92
87
  "eslint-plugin-github": "^5.0.0",
93
88
  "eslint-plugin-prettier": "^5.0.0",
94
- "eslint-plugin-storybook": "^10.0.8",
95
89
  "jest": "^30.0.4",
96
90
  "jest-environment-jsdom": "^30.0.4",
97
91
  "prettier": "^3.0.3",
@@ -99,8 +93,7 @@
99
93
  "react-dom": "^19.0.0",
100
94
  "rimraf": "^6.0.1",
101
95
  "rollup": "^4.18.0",
102
- "size-limit": "^12.0.0",
103
- "storybook": "^10.0.8",
96
+ "size-limit": "^11.1.4",
104
97
  "tslib": "^2.8.1",
105
98
  "typescript": "^5.2.2"
106
99
  }