@fluentui/react-aria 9.10.5 → 9.11.0

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,12 +1,27 @@
1
1
  # Change Log - @fluentui/react-aria
2
2
 
3
- This log was last generated on Tue, 23 Apr 2024 08:12:12 GMT and should not be manually modified.
3
+ This log was last generated on Thu, 02 May 2024 11:31:22 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.11.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-aria_v9.11.0)
8
+
9
+ Thu, 02 May 2024 11:31:22 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-aria_v9.10.5..@fluentui/react-aria_v9.11.0)
11
+
12
+ ### Minor changes
13
+
14
+ - Adding function to focus last active descendant if it exists ([PR #31140](https://github.com/microsoft/fluentui/pull/31140) by stevenco@microsoft.com)
15
+ - ActiveDescendantChangeEvent for tracking active item ([PR #31149](https://github.com/microsoft/fluentui/pull/31149) by jurokapsiar@gmail.com)
16
+ - Bump @fluentui/react-tabster to v9.21.0 ([PR #31231](https://github.com/microsoft/fluentui/pull/31231) by beachball)
17
+
18
+ ### Patches
19
+
20
+ - Updating ActiveDescendent scrollIntoView logic to work with ancester scroll containers and scroll margin styles ([PR #31158](https://github.com/microsoft/fluentui/pull/31158) by stevenco@microsoft.com)
21
+
7
22
  ## [9.10.5](https://github.com/microsoft/fluentui/tree/@fluentui/react-aria_v9.10.5)
8
23
 
9
- Tue, 23 Apr 2024 08:12:12 GMT
24
+ Tue, 23 Apr 2024 08:17:49 GMT
10
25
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-aria_v9.10.4..@fluentui/react-aria_v9.10.5)
11
26
 
12
27
  ### Patches
package/dist/index.d.ts CHANGED
@@ -10,6 +10,13 @@ import type { UnionToIntersection } from '@fluentui/react-utilities';
10
10
  */
11
11
  export declare const ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE = "data-activedescendant-focusvisible";
12
12
 
13
+ export declare type ActiveDescendantChangeEvent = CustomEvent<ActiveDescendantChangeEventDetail>;
14
+
15
+ declare interface ActiveDescendantChangeEventDetail {
16
+ id: string;
17
+ previousId: string | null;
18
+ }
19
+
13
20
  export declare const ActiveDescendantContextProvider: React_2.Provider<ActiveDescendantContextValue | undefined>;
14
21
 
15
22
  export declare type ActiveDescendantContextValue = {
@@ -25,6 +32,11 @@ export declare interface ActiveDescendantImperativeRef {
25
32
  blur: () => void;
26
33
  active: () => string | undefined;
27
34
  focus: (id: string) => void;
35
+ /**
36
+ * Focuses the last active descendant, if it still exists
37
+ * @returns true if the last active descendant was focused
38
+ */
39
+ focusLastActive: () => boolean | undefined;
28
40
  hideAttributes: () => void;
29
41
  showAttributes: () => void;
30
42
  }
@@ -7,6 +7,7 @@ const activeDescendantContextDefaultValue = {
7
7
  find: noop,
8
8
  first: noop,
9
9
  focus: noop,
10
+ focusLastActive: noop,
10
11
  last: noop,
11
12
  next: noop,
12
13
  prev: noop,
@@ -1 +1 @@
1
- {"version":3,"sources":["ActiveDescendantContext.ts"],"sourcesContent":["import * as React from 'react';\nimport { ActiveDescendantImperativeRef } from './types';\n\nexport type ActiveDescendantContextValue = {\n controller: ActiveDescendantImperativeRef;\n};\n\nconst noop = () => undefined;\n\nconst activeDescendantContextDefaultValue: ActiveDescendantContextValue = {\n controller: {\n active: noop,\n blur: noop,\n find: noop,\n first: noop,\n focus: noop,\n last: noop,\n next: noop,\n prev: noop,\n showAttributes: noop,\n hideAttributes: noop,\n },\n};\n\nconst ActiveDescendantContext = React.createContext<ActiveDescendantContextValue | undefined>(undefined);\n\nexport const ActiveDescendantContextProvider = ActiveDescendantContext.Provider;\nexport const useActiveDescendantContext = () =>\n React.useContext(ActiveDescendantContext) ?? activeDescendantContextDefaultValue;\nexport const useHasParentActiveDescendantContext = () => !!React.useContext(ActiveDescendantContext);\n"],"names":["React","noop","undefined","activeDescendantContextDefaultValue","controller","active","blur","find","first","focus","last","next","prev","showAttributes","hideAttributes","ActiveDescendantContext","createContext","ActiveDescendantContextProvider","Provider","useActiveDescendantContext","useContext","useHasParentActiveDescendantContext"],"mappings":"AAAA,YAAYA,WAAW,QAAQ;AAO/B,MAAMC,OAAO,IAAMC;AAEnB,MAAMC,sCAAoE;IACxEC,YAAY;QACVC,QAAQJ;QACRK,MAAML;QACNM,MAAMN;QACNO,OAAOP;QACPQ,OAAOR;QACPS,MAAMT;QACNU,MAAMV;QACNW,MAAMX;QACNY,gBAAgBZ;QAChBa,gBAAgBb;IAClB;AACF;AAEA,MAAMc,0BAA0Bf,MAAMgB,aAAa,CAA2Cd;AAE9F,OAAO,MAAMe,kCAAkCF,wBAAwBG,QAAQ,CAAC;AAChF,OAAO,MAAMC,6BAA6B;QACxCnB;WAAAA,CAAAA,oBAAAA,MAAMoB,UAAU,CAACL,sCAAjBf,+BAAAA,oBAA6CG;AAAkC,EAAE;AACnF,OAAO,MAAMkB,sCAAsC,IAAM,CAAC,CAACrB,MAAMoB,UAAU,CAACL,yBAAyB"}
1
+ {"version":3,"sources":["ActiveDescendantContext.ts"],"sourcesContent":["import * as React from 'react';\nimport { ActiveDescendantImperativeRef } from './types';\n\nexport type ActiveDescendantContextValue = {\n controller: ActiveDescendantImperativeRef;\n};\n\nconst noop = () => undefined;\n\nconst activeDescendantContextDefaultValue: ActiveDescendantContextValue = {\n controller: {\n active: noop,\n blur: noop,\n find: noop,\n first: noop,\n focus: noop,\n focusLastActive: noop,\n last: noop,\n next: noop,\n prev: noop,\n showAttributes: noop,\n hideAttributes: noop,\n },\n};\n\nconst ActiveDescendantContext = React.createContext<ActiveDescendantContextValue | undefined>(undefined);\n\nexport const ActiveDescendantContextProvider = ActiveDescendantContext.Provider;\nexport const useActiveDescendantContext = () =>\n React.useContext(ActiveDescendantContext) ?? activeDescendantContextDefaultValue;\nexport const useHasParentActiveDescendantContext = () => !!React.useContext(ActiveDescendantContext);\n"],"names":["React","noop","undefined","activeDescendantContextDefaultValue","controller","active","blur","find","first","focus","focusLastActive","last","next","prev","showAttributes","hideAttributes","ActiveDescendantContext","createContext","ActiveDescendantContextProvider","Provider","useActiveDescendantContext","useContext","useHasParentActiveDescendantContext"],"mappings":"AAAA,YAAYA,WAAW,QAAQ;AAO/B,MAAMC,OAAO,IAAMC;AAEnB,MAAMC,sCAAoE;IACxEC,YAAY;QACVC,QAAQJ;QACRK,MAAML;QACNM,MAAMN;QACNO,OAAOP;QACPQ,OAAOR;QACPS,iBAAiBT;QACjBU,MAAMV;QACNW,MAAMX;QACNY,MAAMZ;QACNa,gBAAgBb;QAChBc,gBAAgBd;IAClB;AACF;AAEA,MAAMe,0BAA0BhB,MAAMiB,aAAa,CAA2Cf;AAE9F,OAAO,MAAMgB,kCAAkCF,wBAAwBG,QAAQ,CAAC;AAChF,OAAO,MAAMC,6BAA6B;QACxCpB;WAAAA,CAAAA,oBAAAA,MAAMqB,UAAU,CAACL,sCAAjBhB,+BAAAA,oBAA6CG;AAAkC,EAAE;AACnF,OAAO,MAAMmB,sCAAsC,IAAM,CAAC,CAACtB,MAAMqB,UAAU,CAACL,yBAAyB"}
@@ -1,19 +1,54 @@
1
- export const scrollIntoView = (target, scrollParent)=>{
2
- if (!target || !scrollParent) {
1
+ export const scrollIntoView = (target)=>{
2
+ if (!target) {
3
3
  return;
4
4
  }
5
- if (scrollParent.offsetHeight >= scrollParent.scrollHeight) {
5
+ const scrollParent = findScrollableParent(target.parentElement);
6
+ if (!scrollParent) {
6
7
  return;
7
8
  }
8
- const { offsetHeight, offsetTop } = target;
9
+ const { offsetHeight } = target;
10
+ const offsetTop = getTotalOffsetTop(target, scrollParent);
11
+ const { scrollMarginTop, scrollMarginBottom } = getScrollMargins(target);
9
12
  const { offsetHeight: parentOffsetHeight, scrollTop } = scrollParent;
10
- const isAbove = offsetTop < scrollTop;
11
- const isBelow = offsetTop + offsetHeight > scrollTop + parentOffsetHeight;
13
+ const isAbove = offsetTop - scrollMarginTop < scrollTop;
14
+ const isBelow = offsetTop + offsetHeight + scrollMarginBottom > scrollTop + parentOffsetHeight;
12
15
  const buffer = 2;
13
16
  if (isAbove) {
14
- scrollParent.scrollTo(0, offsetTop - buffer);
17
+ scrollParent.scrollTo(0, offsetTop - scrollMarginTop - buffer);
18
+ } else if (isBelow) {
19
+ scrollParent.scrollTo(0, offsetTop + offsetHeight + scrollMarginBottom - parentOffsetHeight + buffer);
15
20
  }
16
- if (isBelow) {
17
- scrollParent.scrollTo(0, offsetTop - parentOffsetHeight + offsetHeight + buffer);
21
+ };
22
+ const findScrollableParent = (element)=>{
23
+ if (!element) {
24
+ return null;
25
+ }
26
+ if (element.scrollHeight > element.offsetHeight) {
27
+ return element;
28
+ }
29
+ return findScrollableParent(element.parentElement);
30
+ };
31
+ const getTotalOffsetTop = (element, scrollParent)=>{
32
+ if (!element || element === scrollParent) {
33
+ return 0;
18
34
  }
35
+ if (element.contains(scrollParent)) {
36
+ // subtract the scroll parent's offset top from the running total if the offsetParent is above it
37
+ return scrollParent.offsetTop * -1;
38
+ }
39
+ return element.offsetTop + getTotalOffsetTop(element.offsetParent, scrollParent);
40
+ };
41
+ const getScrollMargins = (element)=>{
42
+ const computedStyles = getComputedStyle(element);
43
+ var _getIntValueOfComputedStyle;
44
+ const scrollMarginTop = (_getIntValueOfComputedStyle = getIntValueOfComputedStyle(computedStyles.scrollMarginTop)) !== null && _getIntValueOfComputedStyle !== void 0 ? _getIntValueOfComputedStyle : getIntValueOfComputedStyle(computedStyles.scrollMarginBlockStart);
45
+ var _getIntValueOfComputedStyle1;
46
+ const scrollMarginBottom = (_getIntValueOfComputedStyle1 = getIntValueOfComputedStyle(computedStyles.scrollMarginBottom)) !== null && _getIntValueOfComputedStyle1 !== void 0 ? _getIntValueOfComputedStyle1 : getIntValueOfComputedStyle(computedStyles.scrollMarginBlockEnd);
47
+ return {
48
+ scrollMarginTop,
49
+ scrollMarginBottom
50
+ };
51
+ };
52
+ const getIntValueOfComputedStyle = (computedStyle)=>{
53
+ return computedStyle ? parseInt(computedStyle, 10) : 0;
19
54
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["scrollIntoView.ts"],"sourcesContent":["export const scrollIntoView = (\n target: HTMLElement | null | undefined,\n scrollParent: HTMLElement | null | undefined,\n) => {\n if (!target || !scrollParent) {\n return;\n }\n\n if (scrollParent.offsetHeight >= scrollParent.scrollHeight) {\n return;\n }\n\n const { offsetHeight, offsetTop } = target;\n const { offsetHeight: parentOffsetHeight, scrollTop } = scrollParent;\n\n const isAbove = offsetTop < scrollTop;\n const isBelow = offsetTop + offsetHeight > scrollTop + parentOffsetHeight;\n\n const buffer = 2;\n\n if (isAbove) {\n scrollParent.scrollTo(0, offsetTop - buffer);\n }\n\n if (isBelow) {\n scrollParent.scrollTo(0, offsetTop - parentOffsetHeight + offsetHeight + buffer);\n }\n};\n"],"names":["scrollIntoView","target","scrollParent","offsetHeight","scrollHeight","offsetTop","parentOffsetHeight","scrollTop","isAbove","isBelow","buffer","scrollTo"],"mappings":"AAAA,OAAO,MAAMA,iBAAiB,CAC5BC,QACAC;IAEA,IAAI,CAACD,UAAU,CAACC,cAAc;QAC5B;IACF;IAEA,IAAIA,aAAaC,YAAY,IAAID,aAAaE,YAAY,EAAE;QAC1D;IACF;IAEA,MAAM,EAAED,YAAY,EAAEE,SAAS,EAAE,GAAGJ;IACpC,MAAM,EAAEE,cAAcG,kBAAkB,EAAEC,SAAS,EAAE,GAAGL;IAExD,MAAMM,UAAUH,YAAYE;IAC5B,MAAME,UAAUJ,YAAYF,eAAeI,YAAYD;IAEvD,MAAMI,SAAS;IAEf,IAAIF,SAAS;QACXN,aAAaS,QAAQ,CAAC,GAAGN,YAAYK;IACvC;IAEA,IAAID,SAAS;QACXP,aAAaS,QAAQ,CAAC,GAAGN,YAAYC,qBAAqBH,eAAeO;IAC3E;AACF,EAAE"}
1
+ {"version":3,"sources":["scrollIntoView.ts"],"sourcesContent":["export const scrollIntoView = (target: HTMLElement | null | undefined) => {\n if (!target) {\n return;\n }\n\n const scrollParent = findScrollableParent(target.parentElement as HTMLElement);\n if (!scrollParent) {\n return;\n }\n\n const { offsetHeight } = target;\n const offsetTop = getTotalOffsetTop(target, scrollParent);\n\n const { scrollMarginTop, scrollMarginBottom } = getScrollMargins(target);\n\n const { offsetHeight: parentOffsetHeight, scrollTop } = scrollParent;\n\n const isAbove = offsetTop - scrollMarginTop < scrollTop;\n const isBelow = offsetTop + offsetHeight + scrollMarginBottom > scrollTop + parentOffsetHeight;\n\n const buffer = 2;\n\n if (isAbove) {\n scrollParent.scrollTo(0, offsetTop - scrollMarginTop - buffer);\n } else if (isBelow) {\n scrollParent.scrollTo(0, offsetTop + offsetHeight + scrollMarginBottom - parentOffsetHeight + buffer);\n }\n};\n\nconst findScrollableParent = (element: HTMLElement | null): HTMLElement | null => {\n if (!element) {\n return null;\n }\n\n if (element.scrollHeight > element.offsetHeight) {\n return element;\n }\n\n return findScrollableParent(element.parentElement);\n};\n\nconst getTotalOffsetTop = (element: HTMLElement, scrollParent: HTMLElement): number => {\n if (!element || element === scrollParent) {\n return 0;\n }\n\n if (element.contains(scrollParent)) {\n // subtract the scroll parent's offset top from the running total if the offsetParent is above it\n return scrollParent.offsetTop * -1;\n }\n\n return element.offsetTop + getTotalOffsetTop(element.offsetParent as HTMLElement, scrollParent);\n};\n\nconst getScrollMargins = (element: HTMLElement) => {\n const computedStyles = getComputedStyle(element);\n const scrollMarginTop =\n getIntValueOfComputedStyle(computedStyles.scrollMarginTop) ??\n getIntValueOfComputedStyle(computedStyles.scrollMarginBlockStart);\n const scrollMarginBottom =\n getIntValueOfComputedStyle(computedStyles.scrollMarginBottom) ??\n getIntValueOfComputedStyle(computedStyles.scrollMarginBlockEnd);\n return {\n scrollMarginTop,\n scrollMarginBottom,\n };\n};\n\nconst getIntValueOfComputedStyle = (computedStyle: string) => {\n return computedStyle ? parseInt(computedStyle, 10) : 0;\n};\n"],"names":["scrollIntoView","target","scrollParent","findScrollableParent","parentElement","offsetHeight","offsetTop","getTotalOffsetTop","scrollMarginTop","scrollMarginBottom","getScrollMargins","parentOffsetHeight","scrollTop","isAbove","isBelow","buffer","scrollTo","element","scrollHeight","contains","offsetParent","computedStyles","getComputedStyle","getIntValueOfComputedStyle","scrollMarginBlockStart","scrollMarginBlockEnd","computedStyle","parseInt"],"mappings":"AAAA,OAAO,MAAMA,iBAAiB,CAACC;IAC7B,IAAI,CAACA,QAAQ;QACX;IACF;IAEA,MAAMC,eAAeC,qBAAqBF,OAAOG,aAAa;IAC9D,IAAI,CAACF,cAAc;QACjB;IACF;IAEA,MAAM,EAAEG,YAAY,EAAE,GAAGJ;IACzB,MAAMK,YAAYC,kBAAkBN,QAAQC;IAE5C,MAAM,EAAEM,eAAe,EAAEC,kBAAkB,EAAE,GAAGC,iBAAiBT;IAEjE,MAAM,EAAEI,cAAcM,kBAAkB,EAAEC,SAAS,EAAE,GAAGV;IAExD,MAAMW,UAAUP,YAAYE,kBAAkBI;IAC9C,MAAME,UAAUR,YAAYD,eAAeI,qBAAqBG,YAAYD;IAE5E,MAAMI,SAAS;IAEf,IAAIF,SAAS;QACXX,aAAac,QAAQ,CAAC,GAAGV,YAAYE,kBAAkBO;IACzD,OAAO,IAAID,SAAS;QAClBZ,aAAac,QAAQ,CAAC,GAAGV,YAAYD,eAAeI,qBAAqBE,qBAAqBI;IAChG;AACF,EAAE;AAEF,MAAMZ,uBAAuB,CAACc;IAC5B,IAAI,CAACA,SAAS;QACZ,OAAO;IACT;IAEA,IAAIA,QAAQC,YAAY,GAAGD,QAAQZ,YAAY,EAAE;QAC/C,OAAOY;IACT;IAEA,OAAOd,qBAAqBc,QAAQb,aAAa;AACnD;AAEA,MAAMG,oBAAoB,CAACU,SAAsBf;IAC/C,IAAI,CAACe,WAAWA,YAAYf,cAAc;QACxC,OAAO;IACT;IAEA,IAAIe,QAAQE,QAAQ,CAACjB,eAAe;QAClC,iGAAiG;QACjG,OAAOA,aAAaI,SAAS,GAAG,CAAC;IACnC;IAEA,OAAOW,QAAQX,SAAS,GAAGC,kBAAkBU,QAAQG,YAAY,EAAiBlB;AACpF;AAEA,MAAMQ,mBAAmB,CAACO;IACxB,MAAMI,iBAAiBC,iBAAiBL;QAEtCM;IADF,MAAMf,kBACJe,CAAAA,8BAAAA,2BAA2BF,eAAeb,eAAe,eAAzDe,yCAAAA,8BACAA,2BAA2BF,eAAeG,sBAAsB;QAEhED;IADF,MAAMd,qBACJc,CAAAA,+BAAAA,2BAA2BF,eAAeZ,kBAAkB,eAA5Dc,0CAAAA,+BACAA,2BAA2BF,eAAeI,oBAAoB;IAChE,OAAO;QACLjB;QACAC;IACF;AACF;AAEA,MAAMc,6BAA6B,CAACG;IAClC,OAAOA,gBAAgBC,SAASD,eAAe,MAAM;AACvD"}
@@ -1 +1 @@
1
- {"version":3,"sources":["types.ts"],"sourcesContent":["import * as React from 'react';\n\nexport interface ActiveDescendantImperativeRef {\n first: (options?: IteratorOptions) => string | undefined;\n last: (options?: IteratorOptions) => string | undefined;\n next: (options?: IteratorOptions) => string | undefined;\n prev: (options?: IteratorOptions) => string | undefined;\n find: (predicate: (id: string) => boolean, options?: IteratorOptions & FindOptions) => string | undefined;\n blur: () => void;\n active: () => string | undefined;\n focus: (id: string) => void;\n hideAttributes: () => void;\n showAttributes: () => void;\n}\n\nexport interface ActiveDescendantOptions {\n /**\n * @param el - HTML element to test\n * @returns whether the element can be an active descendant\n */\n matchOption: (el: HTMLElement) => boolean;\n /**\n * Forward imperative refs when exposing functionality from a React component\n */\n imperativeRef?: React.RefObject<ActiveDescendantImperativeRef>;\n}\n\nexport interface FindOptions {\n /**\n * Starts the search from a specific id\n */\n startFrom?: string;\n}\n\nexport interface UseActiveDescendantReturn<\n TActiveParentElement extends HTMLElement = HTMLElement,\n TListboxElement extends HTMLElement = HTMLElement,\n> {\n /**\n * Attach this to the element that contains all active descendants\n */\n listboxRef: React.Ref<TListboxElement>;\n /**\n * Attach this to the element that has an active descendant\n */\n activeParentRef: React.Ref<TActiveParentElement>;\n /**\n * Imperative functions to manage active descendants within the listboxRef\n */\n controller: ActiveDescendantImperativeRef;\n}\n\nexport interface IteratorOptions {\n /**\n * When passive, the active descendant is changed\n * @default false\n */\n passive?: boolean;\n}\n"],"names":["React"],"mappings":"AAAA,YAAYA,WAAW,QAAQ"}
1
+ {"version":3,"sources":["types.ts"],"sourcesContent":["import * as React from 'react';\n\nexport interface ActiveDescendantImperativeRef {\n first: (options?: IteratorOptions) => string | undefined;\n last: (options?: IteratorOptions) => string | undefined;\n next: (options?: IteratorOptions) => string | undefined;\n prev: (options?: IteratorOptions) => string | undefined;\n find: (predicate: (id: string) => boolean, options?: IteratorOptions & FindOptions) => string | undefined;\n blur: () => void;\n active: () => string | undefined;\n focus: (id: string) => void;\n /**\n * Focuses the last active descendant, if it still exists\n * @returns true if the last active descendant was focused\n */\n focusLastActive: () => boolean | undefined;\n hideAttributes: () => void;\n showAttributes: () => void;\n}\n\nexport interface ActiveDescendantOptions {\n /**\n * @param el - HTML element to test\n * @returns whether the element can be an active descendant\n */\n matchOption: (el: HTMLElement) => boolean;\n /**\n * Forward imperative refs when exposing functionality from a React component\n */\n imperativeRef?: React.RefObject<ActiveDescendantImperativeRef>;\n}\n\nexport interface FindOptions {\n /**\n * Starts the search from a specific id\n */\n startFrom?: string;\n}\n\nexport interface UseActiveDescendantReturn<\n TActiveParentElement extends HTMLElement = HTMLElement,\n TListboxElement extends HTMLElement = HTMLElement,\n> {\n /**\n * Attach this to the element that contains all active descendants\n */\n listboxRef: React.Ref<TListboxElement>;\n /**\n * Attach this to the element that has an active descendant\n */\n activeParentRef: React.Ref<TActiveParentElement>;\n /**\n * Imperative functions to manage active descendants within the listboxRef\n */\n controller: ActiveDescendantImperativeRef;\n}\n\nexport interface IteratorOptions {\n /**\n * When passive, the active descendant is changed\n * @default false\n */\n passive?: boolean;\n}\n"],"names":["React"],"mappings":"AAAA,YAAYA,WAAW,QAAQ"}
@@ -4,10 +4,17 @@ import { useOnKeyboardNavigationChange } from '@fluentui/react-tabster';
4
4
  import { useOptionWalker } from './useOptionWalker';
5
5
  import { ACTIVEDESCENDANT_ATTRIBUTE, ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE } from './constants';
6
6
  import { scrollIntoView } from './scrollIntoView';
7
+ export const createActiveDescendantChangeEvent = (detail)=>new CustomEvent('activedescendantchange', {
8
+ bubbles: true,
9
+ cancelable: false,
10
+ composed: true,
11
+ detail
12
+ });
7
13
  export function useActiveDescendant(options) {
8
14
  const { imperativeRef, matchOption: matchOptionUnstable } = options;
9
15
  const focusVisibleRef = React.useRef(false);
10
16
  const activeIdRef = React.useRef(null);
17
+ const lastActiveIdRef = React.useRef(null);
11
18
  const activeParentRef = React.useRef(null);
12
19
  const attributeVisibilityRef = React.useRef(true);
13
20
  const removeAttribute = React.useCallback(()=>{
@@ -53,7 +60,10 @@ export function useActiveDescendant(options) {
53
60
  active.removeAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);
54
61
  }
55
62
  removeAttribute();
63
+ lastActiveIdRef.current = activeIdRef.current;
56
64
  activeIdRef.current = null;
65
+ var _active_id;
66
+ return (_active_id = active === null || active === void 0 ? void 0 : active.id) !== null && _active_id !== void 0 ? _active_id : null;
57
67
  }, [
58
68
  getActiveDescendant,
59
69
  removeAttribute
@@ -62,15 +72,19 @@ export function useActiveDescendant(options) {
62
72
  if (!nextActive) {
63
73
  return;
64
74
  }
65
- blurActiveDescendant();
66
- scrollIntoView(nextActive, listboxRef.current);
75
+ const previousActiveId = blurActiveDescendant();
76
+ scrollIntoView(nextActive);
67
77
  setAttribute(nextActive.id);
68
78
  nextActive.setAttribute(ACTIVEDESCENDANT_ATTRIBUTE, '');
69
79
  if (focusVisibleRef.current) {
70
80
  nextActive.setAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');
71
81
  }
82
+ const event = createActiveDescendantChangeEvent({
83
+ id: nextActive.id,
84
+ previousId: previousActiveId
85
+ });
86
+ nextActive.dispatchEvent(event);
72
87
  }, [
73
- listboxRef,
74
88
  blurActiveDescendant,
75
89
  setAttribute
76
90
  ]);
@@ -129,6 +143,16 @@ export function useActiveDescendant(options) {
129
143
  focusActiveDescendant(target);
130
144
  }
131
145
  },
146
+ focusLastActive: ()=>{
147
+ if (!listboxRef.current || !lastActiveIdRef.current) {
148
+ return;
149
+ }
150
+ const target = listboxRef.current.querySelector(`#${lastActiveIdRef.current}`);
151
+ if (target) {
152
+ focusActiveDescendant(target);
153
+ return true;
154
+ }
155
+ },
132
156
  find (predicate, { passive, startFrom } = {}) {
133
157
  const target = optionWalker.find(predicate, startFrom);
134
158
  if (!passive) {
@@ -1 +1 @@
1
- {"version":3,"sources":["useActiveDescendant.ts"],"sourcesContent":["import * as React from 'react';\nimport { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { useOnKeyboardNavigationChange } from '@fluentui/react-tabster';\nimport { useOptionWalker } from './useOptionWalker';\nimport type { ActiveDescendantImperativeRef, ActiveDescendantOptions, UseActiveDescendantReturn } from './types';\nimport { ACTIVEDESCENDANT_ATTRIBUTE, ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE } from './constants';\nimport { scrollIntoView } from './scrollIntoView';\n\nexport function useActiveDescendant<TActiveParentElement extends HTMLElement, TListboxElement extends HTMLElement>(\n options: ActiveDescendantOptions,\n): UseActiveDescendantReturn<TActiveParentElement, TListboxElement> {\n const { imperativeRef, matchOption: matchOptionUnstable } = options;\n const focusVisibleRef = React.useRef(false);\n const activeIdRef = React.useRef<string | null>(null);\n const activeParentRef = React.useRef<TActiveParentElement>(null);\n const attributeVisibilityRef = React.useRef(true);\n\n const removeAttribute = React.useCallback(() => {\n activeParentRef.current?.removeAttribute('aria-activedescendant');\n }, []);\n const setAttribute = React.useCallback((id?: string) => {\n if (id) {\n activeIdRef.current = id;\n }\n if (attributeVisibilityRef.current && activeIdRef.current) {\n activeParentRef.current?.setAttribute('aria-activedescendant', activeIdRef.current);\n }\n }, []);\n\n useOnKeyboardNavigationChange(isNavigatingWithKeyboard => {\n focusVisibleRef.current = isNavigatingWithKeyboard;\n const active = getActiveDescendant();\n if (!active) {\n return;\n }\n\n if (isNavigatingWithKeyboard) {\n active.setAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');\n } else {\n active.removeAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);\n }\n });\n\n const matchOption = useEventCallback(matchOptionUnstable);\n const listboxRef = React.useRef<TListboxElement>(null);\n const { optionWalker, listboxCallbackRef } = useOptionWalker<TListboxElement>({ matchOption });\n const getActiveDescendant = React.useCallback(() => {\n return listboxRef.current?.querySelector<HTMLElement>(`#${activeIdRef.current}`);\n }, [listboxRef]);\n\n const blurActiveDescendant = React.useCallback(() => {\n const active = getActiveDescendant();\n if (active) {\n active.removeAttribute(ACTIVEDESCENDANT_ATTRIBUTE);\n active.removeAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);\n }\n\n removeAttribute();\n activeIdRef.current = null;\n }, [getActiveDescendant, removeAttribute]);\n\n const focusActiveDescendant = React.useCallback(\n (nextActive: HTMLElement | null) => {\n if (!nextActive) {\n return;\n }\n\n blurActiveDescendant();\n\n scrollIntoView(nextActive, listboxRef.current);\n setAttribute(nextActive.id);\n nextActive.setAttribute(ACTIVEDESCENDANT_ATTRIBUTE, '');\n\n if (focusVisibleRef.current) {\n nextActive.setAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');\n }\n },\n [listboxRef, blurActiveDescendant, setAttribute],\n );\n\n const controller: ActiveDescendantImperativeRef = React.useMemo(\n () => ({\n first: ({ passive } = {}) => {\n const first = optionWalker.first();\n if (!passive) {\n focusActiveDescendant(first);\n }\n\n return first?.id;\n },\n last: ({ passive } = {}) => {\n const last = optionWalker.last();\n if (!passive) {\n focusActiveDescendant(last);\n }\n\n return last?.id;\n },\n next: ({ passive } = {}) => {\n const active = getActiveDescendant();\n if (!active) {\n return;\n }\n\n optionWalker.setCurrent(active);\n const next = optionWalker.next();\n if (!passive) {\n focusActiveDescendant(next);\n }\n\n return next?.id;\n },\n prev: ({ passive } = {}) => {\n const active = getActiveDescendant();\n if (!active) {\n return;\n }\n\n optionWalker.setCurrent(active);\n const next = optionWalker.prev();\n\n if (!passive) {\n focusActiveDescendant(next);\n }\n\n return next?.id;\n },\n blur: () => {\n blurActiveDescendant();\n },\n active: () => {\n return getActiveDescendant()?.id;\n },\n\n focus: (id: string) => {\n if (!listboxRef.current) {\n return;\n }\n\n const target = listboxRef.current.querySelector<HTMLElement>(`#${id}`);\n if (target) {\n focusActiveDescendant(target);\n }\n },\n\n find(predicate, { passive, startFrom } = {}) {\n const target = optionWalker.find(predicate, startFrom);\n if (!passive) {\n focusActiveDescendant(target);\n }\n\n return target?.id;\n },\n showAttributes() {\n attributeVisibilityRef.current = true;\n setAttribute();\n },\n hideAttributes() {\n attributeVisibilityRef.current = false;\n removeAttribute();\n },\n }),\n [\n optionWalker,\n listboxRef,\n setAttribute,\n removeAttribute,\n focusActiveDescendant,\n blurActiveDescendant,\n getActiveDescendant,\n ],\n );\n\n React.useImperativeHandle(imperativeRef, () => controller);\n\n return { listboxRef: useMergedRefs(listboxRef, listboxCallbackRef), activeParentRef, controller };\n}\n"],"names":["React","useEventCallback","useMergedRefs","useOnKeyboardNavigationChange","useOptionWalker","ACTIVEDESCENDANT_ATTRIBUTE","ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE","scrollIntoView","useActiveDescendant","options","imperativeRef","matchOption","matchOptionUnstable","focusVisibleRef","useRef","activeIdRef","activeParentRef","attributeVisibilityRef","removeAttribute","useCallback","current","setAttribute","id","isNavigatingWithKeyboard","active","getActiveDescendant","listboxRef","optionWalker","listboxCallbackRef","querySelector","blurActiveDescendant","focusActiveDescendant","nextActive","controller","useMemo","first","passive","last","next","setCurrent","prev","blur","focus","target","find","predicate","startFrom","showAttributes","hideAttributes","useImperativeHandle"],"mappings":"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"}
1
+ {"version":3,"sources":["useActiveDescendant.ts"],"sourcesContent":["import * as React from 'react';\nimport { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { useOnKeyboardNavigationChange } from '@fluentui/react-tabster';\nimport { useOptionWalker } from './useOptionWalker';\nimport type { ActiveDescendantImperativeRef, ActiveDescendantOptions, UseActiveDescendantReturn } from './types';\nimport { ACTIVEDESCENDANT_ATTRIBUTE, ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE } from './constants';\nimport { scrollIntoView } from './scrollIntoView';\n\ninterface ActiveDescendantChangeEventDetail {\n id: string;\n previousId: string | null;\n}\n\nexport type ActiveDescendantChangeEvent = CustomEvent<ActiveDescendantChangeEventDetail>;\n\nexport const createActiveDescendantChangeEvent = (\n detail: ActiveDescendantChangeEventDetail,\n): ActiveDescendantChangeEvent =>\n new CustomEvent<ActiveDescendantChangeEventDetail>('activedescendantchange', {\n bubbles: true,\n cancelable: false,\n composed: true,\n detail,\n });\n\nexport function useActiveDescendant<TActiveParentElement extends HTMLElement, TListboxElement extends HTMLElement>(\n options: ActiveDescendantOptions,\n): UseActiveDescendantReturn<TActiveParentElement, TListboxElement> {\n const { imperativeRef, matchOption: matchOptionUnstable } = options;\n const focusVisibleRef = React.useRef(false);\n const activeIdRef = React.useRef<string | null>(null);\n const lastActiveIdRef = React.useRef<string | null>(null);\n const activeParentRef = React.useRef<TActiveParentElement>(null);\n const attributeVisibilityRef = React.useRef(true);\n\n const removeAttribute = React.useCallback(() => {\n activeParentRef.current?.removeAttribute('aria-activedescendant');\n }, []);\n const setAttribute = React.useCallback((id?: string) => {\n if (id) {\n activeIdRef.current = id;\n }\n if (attributeVisibilityRef.current && activeIdRef.current) {\n activeParentRef.current?.setAttribute('aria-activedescendant', activeIdRef.current);\n }\n }, []);\n\n useOnKeyboardNavigationChange(isNavigatingWithKeyboard => {\n focusVisibleRef.current = isNavigatingWithKeyboard;\n const active = getActiveDescendant();\n if (!active) {\n return;\n }\n\n if (isNavigatingWithKeyboard) {\n active.setAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');\n } else {\n active.removeAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);\n }\n });\n\n const matchOption = useEventCallback(matchOptionUnstable);\n const listboxRef = React.useRef<TListboxElement>(null);\n const { optionWalker, listboxCallbackRef } = useOptionWalker<TListboxElement>({ matchOption });\n const getActiveDescendant = React.useCallback(() => {\n return listboxRef.current?.querySelector<HTMLElement>(`#${activeIdRef.current}`);\n }, [listboxRef]);\n\n const blurActiveDescendant = React.useCallback(() => {\n const active = getActiveDescendant();\n if (active) {\n active.removeAttribute(ACTIVEDESCENDANT_ATTRIBUTE);\n active.removeAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);\n }\n\n removeAttribute();\n lastActiveIdRef.current = activeIdRef.current;\n activeIdRef.current = null;\n return active?.id ?? null;\n }, [getActiveDescendant, removeAttribute]);\n\n const focusActiveDescendant = React.useCallback(\n (nextActive: HTMLElement | null) => {\n if (!nextActive) {\n return;\n }\n\n const previousActiveId = blurActiveDescendant();\n\n scrollIntoView(nextActive);\n setAttribute(nextActive.id);\n nextActive.setAttribute(ACTIVEDESCENDANT_ATTRIBUTE, '');\n\n if (focusVisibleRef.current) {\n nextActive.setAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');\n }\n\n const event = createActiveDescendantChangeEvent({ id: nextActive.id, previousId: previousActiveId });\n nextActive.dispatchEvent(event);\n },\n [blurActiveDescendant, setAttribute],\n );\n\n const controller: ActiveDescendantImperativeRef = React.useMemo(\n () => ({\n first: ({ passive } = {}) => {\n const first = optionWalker.first();\n if (!passive) {\n focusActiveDescendant(first);\n }\n\n return first?.id;\n },\n last: ({ passive } = {}) => {\n const last = optionWalker.last();\n if (!passive) {\n focusActiveDescendant(last);\n }\n\n return last?.id;\n },\n next: ({ passive } = {}) => {\n const active = getActiveDescendant();\n if (!active) {\n return;\n }\n\n optionWalker.setCurrent(active);\n const next = optionWalker.next();\n if (!passive) {\n focusActiveDescendant(next);\n }\n\n return next?.id;\n },\n prev: ({ passive } = {}) => {\n const active = getActiveDescendant();\n if (!active) {\n return;\n }\n\n optionWalker.setCurrent(active);\n const next = optionWalker.prev();\n\n if (!passive) {\n focusActiveDescendant(next);\n }\n\n return next?.id;\n },\n blur: () => {\n blurActiveDescendant();\n },\n active: () => {\n return getActiveDescendant()?.id;\n },\n focus: (id: string) => {\n if (!listboxRef.current) {\n return;\n }\n\n const target = listboxRef.current.querySelector<HTMLElement>(`#${id}`);\n if (target) {\n focusActiveDescendant(target);\n }\n },\n focusLastActive: () => {\n if (!listboxRef.current || !lastActiveIdRef.current) {\n return;\n }\n\n const target = listboxRef.current.querySelector<HTMLElement>(`#${lastActiveIdRef.current}`);\n if (target) {\n focusActiveDescendant(target);\n return true;\n }\n },\n find(predicate, { passive, startFrom } = {}) {\n const target = optionWalker.find(predicate, startFrom);\n if (!passive) {\n focusActiveDescendant(target);\n }\n\n return target?.id;\n },\n showAttributes() {\n attributeVisibilityRef.current = true;\n setAttribute();\n },\n hideAttributes() {\n attributeVisibilityRef.current = false;\n removeAttribute();\n },\n }),\n [\n optionWalker,\n listboxRef,\n setAttribute,\n removeAttribute,\n focusActiveDescendant,\n blurActiveDescendant,\n getActiveDescendant,\n ],\n );\n\n React.useImperativeHandle(imperativeRef, () => controller);\n\n return { listboxRef: useMergedRefs(listboxRef, listboxCallbackRef), activeParentRef, controller };\n}\n"],"names":["React","useEventCallback","useMergedRefs","useOnKeyboardNavigationChange","useOptionWalker","ACTIVEDESCENDANT_ATTRIBUTE","ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE","scrollIntoView","createActiveDescendantChangeEvent","detail","CustomEvent","bubbles","cancelable","composed","useActiveDescendant","options","imperativeRef","matchOption","matchOptionUnstable","focusVisibleRef","useRef","activeIdRef","lastActiveIdRef","activeParentRef","attributeVisibilityRef","removeAttribute","useCallback","current","setAttribute","id","isNavigatingWithKeyboard","active","getActiveDescendant","listboxRef","optionWalker","listboxCallbackRef","querySelector","blurActiveDescendant","focusActiveDescendant","nextActive","previousActiveId","event","previousId","dispatchEvent","controller","useMemo","first","passive","last","next","setCurrent","prev","blur","focus","target","focusLastActive","find","predicate","startFrom","showAttributes","hideAttributes","useImperativeHandle"],"mappings":"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"}
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["index.ts"],"sourcesContent":["export {\n // eslint-disable-next-line deprecation/deprecation\n useARIAButtonShorthand,\n useARIAButtonProps,\n} from './button/index';\nexport {\n useActiveDescendant,\n ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE,\n ActiveDescendantContextProvider,\n useActiveDescendantContext,\n useHasParentActiveDescendantContext,\n} from './activedescendant';\nexport type {\n ActiveDescendantImperativeRef,\n ActiveDescendantOptions,\n ActiveDescendantContextValue,\n} from './activedescendant';\nexport type {\n ARIAButtonSlotProps,\n ARIAButtonProps,\n ARIAButtonResultProps,\n ARIAButtonType,\n ARIAButtonElement,\n ARIAButtonElementIntersection,\n ARIAButtonAlteredProps,\n} from './button/index';\n\nexport {\n AriaLiveAnnouncer,\n renderAriaLiveAnnouncer_unstable,\n useAriaLiveAnnouncer_unstable,\n useAriaLiveAnnouncerContextValues_unstable,\n} from './AriaLiveAnnouncer/index';\nexport type { AriaLiveAnnouncerProps, AriaLiveAnnouncerState } from './AriaLiveAnnouncer/index';\n"],"names":["useARIAButtonShorthand","useARIAButtonProps","useActiveDescendant","ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE","ActiveDescendantContextProvider","useActiveDescendantContext","useHasParentActiveDescendantContext","AriaLiveAnnouncer","renderAriaLiveAnnouncer_unstable","useAriaLiveAnnouncer_unstable","useAriaLiveAnnouncerContextValues_unstable"],"mappings":"AAAA,SACE,mDAAmD;AACnDA,sBAAsB,EACtBC,kBAAkB,QACb,iBAAiB;AACxB,SACEC,mBAAmB,EACnBC,uCAAuC,EACvCC,+BAA+B,EAC/BC,0BAA0B,EAC1BC,mCAAmC,QAC9B,qBAAqB;AAgB5B,SACEC,iBAAiB,EACjBC,gCAAgC,EAChCC,6BAA6B,EAC7BC,0CAA0C,QACrC,4BAA4B"}
1
+ {"version":3,"sources":["index.ts"],"sourcesContent":["export {\n // eslint-disable-next-line deprecation/deprecation\n useARIAButtonShorthand,\n useARIAButtonProps,\n} from './button/index';\nexport {\n useActiveDescendant,\n ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE,\n ActiveDescendantContextProvider,\n useActiveDescendantContext,\n useHasParentActiveDescendantContext,\n} from './activedescendant';\nexport type {\n ActiveDescendantImperativeRef,\n ActiveDescendantOptions,\n ActiveDescendantContextValue,\n ActiveDescendantChangeEvent,\n} from './activedescendant';\nexport type {\n ARIAButtonSlotProps,\n ARIAButtonProps,\n ARIAButtonResultProps,\n ARIAButtonType,\n ARIAButtonElement,\n ARIAButtonElementIntersection,\n ARIAButtonAlteredProps,\n} from './button/index';\n\nexport {\n AriaLiveAnnouncer,\n renderAriaLiveAnnouncer_unstable,\n useAriaLiveAnnouncer_unstable,\n useAriaLiveAnnouncerContextValues_unstable,\n} from './AriaLiveAnnouncer/index';\nexport type { AriaLiveAnnouncerProps, AriaLiveAnnouncerState } from './AriaLiveAnnouncer/index';\n"],"names":["useARIAButtonShorthand","useARIAButtonProps","useActiveDescendant","ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE","ActiveDescendantContextProvider","useActiveDescendantContext","useHasParentActiveDescendantContext","AriaLiveAnnouncer","renderAriaLiveAnnouncer_unstable","useAriaLiveAnnouncer_unstable","useAriaLiveAnnouncerContextValues_unstable"],"mappings":"AAAA,SACE,mDAAmD;AACnDA,sBAAsB,EACtBC,kBAAkB,QACb,iBAAiB;AACxB,SACEC,mBAAmB,EACnBC,uCAAuC,EACvCC,+BAA+B,EAC/BC,0BAA0B,EAC1BC,mCAAmC,QAC9B,qBAAqB;AAiB5B,SACEC,iBAAiB,EACjBC,gCAAgC,EAChCC,6BAA6B,EAC7BC,0CAA0C,QACrC,4BAA4B"}
@@ -29,6 +29,7 @@ const activeDescendantContextDefaultValue = {
29
29
  find: noop,
30
30
  first: noop,
31
31
  focus: noop,
32
+ focusLastActive: noop,
32
33
  last: noop,
33
34
  next: noop,
34
35
  prev: noop,
@@ -1 +1 @@
1
- {"version":3,"sources":["ActiveDescendantContext.js"],"sourcesContent":["import * as React from 'react';\nconst noop = ()=>undefined;\nconst activeDescendantContextDefaultValue = {\n controller: {\n active: noop,\n blur: noop,\n find: noop,\n first: noop,\n focus: noop,\n last: noop,\n next: noop,\n prev: noop,\n showAttributes: noop,\n hideAttributes: noop\n }\n};\nconst ActiveDescendantContext = React.createContext(undefined);\nexport const ActiveDescendantContextProvider = ActiveDescendantContext.Provider;\nexport const useActiveDescendantContext = ()=>{\n var _React_useContext;\n return (_React_useContext = React.useContext(ActiveDescendantContext)) !== null && _React_useContext !== void 0 ? _React_useContext : activeDescendantContextDefaultValue;\n};\nexport const useHasParentActiveDescendantContext = ()=>!!React.useContext(ActiveDescendantContext);\n"],"names":["ActiveDescendantContextProvider","useActiveDescendantContext","useHasParentActiveDescendantContext","noop","undefined","activeDescendantContextDefaultValue","controller","active","blur","find","first","focus","last","next","prev","showAttributes","hideAttributes","ActiveDescendantContext","React","createContext","Provider","_React_useContext","useContext"],"mappings":";;;;;;;;;;;IAiBaA,+BAA+B;eAA/BA;;IACAC,0BAA0B;eAA1BA;;IAIAC,mCAAmC;eAAnCA;;;;iEAtBU;AACvB,MAAMC,OAAO,IAAIC;AACjB,MAAMC,sCAAsC;IACxCC,YAAY;QACRC,QAAQJ;QACRK,MAAML;QACNM,MAAMN;QACNO,OAAOP;QACPQ,OAAOR;QACPS,MAAMT;QACNU,MAAMV;QACNW,MAAMX;QACNY,gBAAgBZ;QAChBa,gBAAgBb;IACpB;AACJ;AACA,MAAMc,wCAA0BC,OAAMC,aAAa,CAACf;AAC7C,MAAMJ,kCAAkCiB,wBAAwBG,QAAQ;AACxE,MAAMnB,6BAA6B;IACtC,IAAIoB;IACJ,OAAO,AAACA,CAAAA,oBAAoBH,OAAMI,UAAU,CAACL,wBAAuB,MAAO,QAAQI,sBAAsB,KAAK,IAAIA,oBAAoBhB;AAC1I;AACO,MAAMH,sCAAsC,IAAI,CAAC,CAACgB,OAAMI,UAAU,CAACL"}
1
+ {"version":3,"sources":["ActiveDescendantContext.js"],"sourcesContent":["import * as React from 'react';\nconst noop = ()=>undefined;\nconst activeDescendantContextDefaultValue = {\n controller: {\n active: noop,\n blur: noop,\n find: noop,\n first: noop,\n focus: noop,\n focusLastActive: noop,\n last: noop,\n next: noop,\n prev: noop,\n showAttributes: noop,\n hideAttributes: noop\n }\n};\nconst ActiveDescendantContext = React.createContext(undefined);\nexport const ActiveDescendantContextProvider = ActiveDescendantContext.Provider;\nexport const useActiveDescendantContext = ()=>{\n var _React_useContext;\n return (_React_useContext = React.useContext(ActiveDescendantContext)) !== null && _React_useContext !== void 0 ? _React_useContext : activeDescendantContextDefaultValue;\n};\nexport const useHasParentActiveDescendantContext = ()=>!!React.useContext(ActiveDescendantContext);\n"],"names":["ActiveDescendantContextProvider","useActiveDescendantContext","useHasParentActiveDescendantContext","noop","undefined","activeDescendantContextDefaultValue","controller","active","blur","find","first","focus","focusLastActive","last","next","prev","showAttributes","hideAttributes","ActiveDescendantContext","React","createContext","Provider","_React_useContext","useContext"],"mappings":";;;;;;;;;;;IAkBaA,+BAA+B;eAA/BA;;IACAC,0BAA0B;eAA1BA;;IAIAC,mCAAmC;eAAnCA;;;;iEAvBU;AACvB,MAAMC,OAAO,IAAIC;AACjB,MAAMC,sCAAsC;IACxCC,YAAY;QACRC,QAAQJ;QACRK,MAAML;QACNM,MAAMN;QACNO,OAAOP;QACPQ,OAAOR;QACPS,iBAAiBT;QACjBU,MAAMV;QACNW,MAAMX;QACNY,MAAMZ;QACNa,gBAAgBb;QAChBc,gBAAgBd;IACpB;AACJ;AACA,MAAMe,wCAA0BC,OAAMC,aAAa,CAAChB;AAC7C,MAAMJ,kCAAkCkB,wBAAwBG,QAAQ;AACxE,MAAMpB,6BAA6B;IACtC,IAAIqB;IACJ,OAAO,AAACA,CAAAA,oBAAoBH,OAAMI,UAAU,CAACL,wBAAuB,MAAO,QAAQI,sBAAsB,KAAK,IAAIA,oBAAoBjB;AAC1I;AACO,MAAMH,sCAAsC,IAAI,CAAC,CAACiB,OAAMI,UAAU,CAACL"}
@@ -8,22 +8,57 @@ Object.defineProperty(exports, "scrollIntoView", {
8
8
  return scrollIntoView;
9
9
  }
10
10
  });
11
- const scrollIntoView = (target, scrollParent)=>{
12
- if (!target || !scrollParent) {
11
+ const scrollIntoView = (target)=>{
12
+ if (!target) {
13
13
  return;
14
14
  }
15
- if (scrollParent.offsetHeight >= scrollParent.scrollHeight) {
15
+ const scrollParent = findScrollableParent(target.parentElement);
16
+ if (!scrollParent) {
16
17
  return;
17
18
  }
18
- const { offsetHeight, offsetTop } = target;
19
+ const { offsetHeight } = target;
20
+ const offsetTop = getTotalOffsetTop(target, scrollParent);
21
+ const { scrollMarginTop, scrollMarginBottom } = getScrollMargins(target);
19
22
  const { offsetHeight: parentOffsetHeight, scrollTop } = scrollParent;
20
- const isAbove = offsetTop < scrollTop;
21
- const isBelow = offsetTop + offsetHeight > scrollTop + parentOffsetHeight;
23
+ const isAbove = offsetTop - scrollMarginTop < scrollTop;
24
+ const isBelow = offsetTop + offsetHeight + scrollMarginBottom > scrollTop + parentOffsetHeight;
22
25
  const buffer = 2;
23
26
  if (isAbove) {
24
- scrollParent.scrollTo(0, offsetTop - buffer);
27
+ scrollParent.scrollTo(0, offsetTop - scrollMarginTop - buffer);
28
+ } else if (isBelow) {
29
+ scrollParent.scrollTo(0, offsetTop + offsetHeight + scrollMarginBottom - parentOffsetHeight + buffer);
25
30
  }
26
- if (isBelow) {
27
- scrollParent.scrollTo(0, offsetTop - parentOffsetHeight + offsetHeight + buffer);
31
+ };
32
+ const findScrollableParent = (element)=>{
33
+ if (!element) {
34
+ return null;
35
+ }
36
+ if (element.scrollHeight > element.offsetHeight) {
37
+ return element;
38
+ }
39
+ return findScrollableParent(element.parentElement);
40
+ };
41
+ const getTotalOffsetTop = (element, scrollParent)=>{
42
+ if (!element || element === scrollParent) {
43
+ return 0;
28
44
  }
45
+ if (element.contains(scrollParent)) {
46
+ // subtract the scroll parent's offset top from the running total if the offsetParent is above it
47
+ return scrollParent.offsetTop * -1;
48
+ }
49
+ return element.offsetTop + getTotalOffsetTop(element.offsetParent, scrollParent);
50
+ };
51
+ const getScrollMargins = (element)=>{
52
+ const computedStyles = getComputedStyle(element);
53
+ var _getIntValueOfComputedStyle;
54
+ const scrollMarginTop = (_getIntValueOfComputedStyle = getIntValueOfComputedStyle(computedStyles.scrollMarginTop)) !== null && _getIntValueOfComputedStyle !== void 0 ? _getIntValueOfComputedStyle : getIntValueOfComputedStyle(computedStyles.scrollMarginBlockStart);
55
+ var _getIntValueOfComputedStyle1;
56
+ const scrollMarginBottom = (_getIntValueOfComputedStyle1 = getIntValueOfComputedStyle(computedStyles.scrollMarginBottom)) !== null && _getIntValueOfComputedStyle1 !== void 0 ? _getIntValueOfComputedStyle1 : getIntValueOfComputedStyle(computedStyles.scrollMarginBlockEnd);
57
+ return {
58
+ scrollMarginTop,
59
+ scrollMarginBottom
60
+ };
61
+ };
62
+ const getIntValueOfComputedStyle = (computedStyle)=>{
63
+ return computedStyle ? parseInt(computedStyle, 10) : 0;
29
64
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["scrollIntoView.js"],"sourcesContent":["export const scrollIntoView = (target, scrollParent)=>{\n if (!target || !scrollParent) {\n return;\n }\n if (scrollParent.offsetHeight >= scrollParent.scrollHeight) {\n return;\n }\n const { offsetHeight, offsetTop } = target;\n const { offsetHeight: parentOffsetHeight, scrollTop } = scrollParent;\n const isAbove = offsetTop < scrollTop;\n const isBelow = offsetTop + offsetHeight > scrollTop + parentOffsetHeight;\n const buffer = 2;\n if (isAbove) {\n scrollParent.scrollTo(0, offsetTop - buffer);\n }\n if (isBelow) {\n scrollParent.scrollTo(0, offsetTop - parentOffsetHeight + offsetHeight + buffer);\n }\n};\n"],"names":["scrollIntoView","target","scrollParent","offsetHeight","scrollHeight","offsetTop","parentOffsetHeight","scrollTop","isAbove","isBelow","buffer","scrollTo"],"mappings":";;;;+BAAaA;;;eAAAA;;;AAAN,MAAMA,iBAAiB,CAACC,QAAQC;IACnC,IAAI,CAACD,UAAU,CAACC,cAAc;QAC1B;IACJ;IACA,IAAIA,aAAaC,YAAY,IAAID,aAAaE,YAAY,EAAE;QACxD;IACJ;IACA,MAAM,EAAED,YAAY,EAAEE,SAAS,EAAE,GAAGJ;IACpC,MAAM,EAAEE,cAAcG,kBAAkB,EAAEC,SAAS,EAAE,GAAGL;IACxD,MAAMM,UAAUH,YAAYE;IAC5B,MAAME,UAAUJ,YAAYF,eAAeI,YAAYD;IACvD,MAAMI,SAAS;IACf,IAAIF,SAAS;QACTN,aAAaS,QAAQ,CAAC,GAAGN,YAAYK;IACzC;IACA,IAAID,SAAS;QACTP,aAAaS,QAAQ,CAAC,GAAGN,YAAYC,qBAAqBH,eAAeO;IAC7E;AACJ"}
1
+ {"version":3,"sources":["scrollIntoView.js"],"sourcesContent":["export const scrollIntoView = (target)=>{\n if (!target) {\n return;\n }\n const scrollParent = findScrollableParent(target.parentElement);\n if (!scrollParent) {\n return;\n }\n const { offsetHeight } = target;\n const offsetTop = getTotalOffsetTop(target, scrollParent);\n const { scrollMarginTop, scrollMarginBottom } = getScrollMargins(target);\n const { offsetHeight: parentOffsetHeight, scrollTop } = scrollParent;\n const isAbove = offsetTop - scrollMarginTop < scrollTop;\n const isBelow = offsetTop + offsetHeight + scrollMarginBottom > scrollTop + parentOffsetHeight;\n const buffer = 2;\n if (isAbove) {\n scrollParent.scrollTo(0, offsetTop - scrollMarginTop - buffer);\n } else if (isBelow) {\n scrollParent.scrollTo(0, offsetTop + offsetHeight + scrollMarginBottom - parentOffsetHeight + buffer);\n }\n};\nconst findScrollableParent = (element)=>{\n if (!element) {\n return null;\n }\n if (element.scrollHeight > element.offsetHeight) {\n return element;\n }\n return findScrollableParent(element.parentElement);\n};\nconst getTotalOffsetTop = (element, scrollParent)=>{\n if (!element || element === scrollParent) {\n return 0;\n }\n if (element.contains(scrollParent)) {\n // subtract the scroll parent's offset top from the running total if the offsetParent is above it\n return scrollParent.offsetTop * -1;\n }\n return element.offsetTop + getTotalOffsetTop(element.offsetParent, scrollParent);\n};\nconst getScrollMargins = (element)=>{\n const computedStyles = getComputedStyle(element);\n var _getIntValueOfComputedStyle;\n const scrollMarginTop = (_getIntValueOfComputedStyle = getIntValueOfComputedStyle(computedStyles.scrollMarginTop)) !== null && _getIntValueOfComputedStyle !== void 0 ? _getIntValueOfComputedStyle : getIntValueOfComputedStyle(computedStyles.scrollMarginBlockStart);\n var _getIntValueOfComputedStyle1;\n const scrollMarginBottom = (_getIntValueOfComputedStyle1 = getIntValueOfComputedStyle(computedStyles.scrollMarginBottom)) !== null && _getIntValueOfComputedStyle1 !== void 0 ? _getIntValueOfComputedStyle1 : getIntValueOfComputedStyle(computedStyles.scrollMarginBlockEnd);\n return {\n scrollMarginTop,\n scrollMarginBottom\n };\n};\nconst getIntValueOfComputedStyle = (computedStyle)=>{\n return computedStyle ? parseInt(computedStyle, 10) : 0;\n};\n"],"names":["scrollIntoView","target","scrollParent","findScrollableParent","parentElement","offsetHeight","offsetTop","getTotalOffsetTop","scrollMarginTop","scrollMarginBottom","getScrollMargins","parentOffsetHeight","scrollTop","isAbove","isBelow","buffer","scrollTo","element","scrollHeight","contains","offsetParent","computedStyles","getComputedStyle","_getIntValueOfComputedStyle","getIntValueOfComputedStyle","scrollMarginBlockStart","_getIntValueOfComputedStyle1","scrollMarginBlockEnd","computedStyle","parseInt"],"mappings":";;;;+BAAaA;;;eAAAA;;;AAAN,MAAMA,iBAAiB,CAACC;IAC3B,IAAI,CAACA,QAAQ;QACT;IACJ;IACA,MAAMC,eAAeC,qBAAqBF,OAAOG,aAAa;IAC9D,IAAI,CAACF,cAAc;QACf;IACJ;IACA,MAAM,EAAEG,YAAY,EAAE,GAAGJ;IACzB,MAAMK,YAAYC,kBAAkBN,QAAQC;IAC5C,MAAM,EAAEM,eAAe,EAAEC,kBAAkB,EAAE,GAAGC,iBAAiBT;IACjE,MAAM,EAAEI,cAAcM,kBAAkB,EAAEC,SAAS,EAAE,GAAGV;IACxD,MAAMW,UAAUP,YAAYE,kBAAkBI;IAC9C,MAAME,UAAUR,YAAYD,eAAeI,qBAAqBG,YAAYD;IAC5E,MAAMI,SAAS;IACf,IAAIF,SAAS;QACTX,aAAac,QAAQ,CAAC,GAAGV,YAAYE,kBAAkBO;IAC3D,OAAO,IAAID,SAAS;QAChBZ,aAAac,QAAQ,CAAC,GAAGV,YAAYD,eAAeI,qBAAqBE,qBAAqBI;IAClG;AACJ;AACA,MAAMZ,uBAAuB,CAACc;IAC1B,IAAI,CAACA,SAAS;QACV,OAAO;IACX;IACA,IAAIA,QAAQC,YAAY,GAAGD,QAAQZ,YAAY,EAAE;QAC7C,OAAOY;IACX;IACA,OAAOd,qBAAqBc,QAAQb,aAAa;AACrD;AACA,MAAMG,oBAAoB,CAACU,SAASf;IAChC,IAAI,CAACe,WAAWA,YAAYf,cAAc;QACtC,OAAO;IACX;IACA,IAAIe,QAAQE,QAAQ,CAACjB,eAAe;QAChC,iGAAiG;QACjG,OAAOA,aAAaI,SAAS,GAAG,CAAC;IACrC;IACA,OAAOW,QAAQX,SAAS,GAAGC,kBAAkBU,QAAQG,YAAY,EAAElB;AACvE;AACA,MAAMQ,mBAAmB,CAACO;IACtB,MAAMI,iBAAiBC,iBAAiBL;IACxC,IAAIM;IACJ,MAAMf,kBAAkB,AAACe,CAAAA,8BAA8BC,2BAA2BH,eAAeb,eAAe,CAAA,MAAO,QAAQe,gCAAgC,KAAK,IAAIA,8BAA8BC,2BAA2BH,eAAeI,sBAAsB;IACtQ,IAAIC;IACJ,MAAMjB,qBAAqB,AAACiB,CAAAA,+BAA+BF,2BAA2BH,eAAeZ,kBAAkB,CAAA,MAAO,QAAQiB,iCAAiC,KAAK,IAAIA,+BAA+BF,2BAA2BH,eAAeM,oBAAoB;IAC7Q,OAAO;QACHnB;QACAC;IACJ;AACJ;AACA,MAAMe,6BAA6B,CAACI;IAChC,OAAOA,gBAAgBC,SAASD,eAAe,MAAM;AACzD"}
@@ -2,9 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "useActiveDescendant", {
6
- enumerable: true,
7
- get: function() {
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ createActiveDescendantChangeEvent: function() {
13
+ return createActiveDescendantChangeEvent;
14
+ },
15
+ useActiveDescendant: function() {
8
16
  return useActiveDescendant;
9
17
  }
10
18
  });
@@ -15,10 +23,17 @@ const _reacttabster = require("@fluentui/react-tabster");
15
23
  const _useOptionWalker = require("./useOptionWalker");
16
24
  const _constants = require("./constants");
17
25
  const _scrollIntoView = require("./scrollIntoView");
26
+ const createActiveDescendantChangeEvent = (detail)=>new CustomEvent('activedescendantchange', {
27
+ bubbles: true,
28
+ cancelable: false,
29
+ composed: true,
30
+ detail
31
+ });
18
32
  function useActiveDescendant(options) {
19
33
  const { imperativeRef, matchOption: matchOptionUnstable } = options;
20
34
  const focusVisibleRef = _react.useRef(false);
21
35
  const activeIdRef = _react.useRef(null);
36
+ const lastActiveIdRef = _react.useRef(null);
22
37
  const activeParentRef = _react.useRef(null);
23
38
  const attributeVisibilityRef = _react.useRef(true);
24
39
  const removeAttribute = _react.useCallback(()=>{
@@ -64,7 +79,10 @@ function useActiveDescendant(options) {
64
79
  active.removeAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);
65
80
  }
66
81
  removeAttribute();
82
+ lastActiveIdRef.current = activeIdRef.current;
67
83
  activeIdRef.current = null;
84
+ var _active_id;
85
+ return (_active_id = active === null || active === void 0 ? void 0 : active.id) !== null && _active_id !== void 0 ? _active_id : null;
68
86
  }, [
69
87
  getActiveDescendant,
70
88
  removeAttribute
@@ -73,15 +91,19 @@ function useActiveDescendant(options) {
73
91
  if (!nextActive) {
74
92
  return;
75
93
  }
76
- blurActiveDescendant();
77
- (0, _scrollIntoView.scrollIntoView)(nextActive, listboxRef.current);
94
+ const previousActiveId = blurActiveDescendant();
95
+ (0, _scrollIntoView.scrollIntoView)(nextActive);
78
96
  setAttribute(nextActive.id);
79
97
  nextActive.setAttribute(_constants.ACTIVEDESCENDANT_ATTRIBUTE, '');
80
98
  if (focusVisibleRef.current) {
81
99
  nextActive.setAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');
82
100
  }
101
+ const event = createActiveDescendantChangeEvent({
102
+ id: nextActive.id,
103
+ previousId: previousActiveId
104
+ });
105
+ nextActive.dispatchEvent(event);
83
106
  }, [
84
- listboxRef,
85
107
  blurActiveDescendant,
86
108
  setAttribute
87
109
  ]);
@@ -140,6 +162,16 @@ function useActiveDescendant(options) {
140
162
  focusActiveDescendant(target);
141
163
  }
142
164
  },
165
+ focusLastActive: ()=>{
166
+ if (!listboxRef.current || !lastActiveIdRef.current) {
167
+ return;
168
+ }
169
+ const target = listboxRef.current.querySelector(`#${lastActiveIdRef.current}`);
170
+ if (target) {
171
+ focusActiveDescendant(target);
172
+ return true;
173
+ }
174
+ },
143
175
  find (predicate, { passive, startFrom } = {}) {
144
176
  const target = optionWalker.find(predicate, startFrom);
145
177
  if (!passive) {
@@ -1 +1 @@
1
- {"version":3,"sources":["useActiveDescendant.js"],"sourcesContent":["import * as React from 'react';\nimport { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { useOnKeyboardNavigationChange } from '@fluentui/react-tabster';\nimport { useOptionWalker } from './useOptionWalker';\nimport { ACTIVEDESCENDANT_ATTRIBUTE, ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE } from './constants';\nimport { scrollIntoView } from './scrollIntoView';\nexport function useActiveDescendant(options) {\n const { imperativeRef, matchOption: matchOptionUnstable } = options;\n const focusVisibleRef = React.useRef(false);\n const activeIdRef = React.useRef(null);\n const activeParentRef = React.useRef(null);\n const attributeVisibilityRef = React.useRef(true);\n const removeAttribute = React.useCallback(()=>{\n var _activeParentRef_current;\n (_activeParentRef_current = activeParentRef.current) === null || _activeParentRef_current === void 0 ? void 0 : _activeParentRef_current.removeAttribute('aria-activedescendant');\n }, []);\n const setAttribute = React.useCallback((id)=>{\n if (id) {\n activeIdRef.current = id;\n }\n if (attributeVisibilityRef.current && activeIdRef.current) {\n var _activeParentRef_current;\n (_activeParentRef_current = activeParentRef.current) === null || _activeParentRef_current === void 0 ? void 0 : _activeParentRef_current.setAttribute('aria-activedescendant', activeIdRef.current);\n }\n }, []);\n useOnKeyboardNavigationChange((isNavigatingWithKeyboard)=>{\n focusVisibleRef.current = isNavigatingWithKeyboard;\n const active = getActiveDescendant();\n if (!active) {\n return;\n }\n if (isNavigatingWithKeyboard) {\n active.setAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');\n } else {\n active.removeAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);\n }\n });\n const matchOption = useEventCallback(matchOptionUnstable);\n const listboxRef = React.useRef(null);\n const { optionWalker, listboxCallbackRef } = useOptionWalker({\n matchOption\n });\n const getActiveDescendant = React.useCallback(()=>{\n var _listboxRef_current;\n return (_listboxRef_current = listboxRef.current) === null || _listboxRef_current === void 0 ? void 0 : _listboxRef_current.querySelector(`#${activeIdRef.current}`);\n }, [\n listboxRef\n ]);\n const blurActiveDescendant = React.useCallback(()=>{\n const active = getActiveDescendant();\n if (active) {\n active.removeAttribute(ACTIVEDESCENDANT_ATTRIBUTE);\n active.removeAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);\n }\n removeAttribute();\n activeIdRef.current = null;\n }, [\n getActiveDescendant,\n removeAttribute\n ]);\n const focusActiveDescendant = React.useCallback((nextActive)=>{\n if (!nextActive) {\n return;\n }\n blurActiveDescendant();\n scrollIntoView(nextActive, listboxRef.current);\n setAttribute(nextActive.id);\n nextActive.setAttribute(ACTIVEDESCENDANT_ATTRIBUTE, '');\n if (focusVisibleRef.current) {\n nextActive.setAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');\n }\n }, [\n listboxRef,\n blurActiveDescendant,\n setAttribute\n ]);\n const controller = React.useMemo(()=>({\n first: ({ passive } = {})=>{\n const first = optionWalker.first();\n if (!passive) {\n focusActiveDescendant(first);\n }\n return first === null || first === void 0 ? void 0 : first.id;\n },\n last: ({ passive } = {})=>{\n const last = optionWalker.last();\n if (!passive) {\n focusActiveDescendant(last);\n }\n return last === null || last === void 0 ? void 0 : last.id;\n },\n next: ({ passive } = {})=>{\n const active = getActiveDescendant();\n if (!active) {\n return;\n }\n optionWalker.setCurrent(active);\n const next = optionWalker.next();\n if (!passive) {\n focusActiveDescendant(next);\n }\n return next === null || next === void 0 ? void 0 : next.id;\n },\n prev: ({ passive } = {})=>{\n const active = getActiveDescendant();\n if (!active) {\n return;\n }\n optionWalker.setCurrent(active);\n const next = optionWalker.prev();\n if (!passive) {\n focusActiveDescendant(next);\n }\n return next === null || next === void 0 ? void 0 : next.id;\n },\n blur: ()=>{\n blurActiveDescendant();\n },\n active: ()=>{\n var _getActiveDescendant;\n return (_getActiveDescendant = getActiveDescendant()) === null || _getActiveDescendant === void 0 ? void 0 : _getActiveDescendant.id;\n },\n focus: (id)=>{\n if (!listboxRef.current) {\n return;\n }\n const target = listboxRef.current.querySelector(`#${id}`);\n if (target) {\n focusActiveDescendant(target);\n }\n },\n find (predicate, { passive, startFrom } = {}) {\n const target = optionWalker.find(predicate, startFrom);\n if (!passive) {\n focusActiveDescendant(target);\n }\n return target === null || target === void 0 ? void 0 : target.id;\n },\n showAttributes () {\n attributeVisibilityRef.current = true;\n setAttribute();\n },\n hideAttributes () {\n attributeVisibilityRef.current = false;\n removeAttribute();\n }\n }), [\n optionWalker,\n listboxRef,\n setAttribute,\n removeAttribute,\n focusActiveDescendant,\n blurActiveDescendant,\n getActiveDescendant\n ]);\n React.useImperativeHandle(imperativeRef, ()=>controller);\n return {\n listboxRef: useMergedRefs(listboxRef, listboxCallbackRef),\n activeParentRef,\n controller\n };\n}\n"],"names":["useActiveDescendant","options","imperativeRef","matchOption","matchOptionUnstable","focusVisibleRef","React","useRef","activeIdRef","activeParentRef","attributeVisibilityRef","removeAttribute","useCallback","_activeParentRef_current","current","setAttribute","id","useOnKeyboardNavigationChange","isNavigatingWithKeyboard","active","getActiveDescendant","ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE","useEventCallback","listboxRef","optionWalker","listboxCallbackRef","useOptionWalker","_listboxRef_current","querySelector","blurActiveDescendant","ACTIVEDESCENDANT_ATTRIBUTE","focusActiveDescendant","nextActive","scrollIntoView","controller","useMemo","first","passive","last","next","setCurrent","prev","blur","_getActiveDescendant","focus","target","find","predicate","startFrom","showAttributes","hideAttributes","useImperativeHandle","useMergedRefs"],"mappings":"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"}
1
+ {"version":3,"sources":["useActiveDescendant.js"],"sourcesContent":["import * as React from 'react';\nimport { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { useOnKeyboardNavigationChange } from '@fluentui/react-tabster';\nimport { useOptionWalker } from './useOptionWalker';\nimport { ACTIVEDESCENDANT_ATTRIBUTE, ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE } from './constants';\nimport { scrollIntoView } from './scrollIntoView';\nexport const createActiveDescendantChangeEvent = (detail)=>new CustomEvent('activedescendantchange', {\n bubbles: true,\n cancelable: false,\n composed: true,\n detail\n });\nexport function useActiveDescendant(options) {\n const { imperativeRef, matchOption: matchOptionUnstable } = options;\n const focusVisibleRef = React.useRef(false);\n const activeIdRef = React.useRef(null);\n const lastActiveIdRef = React.useRef(null);\n const activeParentRef = React.useRef(null);\n const attributeVisibilityRef = React.useRef(true);\n const removeAttribute = React.useCallback(()=>{\n var _activeParentRef_current;\n (_activeParentRef_current = activeParentRef.current) === null || _activeParentRef_current === void 0 ? void 0 : _activeParentRef_current.removeAttribute('aria-activedescendant');\n }, []);\n const setAttribute = React.useCallback((id)=>{\n if (id) {\n activeIdRef.current = id;\n }\n if (attributeVisibilityRef.current && activeIdRef.current) {\n var _activeParentRef_current;\n (_activeParentRef_current = activeParentRef.current) === null || _activeParentRef_current === void 0 ? void 0 : _activeParentRef_current.setAttribute('aria-activedescendant', activeIdRef.current);\n }\n }, []);\n useOnKeyboardNavigationChange((isNavigatingWithKeyboard)=>{\n focusVisibleRef.current = isNavigatingWithKeyboard;\n const active = getActiveDescendant();\n if (!active) {\n return;\n }\n if (isNavigatingWithKeyboard) {\n active.setAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');\n } else {\n active.removeAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);\n }\n });\n const matchOption = useEventCallback(matchOptionUnstable);\n const listboxRef = React.useRef(null);\n const { optionWalker, listboxCallbackRef } = useOptionWalker({\n matchOption\n });\n const getActiveDescendant = React.useCallback(()=>{\n var _listboxRef_current;\n return (_listboxRef_current = listboxRef.current) === null || _listboxRef_current === void 0 ? void 0 : _listboxRef_current.querySelector(`#${activeIdRef.current}`);\n }, [\n listboxRef\n ]);\n const blurActiveDescendant = React.useCallback(()=>{\n const active = getActiveDescendant();\n if (active) {\n active.removeAttribute(ACTIVEDESCENDANT_ATTRIBUTE);\n active.removeAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);\n }\n removeAttribute();\n lastActiveIdRef.current = activeIdRef.current;\n activeIdRef.current = null;\n var _active_id;\n return (_active_id = active === null || active === void 0 ? void 0 : active.id) !== null && _active_id !== void 0 ? _active_id : null;\n }, [\n getActiveDescendant,\n removeAttribute\n ]);\n const focusActiveDescendant = React.useCallback((nextActive)=>{\n if (!nextActive) {\n return;\n }\n const previousActiveId = blurActiveDescendant();\n scrollIntoView(nextActive);\n setAttribute(nextActive.id);\n nextActive.setAttribute(ACTIVEDESCENDANT_ATTRIBUTE, '');\n if (focusVisibleRef.current) {\n nextActive.setAttribute(ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');\n }\n const event = createActiveDescendantChangeEvent({\n id: nextActive.id,\n previousId: previousActiveId\n });\n nextActive.dispatchEvent(event);\n }, [\n blurActiveDescendant,\n setAttribute\n ]);\n const controller = React.useMemo(()=>({\n first: ({ passive } = {})=>{\n const first = optionWalker.first();\n if (!passive) {\n focusActiveDescendant(first);\n }\n return first === null || first === void 0 ? void 0 : first.id;\n },\n last: ({ passive } = {})=>{\n const last = optionWalker.last();\n if (!passive) {\n focusActiveDescendant(last);\n }\n return last === null || last === void 0 ? void 0 : last.id;\n },\n next: ({ passive } = {})=>{\n const active = getActiveDescendant();\n if (!active) {\n return;\n }\n optionWalker.setCurrent(active);\n const next = optionWalker.next();\n if (!passive) {\n focusActiveDescendant(next);\n }\n return next === null || next === void 0 ? void 0 : next.id;\n },\n prev: ({ passive } = {})=>{\n const active = getActiveDescendant();\n if (!active) {\n return;\n }\n optionWalker.setCurrent(active);\n const next = optionWalker.prev();\n if (!passive) {\n focusActiveDescendant(next);\n }\n return next === null || next === void 0 ? void 0 : next.id;\n },\n blur: ()=>{\n blurActiveDescendant();\n },\n active: ()=>{\n var _getActiveDescendant;\n return (_getActiveDescendant = getActiveDescendant()) === null || _getActiveDescendant === void 0 ? void 0 : _getActiveDescendant.id;\n },\n focus: (id)=>{\n if (!listboxRef.current) {\n return;\n }\n const target = listboxRef.current.querySelector(`#${id}`);\n if (target) {\n focusActiveDescendant(target);\n }\n },\n focusLastActive: ()=>{\n if (!listboxRef.current || !lastActiveIdRef.current) {\n return;\n }\n const target = listboxRef.current.querySelector(`#${lastActiveIdRef.current}`);\n if (target) {\n focusActiveDescendant(target);\n return true;\n }\n },\n find (predicate, { passive, startFrom } = {}) {\n const target = optionWalker.find(predicate, startFrom);\n if (!passive) {\n focusActiveDescendant(target);\n }\n return target === null || target === void 0 ? void 0 : target.id;\n },\n showAttributes () {\n attributeVisibilityRef.current = true;\n setAttribute();\n },\n hideAttributes () {\n attributeVisibilityRef.current = false;\n removeAttribute();\n }\n }), [\n optionWalker,\n listboxRef,\n setAttribute,\n removeAttribute,\n focusActiveDescendant,\n blurActiveDescendant,\n getActiveDescendant\n ]);\n React.useImperativeHandle(imperativeRef, ()=>controller);\n return {\n listboxRef: useMergedRefs(listboxRef, listboxCallbackRef),\n activeParentRef,\n controller\n };\n}\n"],"names":["createActiveDescendantChangeEvent","useActiveDescendant","detail","CustomEvent","bubbles","cancelable","composed","options","imperativeRef","matchOption","matchOptionUnstable","focusVisibleRef","React","useRef","activeIdRef","lastActiveIdRef","activeParentRef","attributeVisibilityRef","removeAttribute","useCallback","_activeParentRef_current","current","setAttribute","id","useOnKeyboardNavigationChange","isNavigatingWithKeyboard","active","getActiveDescendant","ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE","useEventCallback","listboxRef","optionWalker","listboxCallbackRef","useOptionWalker","_listboxRef_current","querySelector","blurActiveDescendant","ACTIVEDESCENDANT_ATTRIBUTE","_active_id","focusActiveDescendant","nextActive","previousActiveId","scrollIntoView","event","previousId","dispatchEvent","controller","useMemo","first","passive","last","next","setCurrent","prev","blur","_getActiveDescendant","focus","target","focusLastActive","find","predicate","startFrom","showAttributes","hideAttributes","useImperativeHandle","useMergedRefs"],"mappings":";;;;;;;;;;;IAMaA,iCAAiC;eAAjCA;;IAMGC,mBAAmB;eAAnBA;;;;iEAZO;gCACyB;8BACF;iCACd;2BACoD;gCACrD;AACxB,MAAMD,oCAAoC,CAACE,SAAS,IAAIC,YAAY,0BAA0B;QAC7FC,SAAS;QACTC,YAAY;QACZC,UAAU;QACVJ;IACJ;AACG,SAASD,oBAAoBM,OAAO;IACvC,MAAM,EAAEC,aAAa,EAAEC,aAAaC,mBAAmB,EAAE,GAAGH;IAC5D,MAAMI,kBAAkBC,OAAMC,MAAM,CAAC;IACrC,MAAMC,cAAcF,OAAMC,MAAM,CAAC;IACjC,MAAME,kBAAkBH,OAAMC,MAAM,CAAC;IACrC,MAAMG,kBAAkBJ,OAAMC,MAAM,CAAC;IACrC,MAAMI,yBAAyBL,OAAMC,MAAM,CAAC;IAC5C,MAAMK,kBAAkBN,OAAMO,WAAW,CAAC;QACtC,IAAIC;QACHA,CAAAA,2BAA2BJ,gBAAgBK,OAAO,AAAD,MAAO,QAAQD,6BAA6B,KAAK,IAAI,KAAK,IAAIA,yBAAyBF,eAAe,CAAC;IAC7J,GAAG,EAAE;IACL,MAAMI,eAAeV,OAAMO,WAAW,CAAC,CAACI;QACpC,IAAIA,IAAI;YACJT,YAAYO,OAAO,GAAGE;QAC1B;QACA,IAAIN,uBAAuBI,OAAO,IAAIP,YAAYO,OAAO,EAAE;YACvD,IAAID;YACHA,CAAAA,2BAA2BJ,gBAAgBK,OAAO,AAAD,MAAO,QAAQD,6BAA6B,KAAK,IAAI,KAAK,IAAIA,yBAAyBE,YAAY,CAAC,yBAAyBR,YAAYO,OAAO;QACtM;IACJ,GAAG,EAAE;IACLG,IAAAA,2CAA6B,EAAC,CAACC;QAC3Bd,gBAAgBU,OAAO,GAAGI;QAC1B,MAAMC,SAASC;QACf,IAAI,CAACD,QAAQ;YACT;QACJ;QACA,IAAID,0BAA0B;YAC1BC,OAAOJ,YAAY,CAACM,kDAAuC,EAAE;QACjE,OAAO;YACHF,OAAOR,eAAe,CAACU,kDAAuC;QAClE;IACJ;IACA,MAAMnB,cAAcoB,IAAAA,gCAAgB,EAACnB;IACrC,MAAMoB,aAAalB,OAAMC,MAAM,CAAC;IAChC,MAAM,EAAEkB,YAAY,EAAEC,kBAAkB,EAAE,GAAGC,IAAAA,gCAAe,EAAC;QACzDxB;IACJ;IACA,MAAMkB,sBAAsBf,OAAMO,WAAW,CAAC;QAC1C,IAAIe;QACJ,OAAO,AAACA,CAAAA,sBAAsBJ,WAAWT,OAAO,AAAD,MAAO,QAAQa,wBAAwB,KAAK,IAAI,KAAK,IAAIA,oBAAoBC,aAAa,CAAC,CAAC,CAAC,EAAErB,YAAYO,OAAO,CAAC,CAAC;IACvK,GAAG;QACCS;KACH;IACD,MAAMM,uBAAuBxB,OAAMO,WAAW,CAAC;QAC3C,MAAMO,SAASC;QACf,IAAID,QAAQ;YACRA,OAAOR,eAAe,CAACmB,qCAA0B;YACjDX,OAAOR,eAAe,CAACU,kDAAuC;QAClE;QACAV;QACAH,gBAAgBM,OAAO,GAAGP,YAAYO,OAAO;QAC7CP,YAAYO,OAAO,GAAG;QACtB,IAAIiB;QACJ,OAAO,AAACA,CAAAA,aAAaZ,WAAW,QAAQA,WAAW,KAAK,IAAI,KAAK,IAAIA,OAAOH,EAAE,AAAD,MAAO,QAAQe,eAAe,KAAK,IAAIA,aAAa;IACrI,GAAG;QACCX;QACAT;KACH;IACD,MAAMqB,wBAAwB3B,OAAMO,WAAW,CAAC,CAACqB;QAC7C,IAAI,CAACA,YAAY;YACb;QACJ;QACA,MAAMC,mBAAmBL;QACzBM,IAAAA,8BAAc,EAACF;QACflB,aAAakB,WAAWjB,EAAE;QAC1BiB,WAAWlB,YAAY,CAACe,qCAA0B,EAAE;QACpD,IAAI1B,gBAAgBU,OAAO,EAAE;YACzBmB,WAAWlB,YAAY,CAACM,kDAAuC,EAAE;QACrE;QACA,MAAMe,QAAQ3C,kCAAkC;YAC5CuB,IAAIiB,WAAWjB,EAAE;YACjBqB,YAAYH;QAChB;QACAD,WAAWK,aAAa,CAACF;IAC7B,GAAG;QACCP;QACAd;KACH;IACD,MAAMwB,aAAalC,OAAMmC,OAAO,CAAC,IAAK,CAAA;YAC9BC,OAAO,CAAC,EAAEC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACpB,MAAMD,QAAQjB,aAAaiB,KAAK;gBAChC,IAAI,CAACC,SAAS;oBACVV,sBAAsBS;gBAC1B;gBACA,OAAOA,UAAU,QAAQA,UAAU,KAAK,IAAI,KAAK,IAAIA,MAAMzB,EAAE;YACjE;YACA2B,MAAM,CAAC,EAAED,OAAO,EAAE,GAAG,CAAC,CAAC;gBACnB,MAAMC,OAAOnB,aAAamB,IAAI;gBAC9B,IAAI,CAACD,SAAS;oBACVV,sBAAsBW;gBAC1B;gBACA,OAAOA,SAAS,QAAQA,SAAS,KAAK,IAAI,KAAK,IAAIA,KAAK3B,EAAE;YAC9D;YACA4B,MAAM,CAAC,EAAEF,OAAO,EAAE,GAAG,CAAC,CAAC;gBACnB,MAAMvB,SAASC;gBACf,IAAI,CAACD,QAAQ;oBACT;gBACJ;gBACAK,aAAaqB,UAAU,CAAC1B;gBACxB,MAAMyB,OAAOpB,aAAaoB,IAAI;gBAC9B,IAAI,CAACF,SAAS;oBACVV,sBAAsBY;gBAC1B;gBACA,OAAOA,SAAS,QAAQA,SAAS,KAAK,IAAI,KAAK,IAAIA,KAAK5B,EAAE;YAC9D;YACA8B,MAAM,CAAC,EAAEJ,OAAO,EAAE,GAAG,CAAC,CAAC;gBACnB,MAAMvB,SAASC;gBACf,IAAI,CAACD,QAAQ;oBACT;gBACJ;gBACAK,aAAaqB,UAAU,CAAC1B;gBACxB,MAAMyB,OAAOpB,aAAasB,IAAI;gBAC9B,IAAI,CAACJ,SAAS;oBACVV,sBAAsBY;gBAC1B;gBACA,OAAOA,SAAS,QAAQA,SAAS,KAAK,IAAI,KAAK,IAAIA,KAAK5B,EAAE;YAC9D;YACA+B,MAAM;gBACFlB;YACJ;YACAV,QAAQ;gBACJ,IAAI6B;gBACJ,OAAO,AAACA,CAAAA,uBAAuB5B,qBAAoB,MAAO,QAAQ4B,yBAAyB,KAAK,IAAI,KAAK,IAAIA,qBAAqBhC,EAAE;YACxI;YACAiC,OAAO,CAACjC;gBACJ,IAAI,CAACO,WAAWT,OAAO,EAAE;oBACrB;gBACJ;gBACA,MAAMoC,SAAS3B,WAAWT,OAAO,CAACc,aAAa,CAAC,CAAC,CAAC,EAAEZ,GAAG,CAAC;gBACxD,IAAIkC,QAAQ;oBACRlB,sBAAsBkB;gBAC1B;YACJ;YACAC,iBAAiB;gBACb,IAAI,CAAC5B,WAAWT,OAAO,IAAI,CAACN,gBAAgBM,OAAO,EAAE;oBACjD;gBACJ;gBACA,MAAMoC,SAAS3B,WAAWT,OAAO,CAACc,aAAa,CAAC,CAAC,CAAC,EAAEpB,gBAAgBM,OAAO,CAAC,CAAC;gBAC7E,IAAIoC,QAAQ;oBACRlB,sBAAsBkB;oBACtB,OAAO;gBACX;YACJ;YACAE,MAAMC,SAAS,EAAE,EAAEX,OAAO,EAAEY,SAAS,EAAE,GAAG,CAAC,CAAC;gBACxC,MAAMJ,SAAS1B,aAAa4B,IAAI,CAACC,WAAWC;gBAC5C,IAAI,CAACZ,SAAS;oBACVV,sBAAsBkB;gBAC1B;gBACA,OAAOA,WAAW,QAAQA,WAAW,KAAK,IAAI,KAAK,IAAIA,OAAOlC,EAAE;YACpE;YACAuC;gBACI7C,uBAAuBI,OAAO,GAAG;gBACjCC;YACJ;YACAyC;gBACI9C,uBAAuBI,OAAO,GAAG;gBACjCH;YACJ;QACJ,CAAA,GAAI;QACJa;QACAD;QACAR;QACAJ;QACAqB;QACAH;QACAT;KACH;IACDf,OAAMoD,mBAAmB,CAACxD,eAAe,IAAIsC;IAC7C,OAAO;QACHhB,YAAYmC,IAAAA,6BAAa,EAACnC,YAAYE;QACtChB;QACA8B;IACJ;AACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui/react-aria",
3
- "version": "9.10.5",
3
+ "version": "9.11.0",
4
4
  "description": "React helper to ensure ARIA",
5
5
  "main": "lib-commonjs/index.js",
6
6
  "module": "lib/index.js",
@@ -36,7 +36,7 @@
36
36
  "@fluentui/keyboard-keys": "^9.0.7",
37
37
  "@fluentui/react-shared-contexts": "^9.17.0",
38
38
  "@fluentui/react-jsx-runtime": "^9.0.36",
39
- "@fluentui/react-tabster": "^9.20.1",
39
+ "@fluentui/react-tabster": "^9.21.0",
40
40
  "@fluentui/react-utilities": "^9.18.7",
41
41
  "@swc/helpers": "^0.5.1"
42
42
  },