@elliemae/ds-app-picker 3.70.0-next.52 → 3.70.0-next.54

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 (80) hide show
  1. package/dist/cjs/DSAppPicker.js +6 -64
  2. package/dist/cjs/DSAppPicker.js.map +3 -3
  3. package/dist/cjs/DSAppPickerCTX.js +2 -22
  4. package/dist/cjs/DSAppPickerCTX.js.map +2 -2
  5. package/dist/cjs/config/useAppPicker.js +19 -5
  6. package/dist/cjs/config/useAppPicker.js.map +2 -2
  7. package/dist/cjs/config/useFocusTracker.js +24 -35
  8. package/dist/cjs/config/useFocusTracker.js.map +2 -2
  9. package/dist/cjs/constants/index.js +2 -0
  10. package/dist/cjs/constants/index.js.map +2 -2
  11. package/dist/cjs/parts/AppPanel.js +60 -43
  12. package/dist/cjs/parts/AppPanel.js.map +3 -3
  13. package/dist/cjs/parts/AppPickerFloatingContext/AppPickerContent.js +83 -0
  14. package/dist/cjs/parts/AppPickerFloatingContext/AppPickerContent.js.map +7 -0
  15. package/dist/cjs/parts/AppPickerFloatingContext/useAppPickerFloatingContext.js +171 -0
  16. package/dist/cjs/parts/AppPickerFloatingContext/useAppPickerFloatingContext.js.map +7 -0
  17. package/dist/cjs/parts/AppPickerItem.js +6 -10
  18. package/dist/cjs/parts/AppPickerItem.js.map +2 -2
  19. package/dist/cjs/parts/AppSection.js +2 -0
  20. package/dist/cjs/parts/AppSection.js.map +2 -2
  21. package/dist/cjs/parts/Trigger.js +14 -8
  22. package/dist/cjs/parts/Trigger.js.map +2 -2
  23. package/dist/cjs/parts/style.js +1 -7
  24. package/dist/cjs/parts/style.js.map +2 -2
  25. package/dist/cjs/react-desc-prop-types.js +6 -1
  26. package/dist/cjs/react-desc-prop-types.js.map +2 -2
  27. package/dist/cjs/util/getChipId.js +36 -0
  28. package/dist/cjs/util/getChipId.js.map +7 -0
  29. package/dist/cjs/util/getChipRegionId.js +37 -0
  30. package/dist/cjs/util/getChipRegionId.js.map +7 -0
  31. package/dist/esm/DSAppPicker.js +7 -65
  32. package/dist/esm/DSAppPicker.js.map +3 -3
  33. package/dist/esm/DSAppPickerCTX.js +2 -22
  34. package/dist/esm/DSAppPickerCTX.js.map +2 -2
  35. package/dist/esm/config/useAppPicker.js +22 -8
  36. package/dist/esm/config/useAppPicker.js.map +2 -2
  37. package/dist/esm/config/useFocusTracker.js +23 -34
  38. package/dist/esm/config/useFocusTracker.js.map +2 -2
  39. package/dist/esm/constants/index.js +2 -0
  40. package/dist/esm/constants/index.js.map +2 -2
  41. package/dist/esm/parts/AppPanel.js +61 -44
  42. package/dist/esm/parts/AppPanel.js.map +3 -3
  43. package/dist/esm/parts/AppPickerFloatingContext/AppPickerContent.js +53 -0
  44. package/dist/esm/parts/AppPickerFloatingContext/AppPickerContent.js.map +7 -0
  45. package/dist/esm/parts/AppPickerFloatingContext/useAppPickerFloatingContext.js +141 -0
  46. package/dist/esm/parts/AppPickerFloatingContext/useAppPickerFloatingContext.js.map +7 -0
  47. package/dist/esm/parts/AppPickerItem.js +5 -9
  48. package/dist/esm/parts/AppPickerItem.js.map +2 -2
  49. package/dist/esm/parts/AppSection.js +2 -0
  50. package/dist/esm/parts/AppSection.js.map +2 -2
  51. package/dist/esm/parts/Trigger.js +15 -9
  52. package/dist/esm/parts/Trigger.js.map +2 -2
  53. package/dist/esm/parts/style.js +1 -7
  54. package/dist/esm/parts/style.js.map +2 -2
  55. package/dist/esm/react-desc-prop-types.js +6 -1
  56. package/dist/esm/react-desc-prop-types.js.map +2 -2
  57. package/dist/esm/util/getChipId.js +6 -0
  58. package/dist/esm/util/getChipId.js.map +7 -0
  59. package/dist/esm/util/getChipRegionId.js +7 -0
  60. package/dist/esm/util/getChipRegionId.js.map +7 -0
  61. package/dist/types/DSAppPicker.d.ts +1 -1
  62. package/dist/types/DSAppPickerCTX.d.ts +6 -17
  63. package/dist/types/config/useAppPicker.d.ts +109 -91
  64. package/dist/types/config/useFocusTracker.d.ts +10 -6
  65. package/dist/types/constants/index.d.ts +1 -0
  66. package/dist/types/parts/AppPanel.d.ts +1 -8
  67. package/dist/types/parts/AppPickerFloatingContext/AppPickerContent.d.ts +3 -0
  68. package/dist/types/parts/AppPickerFloatingContext/useAppPickerFloatingContext.d.ts +170 -0
  69. package/dist/types/parts/AppPickerItem.d.ts +1 -0
  70. package/dist/types/parts/Trigger.d.ts +10 -14
  71. package/dist/types/parts/style.d.ts +0 -1
  72. package/dist/types/react-desc-prop-types.d.ts +31 -1
  73. package/dist/types/util/getChipId.d.ts +2 -0
  74. package/dist/types/util/getChipRegionId.d.ts +1 -0
  75. package/package.json +13 -14
  76. package/dist/cjs/config/useAppPickerBehavior.js +0 -156
  77. package/dist/cjs/config/useAppPickerBehavior.js.map +0 -7
  78. package/dist/esm/config/useAppPickerBehavior.js +0 -126
  79. package/dist/esm/config/useAppPickerBehavior.js.map +0 -7
  80. package/dist/types/config/useAppPickerBehavior.d.ts +0 -39
