@elliemae/ds-form-layout-autocomplete 3.14.8 → 3.14.10

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.
Files changed (54) hide show
  1. package/dist/cjs/AutocompleteCTX.js +2 -22
  2. package/dist/cjs/AutocompleteCTX.js.map +2 -2
  3. package/dist/cjs/config/useAutocomplete.js +17 -45
  4. package/dist/cjs/config/useAutocomplete.js.map +3 -3
  5. package/dist/cjs/config/usePopoverLogic.js +105 -0
  6. package/dist/cjs/config/usePopoverLogic.js.map +7 -0
  7. package/dist/cjs/{sharedTypes.js → config/useRefs.js} +16 -3
  8. package/dist/cjs/config/useRefs.js.map +7 -0
  9. package/dist/cjs/config/useVirtualization.js +62 -0
  10. package/dist/cjs/config/useVirtualization.js.map +7 -0
  11. package/dist/cjs/parts/A11yFocusedOption.js +3 -3
  12. package/dist/cjs/parts/A11yFocusedOption.js.map +2 -2
  13. package/dist/cjs/parts/container/Container.js +16 -15
  14. package/dist/cjs/parts/container/Container.js.map +2 -2
  15. package/dist/cjs/parts/container/useKeyboardNavigation.js +15 -18
  16. package/dist/cjs/parts/container/useKeyboardNavigation.js.map +2 -2
  17. package/dist/cjs/parts/menu-list/MenuList.js +6 -3
  18. package/dist/cjs/parts/menu-list/MenuList.js.map +2 -2
  19. package/dist/cjs/parts/menu-list/useItemRenderer.js +5 -3
  20. package/dist/cjs/parts/menu-list/useItemRenderer.js.map +2 -2
  21. package/dist/cjs/react-desc-prop-types.js +7 -0
  22. package/dist/cjs/react-desc-prop-types.js.map +2 -2
  23. package/dist/esm/AutocompleteCTX.js +3 -23
  24. package/dist/esm/AutocompleteCTX.js.map +2 -2
  25. package/dist/esm/config/useAutocomplete.js +17 -45
  26. package/dist/esm/config/useAutocomplete.js.map +3 -3
  27. package/dist/esm/config/usePopoverLogic.js +79 -0
  28. package/dist/esm/config/usePopoverLogic.js.map +7 -0
  29. package/dist/esm/config/useRefs.js +11 -0
  30. package/dist/esm/config/useRefs.js.map +7 -0
  31. package/dist/esm/config/useVirtualization.js +36 -0
  32. package/dist/esm/config/useVirtualization.js.map +7 -0
  33. package/dist/esm/parts/A11yFocusedOption.js +3 -3
  34. package/dist/esm/parts/A11yFocusedOption.js.map +2 -2
  35. package/dist/esm/parts/container/Container.js +17 -16
  36. package/dist/esm/parts/container/Container.js.map +2 -2
  37. package/dist/esm/parts/container/useKeyboardNavigation.js +15 -18
  38. package/dist/esm/parts/container/useKeyboardNavigation.js.map +2 -2
  39. package/dist/esm/parts/menu-list/MenuList.js +6 -3
  40. package/dist/esm/parts/menu-list/MenuList.js.map +2 -2
  41. package/dist/esm/parts/menu-list/useItemRenderer.js +5 -3
  42. package/dist/esm/parts/menu-list/useItemRenderer.js.map +2 -2
  43. package/dist/esm/react-desc-prop-types.js +7 -0
  44. package/dist/esm/react-desc-prop-types.js.map +2 -2
  45. package/dist/types/AutocompleteCTX.d.ts +2 -4
  46. package/dist/types/config/useAutocomplete.d.ts +12 -2
  47. package/dist/types/config/usePopoverLogic.d.ts +12 -0
  48. package/dist/types/config/useRefs.d.ts +5 -0
  49. package/dist/types/react-desc-prop-types.d.ts +2 -1
  50. package/package.json +6 -6
  51. package/dist/cjs/sharedTypes.js.map +0 -7
  52. package/dist/esm/sharedTypes.js +0 -2
  53. package/dist/esm/sharedTypes.js.map +0 -7
  54. package/dist/types/sharedTypes.d.ts +0 -18
@@ -25,32 +25,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
25
25
  var AutocompleteCTX_exports = {};
26
26
  __export(AutocompleteCTX_exports, {
27
27
  AutocompleteContext: () => AutocompleteContext,
28
- default: () => AutocompleteCTX_default,
29
- defaultProps: () => defaultProps
28
+ default: () => AutocompleteCTX_default
30
29
  });
31
30
  module.exports = __toCommonJS(AutocompleteCTX_exports);
32
31
  var React = __toESM(require("react"));
33
32
  var import_react = require("react");
34
- const noop = () => {
35
- };
36
- const defaultProps = {
37
- zIndex: 10,
38
- withoutPortal: false,
39
- startPlacementPreference: "bottom-start",
40
- placementOrderPreference: ["bottom-start", "bottom-end"]
41
- };
42
- const defaultContext = {
43
- props: defaultProps,
44
- showPopover: false,
45
- setShowPopover: noop,
46
- scrollOptionIntoView: noop,
47
- referenceElement: null,
48
- setReferenceElement: noop,
49
- inputRef: (0, import_react.createRef)(),
50
- listRef: (0, import_react.createRef)(),
51
- focusOptionIdx: "",
52
- setCurrentOption: noop
53
- };
33
+ const defaultContext = {};
54
34
  const AutocompleteContext = (0, import_react.createContext)(defaultContext);
55
35
  var AutocompleteCTX_default = AutocompleteContext;
56
36
  //# sourceMappingURL=AutocompleteCTX.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/AutocompleteCTX.tsx", "../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import { createContext, createRef } from 'react';\nimport type { DSAutocompleteT } from './react-desc-prop-types';\nimport type { DSAutoCompleteInternalsT } from './sharedTypes';\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nconst noop = () => {};\nexport const defaultProps: DSAutocompleteT.DefaultProps = {\n zIndex: 10,\n withoutPortal: false,\n startPlacementPreference: 'bottom-start',\n placementOrderPreference: ['bottom-start', 'bottom-end'],\n};\nconst defaultContext = {\n props: defaultProps as DSAutocompleteT.InternalProps,\n showPopover: false,\n setShowPopover: noop,\n scrollOptionIntoView: noop,\n referenceElement: null,\n setReferenceElement: noop,\n inputRef: createRef<HTMLInputElement>(),\n listRef: createRef<HTMLDivElement>(),\n focusOptionIdx: '',\n setCurrentOption: noop,\n};\n/** Context for cross component communication */\nexport const AutocompleteContext = createContext<DSAutoCompleteInternalsT.AutocompleteContext>(defaultContext);\n\nexport default AutocompleteContext;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAyC;AAIzC,MAAM,OAAO,MAAM;AAAC;AACb,MAAM,eAA6C;AAAA,EACxD,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,0BAA0B;AAAA,EAC1B,0BAA0B,CAAC,gBAAgB,YAAY;AACzD;AACA,MAAM,iBAAiB;AAAA,EACrB,OAAO;AAAA,EACP,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,cAAU,wBAA4B;AAAA,EACtC,aAAS,wBAA0B;AAAA,EACnC,gBAAgB;AAAA,EAChB,kBAAkB;AACpB;AAEO,MAAM,0BAAsB,4BAA4D,cAAc;AAE7G,IAAO,0BAAQ;",
4
+ "sourcesContent": ["import { createContext } from 'react';\nimport type { AutocompleteContextT } from './config/useAutocomplete';\n\nconst defaultContext = {} as AutocompleteContextT;\n/** Context for cross component communication */\nexport const AutocompleteContext = createContext<AutocompleteContextT>(defaultContext);\n\nexport default AutocompleteContext;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAA8B;AAG9B,MAAM,iBAAiB,CAAC;AAEjB,MAAM,0BAAsB,4BAAoC,cAAc;AAErF,IAAO,0BAAQ;",
6
6
  "names": []
7
7
  }