@@ -0,0 +1,170 @@
1
+ import type React from 'react';
2
+ import type { useAppPicker } from '../../config/useAppPicker.js';
3
+ import type { DSAppPickerT } from '../../react-desc-prop-types.js';
4
+ /**
5
+ * useAppPickerFloatingContext — the single point that wires DSAppPicker to
6
+ * `@elliemae/ds-floating-context`'s `useFloatingContext`.
7
+ *
8
+ * WHAT IT DOES (as a black box):
9
+ * AppPicker can be used in two very different ways:
10
+ * - Controlled: the consumer supplies `isOpen` and drives the open/close transition.
11
+ * └→ AppPicker can't be event-based as the flip might originate from any cause and we don't own the business logic
12
+ * └→ we need to ensure WCAG embedded behaviours (focus, Escape, click-outside) are wired to the consumer's `isOpen` flip.
13
+ * - Uncontrolled: the consumer does not supply `isOpen` and AppPicker owns the full flows, we only notify the consumer of the transition and its cause.
14
+ *
15
+ * The AppPicker and this file in particular serves as the one place that coordinates the two different ways to use the component and wires with the useFloatingContext hook.
16
+ * This files owns:
17
+ * - Focus management relative to open/close transitions (initial focus on open, return focus to trigger on close)
18
+ * - Escape key handling (scoped to the panel and trigger)
19
+ * - Click-outside handling (panel and trigger)
20
+ * - Imperative focus API via actionRef
21
+ * - Controlled/Uncontrolled forks and differences in event notification (eager vs controlled-flip)
22
+ * - OnOpen and OnClose notification to the consumer with the correct reason and event (if any)
23
+ *
24
+ * IMPORTANT:
25
+ * Parts of the flow/logic required in this file is offloaded to useFloatingContext internal assumptions and logics.
26
+ * Changes to useFloatingContext may break the flows in this file, or alter them in ways that are not obvious, the two are closely coupled.
27
+ *
28
+ * DATA / EVENT FLOW
29
+ *
30
+ * Two concerns run in parallel and must not be conflated: (A) what makes the panel show/hide and take
31
+ * focus, and (B) how the consumer is told it opened/closed. They have different origins.
32
+ *
33
+ * (A) PANEL VISIBILITY + FOCUS — useFloatingContext internal co-ownership of the flow.
34
+ *
35
+ * a user action │ │ isOpen prop flip
36
+ * (trigger click / scoped Escape / click outside) │ │ (not a traceable user action, but the consumer's own flip)
37
+ * uncontrolled - flips the internal flag │ │ controlled - AppPicker's own flip is inert, consumer drives it
38
+ * │
39
+ * ▼
40
+ * resolvedIsOpen changes
41
+ * │
42
+ * ▼
43
+ * useFloatingContext (externallyControlledIsOpen) detects the transition
44
+ * │
45
+ * ▼
46
+ * on open │ │ on close
47
+ * handleFloatingOpen │ │ focus is only restored after a SCOPED ESCAPE:
48
+ * AppPicker business logic seeds initial focus │ │ useFloatingContext returns focus to the trigger
49
+ * │ │ (returnFocusToReference). Click-outside / toggle
50
+ * │ │ / controlled closes do NOT move focus, and
51
+ * │ │ handleFloatingClose only NOTIFIES (see (B)).
52
+ * │
53
+ * ▼
54
+ * ┌─────────────────────────────────────────────────────────────┐
55
+ * │ visibility + focus are delivered to final user as expected │
56
+ * └─────────────────────────────────────────────────────────────┘
57
+ *
58
+ * (B) CONSUMER NOTIFICATION
59
+ * Each flow below is the UNCONTROLLED path, where AppPicker owns the transition and can name the true cause.
60
+ * The controlled equivalent for every trigger is stated once at the end.
61
+ * ┌────────────────────────┐
62
+ * │ OPENING TRIGGERS FLOWS │
63
+ * └────────────────────────┘
64
+ * TRIGGER CLICK (uncontrolled)
65
+ * trigger click
66
+ * user clicks the internal trigger, panel closed
67
+ * │
68
+ * ▼
69
+ * handleTriggerClick
70
+ * ( flips the flag and wires the visual and focus Flow (A) above )
71
+ * │
72
+ * ▼
73
+ * ┌──────────────────────────────────────────────┐
74
+ * │ onOpen { reason: 'trigger', event } │ fired EAGERLY, when the event is triggered
75
+ * └──────────────────────────────────────────────┘
76
+ * ------------------------------------------------------------------------------------------------------------------------
77
+ * ┌────────────────────────┐
78
+ * │ CLOSING TRIGGERS FLOWS │
79
+ * └────────────────────────┘
80
+ * KEYBOARD ESCAPE (uncontrolled)
81
+ * Escape within the panel DOM tree or the trigger
82
+ * scoped Escape (routed only while closeOnEscape, i.e. no consumer onKeyDown)
83
+ * │
84
+ * ▼
85
+ * onEscape → handleScopedEscape
86
+ * ( flips the flag and wires the visual and focus Flow (A) above )
87
+ * │
88
+ * ▼
89
+ * ┌──────────────────────────────────────────────┐
90
+ * │ onClose { reason: 'escape', event } │ fired EAGERLY, when the event is triggered
91
+ * └──────────────────────────────────────────────┘
92
+ *
93
+ * CLICK OUTSIDE (uncontrolled)
94
+ * Click outside the panel DOM tree and the trigger
95
+ * useFloatingContext detects a pointer press outside the panel + trigger
96
+ * │
97
+ * ▼
98
+ * handleClickOutside
99
+ * ( flips the flag and wires the visual and focus Flow (A) above )
100
+ * │
101
+ * ▼
102
+ * ┌──────────────────────────────────────────────┐
103
+ * │ onClose { reason: 'click-outside', event } │ fired EAGERLY, when the event is triggered
104
+ * └──────────────────────────────────────────────┘
105
+ *
106
+ * CLICK ON TRIGGER (uncontrolled, while internal state is open)
107
+ * trigger click while open
108
+ * user clicks the internal trigger, panel open
109
+ * │
110
+ * ▼
111
+ * handleTriggerClick
112
+ * ( flips the flag and wires the visual and focus Flow (A) above )
113
+ * │
114
+ * ▼
115
+ * ┌──────────────────────────────────────────────┐
116
+ * │ onClose { reason: 'trigger-toggle', event } │ fired EAGERLY, when the event is triggered
117
+ * └──────────────────────────────────────────────┘
118
+ * ------------------------------------------------------------------------------------------------------------------------
119
+ * ┌──────────────────────────────────┐
120
+ * │ CONTROLLED OPEN & CLOSE FLOWS │
121
+ * └──────────────────────────────────┘
122
+ * AppPicker's own flip is inert;
123
+ * We can't fire EAGERLY and we can't track an originating event, there may be NONE
124
+ * The consumer's `isOpen` flip is reacted to by useFloatingContext, which fires onOpen / onClose with reason 'controlled-flip'
125
+ * We wire the visual and focus Flow (A) above, and then notify the consumer with reason 'controlled' (no event)
126
+ * │
127
+ * ▼
128
+ * ┌──────────────────────────────────────────────┐
129
+ * │ onOpen { reason: 'controlled' } │ no event
130
+ * │ onClose { reason: 'controlled' } │ a prop flip is not a traceable user action
131
+ * └──────────────────────────────────────────────┘
132
+ * ------------------------------------------------------------------------------------------------------------------------
133
+ *
134
+ * Eager (uncontrolled) and controlled-flip paths are mutually exclusive on `isControlled`.
135
+ * the consumer is notified exactly once per transition — never twice.
136
+ * On Escape specifically
137
+ * a controlled consumer supplies onKeyDown, so closeOnEscape is false in useFloatingContext
138
+ * └→ AppPicker's onEscape never runs —
139
+ * └→ the close arrives purely by listening to the flag transition
140
+ * ------------------------------------------------------------------------------------------------------------------------
141
+ * A nuance for an edge case:
142
+ *
143
+ * Declarative mount-open (rendered already-open).
144
+ * useFloatingContext fires no onOpen for it (it did not transition to open, it started open),
145
+ * └→ neither the focus-seed (A) nor the notification (B) runs
146
+ * AppPanel compensates this locally via useMountedOpenAutofocusNuance, it needs to be seen if this is even desired or should be removed
147
+ * ------------------------------------------------------------------------------------------------------------------------
148
+ */
149
+ type ConfiguredAppPickerCtx = ReturnType<typeof useAppPicker>;
150
+ type AppPickerFloatingContextConfig = {
151
+ propsWithDefault: DSAppPickerT.InternalProps;
152
+ focusTrackers: ConfiguredAppPickerCtx['focusTrackers'];
153
+ wasOpenedByKeyboardRef: ConfiguredAppPickerCtx['wasOpenedByKeyboardRef'];
154
+ resolvedIsOpen: ConfiguredAppPickerCtx['resolvedIsOpen'];
155
+ setInternalIsOpen: ConfiguredAppPickerCtx['setInternalIsOpen'];
156
+ };
157
+ export declare const useAppPickerFloatingContext: (appPickerConfig: AppPickerFloatingContextConfig) => {
158
+ floatingStyles: React.CSSProperties;
159
+ arrowStyles: import("@elliemae/ds-floating-context/dist/types/parts/PopoverArrow.js").PopoverArrowT;
160
+ floatingContext: {
161
+ withoutPortal: boolean;
162
+ withoutAnimation: boolean;
163
+ portalDOMContainer: HTMLElement | undefined;
164
+ animationDuration: number;
165
+ };
166
+ handleTriggerRef: (instance: HTMLButtonElement | null) => void | React.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof React.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES];
167
+ handleTriggerClick: (e: React.MouseEvent | React.KeyboardEvent) => void;
168
+ floatingInnerRef: (instance: HTMLDivElement | null) => void | React.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof React.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES];
169
+ };
170
+ export {};
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import type { DSAppPickerT } from '../react-desc-prop-types.js';
3
3
  interface AppPickerItemProps {
4
4
  app: DSAppPickerT.AppItem;
5
+ chipId: string;
5
6
  positionLabel: string;
6
7
  ownerProps: {
7
8
  getOwnerProps: () => object;
@@ -1,15 +1,11 @@
1
- import React from 'react';
2
- import type { DSAppPickerT } from '../react-desc-prop-types.js';
3
- interface TriggerProps {
4
- Icon: DSAppPickerT.InternalProps['icon'];
5
- isOpen: boolean;
6
- setRef: React.RefCallback<HTMLButtonElement>;
7
- ownerProps: {
8
- getOwnerProps: () => object;
9
- getOwnerPropsArguments: () => object;
10
- };
11
- onClick: (e: React.MouseEvent | React.KeyboardEvent) => void;
12
- renderTrigger?: DSAppPickerT.OptionalProps['renderTrigger'];
13
- }
14
- export declare const Trigger: React.FC<TriggerProps>;
1
+ import type { useAppPickerFloatingContext } from './AppPickerFloatingContext/useAppPickerFloatingContext.js';
2
+ type UseAppPickerFloatingContextT = ReturnType<typeof useAppPickerFloatingContext>;
3
+ type FloatingContextDictatedProps = {
4
+ handleTriggerRef: UseAppPickerFloatingContextT['handleTriggerRef'];
5
+ handleTriggerClick: UseAppPickerFloatingContextT['handleTriggerClick'];
6
+ };
7
+ export declare const Trigger: {
8
+ (PropsFromFloatingContext: FloatingContextDictatedProps): import("react/jsx-runtime.js").JSX.Element | null;
9
+ displayName: string;
10
+ };
15
11
  export {};
@@ -1,4 +1,3 @@
1
- export declare const StyledAppPickerFloating: import("styled-components").StyledComponent<import("react").ComponentType<import("@elliemae/ds-floating-context").DSFloatingWrapperT.Props>, import("@elliemae/ds-system").Theme, object & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<import("react").ComponentType<import("@elliemae/ds-floating-context").DSFloatingWrapperT.Props>>, never>;
2
1
  export declare const StyledWrapper: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("@elliemae/ds-grid").DSGridT.Props & import("react").RefAttributes<HTMLDivElement>>, import("@elliemae/ds-system").Theme, object & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<import("react").ForwardRefExoticComponent<import("@elliemae/ds-grid").DSGridT.Props & import("react").RefAttributes<HTMLDivElement>>>, never>;
3
2
  export declare const StyledListItem: import("styled-components").StyledComponent<"li", import("@elliemae/ds-system").Theme, object & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<"li">, never>;
4
3
  export declare const StyledListItemFullRow: import("styled-components").StyledComponent<"li", import("@elliemae/ds-system").Theme, object & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<"li">, never>;
@@ -22,6 +22,35 @@ export declare namespace DSAppPickerT {
22
22
  focusSelectedOrFirstAvailable?: () => void;
23
23
  focusWrapper: () => void;
24
24
  }>;
25
+ /**
26
+ * Why the panel opened. `trigger` carries the activating event and fires synchronously in the
27
+ * trigger's click handler (AppPicker owns the open). `controlled` fires when the consumer flips
28
+ * the `isOpen` prop themselves — no event, delivered when that flip takes effect.
29
+ */
30
+ type OpenChange = {
31
+ reason: 'trigger';
32
+ event: React.MouseEvent | React.KeyboardEvent;
33
+ } | {
34
+ reason: 'controlled';
35
+ };
36
+ /**
37
+ * Why the panel closed. The event-carrying reasons fire synchronously from the handler that owns
38
+ * the close (AppPicker in uncontrolled mode): `escape` (a scoped Escape), `click-outside`, and
39
+ * `trigger-toggle` (the trigger clicked while open). `controlled` fires when the consumer flips the
40
+ * `isOpen` prop themselves — no event, delivered when that flip takes effect.
41
+ */
42
+ type CloseChange = {
43
+ reason: 'escape';
44
+ event: KeyboardEvent;
45
+ } | {
46
+ reason: 'click-outside';
47
+ event: MouseEvent | TouchEvent;
48
+ } | {
49
+ reason: 'trigger-toggle';
50
+ event: React.MouseEvent | React.KeyboardEvent;
51
+ } | {
52
+ reason: 'controlled';
53
+ };
25
54
  interface RequiredProps {
26
55
  }
27
56
  type SlotFunctionArguments = {
@@ -46,7 +75,8 @@ export declare namespace DSAppPickerT {
46
75
  [key: string]: unknown;
47
76
  }
48
77
  interface OptionalProps extends TypescriptHelpersT.PropsForGlobalOnSlots<typeof DSAppPickerName, typeof DSAppPickerSlots> {
49
- onClose?: () => void;
78
+ onOpen?: (info: OpenChange) => void;
79
+ onClose?: (info: CloseChange) => void;
50
80
  onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;
51
81
  onClickOutside?: (e: MouseEvent | React.MouseEvent) => void;
52
82
  onKeyDown?: (e: React.KeyboardEvent) => void;
@@ -0,0 +1,2 @@
1
+ import type { DSAppPickerT } from '../react-desc-prop-types.js';
2
+ export declare const getChipId: (app: DSAppPickerT.AppItem, flatIndex: number) => string;
@@ -0,0 +1 @@
1
+ export declare const getChipRegionId: (chipId: string) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-app-picker",
3
- "version": "3.70.0-next.52",
3
+ "version": "3.70.0-next.54",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - App Picker",
6
6
  "files": [
@@ -36,24 +36,23 @@
36
36
  "indent": 4
37
37
  },
38
38
  "dependencies": {
39
- "uid": "^2.0.2",
40
- "@elliemae/ds-button-v2": "3.70.0-next.52",
41
- "@elliemae/ds-chip": "3.70.0-next.52",
42
- "@elliemae/ds-floating-context": "3.70.0-next.52",
43
- "@elliemae/ds-grid": "3.70.0-next.52",
44
- "@elliemae/ds-hooks-focus-trap": "3.70.0-next.52",
45
- "@elliemae/ds-props-helpers": "3.70.0-next.52",
46
- "@elliemae/ds-icons": "3.70.0-next.52",
47
- "@elliemae/ds-system": "3.70.0-next.52",
48
- "@elliemae/ds-typography": "3.70.0-next.52"
39
+ "@elliemae/ds-button-v2": "3.70.0-next.54",
40
+ "@elliemae/ds-floating-context": "3.70.0-next.54",
41
+ "@elliemae/ds-hooks-focus-trap": "3.70.0-next.54",
42
+ "@elliemae/ds-grid": "3.70.0-next.54",
43
+ "@elliemae/ds-props-helpers": "3.70.0-next.54",
44
+ "@elliemae/ds-system": "3.70.0-next.54",
45
+ "@elliemae/ds-chip": "3.70.0-next.54",
46
+ "@elliemae/ds-icons": "3.70.0-next.54",
47
+ "@elliemae/ds-typography": "3.70.0-next.54"
49
48
  },
50
49
  "devDependencies": {
51
50
  "@playwright/experimental-ct-react": "^1.60.0",
52
51
  "jest": "^30.0.0",
53
52
  "styled-components": "~5.3.9",
54
- "@elliemae/ds-monorepo-devops": "3.70.0-next.52",
55
- "@elliemae/ds-test-utils": "3.70.0-next.52",
56
- "@elliemae/ds-typescript-helpers": "3.70.0-next.52"
53
+ "@elliemae/ds-typescript-helpers": "3.70.0-next.54",
54
+ "@elliemae/ds-monorepo-devops": "3.70.0-next.54",
55
+ "@elliemae/ds-test-utils": "3.70.0-next.54"
57
56
  },
58
57
  "peerDependencies": {
59
58
  "react": "^18.3.1",
@@ -1,156 +0,0 @@
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
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var useAppPickerBehavior_exports = {};
30
- __export(useAppPickerBehavior_exports, {
31
- useAppPickerBehavior: () => useAppPickerBehavior
32
- });
33
- module.exports = __toCommonJS(useAppPickerBehavior_exports);
34
- var React = __toESM(require("react"));
35
- var import_react = require("react");
36
- var import_ds_floating_context = require("@elliemae/ds-floating-context");
37
- var import_useFocusTracker = require("./useFocusTracker.js");
38
- const useAppPickerBehavior = (appPickerConfig) => {
39
- const { propsWithDefault, ownerPropsConfig } = appPickerConfig;
40
- const {
41
- apps,
42
- customApps,
43
- icon: Icon,
44
- renderTrigger,
45
- isOpen,
46
- onClose,
47
- actionRef,
48
- onClick,
49
- onClickOutside,
50
- triggerRef
51
- } = propsWithDefault;
52
- const focusTracker = (0, import_useFocusTracker.useFocusTracker)();
53
- const { trackFocusSelectedItem, trackFocusItemAtIndex, trackFocusPanel } = focusTracker;
54
- const [open, setOpen] = (0, import_react.useState)(false);
55
- const defaultTriggerRef = (0, import_react.useRef)(null);
56
- const wasOpenedByKeyboardRef = (0, import_react.useRef)(false);
57
- const appsRef = (0, import_react.useRef)(apps);
58
- appsRef.current = apps;
59
- const customAppsRef = (0, import_react.useRef)(customApps);
60
- customAppsRef.current = customApps;
61
- const resolvedIsOpen = typeof isOpen === "boolean" ? isOpen : open;
62
- const handleClose = (0, import_react.useCallback)(() => {
63
- setOpen(false);
64
- onClose?.();
65
- }, [onClose]);
66
- const handleClickOutside = (0, import_react.useCallback)(
67
- (e) => {
68
- setOpen(false);
69
- onClose?.();
70
- onClickOutside?.(e);
71
- },
72
- [onClose, onClickOutside]
73
- );
74
- const {
75
- refs: floatingRefs,
76
- floatingStyles,
77
- arrowStyles,
78
- context: floatingContext
79
- } = (0, import_ds_floating_context.useFloatingContext)({
80
- placement: "bottom",
81
- // Arrow tip is ~6.1px above the panel top (arrowPlacementBase16 ≈ 17.5px, tip at 11.4px from box top).
82
- // 4px spec gap → 4 + 6.1 ≈ 10px offset.
83
- customOffset: [0, 10],
84
- externallyControlledIsOpen: resolvedIsOpen,
85
- withoutAnimation: true,
86
- onClickOutside: handleClickOutside
87
- });
88
- const handleTriggerRef = (0, import_react.useCallback)(
89
- (node) => {
90
- defaultTriggerRef.current = node;
91
- floatingRefs.setReference(node);
92
- if (triggerRef) {
93
- triggerRef.current = node;
94
- }
95
- },
96
- [floatingRefs, triggerRef]
97
- );
98
- const handleActionRef = (0, import_react.useCallback)(
99
- (node) => {
100
- if (node && actionRef?.current) {
101
- actionRef.current.focusToIndex = (index) => {
102
- trackFocusItemAtIndex(appsRef.current, customAppsRef.current, index);
103
- };
104
- actionRef.current.focusWrapper = () => {
105
- trackFocusPanel();
106
- };
107
- actionRef.current.focusSelectedOrFirstAvailable = () => {
108
- trackFocusSelectedItem(appsRef.current, customAppsRef.current);
109
- };
110
- }
111
- },
112
- [actionRef, trackFocusItemAtIndex, trackFocusPanel, trackFocusSelectedItem]
113
- );
114
- const floatingInnerRef = (0, import_react.useCallback)(
115
- (node) => {
116
- floatingRefs.setFloating(node);
117
- handleActionRef(node);
118
- },
119
- [floatingRefs.setFloating, handleActionRef]
120
- );
121
- (0, import_react.useEffect)(() => {
122
- if (resolvedIsOpen && wasOpenedByKeyboardRef.current) {
123
- trackFocusSelectedItem(apps, customApps);
124
- }
125
- }, [resolvedIsOpen, trackFocusSelectedItem, apps, customApps]);
126
- const handleTriggerClick = (0, import_react.useCallback)(
127
- (e) => {
128
- wasOpenedByKeyboardRef.current = e.detail === 0;
129
- onClick?.(e);
130
- setOpen((prev) => !prev);
131
- },
132
- [onClick]
133
- );
134
- return {
135
- // For rendering
136
- Icon,
137
- renderTrigger,
138
- resolvedIsOpen,
139
- floatingStyles,
140
- arrowStyles,
141
- floatingContext,
142
- ownerPropsConfig,
143
- // Refs
144
- defaultTriggerRef,
145
- triggerRef,
146
- wasOpenedByKeyboardRef,
147
- // Handlers
148
- handleClose,
149
- handleTriggerRef,
150
- handleTriggerClick,
151
- floatingInnerRef,
152
- // Context value
153
- focusTracker
154
- };
155
- };
156
- //# sourceMappingURL=useAppPickerBehavior.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/config/useAppPickerBehavior.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable max-statements */\nimport type React from 'react';\nimport { useState, useRef, useCallback, useEffect } from 'react';\nimport { useFloatingContext } from '@elliemae/ds-floating-context';\nimport { useFocusTracker } from './useFocusTracker.js';\nimport type { useAppPicker } from './useAppPicker.js';\n\nexport const useAppPickerBehavior = (appPickerConfig: ReturnType<typeof useAppPicker>) => {\n const { propsWithDefault, ownerPropsConfig } = appPickerConfig;\n const {\n apps,\n customApps,\n icon: Icon,\n renderTrigger,\n isOpen,\n onClose,\n actionRef,\n onClick,\n onClickOutside,\n triggerRef,\n } = propsWithDefault;\n\n const focusTracker = useFocusTracker();\n const { trackFocusSelectedItem, trackFocusItemAtIndex, trackFocusPanel } = focusTracker;\n\n const [open, setOpen] = useState(false);\n const defaultTriggerRef = useRef<HTMLButtonElement>(null);\n const wasOpenedByKeyboardRef = useRef(false);\n\n // Stable refs for actionRef methods \u2014 closed over by the callback below so they are\n // always current without causing the ref callback to regenerate on every data change.\n const appsRef = useRef(apps);\n appsRef.current = apps;\n const customAppsRef = useRef(customApps);\n customAppsRef.current = customApps;\n\n const resolvedIsOpen = typeof isOpen === 'boolean' ? isOpen : open;\n\n const handleClose = useCallback(() => {\n setOpen(false);\n onClose?.();\n }, [onClose]);\n\n const handleClickOutside = useCallback(\n (e: MouseEvent | TouchEvent) => {\n setOpen(false);\n onClose?.();\n onClickOutside?.(e as MouseEvent);\n },\n [onClose, onClickOutside],\n );\n\n const {\n refs: floatingRefs,\n floatingStyles,\n arrowStyles,\n context: floatingContext,\n } = useFloatingContext({\n placement: 'bottom',\n // Arrow tip is ~6.1px above the panel top (arrowPlacementBase16 \u2248 17.5px, tip at 11.4px from box top).\n // 4px spec gap \u2192 4 + 6.1 \u2248 10px offset.\n customOffset: [0, 10],\n externallyControlledIsOpen: resolvedIsOpen,\n withoutAnimation: true,\n onClickOutside: handleClickOutside,\n });\n\n const handleTriggerRef = useCallback<React.RefCallback<HTMLButtonElement>>(\n (node) => {\n (defaultTriggerRef as React.MutableRefObject<HTMLButtonElement | null>).current = node;\n floatingRefs.setReference(node);\n if (triggerRef) {\n (triggerRef as React.MutableRefObject<HTMLButtonElement | null>).current = node;\n }\n },\n [floatingRefs, triggerRef],\n );\n\n // Ref callback on StyledAppPickerFloating: fires on mount with the panel node, populating\n // actionRef methods. All focus operations go through the tracker \u2014 no DOM queries.\n const handleActionRef = useCallback<React.RefCallback<HTMLDivElement>>(\n (node) => {\n if (node && actionRef?.current) {\n actionRef.current.focusToIndex = (index: number) => {\n trackFocusItemAtIndex(appsRef.current, customAppsRef.current, index);\n };\n actionRef.current.focusWrapper = () => {\n trackFocusPanel();\n };\n actionRef.current.focusSelectedOrFirstAvailable = () => {\n trackFocusSelectedItem(appsRef.current, customAppsRef.current);\n };\n }\n },\n [actionRef, trackFocusItemAtIndex, trackFocusPanel, trackFocusSelectedItem],\n );\n\n const floatingInnerRef = useCallback<React.RefCallback<HTMLDivElement>>(\n (node) => {\n (floatingRefs.setFloating as React.RefCallback<HTMLDivElement>)(node);\n handleActionRef(node);\n },\n [floatingRefs.setFloating, handleActionRef],\n );\n\n // When panel opens via keyboard, seed the focus tracker so the correct chip gets focus\n // via its innerRef callback. Non-keyboard paths are handled by AppPanel on mount.\n useEffect(() => {\n if (resolvedIsOpen && wasOpenedByKeyboardRef.current) {\n trackFocusSelectedItem(apps, customApps);\n }\n }, [resolvedIsOpen, trackFocusSelectedItem, apps, customApps]);\n\n const handleTriggerClick = useCallback(\n (e: React.MouseEvent | React.KeyboardEvent) => {\n wasOpenedByKeyboardRef.current = (e as React.MouseEvent).detail === 0;\n onClick?.(e);\n setOpen((prev) => !prev);\n },\n [onClick],\n );\n\n return {\n // For rendering\n Icon,\n renderTrigger,\n resolvedIsOpen,\n floatingStyles,\n arrowStyles,\n floatingContext,\n ownerPropsConfig,\n // Refs\n defaultTriggerRef,\n triggerRef,\n wasOpenedByKeyboardRef,\n // Handlers\n handleClose,\n handleTriggerRef,\n handleTriggerClick,\n floatingInnerRef,\n // Context value\n focusTracker,\n };\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,126 +0,0 @@
1
- import * as React from "react";
2
- import { useState, useRef, useCallback, useEffect } from "react";
3
- import { useFloatingContext } from "@elliemae/ds-floating-context";
4
- import { useFocusTracker } from "./useFocusTracker.js";
5
- const useAppPickerBehavior = (appPickerConfig) => {
6
- const { propsWithDefault, ownerPropsConfig } = appPickerConfig;
7
- const {
8
- apps,
9
- customApps,
10
- icon: Icon,
11
- renderTrigger,
12
- isOpen,
13
- onClose,
14
- actionRef,
15
- onClick,
16
- onClickOutside,
17
- triggerRef
18
- } = propsWithDefault;
19
- const focusTracker = useFocusTracker();
20
- const { trackFocusSelectedItem, trackFocusItemAtIndex, trackFocusPanel } = focusTracker;
21
- const [open, setOpen] = useState(false);
22
- const defaultTriggerRef = useRef(null);
23
- const wasOpenedByKeyboardRef = useRef(false);
24
- const appsRef = useRef(apps);
25
- appsRef.current = apps;
26
- const customAppsRef = useRef(customApps);
27
- customAppsRef.current = customApps;
28
- const resolvedIsOpen = typeof isOpen === "boolean" ? isOpen : open;
29
- const handleClose = useCallback(() => {
30
- setOpen(false);
31
- onClose?.();
32
- }, [onClose]);
33
- const handleClickOutside = useCallback(
34
- (e) => {
35
- setOpen(false);
36
- onClose?.();
37
- onClickOutside?.(e);
38
- },
39
- [onClose, onClickOutside]
40
- );
41
- const {
42
- refs: floatingRefs,
43
- floatingStyles,
44
- arrowStyles,
45
- context: floatingContext
46
- } = useFloatingContext({
47
- placement: "bottom",
48
- // Arrow tip is ~6.1px above the panel top (arrowPlacementBase16 ≈ 17.5px, tip at 11.4px from box top).
49
- // 4px spec gap → 4 + 6.1 ≈ 10px offset.
50
- customOffset: [0, 10],
51
- externallyControlledIsOpen: resolvedIsOpen,
52
- withoutAnimation: true,
53
- onClickOutside: handleClickOutside
54
- });
55
- const handleTriggerRef = useCallback(
56
- (node) => {
57
- defaultTriggerRef.current = node;
58
- floatingRefs.setReference(node);
59
- if (triggerRef) {
60
- triggerRef.current = node;
61
- }
62
- },
63
- [floatingRefs, triggerRef]
64
- );
65
- const handleActionRef = useCallback(
66
- (node) => {
67
- if (node && actionRef?.current) {
68
- actionRef.current.focusToIndex = (index) => {
69
- trackFocusItemAtIndex(appsRef.current, customAppsRef.current, index);
70
- };
71
- actionRef.current.focusWrapper = () => {
72
- trackFocusPanel();
73
- };
74
- actionRef.current.focusSelectedOrFirstAvailable = () => {
75
- trackFocusSelectedItem(appsRef.current, customAppsRef.current);
76
- };
77
- }
78
- },
79
- [actionRef, trackFocusItemAtIndex, trackFocusPanel, trackFocusSelectedItem]
80
- );
81
- const floatingInnerRef = useCallback(
82
- (node) => {
83
- floatingRefs.setFloating(node);
84
- handleActionRef(node);
85
- },
86
- [floatingRefs.setFloating, handleActionRef]
87
- );
88
- useEffect(() => {
89
- if (resolvedIsOpen && wasOpenedByKeyboardRef.current) {
90
- trackFocusSelectedItem(apps, customApps);
91
- }
92
- }, [resolvedIsOpen, trackFocusSelectedItem, apps, customApps]);
93
- const handleTriggerClick = useCallback(
94
- (e) => {
95
- wasOpenedByKeyboardRef.current = e.detail === 0;
96
- onClick?.(e);
97
- setOpen((prev) => !prev);
98
- },
99
- [onClick]
100
- );
101
- return {
102
- // For rendering
103
- Icon,
104
- renderTrigger,
105
- resolvedIsOpen,
106
- floatingStyles,
107
- arrowStyles,
108
- floatingContext,
109
- ownerPropsConfig,
110
- // Refs
111
- defaultTriggerRef,
112
- triggerRef,
113
- wasOpenedByKeyboardRef,
114
- // Handlers
115
- handleClose,
116
- handleTriggerRef,
117
- handleTriggerClick,
118
- floatingInnerRef,
119
- // Context value
120
- focusTracker
121
- };
122
- };
123
- export {
124
- useAppPickerBehavior
125
- };
126
- //# sourceMappingURL=useAppPickerBehavior.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/config/useAppPickerBehavior.ts"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-statements */\nimport type React from 'react';\nimport { useState, useRef, useCallback, useEffect } from 'react';\nimport { useFloatingContext } from '@elliemae/ds-floating-context';\nimport { useFocusTracker } from './useFocusTracker.js';\nimport type { useAppPicker } from './useAppPicker.js';\n\nexport const useAppPickerBehavior = (appPickerConfig: ReturnType<typeof useAppPicker>) => {\n const { propsWithDefault, ownerPropsConfig } = appPickerConfig;\n const {\n apps,\n customApps,\n icon: Icon,\n renderTrigger,\n isOpen,\n onClose,\n actionRef,\n onClick,\n onClickOutside,\n triggerRef,\n } = propsWithDefault;\n\n const focusTracker = useFocusTracker();\n const { trackFocusSelectedItem, trackFocusItemAtIndex, trackFocusPanel } = focusTracker;\n\n const [open, setOpen] = useState(false);\n const defaultTriggerRef = useRef<HTMLButtonElement>(null);\n const wasOpenedByKeyboardRef = useRef(false);\n\n // Stable refs for actionRef methods \u2014 closed over by the callback below so they are\n // always current without causing the ref callback to regenerate on every data change.\n const appsRef = useRef(apps);\n appsRef.current = apps;\n const customAppsRef = useRef(customApps);\n customAppsRef.current = customApps;\n\n const resolvedIsOpen = typeof isOpen === 'boolean' ? isOpen : open;\n\n const handleClose = useCallback(() => {\n setOpen(false);\n onClose?.();\n }, [onClose]);\n\n const handleClickOutside = useCallback(\n (e: MouseEvent | TouchEvent) => {\n setOpen(false);\n onClose?.();\n onClickOutside?.(e as MouseEvent);\n },\n [onClose, onClickOutside],\n );\n\n const {\n refs: floatingRefs,\n floatingStyles,\n arrowStyles,\n context: floatingContext,\n } = useFloatingContext({\n placement: 'bottom',\n // Arrow tip is ~6.1px above the panel top (arrowPlacementBase16 \u2248 17.5px, tip at 11.4px from box top).\n // 4px spec gap \u2192 4 + 6.1 \u2248 10px offset.\n customOffset: [0, 10],\n externallyControlledIsOpen: resolvedIsOpen,\n withoutAnimation: true,\n onClickOutside: handleClickOutside,\n });\n\n const handleTriggerRef = useCallback<React.RefCallback<HTMLButtonElement>>(\n (node) => {\n (defaultTriggerRef as React.MutableRefObject<HTMLButtonElement | null>).current = node;\n floatingRefs.setReference(node);\n if (triggerRef) {\n (triggerRef as React.MutableRefObject<HTMLButtonElement | null>).current = node;\n }\n },\n [floatingRefs, triggerRef],\n );\n\n // Ref callback on StyledAppPickerFloating: fires on mount with the panel node, populating\n // actionRef methods. All focus operations go through the tracker \u2014 no DOM queries.\n const handleActionRef = useCallback<React.RefCallback<HTMLDivElement>>(\n (node) => {\n if (node && actionRef?.current) {\n actionRef.current.focusToIndex = (index: number) => {\n trackFocusItemAtIndex(appsRef.current, customAppsRef.current, index);\n };\n actionRef.current.focusWrapper = () => {\n trackFocusPanel();\n };\n actionRef.current.focusSelectedOrFirstAvailable = () => {\n trackFocusSelectedItem(appsRef.current, customAppsRef.current);\n };\n }\n },\n [actionRef, trackFocusItemAtIndex, trackFocusPanel, trackFocusSelectedItem],\n );\n\n const floatingInnerRef = useCallback<React.RefCallback<HTMLDivElement>>(\n (node) => {\n (floatingRefs.setFloating as React.RefCallback<HTMLDivElement>)(node);\n handleActionRef(node);\n },\n [floatingRefs.setFloating, handleActionRef],\n );\n\n // When panel opens via keyboard, seed the focus tracker so the correct chip gets focus\n // via its innerRef callback. Non-keyboard paths are handled by AppPanel on mount.\n useEffect(() => {\n if (resolvedIsOpen && wasOpenedByKeyboardRef.current) {\n trackFocusSelectedItem(apps, customApps);\n }\n }, [resolvedIsOpen, trackFocusSelectedItem, apps, customApps]);\n\n const handleTriggerClick = useCallback(\n (e: React.MouseEvent | React.KeyboardEvent) => {\n wasOpenedByKeyboardRef.current = (e as React.MouseEvent).detail === 0;\n onClick?.(e);\n setOpen((prev) => !prev);\n },\n [onClick],\n );\n\n return {\n // For rendering\n Icon,\n renderTrigger,\n resolvedIsOpen,\n floatingStyles,\n arrowStyles,\n floatingContext,\n ownerPropsConfig,\n // Refs\n defaultTriggerRef,\n triggerRef,\n wasOpenedByKeyboardRef,\n // Handlers\n handleClose,\n handleTriggerRef,\n handleTriggerClick,\n floatingInnerRef,\n // Context value\n focusTracker,\n };\n};\n"],
5
- "mappings": "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",
6
- "names": []
7
- }