@@ -28,73 +28,45 @@ __export(useAutocomplete_exports, {
28
28
  });
29
29
  module.exports = __toCommonJS(useAutocomplete_exports);
30
30
  var React = __toESM(require("react"));
31
- var import_react = require("react");
31
+ var import_react = __toESM(require("react"));
32
32
  var import_ds_utilities = require("@elliemae/ds-utilities");
33
- var import_react_virtual = require("react-virtual");
34
33
  var import_react_desc_prop_types = require("../react-desc-prop-types");
35
- var import_AutocompleteCTX = require("../AutocompleteCTX");
36
34
  var import_listHelper = require("../utils/listHelper");
37
35
  var import_DSAutocompleteDefinitions = require("../DSAutocompleteDefinitions");
36
+ var import_useRefs = require("./useRefs");
37
+ var import_useVirtualization = require("./useVirtualization");
38
+ var import_usePopoverLogic = require("./usePopoverLogic");
38
39
  const useAutocomplete = (props) => {
39
40
  const defaultPropsWithInnerRef = {
40
- ...import_AutocompleteCTX.defaultProps,
41
+ ...import_react_desc_prop_types.defaultProps,
41
42
  innerRef: (0, import_react.useRef)(null)
42
43
  };
43
44
  const propsWithDefault = (0, import_ds_utilities.useMemoMergePropsWithDefault)(props, defaultPropsWithInnerRef);
44
45
  (0, import_ds_utilities.useValidateTypescriptPropTypes)(propsWithDefault, import_react_desc_prop_types.propTypes, import_DSAutocompleteDefinitions.DSAutocompleteName);
45
- const [showPopover, setShowPopover] = (0, import_react.useState)(false);
46
+ const { options } = propsWithDefault;
46
47
  const [referenceElement, setReferenceElement] = (0, import_react.useState)(null);
47
48
  const [focusOptionIdx, setCurrentOption] = (0, import_react.useState)("");
48
- const inputRef = (0, import_react.useRef)(null);
49
- const listRef = (0, import_react.useRef)(null);
50
- const { options, filter } = propsWithDefault;
51
- const virtualListHelpers = (0, import_react_virtual.useVirtual)({
52
- size: options.length,
53
- parentRef: listRef,
54
- overscan: 15,
55
- paddingStart: 0
49
+ const references = (0, import_useRefs.useRefs)();
50
+ const virtualizationManager = (0, import_useVirtualization.useVirtualization)({
51
+ references,
52
+ propsWithDefault
56
53
  });
57
- const scrollOptionIntoView = (0, import_react.useCallback)(
58
- (dsId, opts = { align: "center" }) => {
59
- virtualListHelpers.scrollToIndex(
60
- options.findIndex((opt) => opt.dsId === dsId),
61
- opts
62
- );
63
- },
64
- [options, virtualListHelpers]
65
- );
66
- (0, import_react.useEffect)(() => {
67
- if (filter.length === 0 || options.length === 0) {
68
- setShowPopover(false);
69
- }
70
- }, [filter, options.length, setShowPopover]);
71
- (0, import_react.useEffect)(() => {
54
+ const popoverManager = (0, import_usePopoverLogic.usePopoverLogic)(propsWithDefault);
55
+ import_react.default.useEffect(() => {
72
56
  setCurrentOption((0, import_listHelper.getFirstOption)(options));
73
- }, [options, showPopover]);
57
+ }, [options]);
74
58
  const ctx = (0, import_react.useMemo)(
75
59
  () => ({
76
60
  props: { ...propsWithDefault },
77
- virtualListHelpers,
78
- showPopover,
79
61
  referenceElement,
80
- inputRef,
81
- listRef,
82
62
  focusOptionIdx,
83
63
  setCurrentOption,
84
- scrollOptionIntoView,
85
64
  setReferenceElement,
86
- setShowPopover
65
+ ...references,
66
+ ...popoverManager,
67
+ ...virtualizationManager
87
68
  }),
88
- [
89
- scrollOptionIntoView,
90
- propsWithDefault,
91
- virtualListHelpers,
92
- focusOptionIdx,
93
- showPopover,
94
- referenceElement,
95
- inputRef,
96
- listRef
97
- ]
69
+ [propsWithDefault, referenceElement, focusOptionIdx, popoverManager, references, virtualizationManager]
98
70
  );
99
71
  return ctx;
100
72
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/config/useAutocomplete.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable max-lines */\n/* eslint-disable import/prefer-default-export */\n/* eslint-disable complexity */\n/* eslint-disable max-statements */\nimport { useMemo, useState, useEffect, useRef, useCallback } from 'react';\nimport { useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-utilities';\n\nimport { useVirtual } from 'react-virtual';\nimport type { DSAutocompleteT } from '../react-desc-prop-types';\nimport { propTypes } from '../react-desc-prop-types';\nimport type { DSAutoCompleteInternalsT } from '../sharedTypes';\nimport { defaultProps } from '../AutocompleteCTX';\nimport { getFirstOption } from '../utils/listHelper';\nimport { DSAutocompleteName } from '../DSAutocompleteDefinitions';\n\nexport const useAutocomplete = (props: DSAutocompleteT.Props): DSAutoCompleteInternalsT.AutocompleteContext => {\n const defaultPropsWithInnerRef = {\n ...defaultProps,\n innerRef: useRef(null),\n };\n const propsWithDefault = useMemoMergePropsWithDefault(props, defaultPropsWithInnerRef);\n useValidateTypescriptPropTypes(propsWithDefault, propTypes, DSAutocompleteName);\n const [showPopover, setShowPopover] = useState<boolean>(false);\n const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null);\n\n const [focusOptionIdx, setCurrentOption] = useState<string>('');\n\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n\n const { options, filter } = propsWithDefault;\n\n // ===========================================================================\n // Virtualization setup\n // ===========================================================================\n\n const virtualListHelpers: ReturnType<typeof useVirtual> = useVirtual({\n size: options.length,\n parentRef: listRef,\n overscan: 15,\n paddingStart: 0,\n });\n\n // ===========================================================================\n // Scroll into view function\n // ===========================================================================\n const scrollOptionIntoView = useCallback(\n (dsId: string, opts = { align: 'center' }) => {\n virtualListHelpers.scrollToIndex(\n options.findIndex((opt) => opt.dsId === dsId),\n opts,\n );\n },\n [options, virtualListHelpers],\n );\n\n useEffect(() => {\n if (filter.length === 0 || options.length === 0) {\n setShowPopover(false);\n }\n }, [filter, options.length, setShowPopover]);\n\n useEffect(() => {\n setCurrentOption(getFirstOption(options));\n }, [options, showPopover]);\n\n const ctx = useMemo(\n () => ({\n props: { ...propsWithDefault },\n virtualListHelpers,\n showPopover,\n referenceElement,\n inputRef,\n listRef,\n focusOptionIdx,\n setCurrentOption,\n scrollOptionIntoView,\n setReferenceElement,\n setShowPopover,\n }),\n [\n scrollOptionIntoView,\n propsWithDefault,\n virtualListHelpers,\n focusOptionIdx,\n showPopover,\n referenceElement,\n inputRef,\n listRef,\n ],\n );\n\n return ctx;\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADIvB,mBAAkE;AAClE,0BAA6E;AAE7E,2BAA2B;AAE3B,mCAA0B;AAE1B,6BAA6B;AAC7B,wBAA+B;AAC/B,uCAAmC;AAE5B,MAAM,kBAAkB,CAAC,UAA+E;AAC7G,QAAM,2BAA2B;AAAA,IAC/B,GAAG;AAAA,IACH,cAAU,qBAAO,IAAI;AAAA,EACvB;AACA,QAAM,uBAAmB,kDAA6B,OAAO,wBAAwB;AACrF,0DAA+B,kBAAkB,wCAAW,mDAAkB;AAC9E,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAkB,KAAK;AAC7D,QAAM,CAAC,kBAAkB,mBAAmB,QAAI,uBAA6B,IAAI;AAEjF,QAAM,CAAC,gBAAgB,gBAAgB,QAAI,uBAAiB,EAAE;AAE9D,QAAM,eAAW,qBAAyB,IAAI;AAC9C,QAAM,cAAU,qBAAuB,IAAI;AAE3C,QAAM,EAAE,SAAS,OAAO,IAAI;AAM5B,QAAM,yBAAoD,iCAAW;AAAA,IACnE,MAAM,QAAQ;AAAA,IACd,WAAW;AAAA,IACX,UAAU;AAAA,IACV,cAAc;AAAA,EAChB,CAAC;AAKD,QAAM,2BAAuB;AAAA,IAC3B,CAAC,MAAc,OAAO,EAAE,OAAO,SAAS,MAAM;AAC5C,yBAAmB;AAAA,QACjB,QAAQ,UAAU,CAAC,QAAQ,IAAI,SAAS,IAAI;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS,kBAAkB;AAAA,EAC9B;AAEA,8BAAU,MAAM;AACd,QAAI,OAAO,WAAW,KAAK,QAAQ,WAAW,GAAG;AAC/C,qBAAe,KAAK;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,QAAQ,cAAc,CAAC;AAE3C,8BAAU,MAAM;AACd,yBAAiB,kCAAe,OAAO,CAAC;AAAA,EAC1C,GAAG,CAAC,SAAS,WAAW,CAAC;AAEzB,QAAM,UAAM;AAAA,IACV,OAAO;AAAA,MACL,OAAO,EAAE,GAAG,iBAAiB;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;",
6
- "names": []
4
+ "sourcesContent": ["/* eslint-disable max-lines */\n/* eslint-disable import/prefer-default-export */\n/* eslint-disable complexity */\n/* eslint-disable max-statements */\nimport React, { useMemo, useState, useRef } from 'react';\nimport { useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-utilities';\nimport type { DSAutocompleteT } from '../react-desc-prop-types';\nimport { propTypes, defaultProps } from '../react-desc-prop-types';\nimport { getFirstOption } from '../utils/listHelper';\nimport { DSAutocompleteName } from '../DSAutocompleteDefinitions';\nimport { useRefs } from './useRefs';\nimport { useVirtualization } from './useVirtualization';\nimport { usePopoverLogic } from './usePopoverLogic';\n\nexport type AutocompleteContextT = ReturnType<typeof useRefs> &\n ReturnType<typeof useVirtualization> &\n ReturnType<typeof usePopoverLogic> & {\n props: DSAutocompleteT.InternalProps;\n referenceElement: HTMLElement | null;\n focusOptionIdx: string;\n setCurrentOption: React.Dispatch<React.SetStateAction<string>>;\n setReferenceElement: React.Dispatch<React.SetStateAction<HTMLElement | null>>;\n };\n\nexport const useAutocomplete = (props: DSAutocompleteT.Props): AutocompleteContextT => {\n const defaultPropsWithInnerRef = {\n ...defaultProps,\n innerRef: useRef(null),\n };\n const propsWithDefault = useMemoMergePropsWithDefault(props, defaultPropsWithInnerRef);\n useValidateTypescriptPropTypes(propsWithDefault, propTypes, DSAutocompleteName);\n\n const { options } = propsWithDefault;\n const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null);\n const [focusOptionIdx, setCurrentOption] = useState<string>('');\n\n const references = useRefs();\n\n const virtualizationManager = useVirtualization({\n references,\n propsWithDefault,\n });\n\n const popoverManager = usePopoverLogic(propsWithDefault);\n\n React.useEffect(() => {\n setCurrentOption(getFirstOption(options));\n }, [options]);\n\n const ctx = useMemo(\n () => ({\n props: { ...propsWithDefault },\n referenceElement,\n focusOptionIdx,\n setCurrentOption,\n setReferenceElement,\n ...references,\n ...popoverManager,\n ...virtualizationManager,\n }),\n [propsWithDefault, referenceElement, focusOptionIdx, popoverManager, references, virtualizationManager],\n );\n\n return ctx;\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADIvB,mBAAiD;AACjD,0BAA6E;AAE7E,mCAAwC;AACxC,wBAA+B;AAC/B,uCAAmC;AACnC,qBAAwB;AACxB,+BAAkC;AAClC,6BAAgC;AAYzB,MAAM,kBAAkB,CAAC,UAAuD;AACrF,QAAM,2BAA2B;AAAA,IAC/B,GAAG;AAAA,IACH,cAAU,qBAAO,IAAI;AAAA,EACvB;AACA,QAAM,uBAAmB,kDAA6B,OAAO,wBAAwB;AACrF,0DAA+B,kBAAkB,wCAAW,mDAAkB;AAE9E,QAAM,EAAE,QAAQ,IAAI;AACpB,QAAM,CAAC,kBAAkB,mBAAmB,QAAI,uBAA6B,IAAI;AACjF,QAAM,CAAC,gBAAgB,gBAAgB,QAAI,uBAAiB,EAAE;AAE9D,QAAM,iBAAa,wBAAQ;AAE3B,QAAM,4BAAwB,4CAAkB;AAAA,IAC9C;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,qBAAiB,wCAAgB,gBAAgB;AAEvD,eAAAA,QAAM,UAAU,MAAM;AACpB,yBAAiB,kCAAe,OAAO,CAAC;AAAA,EAC1C,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,UAAM;AAAA,IACV,OAAO;AAAA,MACL,OAAO,EAAE,GAAG,iBAAiB;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,CAAC,kBAAkB,kBAAkB,gBAAgB,gBAAgB,YAAY,qBAAqB;AAAA,EACxG;AAEA,SAAO;AACT;",
6
+ "names": ["React"]
7
7
  }
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
+ var usePopoverLogic_exports = {};
26
+ __export(usePopoverLogic_exports, {
27
+ usePopoverLogic: () => usePopoverLogic
28
+ });
29
+ module.exports = __toCommonJS(usePopoverLogic_exports);
30
+ var React = __toESM(require("react"));
31
+ var import_react = __toESM(require("react"));
32
+ const usePopoverLogic = (propsWithDefault) => {
33
+ const { options, filter } = propsWithDefault;
34
+ const [forceClosePopover, setForceClosePopover] = (0, import_react.useState)(false);
35
+ const [userTypedSomething, setUserTypedSomething] = (0, import_react.useState)(false);
36
+ const [userIsNavigatingWithArrows, setUserIsNavigatingWithArrows] = (0, import_react.useState)(false);
37
+ const [userJustSelectedAnOption, setUserJustSelectedAnOption] = (0, import_react.useState)(false);
38
+ const userSelectedAndDidNotType = userJustSelectedAnOption && !userTypedSomething;
39
+ const popoverHasAnythingToShow = options.length > 0 && filter.length > 0;
40
+ const isShowingPopover = !forceClosePopover && popoverHasAnythingToShow && !userSelectedAndDidNotType && (userTypedSomething || userIsNavigatingWithArrows);
41
+ const trackUserTyping = import_react.default.useCallback(
42
+ (e) => {
43
+ const { key } = e;
44
+ if ([...e.key].length === 1 || key === "Backspace" || key === "Delete") {
45
+ setUserTypedSomething(true);
46
+ setForceClosePopover(false);
47
+ setUserJustSelectedAnOption(false);
48
+ } else {
49
+ setUserTypedSomething(false);
50
+ }
51
+ },
52
+ [setUserTypedSomething]
53
+ );
54
+ const trackUserNavigatingWithArrows = import_react.default.useCallback(
55
+ (e) => {
56
+ const { key } = e;
57
+ if (isShowingPopover && (key === "ArrowUp" || key === "ArrowDown")) {
58
+ setUserIsNavigatingWithArrows(true);
59
+ } else {
60
+ setUserIsNavigatingWithArrows(false);
61
+ }
62
+ },
63
+ [isShowingPopover]
64
+ );
65
+ const trackUserSelectingAnOption = import_react.default.useCallback(
66
+ (e) => {
67
+ const { key } = e;
68
+ if (key === "Enter" && isShowingPopover) {
69
+ setUserJustSelectedAnOption(true);
70
+ }
71
+ },
72
+ [isShowingPopover]
73
+ );
74
+ const trackUserInteractingViaKeyboard = import_react.default.useCallback(
75
+ (e) => {
76
+ trackUserTyping(e);
77
+ trackUserNavigatingWithArrows(e);
78
+ trackUserSelectingAnOption(e);
79
+ },
80
+ [trackUserTyping, trackUserNavigatingWithArrows, trackUserSelectingAnOption]
81
+ );
82
+ (0, import_react.useEffect)(() => {
83
+ const closePopper = () => {
84
+ setForceClosePopover(true);
85
+ };
86
+ window.addEventListener("blur", closePopper);
87
+ return () => {
88
+ window.removeEventListener("blur", closePopper);
89
+ };
90
+ }, []);
91
+ return import_react.default.useMemo(
92
+ () => ({
93
+ isShowingPopover,
94
+ forceClosePopover,
95
+ setForceClosePopover,
96
+ userTypedSomething,
97
+ setUserTypedSomething,
98
+ setUserJustSelectedAnOption,
99
+ setUserIsNavigatingWithArrows,
100
+ trackUserInteractingViaKeyboard
101
+ }),
102
+ [isShowingPopover, forceClosePopover, userTypedSomething, trackUserInteractingViaKeyboard]
103
+ );
104
+ };
105
+ //# sourceMappingURL=usePopoverLogic.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/config/usePopoverLogic.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
+ "sourcesContent": ["import React, { useState, useEffect } from 'react';\nimport type { DSAutocompleteT } from '../react-desc-prop-types';\n\n// we want to own all the popover logic in a single place\n// we handle global events via window.addEventListener/RemoveEventListener\n// the logic to show/hide the popover accounts for\n// show:\n// - the user just typed something (excluding special keys like arrows, enter, etc)\n// - any options are available\n// - the user did not just select an option\n// N.B. this must react to options.length changing in an async way\n// hide:\n// - the user just selected an option and did not type anything after\n// - no options are available\n// - the focus is not on the input\n// - the user pressed the escape key\nexport const usePopoverLogic = (propsWithDefault: DSAutocompleteT.InternalProps) => {\n const { options, filter } = propsWithDefault;\n\n const [forceClosePopover, setForceClosePopover] = useState<boolean>(false);\n\n const [userTypedSomething, setUserTypedSomething] = useState<boolean>(false);\n const [userIsNavigatingWithArrows, setUserIsNavigatingWithArrows] = useState<boolean>(false);\n const [userJustSelectedAnOption, setUserJustSelectedAnOption] = useState<boolean>(false);\n\n const userSelectedAndDidNotType = userJustSelectedAnOption && !userTypedSomething;\n const popoverHasAnythingToShow = options.length > 0 && filter.length > 0;\n\n const isShowingPopover =\n !forceClosePopover && // user pressed escape (or other interaction that forces close) --> hide popover\n popoverHasAnythingToShow && // nothing to show --> hide popover\n !userSelectedAndDidNotType && // user just selected an option --> hide popover\n (userTypedSomething || // user typed something --> show popover\n userIsNavigatingWithArrows); // user is navigating with arrows --> show popover\n\n const trackUserTyping: React.KeyboardEventHandler<HTMLInputElement> = React.useCallback(\n (e) => {\n const { key } = e;\n // [...e.key].length === 1 -> \"printable\" characters including https://mathiasbynens.be/notes/javascript-unicode\n if ([...e.key].length === 1 || key === 'Backspace' || key === 'Delete') {\n setUserTypedSomething(true);\n setForceClosePopover(false);\n setUserJustSelectedAnOption(false);\n } else {\n setUserTypedSomething(false);\n }\n },\n [setUserTypedSomething],\n );\n const trackUserNavigatingWithArrows: React.KeyboardEventHandler<HTMLInputElement> = React.useCallback(\n (e) => {\n const { key } = e;\n if (isShowingPopover && (key === 'ArrowUp' || key === 'ArrowDown')) {\n setUserIsNavigatingWithArrows(true);\n } else {\n setUserIsNavigatingWithArrows(false);\n }\n },\n [isShowingPopover],\n );\n\n const trackUserSelectingAnOption: React.KeyboardEventHandler<HTMLInputElement> = React.useCallback(\n (e) => {\n const { key } = e;\n if (key === 'Enter' && isShowingPopover) {\n setUserJustSelectedAnOption(true);\n }\n },\n [isShowingPopover],\n );\n\n const trackUserInteractingViaKeyboard: React.KeyboardEventHandler<HTMLInputElement> = React.useCallback(\n (e) => {\n trackUserTyping(e);\n trackUserNavigatingWithArrows(e);\n trackUserSelectingAnOption(e);\n },\n [trackUserTyping, trackUserNavigatingWithArrows, trackUserSelectingAnOption],\n );\n\n // when the webpage is blurred, we want to close the popover\n // should be fixing iframes interactions?\n useEffect(() => {\n const closePopper = () => {\n setForceClosePopover(true);\n };\n window.addEventListener('blur', closePopper);\n\n return () => {\n window.removeEventListener('blur', closePopper);\n };\n }, []);\n\n return React.useMemo(\n () => ({\n isShowingPopover,\n forceClosePopover,\n setForceClosePopover,\n userTypedSomething,\n setUserTypedSomething,\n setUserJustSelectedAnOption,\n setUserIsNavigatingWithArrows,\n trackUserInteractingViaKeyboard,\n }),\n [isShowingPopover, forceClosePopover, userTypedSomething, trackUserInteractingViaKeyboard],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAA2C;AAgBpC,MAAM,kBAAkB,CAAC,qBAAoD;AAClF,QAAM,EAAE,SAAS,OAAO,IAAI;AAE5B,QAAM,CAAC,mBAAmB,oBAAoB,QAAI,uBAAkB,KAAK;AAEzE,QAAM,CAAC,oBAAoB,qBAAqB,QAAI,uBAAkB,KAAK;AAC3E,QAAM,CAAC,4BAA4B,6BAA6B,QAAI,uBAAkB,KAAK;AAC3F,QAAM,CAAC,0BAA0B,2BAA2B,QAAI,uBAAkB,KAAK;AAEvF,QAAM,4BAA4B,4BAA4B,CAAC;AAC/D,QAAM,2BAA2B,QAAQ,SAAS,KAAK,OAAO,SAAS;AAEvE,QAAM,mBACJ,CAAC,qBACD,4BACA,CAAC,8BACA,sBACC;AAEJ,QAAM,kBAAgE,aAAAA,QAAM;AAAA,IAC1E,CAAC,MAAM;AACL,YAAM,EAAE,IAAI,IAAI;AAEhB,UAAI,CAAC,GAAG,EAAE,GAAG,EAAE,WAAW,KAAK,QAAQ,eAAe,QAAQ,UAAU;AACtE,8BAAsB,IAAI;AAC1B,6BAAqB,KAAK;AAC1B,oCAA4B,KAAK;AAAA,MACnC,OAAO;AACL,8BAAsB,KAAK;AAAA,MAC7B;AAAA,IACF;AAAA,IACA,CAAC,qBAAqB;AAAA,EACxB;AACA,QAAM,gCAA8E,aAAAA,QAAM;AAAA,IACxF,CAAC,MAAM;AACL,YAAM,EAAE,IAAI,IAAI;AAChB,UAAI,qBAAqB,QAAQ,aAAa,QAAQ,cAAc;AAClE,sCAA8B,IAAI;AAAA,MACpC,OAAO;AACL,sCAA8B,KAAK;AAAA,MACrC;AAAA,IACF;AAAA,IACA,CAAC,gBAAgB;AAAA,EACnB;AAEA,QAAM,6BAA2E,aAAAA,QAAM;AAAA,IACrF,CAAC,MAAM;AACL,YAAM,EAAE,IAAI,IAAI;AAChB,UAAI,QAAQ,WAAW,kBAAkB;AACvC,oCAA4B,IAAI;AAAA,MAClC;AAAA,IACF;AAAA,IACA,CAAC,gBAAgB;AAAA,EACnB;AAEA,QAAM,kCAAgF,aAAAA,QAAM;AAAA,IAC1F,CAAC,MAAM;AACL,sBAAgB,CAAC;AACjB,oCAA8B,CAAC;AAC/B,iCAA2B,CAAC;AAAA,IAC9B;AAAA,IACA,CAAC,iBAAiB,+BAA+B,0BAA0B;AAAA,EAC7E;AAIA,8BAAU,MAAM;AACd,UAAM,cAAc,MAAM;AACxB,2BAAqB,IAAI;AAAA,IAC3B;AACA,WAAO,iBAAiB,QAAQ,WAAW;AAE3C,WAAO,MAAM;AACX,aAAO,oBAAoB,QAAQ,WAAW;AAAA,IAChD;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO,aAAAA,QAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,mBAAmB,oBAAoB,+BAA+B;AAAA,EAC3F;AACF;",
6
+ "names": ["React"]
7
+ }
@@ -5,6 +5,10 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
8
12
  var __copyProps = (to, from, except, desc) => {
9
13
  if (from && typeof from === "object" || typeof from === "function") {
10
14
  for (let key of __getOwnPropNames(from))
@@ -18,7 +22,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
18
22
  mod
19
23
  ));
20
24
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
- var sharedTypes_exports = {};
22
- module.exports = __toCommonJS(sharedTypes_exports);
25
+ var useRefs_exports = {};
26
+ __export(useRefs_exports, {
27
+ useRefs: () => useRefs
28
+ });
29
+ module.exports = __toCommonJS(useRefs_exports);
23
30
  var React = __toESM(require("react"));
24
- //# sourceMappingURL=sharedTypes.js.map
31
+ var import_react = __toESM(require("react"));
32
+ const useRefs = () => {
33
+ const inputRef = (0, import_react.useRef)(null);
34
+ const listRef = (0, import_react.useRef)(null);
35
+ return import_react.default.useMemo(() => ({ inputRef, listRef }), [inputRef, listRef]);
36
+ };
37
+ //# sourceMappingURL=useRefs.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/config/useRefs.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
+ "sourcesContent": ["import React, { useRef } from 'react';\n\nexport const useRefs = () => {\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n return React.useMemo(() => ({ inputRef, listRef }), [inputRef, listRef]);\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAA8B;AAEvB,MAAM,UAAU,MAAM;AAC3B,QAAM,eAAW,qBAAyB,IAAI;AAC9C,QAAM,cAAU,qBAAuB,IAAI;AAC3C,SAAO,aAAAA,QAAM,QAAQ,OAAO,EAAE,UAAU,QAAQ,IAAI,CAAC,UAAU,OAAO,CAAC;AACzE;",
6
+ "names": ["React"]
7
+ }
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
+ var useVirtualization_exports = {};
26
+ __export(useVirtualization_exports, {
27
+ useVirtualization: () => useVirtualization
28
+ });
29
+ module.exports = __toCommonJS(useVirtualization_exports);
30
+ var React = __toESM(require("react"));
31
+ var import_react = __toESM(require("react"));
32
+ var import_react_virtual = require("react-virtual");
33
+ const useVirtualization = ({
34
+ references,
35
+ propsWithDefault
36
+ }) => {
37
+ const { options } = propsWithDefault;
38
+ const { listRef } = references;
39
+ const virtualListHelpers = (0, import_react_virtual.useVirtual)({
40
+ size: options.length,
41
+ parentRef: listRef,
42
+ overscan: 15,
43
+ paddingStart: 0
44
+ });
45
+ const scrollOptionIntoView = (0, import_react.useCallback)(
46
+ (dsId, opts = { align: "center" }) => {
47
+ virtualListHelpers.scrollToIndex(
48
+ options.findIndex((opt) => opt.dsId === dsId),
49
+ opts
50
+ );
51
+ },
52
+ [options, virtualListHelpers]
53
+ );
54
+ return import_react.default.useMemo(
55
+ () => ({
56
+ virtualListHelpers,
57
+ scrollOptionIntoView
58
+ }),
59
+ [virtualListHelpers, scrollOptionIntoView]
60
+ );
61
+ };
62
+ //# sourceMappingURL=useVirtualization.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/config/useVirtualization.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
+ "sourcesContent": ["import React, { useCallback } from 'react';\nimport { useVirtual } from 'react-virtual';\nimport type {} from 'react-virtual';\nimport type { DSAutocompleteT } from '../react-desc-prop-types';\nimport type { useRefs } from './useRefs';\n\nexport const useVirtualization = ({\n references,\n propsWithDefault,\n}: {\n references: ReturnType<typeof useRefs>;\n propsWithDefault: DSAutocompleteT.InternalProps;\n}) => {\n const { options } = propsWithDefault;\n const { listRef } = references;\n\n // ===========================================================================\n // Virtualization setup\n // ===========================================================================\n const virtualListHelpers: ReturnType<typeof useVirtual> = useVirtual({\n size: options.length,\n parentRef: listRef,\n overscan: 15,\n paddingStart: 0,\n });\n\n // ===========================================================================\n // Scroll into view function\n // ===========================================================================\n const scrollOptionIntoView = useCallback(\n (dsId: string, opts = { align: 'center' }) => {\n virtualListHelpers.scrollToIndex(\n options.findIndex((opt) => opt.dsId === dsId),\n opts,\n );\n },\n [options, virtualListHelpers],\n );\n\n return React.useMemo(\n () => ({\n virtualListHelpers,\n scrollOptionIntoView,\n }),\n [virtualListHelpers, scrollOptionIntoView],\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAmC;AACnC,2BAA2B;AAKpB,MAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA;AACF,MAGM;AACJ,QAAM,EAAE,QAAQ,IAAI;AACpB,QAAM,EAAE,QAAQ,IAAI;AAKpB,QAAM,yBAAoD,iCAAW;AAAA,IACnE,MAAM,QAAQ;AAAA,IACd,WAAW;AAAA,IACX,UAAU;AAAA,IACV,cAAc;AAAA,EAChB,CAAC;AAKD,QAAM,2BAAuB;AAAA,IAC3B,CAAC,MAAc,OAAO,EAAE,OAAO,SAAS,MAAM;AAC5C,yBAAmB;AAAA,QACjB,QAAQ,UAAU,CAAC,QAAQ,IAAI,SAAS,IAAI;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS,kBAAkB;AAAA,EAC9B;AAEA,SAAO,aAAAA,QAAM;AAAA,IACX,OAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,oBAAoB,oBAAoB;AAAA,EAC3C;AACF;",
6
+ "names": ["React"]
7
+ }
@@ -46,14 +46,14 @@ const A11yFocusedOption = () => {
46
46
  const {
47
47
  props: { options },
48
48
  focusOptionIdx,
49
- showPopover
49
+ isShowingPopover
50
50
  } = (0, import_react.useContext)(import_AutocompleteCTX.default);
51
51
  return (0, import_react.useMemo)(() => {
52
52
  const selectabledOptions = (0, import_listHelper.getSelectableOptions)(options);
53
53
  const focusOption = options.find((option) => !isSeparator(option) && option.dsId === focusOptionIdx);
54
54
  const focusSelectableOptionIdx = selectabledOptions.findIndex((option) => option.dsId === focusOptionIdx);
55
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StyledA11ySelectedValues, { "aria-live": "polite", children: !isSeparator(focusOption) && showPopover && focusOption && `option ${focusOption.label} focused.${focusSelectableOptionIdx + 1} of ${selectabledOptions.length}
55
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StyledA11ySelectedValues, { "aria-live": "polite", children: !isSeparator(focusOption) && isShowingPopover && focusOption && `option ${focusOption.label} focused.${focusSelectableOptionIdx + 1} of ${selectabledOptions.length}
56
56
  ` });
57
- }, [options, showPopover, focusOptionIdx]);
57
+ }, [options, isShowingPopover, focusOptionIdx]);
58
58
  };
59
59
  //# sourceMappingURL=A11yFocusedOption.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/parts/A11yFocusedOption.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import React, { useContext, useMemo } from 'react';\nimport { styled } from '@elliemae/ds-system';\nimport AutocompleteContext from '../AutocompleteCTX';\nimport { getSelectableOptions } from '../utils/listHelper';\nimport type { DSAutocompleteT } from '../react-desc-prop-types';\nexport const isSeparator = (el: DSAutocompleteT.OptionTypes | undefined): el is DSAutocompleteT.ItemSeparatorOptions =>\n el?.type === 'separator';\n\nexport const StyledA11ySelectedValues = styled.span`\n width: 1px;\n height: 1px;\n position: absolute;\n clip: rect(1px, 1px, 1px, 1px);\n`;\n\nexport const A11yFocusedOption: React.ComponentType = () => {\n const {\n props: { options },\n focusOptionIdx,\n showPopover,\n } = useContext(AutocompleteContext);\n\n return useMemo(() => {\n const selectabledOptions = getSelectableOptions(options);\n const focusOption = options.find((option) => !isSeparator(option) && option.dsId === focusOptionIdx);\n const focusSelectableOptionIdx = selectabledOptions.findIndex((option) => option.dsId === focusOptionIdx);\n\n return (\n <StyledA11ySelectedValues aria-live=\"polite\">\n {!isSeparator(focusOption) &&\n showPopover &&\n focusOption &&\n `option ${focusOption.label} focused.${focusSelectableOptionIdx + 1} of ${selectabledOptions.length}\n `}\n </StyledA11ySelectedValues>\n );\n }, [options, showPopover, focusOptionIdx]);\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;AD4BjB;AA5BN,mBAA2C;AAC3C,uBAAuB;AACvB,6BAAgC;AAChC,wBAAqC;AAE9B,MAAM,cAAc,CAAC,OAC1B,IAAI,SAAS;AAER,MAAM,2BAA2B,wBAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAOxC,MAAM,oBAAyC,MAAM;AAC1D,QAAM;AAAA,IACJ,OAAO,EAAE,QAAQ;AAAA,IACjB;AAAA,IACA;AAAA,EACF,QAAI,yBAAW,uBAAAA,OAAmB;AAElC,aAAO,sBAAQ,MAAM;AACnB,UAAM,yBAAqB,wCAAqB,OAAO;AACvD,UAAM,cAAc,QAAQ,KAAK,CAAC,WAAW,CAAC,YAAY,MAAM,KAAK,OAAO,SAAS,cAAc;AACnG,UAAM,2BAA2B,mBAAmB,UAAU,CAAC,WAAW,OAAO,SAAS,cAAc;AAExG,WACE,4CAAC,4BAAyB,aAAU,UACjC,WAAC,YAAY,WAAW,KACvB,eACA,eACA,UAAU,YAAY,iBAAiB,2BAA2B,QAAQ,mBAAmB;AAAA,cAEjG;AAAA,EAEJ,GAAG,CAAC,SAAS,aAAa,cAAc,CAAC;AAC3C;",
4
+ "sourcesContent": ["import React, { useContext, useMemo } from 'react';\nimport { styled } from '@elliemae/ds-system';\nimport AutocompleteContext from '../AutocompleteCTX';\nimport { getSelectableOptions } from '../utils/listHelper';\nimport type { DSAutocompleteT } from '../react-desc-prop-types';\nexport const isSeparator = (el: DSAutocompleteT.OptionTypes | undefined): el is DSAutocompleteT.ItemSeparatorOptions =>\n el?.type === 'separator';\n\nexport const StyledA11ySelectedValues = styled.span`\n width: 1px;\n height: 1px;\n position: absolute;\n clip: rect(1px, 1px, 1px, 1px);\n`;\n\nexport const A11yFocusedOption: React.ComponentType = () => {\n const {\n props: { options },\n focusOptionIdx,\n isShowingPopover,\n } = useContext(AutocompleteContext);\n\n return useMemo(() => {\n const selectabledOptions = getSelectableOptions(options);\n const focusOption = options.find((option) => !isSeparator(option) && option.dsId === focusOptionIdx);\n const focusSelectableOptionIdx = selectabledOptions.findIndex((option) => option.dsId === focusOptionIdx);\n\n return (\n <StyledA11ySelectedValues aria-live=\"polite\">\n {!isSeparator(focusOption) &&\n isShowingPopover &&\n focusOption &&\n `option ${focusOption.label} focused.${focusSelectableOptionIdx + 1} of ${selectabledOptions.length}\n `}\n </StyledA11ySelectedValues>\n );\n }, [options, isShowingPopover, focusOptionIdx]);\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;AD4BjB;AA5BN,mBAA2C;AAC3C,uBAAuB;AACvB,6BAAgC;AAChC,wBAAqC;AAE9B,MAAM,cAAc,CAAC,OAC1B,IAAI,SAAS;AAER,MAAM,2BAA2B,wBAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAOxC,MAAM,oBAAyC,MAAM;AAC1D,QAAM;AAAA,IACJ,OAAO,EAAE,QAAQ;AAAA,IACjB;AAAA,IACA;AAAA,EACF,QAAI,yBAAW,uBAAAA,OAAmB;AAElC,aAAO,sBAAQ,MAAM;AACnB,UAAM,yBAAqB,wCAAqB,OAAO;AACvD,UAAM,cAAc,QAAQ,KAAK,CAAC,WAAW,CAAC,YAAY,MAAM,KAAK,OAAO,SAAS,cAAc;AACnG,UAAM,2BAA2B,mBAAmB,UAAU,CAAC,WAAW,OAAO,SAAS,cAAc;AAExG,WACE,4CAAC,4BAAyB,aAAU,UACjC,WAAC,YAAY,WAAW,KACvB,oBACA,eACA,UAAU,YAAY,iBAAiB,2BAA2B,QAAQ,mBAAmB;AAAA,cAEjG;AAAA,EAEJ,GAAG,CAAC,SAAS,kBAAkB,cAAc,CAAC;AAChD;",
6
6
  "names": ["AutocompleteContext"]
7
7
  }
@@ -40,28 +40,28 @@ var import_A11yFocusedOption = require("../A11yFocusedOption");
40
40
  const Container = () => {
41
41
  const {
42
42
  props: { id, startPlacementPreference, children, filter, placementOrderPreference },
43
- showPopover,
43
+ isShowingPopover,
44
44
  setReferenceElement,
45
- setShowPopover,
45
+ setUserJustSelectedAnOption,
46
+ setUserTypedSomething,
47
+ setUserIsNavigatingWithArrows,
48
+ setForceClosePopover,
46
49
  focusOptionIdx,
47
50
  referenceElement
48
51
  } = (0, import_react.useContext)(import_AutocompleteCTX.default);
49
- (0, import_react.useEffect)(() => {
50
- const closePopper = () => {
51
- setShowPopover(false);
52
- };
53
- window.addEventListener("blur", closePopper);
54
- return () => {
55
- window.removeEventListener("blur", closePopper);
56
- };
57
- }, [setShowPopover]);
58
52
  const handleCloseMenu = (0, import_react.useCallback)(() => {
59
- setShowPopover(false);
60
- }, [setShowPopover]);
53
+ setForceClosePopover(true);
54
+ }, [setForceClosePopover]);
61
55
  const { onInputKeyDown } = (0, import_useKeyboardNavigation.useKeyboardNavigation)();
62
56
  const input = import_react.default.Children.only(children);
63
57
  const childrenWithProps = import_react.default.isValidElement(input) ? import_react.default.cloneElement(input, { "aria-activedescendant": focusOptionIdx }) : input;
64
58
  const idList = (0, import_react.useMemo)(() => `${id ? `${id}-` : ""}listbox`, [id]);
59
+ const onFocusPopoverStatusSync = (0, import_react.useCallback)(() => {
60
+ setForceClosePopover(false);
61
+ setUserJustSelectedAnOption(false);
62
+ setUserTypedSomething(false);
63
+ setUserIsNavigatingWithArrows(false);
64
+ }, [setForceClosePopover, setUserIsNavigatingWithArrows, setUserJustSelectedAnOption, setUserTypedSomething]);
65
65
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
66
66
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_A11yFocusedOption.A11yFocusedOption, {}),
67
67
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
@@ -72,10 +72,11 @@ const Container = () => {
72
72
  role: "combobox",
73
73
  "aria-autocomplete": "list",
74
74
  "aria-controls": "autocomplete-listbox",
75
- "aria-expanded": showPopover,
75
+ "aria-expanded": isShowingPopover,
76
76
  "aria-haspopup": "listbox",
77
77
  "aria-owns": idList,
78
78
  onKeyDown: onInputKeyDown,
79
+ onFocus: onFocusPopoverStatusSync,
79
80
  "data-testid": import_AutocompleteDataTestids.AutocompleteDataTestid.CONTAINER,
80
81
  children: [
81
82
  childrenWithProps,
@@ -85,7 +86,7 @@ const Container = () => {
85
86
  customOffset: [0, 5],
86
87
  closeContextMenu: handleCloseMenu,
87
88
  referenceElement,
88
- showPopover,
89
+ showPopover: isShowingPopover,
89
90
  startPlacementPreference,
90
91
  placementOrderPreference,
91
92
  withoutPortal: true,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/parts/container/Container.tsx", "../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable complexity */\nimport React, { useCallback, useMemo, useEffect, useContext } from 'react';\nimport { DSPopperJS } from '@elliemae/ds-popperjs';\nimport AutocompleteContext from '../../AutocompleteCTX';\nimport { StyledContainer, StyledPopperWrapper } from './styled';\nimport { MenuList } from '../menu-list';\nimport { useKeyboardNavigation } from './useKeyboardNavigation';\nimport { AutocompleteDataTestid } from '../../AutocompleteDataTestids';\nimport { A11yFocusedOption } from '../A11yFocusedOption';\nexport const Container = (): JSX.Element => {\n const {\n props: { id, startPlacementPreference, children, filter, placementOrderPreference },\n showPopover,\n setReferenceElement,\n setShowPopover,\n focusOptionIdx,\n referenceElement,\n } = useContext(AutocompleteContext);\n\n useEffect(() => {\n const closePopper = () => {\n setShowPopover(false);\n };\n window.addEventListener('blur', closePopper);\n\n return () => {\n window.removeEventListener('blur', closePopper);\n };\n }, [setShowPopover]);\n\n const handleCloseMenu = useCallback(() => {\n setShowPopover(false);\n }, [setShowPopover]);\n\n const { onInputKeyDown } = useKeyboardNavigation();\n\n const input = React.Children.only(children);\n\n const childrenWithProps = React.isValidElement(input)\n ? React.cloneElement(input, { 'aria-activedescendant': focusOptionIdx })\n : input;\n\n const idList = useMemo(() => `${id ? `${id}-` : ''}listbox`, [id]);\n\n return (\n <>\n <A11yFocusedOption />\n\n <StyledContainer\n id={id}\n ref={setReferenceElement}\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-controls=\"autocomplete-listbox\"\n aria-expanded={showPopover}\n aria-haspopup=\"listbox\"\n aria-owns={idList}\n onKeyDown={onInputKeyDown}\n data-testid={AutocompleteDataTestid.CONTAINER}\n >\n {childrenWithProps}\n {filter && (\n <DSPopperJS\n customOffset={[0, 5]}\n closeContextMenu={handleCloseMenu}\n referenceElement={referenceElement}\n showPopover={showPopover}\n startPlacementPreference={startPlacementPreference}\n placementOrderPreference={placementOrderPreference}\n withoutPortal\n withoutArrow\n withoutAnimation\n zIndex={10}\n >\n <StyledPopperWrapper tabIndex={-1}>\n <MenuList />\n </StyledPopperWrapper>\n </DSPopperJS>\n )}\n </StyledContainer>\n </>\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;AD6CnB;AA5CJ,mBAAmE;AACnE,yBAA2B;AAC3B,6BAAgC;AAChC,oBAAqD;AACrD,uBAAyB;AACzB,mCAAsC;AACtC,qCAAuC;AACvC,+BAAkC;AAC3B,MAAM,YAAY,MAAmB;AAC1C,QAAM;AAAA,IACJ,OAAO,EAAE,IAAI,0BAA0B,UAAU,QAAQ,yBAAyB;AAAA,IAClF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,QAAI,yBAAW,uBAAAA,OAAmB;AAElC,8BAAU,MAAM;AACd,UAAM,cAAc,MAAM;AACxB,qBAAe,KAAK;AAAA,IACtB;AACA,WAAO,iBAAiB,QAAQ,WAAW;AAE3C,WAAO,MAAM;AACX,aAAO,oBAAoB,QAAQ,WAAW;AAAA,IAChD;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,sBAAkB,0BAAY,MAAM;AACxC,mBAAe,KAAK;AAAA,EACtB,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,EAAE,eAAe,QAAI,oDAAsB;AAEjD,QAAM,QAAQ,aAAAC,QAAM,SAAS,KAAK,QAAQ;AAE1C,QAAM,oBAAoB,aAAAA,QAAM,eAAe,KAAK,IAChD,aAAAA,QAAM,aAAa,OAAO,EAAE,yBAAyB,eAAe,CAAC,IACrE;AAEJ,QAAM,aAAS,sBAAQ,MAAM,GAAG,KAAK,GAAG,QAAQ,aAAa,CAAC,EAAE,CAAC;AAEjE,SACE,4EACE;AAAA,gDAAC,8CAAkB;AAAA,IAEnB;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,KAAK;AAAA,QACL,MAAK;AAAA,QACL,qBAAkB;AAAA,QAClB,iBAAc;AAAA,QACd,iBAAe;AAAA,QACf,iBAAc;AAAA,QACd,aAAW;AAAA,QACX,WAAW;AAAA,QACX,eAAa,sDAAuB;AAAA,QAEnC;AAAA;AAAA,UACA,UACC;AAAA,YAAC;AAAA;AAAA,cACC,cAAc,CAAC,GAAG,CAAC;AAAA,cACnB,kBAAkB;AAAA,cAClB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,eAAa;AAAA,cACb,cAAY;AAAA,cACZ,kBAAgB;AAAA,cAChB,QAAQ;AAAA,cAER,sDAAC,qCAAoB,UAAU,IAC7B,sDAAC,6BAAS,GACZ;AAAA;AAAA,UACF;AAAA;AAAA;AAAA,IAEJ;AAAA,KACF;AAEJ;",
4
+ "sourcesContent": ["/* eslint-disable complexity */\nimport React, { useCallback, useMemo, useContext } from 'react';\nimport { DSPopperJS } from '@elliemae/ds-popperjs';\nimport AutocompleteContext from '../../AutocompleteCTX';\nimport { StyledContainer, StyledPopperWrapper } from './styled';\nimport { MenuList } from '../menu-list';\nimport { useKeyboardNavigation } from './useKeyboardNavigation';\nimport { AutocompleteDataTestid } from '../../AutocompleteDataTestids';\nimport { A11yFocusedOption } from '../A11yFocusedOption';\nexport const Container = (): JSX.Element => {\n const {\n props: { id, startPlacementPreference, children, filter, placementOrderPreference },\n isShowingPopover,\n setReferenceElement,\n setUserJustSelectedAnOption,\n setUserTypedSomething,\n setUserIsNavigatingWithArrows,\n setForceClosePopover,\n focusOptionIdx,\n referenceElement,\n } = useContext(AutocompleteContext);\n\n const handleCloseMenu = useCallback(() => {\n setForceClosePopover(true);\n }, [setForceClosePopover]);\n\n const { onInputKeyDown } = useKeyboardNavigation();\n\n const input = React.Children.only(children);\n\n const childrenWithProps = React.isValidElement(input)\n ? React.cloneElement(input, { 'aria-activedescendant': focusOptionIdx })\n : input;\n\n const idList = useMemo(() => `${id ? `${id}-` : ''}listbox`, [id]);\n\n const onFocusPopoverStatusSync = useCallback(() => {\n setForceClosePopover(false);\n setUserJustSelectedAnOption(false);\n setUserTypedSomething(false);\n setUserIsNavigatingWithArrows(false);\n }, [setForceClosePopover, setUserIsNavigatingWithArrows, setUserJustSelectedAnOption, setUserTypedSomething]);\n\n return (\n <>\n <A11yFocusedOption />\n\n <StyledContainer\n id={id}\n ref={setReferenceElement}\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-controls=\"autocomplete-listbox\"\n aria-expanded={isShowingPopover}\n aria-haspopup=\"listbox\"\n aria-owns={idList}\n onKeyDown={onInputKeyDown}\n onFocus={onFocusPopoverStatusSync}\n data-testid={AutocompleteDataTestid.CONTAINER}\n >\n {childrenWithProps}\n {filter && (\n <DSPopperJS\n customOffset={[0, 5]}\n closeContextMenu={handleCloseMenu}\n referenceElement={referenceElement}\n showPopover={isShowingPopover}\n startPlacementPreference={startPlacementPreference}\n placementOrderPreference={placementOrderPreference}\n withoutPortal\n withoutArrow\n withoutAnimation\n zIndex={10}\n >\n <StyledPopperWrapper tabIndex={-1}>\n <MenuList />\n </StyledPopperWrapper>\n </DSPopperJS>\n )}\n </StyledContainer>\n </>\n );\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;AD4CnB;AA3CJ,mBAAwD;AACxD,yBAA2B;AAC3B,6BAAgC;AAChC,oBAAqD;AACrD,uBAAyB;AACzB,mCAAsC;AACtC,qCAAuC;AACvC,+BAAkC;AAC3B,MAAM,YAAY,MAAmB;AAC1C,QAAM;AAAA,IACJ,OAAO,EAAE,IAAI,0BAA0B,UAAU,QAAQ,yBAAyB;AAAA,IAClF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,QAAI,yBAAW,uBAAAA,OAAmB;AAElC,QAAM,sBAAkB,0BAAY,MAAM;AACxC,yBAAqB,IAAI;AAAA,EAC3B,GAAG,CAAC,oBAAoB,CAAC;AAEzB,QAAM,EAAE,eAAe,QAAI,oDAAsB;AAEjD,QAAM,QAAQ,aAAAC,QAAM,SAAS,KAAK,QAAQ;AAE1C,QAAM,oBAAoB,aAAAA,QAAM,eAAe,KAAK,IAChD,aAAAA,QAAM,aAAa,OAAO,EAAE,yBAAyB,eAAe,CAAC,IACrE;AAEJ,QAAM,aAAS,sBAAQ,MAAM,GAAG,KAAK,GAAG,QAAQ,aAAa,CAAC,EAAE,CAAC;AAEjE,QAAM,+BAA2B,0BAAY,MAAM;AACjD,yBAAqB,KAAK;AAC1B,gCAA4B,KAAK;AACjC,0BAAsB,KAAK;AAC3B,kCAA8B,KAAK;AAAA,EACrC,GAAG,CAAC,sBAAsB,+BAA+B,6BAA6B,qBAAqB,CAAC;AAE5G,SACE,4EACE;AAAA,gDAAC,8CAAkB;AAAA,IAEnB;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,KAAK;AAAA,QACL,MAAK;AAAA,QACL,qBAAkB;AAAA,QAClB,iBAAc;AAAA,QACd,iBAAe;AAAA,QACf,iBAAc;AAAA,QACd,aAAW;AAAA,QACX,WAAW;AAAA,QACX,SAAS;AAAA,QACT,eAAa,sDAAuB;AAAA,QAEnC;AAAA;AAAA,UACA,UACC;AAAA,YAAC;AAAA;AAAA,cACC,cAAc,CAAC,GAAG,CAAC;AAAA,cACnB,kBAAkB;AAAA,cAClB;AAAA,cACA,aAAa;AAAA,cACb;AAAA,cACA;AAAA,cACA,eAAa;AAAA,cACb,cAAY;AAAA,cACZ,kBAAgB;AAAA,cAChB,QAAQ;AAAA,cAER,sDAAC,qCAAoB,UAAU,IAC7B,sDAAC,6BAAS,GACZ;AAAA;AAAA,UACF;AAAA;AAAA;AAAA,IAEJ;AAAA,KACF;AAEJ;",
6
6
  "names": ["AutocompleteContext", "React"]
7
7
  }
@@ -35,8 +35,9 @@ const isOptionFocuseable = (opt) => !["section", "separator"].includes(opt.type)
35
35
  const useKeyboardNavigation = () => {
36
36
  const {
37
37
  props: { onSelect, options },
38
- setShowPopover,
39
- showPopover,
38
+ trackUserInteractingViaKeyboard,
39
+ setForceClosePopover,
40
+ isShowingPopover,
40
41
  focusOptionIdx,
41
42
  setCurrentOption,
42
43
  scrollOptionIntoView
@@ -47,18 +48,16 @@ const useKeyboardNavigation = () => {
47
48
  );
48
49
  const onInputKeyDown = (0, import_react.useCallback)(
49
50
  (e) => {
50
- if ((e.keyCode >= 48 && e.keyCode <= 90 || e.key === "Backspace") && !showPopover) {
51
- setShowPopover(true);
52
- } else if (e.key === "Tab")
53
- setShowPopover(false);
54
- if (e.key === "Enter" && showPopover) {
51
+ trackUserInteractingViaKeyboard(e);
52
+ if (e.key === "Tab" || e.key === "Escape")
53
+ setForceClosePopover(true);
54
+ if (e.key === "Enter" && isShowingPopover) {
55
55
  e.preventDefault();
56
56
  onSelect(currentItem?.label, e);
57
- setShowPopover(false);
58
57
  }
59
58
  if (e.key === "ArrowDown") {
60
59
  e.preventDefault();
61
- if (showPopover) {
60
+ if (isShowingPopover) {
62
61
  const nextItemIndex = (0, import_listHelper.findInCircularList)(options, currentItemIndex, isOptionFocuseable);
63
62
  setCurrentOption(options[nextItemIndex].dsId);
64
63
  scrollOptionIntoView(options[nextItemIndex].dsId);
@@ -66,25 +65,23 @@ const useKeyboardNavigation = () => {
66
65
  }
67
66
  if (e.key === "ArrowUp") {
68
67
  e.preventDefault();
69
- if (showPopover) {
68
+ if (isShowingPopover) {
70
69
  const nextItemIndex = (0, import_listHelper.findInCircularList)(options, currentItemIndex, isOptionFocuseable, -1);
71
70
  setCurrentOption(options[nextItemIndex].dsId);
72
71
  scrollOptionIntoView(options[nextItemIndex].dsId);
73
72
  }
74
73
  }
75
- if (e.key === "Escape") {
76
- setShowPopover(false);
77
- }
78
74
  },
79
75
  [
80
- currentItem?.label,
81
- currentItemIndex,
76
+ trackUserInteractingViaKeyboard,
77
+ setForceClosePopover,
78
+ isShowingPopover,
82
79
  onSelect,
80
+ currentItem?.label,
83
81
  options,
84
- scrollOptionIntoView,
82
+ currentItemIndex,
85
83
  setCurrentOption,
86
- setShowPopover,
87
- showPopover
84
+ scrollOptionIntoView
88
85
  ]
89
86
  );
90
87
  return { onInputKeyDown };